Updated Branches: refs/heads/master 2febc318a -> 917ea33ba
added LDAP group name label in add account wizard changed the parameter for domain in api importLdapUser from name to UUID improved error handling Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/917ea33b Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/917ea33b Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/917ea33b Branch: refs/heads/master Commit: 917ea33ba93325dabdac55df156159334285ab01 Parents: 2febc31 Author: Rajani Karuturi <rajanikarut...@gmail.com> Authored: Fri Nov 15 14:20:40 2013 +0530 Committer: Ian Duffy <i...@ianduffy.ie> Committed: Wed Nov 20 13:57:41 2013 +0100 ---------------------------------------------------------------------- .../classes/resources/messages.properties | 1 + .../api/command/LdapImportUsersCmd.java | 200 +++++++------ .../ldap/LdapImportUsersCmdSpec.groovy | 289 ++++++++++--------- ui/dictionary.jsp | 1 + ui/scripts/accountsWizard.js | 67 +++-- ui/scripts/docs.js | 4 + ui/scripts/ui-custom/accountsWizard.js | 106 ++++--- 7 files changed, 380 insertions(+), 288 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/917ea33b/client/WEB-INF/classes/resources/messages.properties ---------------------------------------------------------------------- diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties index 5885bd0..1303562 100644 --- a/client/WEB-INF/classes/resources/messages.properties +++ b/client/WEB-INF/classes/resources/messages.properties @@ -1250,6 +1250,7 @@ label.zoneWizard.trafficType.guest=Guest\: Traffic between end-user virtual mach label.zoneWizard.trafficType.management=Management\: Traffic between CloudStack\\\\'s internal resources, including any components that communicate with the Management Server, such as hosts and CloudStack system VMs label.zoneWizard.trafficType.public=Public\: Traffic between the internet and virtual machines in the cloud. label.zoneWizard.trafficType.storage=Storage\: Traffic between primary and secondary storage servers, such as VM templates and snapshots +label.ldap.group.name=LDAP Group managed.state=Managed State message.acquire.new.ip.vpc=Please confirm that you would like to acquire a new IP for this VPC. message.acquire.new.ip=Please confirm that you would like to acquire a new IP for this network. http://git-wip-us.apache.org/repos/asf/cloudstack/blob/917ea33b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapImportUsersCmd.java ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapImportUsersCmd.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapImportUsersCmd.java index 063db0e..1855d5d 100644 --- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapImportUsersCmd.java +++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapImportUsersCmd.java @@ -16,11 +16,17 @@ // under the License. package org.apache.cloudstack.api.command; -import com.cloud.domain.Domain; -import com.cloud.exception.*; -import com.cloud.user.AccountService; -import com.cloud.user.DomainService; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import javax.inject.Inject; + import org.apache.cloudstack.api.*; +import org.apache.cloudstack.api.response.DomainResponse; import org.apache.cloudstack.api.response.LdapUserResponse; import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.ldap.LdapManager; @@ -30,13 +36,10 @@ import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.bouncycastle.util.encoders.Base64; -import javax.inject.Inject; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.UUID; +import com.cloud.domain.Domain; +import com.cloud.exception.*; +import com.cloud.user.AccountService; +import com.cloud.user.DomainService; @APICommand(name = "importLdapUsers", description = "Import LDAP users", responseObject = LdapUserResponse.class, since = "4.3.0") public class LdapImportUsersCmd extends BaseListCmd { @@ -45,117 +48,136 @@ public class LdapImportUsersCmd extends BaseListCmd { private static final String s_name = "ldapuserresponse"; - @Parameter(name = ApiConstants.TIMEZONE, type = CommandType.STRING, - description = "Specifies a timezone for this command. For more information on the timezone parameter, see Time Zone Format.") + @Parameter(name = ApiConstants.TIMEZONE, type = CommandType.STRING, description = "Specifies a timezone for this command. For more information on the timezone parameter, see Time Zone Format.") private String timezone; - @Parameter(name = ApiConstants.ACCOUNT_TYPE, type = CommandType.SHORT, required = true, - description = "Type of the account. Specify 0 for user, 1 for root admin, and 2 for domain admin") + @Parameter(name = ApiConstants.ACCOUNT_TYPE, type = CommandType.SHORT, required = true, description = "Type of the account. Specify 0 for user, 1 for root admin, and 2 for domain admin") private Short accountType; @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.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, 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 Long domainId; - @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.") + @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; + private Domain _domain; + @Inject private LdapManager _ldapManager; public LdapImportUsersCmd() { - super(); + super(); } public LdapImportUsersCmd(final LdapManager ldapManager, final DomainService domainService, final AccountService accountService) { - super(); - _ldapManager = ldapManager; - _domainService = domainService; - _accountService = accountService; + super(); + _ldapManager = ldapManager; + _domainService = domainService; + _accountService = accountService; } @Override public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, - NetworkRuleConflictException { - List<LdapUserResponse> ldapResponses = null; - final ListResponse<LdapUserResponse> response = new ListResponse<LdapUserResponse>(); - try { - List<LdapUser> users; - if(StringUtils.isNotBlank(groupName)) { - users = _ldapManager.getUsersInGroup(groupName); - } else { - users = _ldapManager.getUsers(); - } - for (LdapUser user : users) { - 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); - } catch (final NoLdapUserMatchingQueryException ex) { - ldapResponses = new ArrayList<LdapUserResponse>(); - } finally { - response.setResponses(ldapResponses); - response.setResponseName(getCommandName()); - setResponseObject(response); - } + NetworkRuleConflictException { + + List<LdapUser> users; + try { + if (StringUtils.isNotBlank(groupName)) { + users = _ldapManager.getUsersInGroup(groupName); + } else { + users = _ldapManager.getUsers(); + } + } catch (NoLdapUserMatchingQueryException ex) { + users = new ArrayList<LdapUser>(); + s_logger.info("No Ldap user matching query. "+" ::: "+ex.getMessage()); + } + + List<LdapUser> addedUsers = new ArrayList<LdapUser>(); + for (LdapUser user : users) { + Domain domain = getDomain(user); + try { + _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()); + addedUsers.add(user); + } catch (InvalidParameterValueException ex) { + s_logger.error("Failed to create user with username: " + user.getUsername() +" ::: "+ex.getMessage()); + } + } + ListResponse<LdapUserResponse> response = new ListResponse<LdapUserResponse>(); + response.setResponses(createLdapUserResponse(addedUsers)); + response.setResponseName(getCommandName()); + setResponseObject(response); + } + + private Domain getDomainForName(String name) { + Domain domain = null; + if (StringUtils.isNotBlank(name)) { + //removing all the special characters and trimming its length to 190 to make the domain valid. + String domainName = StringUtils.substring(name.replaceAll("\\W", ""), 0, 190); + if (StringUtils.isNotBlank(domainName)) { + domain = _domainService.getDomainByName(domainName, Domain.ROOT_DOMAIN); + if (domain == null) { + domain = _domainService.createDomain(domainName, Domain.ROOT_DOMAIN, domainName, UUID.randomUUID().toString()); + } + } + } + return domain; } 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; + Domain domain; + if (_domain != null) { + //this means either domain id or groupname is passed and this will be same for all the users in this call. hence returning it. + domain = _domain; + } else { + if (domainId != null) { + // a domain Id is passed. use it for this user and all the users in the same api call (by setting _domain) + domain = _domain = _domainService.getDomain(domainId); + } else { + // a group name is passed. use it for this user and all the users in the same api call(by setting _domain) + domain = _domain = getDomainForName(groupName); + if (domain == null) { + //use the domain from the LDAP for this user + domain = getDomainForName(user.getDomain()); + } + } + if (domain == null) { + // could not get a domain using domainId / LDAP group / OU of LDAP user. using ROOT domain for this user + 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) { - final LdapUserResponse ldapResponse = _ldapManager.createLdapUserResponse(user); - ldapResponse.setObjectName("LdapUser"); - ldapResponses.add(ldapResponse); - } - return ldapResponses; + final List<LdapUserResponse> ldapResponses = new ArrayList<LdapUserResponse>(); + for (final LdapUser user : users) { + final LdapUserResponse ldapResponse = _ldapManager.createLdapUserResponse(user); + ldapResponse.setObjectName("LdapUser"); + ldapResponses.add(ldapResponse); + } + return ldapResponses; } @Override public String getCommandName() { - return s_name; + return s_name; } private String generatePassword() throws ServerApiException { - try { - final SecureRandom randomGen = SecureRandom.getInstance("SHA1PRNG"); - final byte bytes[] = new byte[20]; - randomGen.nextBytes(bytes); - return Base64.encode(bytes).toString(); - } catch (final NoSuchAlgorithmException e) { - throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to generate random password"); - } + try { + final SecureRandom randomGen = SecureRandom.getInstance("SHA1PRNG"); + final byte bytes[] = new byte[20]; + randomGen.nextBytes(bytes); + return Base64.encode(bytes).toString(); + } catch (final NoSuchAlgorithmException e) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to generate random password"); + } } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/917ea33b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapImportUsersCmdSpec.groovy ---------------------------------------------------------------------- diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapImportUsersCmdSpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapImportUsersCmdSpec.groovy index 0455640..a66da1f 100644 --- a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapImportUsersCmdSpec.groovy +++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapImportUsersCmdSpec.groovy @@ -20,8 +20,6 @@ import com.cloud.domain.Domain import com.cloud.domain.DomainVO import com.cloud.user.AccountService import com.cloud.user.DomainService -import com.cloud.user.UserAccount -import com.cloud.user.UserAccountVO import org.apache.cloudstack.api.command.LdapImportUsersCmd import org.apache.cloudstack.api.response.LdapUserResponse import org.apache.cloudstack.ldap.LdapManager @@ -31,160 +29,167 @@ class LdapImportUsersCmdSpec extends spock.lang.Specification { def "Test successful return of getCommandName"() { - given: "We have an LdapManager, DomainService and a LdapImportUsersCmd" - def ldapManager = Mock(LdapManager) - def domainService = Mock(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" - commandName == "ldapuserresponse" + given: "We have an LdapManager, DomainService and a LdapImportUsersCmd" + def ldapManager = Mock(LdapManager) + def domainService = Mock(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" + commandName == "ldapuserresponse" } def "Test successful response from execute"() { - 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", "rmur...@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering")) - users.add(new LdapUser("bob", "b...@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering")) - ldapManager.getUsers() >> users - LdapUserResponse response1 = new LdapUserResponse("rmurphy", "rmur...@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering") - LdapUserResponse response2 = new LdapUserResponse("bob", "b...@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering") - ldapManager.createLdapUserResponse(_) >>>[response1, response2] - - - Domain domain = new DomainVO("engineering", 1L, 1L, "engineering", UUID.randomUUID().toString()) - domainService.getDomainByName("engineering", 1L) >>> [null, domain] - 1 * domainService.createDomain("engineering", 1L, "engineering", _) >> domain - - def ldapImportUsersCmd = new LdapImportUsersCmd(ldapManager, domainService, accountService) - ldapImportUsersCmd.accountType = 2; - - when: "LdapListUsersCmd is executed" - ldapImportUsersCmd.execute() - then: "a list of size 2 is returned" - ldapImportUsersCmd.responseObject.getResponses().size() == 2 + 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", "rmur...@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering")) + users.add(new LdapUser("bob", "b...@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering")) + ldapManager.getUsers() >> users + LdapUserResponse response1 = new LdapUserResponse("rmurphy", "rmur...@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering") + LdapUserResponse response2 = new LdapUserResponse("bob", "b...@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering") + ldapManager.createLdapUserResponse(_) >>> [response1, response2] + + + Domain domain = new DomainVO("engineering", 1L, 1L, "engineering", UUID.randomUUID().toString()) + 2 * domainService.getDomainByName("engineering", 1L) >>> [null, domain] + 1 * domainService.createDomain("engineering", 1L, "engineering", _) >> domain + + def ldapImportUsersCmd = new LdapImportUsersCmd(ldapManager, domainService, accountService) + ldapImportUsersCmd.accountType = 2; + + 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 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", "rmur...@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering")) - users.add(new LdapUser("bob", "b...@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering")) - ldapManager.getUsersInGroup("TestGroup") >> users - LdapUserResponse response1 = new LdapUserResponse("rmurphy", "rmur...@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering") - LdapUserResponse response2 = new LdapUserResponse("bob", "b...@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 + 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", "rmur...@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering")) + users.add(new LdapUser("bob", "b...@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering")) + ldapManager.getUsersInGroup("TestGroup") >> users + LdapUserResponse response1 = new LdapUserResponse("rmurphy", "rmur...@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering") + LdapUserResponse response2 = new LdapUserResponse("bob", "b...@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()) + 1 * domainService.getDomainByName("TestGroup", 1L) >>> null + 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", "rmur...@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering")) - users.add(new LdapUser("bob", "b...@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering")) - ldapManager.getUsersInGroup("TestGroup") >> users - LdapUserResponse response1 = new LdapUserResponse("rmurphy", "rmur...@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering") - LdapUserResponse response2 = new LdapUserResponse("bob", "b...@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 + 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", "rmur...@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering")) + users.add(new LdapUser("bob", "b...@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering")) + ldapManager.getUsersInGroup("TestGroup") >> users + LdapUserResponse response1 = new LdapUserResponse("rmurphy", "rmur...@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering") + LdapUserResponse response2 = new LdapUserResponse("bob", "b...@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()) + 1 * domainService.getDomain(1L) >> domain; + + def ldapImportUsersCmd = new LdapImportUsersCmd(ldapManager, domainService, accountService) + ldapImportUsersCmd.accountType = 2; + ldapImportUsersCmd.groupName = "TestGroup"; + ldapImportUsersCmd.domainId = 1L; + + 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", "rmur...@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering")) - users.add(new LdapUser("bob", "b...@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering")) - ldapManager.getUsers() >> users - LdapUserResponse response1 = new LdapUserResponse("rmurphy", "rmur...@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering") - LdapUserResponse response2 = new LdapUserResponse("bob", "b...@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 + 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", "rmur...@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering")) + users.add(new LdapUser("bob", "b...@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering")) + ldapManager.getUsers() >> users + LdapUserResponse response1 = new LdapUserResponse("rmurphy", "rmur...@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering") + LdapUserResponse response2 = new LdapUserResponse("bob", "b...@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()) + 1 * domainService.getDomain(1L) >> domain; + + def ldapImportUsersCmd = new LdapImportUsersCmd(ldapManager, domainService, accountService) + ldapImportUsersCmd.accountType = 2; + ldapImportUsersCmd.domainId = 1L; + + 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", "rmur...@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering") - def ldapUser2 = new LdapUser("bob", "b...@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" + def "Test getDomain"() { + 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.domainId = varDomainId + ldapImportUsersCmd.groupName = varGroupName + + def ldapUser1 = new LdapUser("rmurphy", "rmur...@test.com", "Ryan", "Murphy", "cn=rmurphy,ou=engineering,dc=cloudstack,dc=org", "engineering") + def ldapUser2 = new LdapUser("bob", "b...@test.com", "Robert", "Young", "cn=bob,ou=engineering,dc=cloudstack,dc=org", "engineering"); + + Domain domain = new DomainVO(expectedDomainName, 1L, 1L, expectedDomainName, UUID.randomUUID().toString()); + if (varDomainId != null) { + 1 * domainService.getDomain(varDomainId) >> domain; + } else { + if(varGroupName != null) { + 1 * domainService.getDomainByName(expectedDomainName, 1L) >> null + } else { + 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" + varDomainId | varGroupName | expectedDomainName + null | null | "engineering" + 1L | null | "TestDomain" + 1L | "TestGroup" | "TestDomain" + null | "TestGroup" | "TestGroup" + null | "Test Group" | "TestGroup" } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/917ea33b/ui/dictionary.jsp ---------------------------------------------------------------------- diff --git a/ui/dictionary.jsp b/ui/dictionary.jsp index 0ccfc23..f069588 100644 --- a/ui/dictionary.jsp +++ b/ui/dictionary.jsp @@ -1219,6 +1219,7 @@ dictionary = { 'label.zone.step.3.title': '<fmt:message key="label.zone.step.3.title" />', 'label.zone.step.4.title': '<fmt:message key="label.zone.step.4.title" />', 'label.zone.wide': '<fmt:message key="label.zone.wide" />', +'label.ldap.group.name': '<fmt:message key="label.ldap.group.name" />', 'managed.state': '<fmt:message key="managed.state" />', 'message.acquire.new.ip': '<fmt:message key="message.acquire.new.ip" />', 'message.acquire.new.ip.vpc': '<fmt:message key="message.acquire.new.ip.vpc" />', http://git-wip-us.apache.org/repos/asf/cloudstack/blob/917ea33b/ui/scripts/accountsWizard.js ---------------------------------------------------------------------- diff --git a/ui/scripts/accountsWizard.js b/ui/scripts/accountsWizard.js index 70ef082..e41f8c4 100644 --- a/ui/scripts/accountsWizard.js +++ b/ui/scripts/accountsWizard.js @@ -161,14 +161,23 @@ validation: { required: false } + }, + ldapGroupName: { + label: 'label.ldap.group.name', + docID: 'helpLdapGroupName', + validation: { + required: false + } } + }, action: function(args) { var array1 = []; var ldapStatus = isLdapEnabled(); - console.log("creating user: " + args.username); - array1.push("&username=" + args.username); + if (args.username) { + array1.push("&username=" + args.username); + } if (!ldapStatus) { var password = args.data.password; @@ -179,7 +188,7 @@ array1.push("&firstname=" + args.data.firstname); array1.push("&lastname=" + args.data.lastname); - var password = args.data.password; + password = args.data.password; if (md5Hashed) { password = $.md5(password); } @@ -207,25 +216,43 @@ if (args.data.networkdomain !== null && args.data.networkdomain.length > 0) { array1.push("&networkdomain=" + args.data.networkdomain); } + if (args.groupname && args.groupname !== null && args.groupname.length > 0) { + array1.push("&group=" + args.groupname); + } if (ldapStatus) { - console.log("doing an ldap add"); - $.ajax({ - url: createURL('ldapCreateAccount' + array1.join("")), - dataType: "json", - async: false, - success: function(json) { - var item = json.createaccountresponse.account; - args.response.success({ - data: item - }); - }, - error: function(XMLHttpResponse) { - args.response.error(parseXMLHttpResponse(XMLHttpResponse)); - } - }); + if (args.groupname) { + $.ajax({ + url: createURL('importLdapUsers' + array1.join("")), + dataType: "json", + async: false, + success: function(json) { + var count = json.ldapuserresponse.count; + args.response.success({ + data: count + }); + }, + error: function(XMLHttpResponse) { + args.response.error(parseXMLHttpResponse(XMLHttpResponse)); + } + }); + } else if (args.username) { + $.ajax({ + url: createURL('ldapCreateAccount' + array1.join("")), + dataType: "json", + async: false, + success: function(json) { + var item = json.createaccountresponse.account; + args.response.success({ + data: item + }); + }, + error: function(XMLHttpResponse) { + args.response.error(parseXMLHttpResponse(XMLHttpResponse)); + } + }); + } } else { - console.log("doing normal user add"); $.ajax({ url: createURL('createAccount' + array1.join("")), dataType: "json", @@ -285,4 +312,4 @@ } */ }; -}(cloudStack, jQuery)); +}(cloudStack, jQuery)); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/917ea33b/ui/scripts/docs.js ---------------------------------------------------------------------- diff --git a/ui/scripts/docs.js b/ui/scripts/docs.js index 562ac25..8e7ea75 100755 --- a/ui/scripts/docs.js +++ b/ui/scripts/docs.js @@ -1196,5 +1196,9 @@ cloudStack.docs = { helpUploadVolumeChecksum: { desc: 'Use the hash that you created at the start of the volume upload procedure', externalLink: '' + }, + helpLdapGroupName: { + desc: 'The group name from which you want to import LDAP users', + externalLink: '' } }; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/917ea33b/ui/scripts/ui-custom/accountsWizard.js ---------------------------------------------------------------------- diff --git a/ui/scripts/ui-custom/accountsWizard.js b/ui/scripts/ui-custom/accountsWizard.js index 358e29c..f341711 100644 --- a/ui/scripts/ui-custom/accountsWizard.js +++ b/ui/scripts/ui-custom/accountsWizard.js @@ -33,16 +33,47 @@ var completeAction = function() { var data = cloudStack.serializeForm($form); - var username = data.username; - var bulkAdd = (username instanceof Array); - if (bulkAdd) { - console.log("doing bulk add"); - for (var i = 0; i < username.length; i++) { - console.log("creating user " + username[i]); + var groupname = $.trim(data.ldapGroupName); + if (groupname) { + args.action({ + context: context, + data: data, + groupname: groupname, + response: { + error: function(message) { + if (message) { + cloudStack.dialog.notice({ + message: message + }); + } + } + } + }); + } else { + var username = data.username; + var bulkAdd = (username instanceof Array); + if (bulkAdd) { + for (var i = 0; i < username.length; i++) { + args.action({ + context: context, + data: data, + username: username[i], + response: { + error: function(message) { + if (message) { + cloudStack.dialog.notice({ + message: message + }); + } + } + } + }); + } + } else { args.action({ context: context, data: data, - username: username[i], + username: username, response: { error: function(message) { if (message) { @@ -54,21 +85,6 @@ } }); } - } else { - args.action({ - context: context, - data: data, - username: username, - response: { - error: function(message) { - if (message) { - cloudStack.dialog.notice({ - message: message - }); - } - } - } - }); } }; @@ -92,25 +108,38 @@ if (ldapStatus) { var $table = $wizard.find('.ldap-account-choice tbody'); + $("#label_ldap_group_name").live("keypress", function(event) { + if ($table.find("#tr-groupname-message").length === 0) { + $("<tr id='tr-groupname-message'>").appendTo($table).append("<td colspan=\"4\">All The users from the given group name will be imported</td>"); + } + $table.find("tr").hide(); + $table.find("#tr-groupname-message").show(); + }); + $("#label_ldap_group_name").live("blur", function(event) { + if (!$(this).val()) { + $table.find("tr").show(); + $table.find("#tr-groupname-message").hide(); + } + }); $.ajax({ - url: createURL("listLdapUsers&listtype=new"), + url: createURL("listLdapUsers&listtype=new"), dataType: "json", async: false, success: function(json) { - if (json.ldapuserresponse.count > 0) { - $(json.ldapuserresponse.LdapUser).each(function() { - var result = $("<tr>"); - result.append("<td><input type=\"checkbox\" class=\"required\" name=\"username\" value=\"" + this.username + "\"></td>"); - result.append("<td>" + this.firstname + " " + this.lastname + "</td>"); - result.append("<td>" + this.username + "</td>"); - result.append("<td>" + this.email + "</td>"); - $table.append(result); - }); - } else { + if (json.ldapuserresponse.count > 0) { + $(json.ldapuserresponse.LdapUser).each(function() { + var result = $("<tr>"); + result.append("<td><input type=\"checkbox\" name=\"username\" value=\"" + this.username + "\"></td>"); + result.append("<td>" + this.firstname + " " + this.lastname + "</td>"); + result.append("<td>" + this.username + "</td>"); + result.append("<td>" + this.email + "</td>"); + $table.append(result); + }); + } else { var result = $("<tr>"); - result.append("<td colspan=\"4\">No data to show</td>"); + result.append("<td colspan=\"4\">No data to show</td>"); $table.append(result); - } + } } }); } else { @@ -123,7 +152,6 @@ } }); - //console.log(informationWithinLdap.$formContainer); var informationWithinLdapForm = informationWithinLdap.$formContainer.find('form .form-item'); informationWithinLdapForm.find('.value #label_username').addClass('required'); informationWithinLdapForm.find('.value #password').addClass('required'); @@ -137,6 +165,10 @@ $wizard.removeClass('multi-wizard'); } + if (!ldapStatus) { + delete args.informationNotInLdap.ldapGroupName; + } + var informationNotInLdap = cloudStack.dialog.createForm({ context: context, noDialog: true, @@ -166,4 +198,4 @@ accountsWizard(args); }; }; -})(jQuery, cloudStack); +})(jQuery, cloudStack); \ No newline at end of file