Skip to content

Commit 917ea33

Browse files
karuturiimduffy15
authored andcommitted
added LDAP group name label in add account wizard
changed the parameter for domain in api importLdapUser from name to UUID improved error handling
1 parent 2febc31 commit 917ea33

7 files changed

Lines changed: 380 additions & 288 deletions

File tree

client/WEB-INF/classes/resources/messages.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,6 +1250,7 @@ label.zoneWizard.trafficType.guest=Guest\: Traffic between end-user virtual mach
12501250
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
12511251
label.zoneWizard.trafficType.public=Public\: Traffic between the internet and virtual machines in the cloud.
12521252
label.zoneWizard.trafficType.storage=Storage\: Traffic between primary and secondary storage servers, such as VM templates and snapshots
1253+
label.ldap.group.name=LDAP Group
12531254
managed.state=Managed State
12541255
message.acquire.new.ip.vpc=Please confirm that you would like to acquire a new IP for this VPC.
12551256
message.acquire.new.ip=Please confirm that you would like to acquire a new IP for this network.

plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapImportUsersCmd.java

Lines changed: 111 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,17 @@
1616
// under the License.
1717
package org.apache.cloudstack.api.command;
1818

19-
import com.cloud.domain.Domain;
20-
import com.cloud.exception.*;
21-
import com.cloud.user.AccountService;
22-
import com.cloud.user.DomainService;
19+
import java.security.NoSuchAlgorithmException;
20+
import java.security.SecureRandom;
21+
import java.util.ArrayList;
22+
import java.util.List;
23+
import java.util.Map;
24+
import java.util.UUID;
25+
26+
import javax.inject.Inject;
27+
2328
import org.apache.cloudstack.api.*;
29+
import org.apache.cloudstack.api.response.DomainResponse;
2430
import org.apache.cloudstack.api.response.LdapUserResponse;
2531
import org.apache.cloudstack.api.response.ListResponse;
2632
import org.apache.cloudstack.ldap.LdapManager;
@@ -30,13 +36,10 @@
3036
import org.apache.log4j.Logger;
3137
import org.bouncycastle.util.encoders.Base64;
3238

33-
import javax.inject.Inject;
34-
import java.security.NoSuchAlgorithmException;
35-
import java.security.SecureRandom;
36-
import java.util.ArrayList;
37-
import java.util.List;
38-
import java.util.Map;
39-
import java.util.UUID;
39+
import com.cloud.domain.Domain;
40+
import com.cloud.exception.*;
41+
import com.cloud.user.AccountService;
42+
import com.cloud.user.DomainService;
4043

4144
@APICommand(name = "importLdapUsers", description = "Import LDAP users", responseObject = LdapUserResponse.class, since = "4.3.0")
4245
public class LdapImportUsersCmd extends BaseListCmd {
@@ -45,117 +48,136 @@ public class LdapImportUsersCmd extends BaseListCmd {
4548

4649
private static final String s_name = "ldapuserresponse";
4750

48-
@Parameter(name = ApiConstants.TIMEZONE, type = CommandType.STRING,
49-
description = "Specifies a timezone for this command. For more information on the timezone parameter, see Time Zone Format.")
51+
@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.")
5052
private String timezone;
5153

52-
@Parameter(name = ApiConstants.ACCOUNT_TYPE, type = CommandType.SHORT, required = true,
53-
description = "Type of the account. Specify 0 for user, 1 for root admin, and 2 for domain admin")
54+
@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")
5455
private Short accountType;
5556

5657
@Parameter(name = ApiConstants.ACCOUNT_DETAILS, type = CommandType.MAP, description = "details for account used to store specific parameters")
5758
private Map<String, String> details;
5859

59-
@Parameter(name = ApiConstants.DOMAIN, type = CommandType.STRING,
60-
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 " +
61-
"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")
62-
private String domainName;
60+
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "Specifies the domain to which the ldap users are to be "
61+
+ "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 "
62+
+ "created. If no OU hierarchy exists, will be defaulted to ROOT domain")
63+
private Long domainId;
6364

64-
@Parameter(name = ApiConstants.GROUP, type = CommandType.STRING,
65-
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.")
65+
@Parameter(name = ApiConstants.GROUP, type = CommandType.STRING, description = "Specifies the group name from which the ldap users are to be imported. "
66+
+ "If no group is specified, all the users will be imported.")
6667
private String groupName;
6768

69+
private Domain _domain;
70+
6871
@Inject
6972
private LdapManager _ldapManager;
7073

7174
public LdapImportUsersCmd() {
72-
super();
75+
super();
7376
}
7477

7578
public LdapImportUsersCmd(final LdapManager ldapManager, final DomainService domainService, final AccountService accountService) {
76-
super();
77-
_ldapManager = ldapManager;
78-
_domainService = domainService;
79-
_accountService = accountService;
79+
super();
80+
_ldapManager = ldapManager;
81+
_domainService = domainService;
82+
_accountService = accountService;
8083
}
8184

8285
@Override
8386
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException,
84-
NetworkRuleConflictException {
85-
List<LdapUserResponse> ldapResponses = null;
86-
final ListResponse<LdapUserResponse> response = new ListResponse<LdapUserResponse>();
87-
try {
88-
List<LdapUser> users;
89-
if(StringUtils.isNotBlank(groupName)) {
90-
users = _ldapManager.getUsersInGroup(groupName);
91-
} else {
92-
users = _ldapManager.getUsers();
93-
}
94-
for (LdapUser user : users) {
95-
Domain domain = getDomain(user);
96-
_accountService.createUserAccount(user.getUsername(), generatePassword(), user.getFirstname(), user.getLastname(), user.getEmail(), timezone, user.getUsername(),
97-
accountType, domain.getId(), domain.getNetworkDomain(), details, UUID.randomUUID().toString(), UUID.randomUUID().toString());
98-
}
99-
ldapResponses = createLdapUserResponse(users);
100-
} catch (final NoLdapUserMatchingQueryException ex) {
101-
ldapResponses = new ArrayList<LdapUserResponse>();
102-
} finally {
103-
response.setResponses(ldapResponses);
104-
response.setResponseName(getCommandName());
105-
setResponseObject(response);
106-
}
87+
NetworkRuleConflictException {
88+
89+
List<LdapUser> users;
90+
try {
91+
if (StringUtils.isNotBlank(groupName)) {
92+
users = _ldapManager.getUsersInGroup(groupName);
93+
} else {
94+
users = _ldapManager.getUsers();
95+
}
96+
} catch (NoLdapUserMatchingQueryException ex) {
97+
users = new ArrayList<LdapUser>();
98+
s_logger.info("No Ldap user matching query. "+" ::: "+ex.getMessage());
99+
}
100+
101+
List<LdapUser> addedUsers = new ArrayList<LdapUser>();
102+
for (LdapUser user : users) {
103+
Domain domain = getDomain(user);
104+
try {
105+
_accountService.createUserAccount(user.getUsername(), generatePassword(), user.getFirstname(), user.getLastname(), user.getEmail(), timezone, user.getUsername(),
106+
accountType, domain.getId(), domain.getNetworkDomain(), details, UUID.randomUUID().toString(), UUID.randomUUID().toString());
107+
addedUsers.add(user);
108+
} catch (InvalidParameterValueException ex) {
109+
s_logger.error("Failed to create user with username: " + user.getUsername() +" ::: "+ex.getMessage());
110+
}
111+
}
112+
ListResponse<LdapUserResponse> response = new ListResponse<LdapUserResponse>();
113+
response.setResponses(createLdapUserResponse(addedUsers));
114+
response.setResponseName(getCommandName());
115+
setResponseObject(response);
116+
}
117+
118+
private Domain getDomainForName(String name) {
119+
Domain domain = null;
120+
if (StringUtils.isNotBlank(name)) {
121+
//removing all the special characters and trimming its length to 190 to make the domain valid.
122+
String domainName = StringUtils.substring(name.replaceAll("\\W", ""), 0, 190);
123+
if (StringUtils.isNotBlank(domainName)) {
124+
domain = _domainService.getDomainByName(domainName, Domain.ROOT_DOMAIN);
125+
if (domain == null) {
126+
domain = _domainService.createDomain(domainName, Domain.ROOT_DOMAIN, domainName, UUID.randomUUID().toString());
127+
}
128+
}
129+
}
130+
return domain;
107131
}
108132

109133
private Domain getDomain(LdapUser user) {
110-
String csDomainName = null;
111-
if (StringUtils.isNotBlank(domainName)) {
112-
csDomainName = domainName;
113-
} else {
114-
if (StringUtils.isNotBlank(groupName)) {
115-
csDomainName = groupName;
116-
} else if (StringUtils.isNotBlank(user.getDomain())) {
117-
csDomainName = user.getDomain();
118-
}
119-
//removing all the special characters and trimming it length 190 to make the domain valid.
120-
csDomainName = StringUtils.substring(csDomainName.replaceAll("\\W",""),0,190);
121-
}
122-
Domain domain;
123-
if (StringUtils.isNotBlank(csDomainName)) {
124-
domain = _domainService.getDomainByName(csDomainName, Domain.ROOT_DOMAIN);
125-
126-
if (domain == null) {
127-
domain = _domainService.createDomain(csDomainName, Domain.ROOT_DOMAIN, csDomainName, UUID.randomUUID().toString());
128-
}
129-
} else {
130-
domain = _domainService.getDomain(Domain.ROOT_DOMAIN);
131-
}
132-
133-
return domain;
134+
Domain domain;
135+
if (_domain != null) {
136+
//this means either domain id or groupname is passed and this will be same for all the users in this call. hence returning it.
137+
domain = _domain;
138+
} else {
139+
if (domainId != null) {
140+
// a domain Id is passed. use it for this user and all the users in the same api call (by setting _domain)
141+
domain = _domain = _domainService.getDomain(domainId);
142+
} else {
143+
// a group name is passed. use it for this user and all the users in the same api call(by setting _domain)
144+
domain = _domain = getDomainForName(groupName);
145+
if (domain == null) {
146+
//use the domain from the LDAP for this user
147+
domain = getDomainForName(user.getDomain());
148+
}
149+
}
150+
if (domain == null) {
151+
// could not get a domain using domainId / LDAP group / OU of LDAP user. using ROOT domain for this user
152+
domain = _domainService.getDomain(Domain.ROOT_DOMAIN);
153+
}
154+
}
155+
return domain;
134156
}
135157

136158
private List<LdapUserResponse> createLdapUserResponse(List<LdapUser> users) {
137-
final List<LdapUserResponse> ldapResponses = new ArrayList<LdapUserResponse>();
138-
for (final LdapUser user : users) {
139-
final LdapUserResponse ldapResponse = _ldapManager.createLdapUserResponse(user);
140-
ldapResponse.setObjectName("LdapUser");
141-
ldapResponses.add(ldapResponse);
142-
}
143-
return ldapResponses;
159+
final List<LdapUserResponse> ldapResponses = new ArrayList<LdapUserResponse>();
160+
for (final LdapUser user : users) {
161+
final LdapUserResponse ldapResponse = _ldapManager.createLdapUserResponse(user);
162+
ldapResponse.setObjectName("LdapUser");
163+
ldapResponses.add(ldapResponse);
164+
}
165+
return ldapResponses;
144166
}
145167

146168
@Override
147169
public String getCommandName() {
148-
return s_name;
170+
return s_name;
149171
}
150172

151173
private String generatePassword() throws ServerApiException {
152-
try {
153-
final SecureRandom randomGen = SecureRandom.getInstance("SHA1PRNG");
154-
final byte bytes[] = new byte[20];
155-
randomGen.nextBytes(bytes);
156-
return Base64.encode(bytes).toString();
157-
} catch (final NoSuchAlgorithmException e) {
158-
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to generate random password");
159-
}
174+
try {
175+
final SecureRandom randomGen = SecureRandom.getInstance("SHA1PRNG");
176+
final byte bytes[] = new byte[20];
177+
randomGen.nextBytes(bytes);
178+
return Base64.encode(bytes).toString();
179+
} catch (final NoSuchAlgorithmException e) {
180+
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to generate random password");
181+
}
160182
}
161183
}

0 commit comments

Comments
 (0)