Fixed CLOUDSTACK-6509 Cannot import multiple LDAP/AD users into a cloudstack account

Signed-off-by: Koushik Das <koushik@apache.org>
This commit is contained in:
Rajani Karuturi 2014-04-25 16:42:39 +05:30 committed by Koushik Das
parent c37df38c83
commit 9303e7016b
8 changed files with 149 additions and 14 deletions

View File

@ -102,4 +102,12 @@ public interface AccountService {
void checkAccess(Account account, AccessType accessType, boolean sameOwner, ControlledEntity... entities) throws PermissionDeniedException;
/**
* returns the user account object for a given user id
* @param userId user id
* @return useraccount object if it exists else null
*/
UserAccount getUserAccountById(Long userId);
}

View File

@ -106,6 +106,12 @@ public class MockAccountManager extends ManagerBase implements AccountManager {
}
@Override
public UserAccount getUserAccountById(Long userId) {
// TODO Auto-generated method stub
return null;
}
@Override
public String[] createApiKeyAndSecretKey(RegisterCmd arg0) {
// TODO Auto-generated method stub

View File

@ -23,6 +23,8 @@ import java.util.Map;
import javax.inject.Inject;
import javax.naming.NamingException;
import com.cloud.domain.DomainVO;
import com.cloud.user.User;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
@ -88,22 +90,46 @@ public class LdapCreateAccountCmd extends BaseCmd {
_accountService = accountService;
}
UserAccount createCloudstackUserAccount(final LdapUser user) {
return _accountService.createUserAccount(username, generatePassword(),
user.getFirstname(), user.getLastname(), user.getEmail(),
timezone, accountName, accountType, domainId, networkDomain,
details, accountUUID, userUUID);
}
UserAccount createCloudstackUserAccount(final LdapUser user, String accountName, Long domainId ) {
Account account = _accountService.getActiveAccountByName(accountName, domainId);
if (account == null) {
return _accountService.createUserAccount(username, generatePassword(), user.getFirstname(), user.getLastname(), user.getEmail(), timezone, accountName,
accountType, domainId, networkDomain, details, accountUUID, userUUID);
} else {
User newUser = _accountService.createUser(username, generatePassword(), user.getFirstname(), user.getLastname(), user.getEmail(), timezone, accountName,
domainId, userUUID);
return _accountService.getUserAccountById(newUser.getId());
}
}
private String getAccountName() {
String name = accountName;
if (accountName == null) {
name = username;
}
return name;
}
private Long getDomainId() {
Long id = domainId;
if (id == null) {
id = DomainVO.ROOT_DOMAIN;
}
return id;
}
@Override
public void execute() throws ServerApiException {
final CallContext callContext = getCurrentContext();
callContext.setEventDetails("Account Name: " + accountName
+ ", Domain Id:" + domainId);
String finalAccountName = getAccountName();
Long finalDomainId = getDomainId();
callContext.setEventDetails("Account Name: " + finalAccountName
+ ", Domain Id:" + finalDomainId);
try {
final LdapUser user = _ldapManager.getUser(username);
validateUser(user);
final UserAccount userAccount = createCloudstackUserAccount(user);
final UserAccount userAccount = createCloudstackUserAccount(user, finalAccountName, finalDomainId);
if (userAccount != null) {
final AccountResponse response = _responseGenerator
.createUserAccountResponse(userAccount);

View File

@ -25,6 +25,9 @@ import java.util.UUID;
import javax.inject.Inject;
import com.cloud.user.Account;
import com.cloud.user.User;
import com.cloud.user.UserAccount;
import org.apache.cloudstack.api.*;
import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.LdapUserResponse;
@ -68,6 +71,9 @@ public class LdapImportUsersCmd extends BaseListCmd {
private Domain _domain;
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "Creates the user under the specified account. If no account is specified, the username will be used as the account name.")
private String accountName;
@Inject
private LdapManager _ldapManager;
@ -82,6 +88,17 @@ public class LdapImportUsersCmd extends BaseListCmd {
_accountService = accountService;
}
private void createCloudstackUserAccount(LdapUser user, String accountName, Domain domain) {
Account account = _accountService.getActiveAccountByName(accountName, domain.getId());
if (account == null) {
_accountService.createUserAccount(user.getUsername(), generatePassword(), user.getFirstname(), user.getLastname(), user.getEmail(), timezone, accountName, accountType,
domain.getId(), domain.getNetworkDomain(), details, UUID.randomUUID().toString(), UUID.randomUUID().toString());
} else {
_accountService.createUser(user.getUsername(), generatePassword(), user.getFirstname(), user.getLastname(), user.getEmail(), timezone, accountName, domain.getId(),
UUID.randomUUID().toString());
}
}
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException,
NetworkRuleConflictException {
@ -102,8 +119,7 @@ public class LdapImportUsersCmd extends BaseListCmd {
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());
createCloudstackUserAccount(user, getAccountName(user), domain);
addedUsers.add(user);
} catch (InvalidParameterValueException ex) {
s_logger.error("Failed to create user with username: " + user.getUsername() +" ::: "+ex.getMessage());
@ -115,6 +131,14 @@ public class LdapImportUsersCmd extends BaseListCmd {
setResponseObject(response);
}
private String getAccountName(LdapUser user) {
String finalAccountName = accountName;
if(finalAccountName == null ) {
finalAccountName = user.getUsername();
}
return finalAccountName;
}
private Domain getDomainForName(String name) {
Domain domain = null;
if (StringUtils.isNotBlank(name)) {

View File

@ -19,9 +19,14 @@ package groovy.org.apache.cloudstack.ldap
import com.cloud.domain.Domain
import com.cloud.domain.DomainVO
import com.cloud.user.AccountService
import com.cloud.user.AccountVO
import com.cloud.user.DomainService
import com.cloud.user.UserAccountVO
import com.cloud.user.UserVO
import org.apache.cloudstack.api.command.LdapCreateAccountCmd
import org.apache.cloudstack.api.command.LdapImportUsersCmd
import org.apache.cloudstack.api.response.LdapUserResponse
import org.apache.cloudstack.context.CallContext
import org.apache.cloudstack.ldap.LdapManager
import org.apache.cloudstack.ldap.LdapUser
@ -193,4 +198,59 @@ class LdapImportUsersCmdSpec extends spock.lang.Specification {
}
def "Test create ldap import account for an already existing cloudstack account"() {
given: "We have an LdapManager, DomainService, two users and a LdapImportUsersCmd"
def ldapManager = Mock(LdapManager)
List<LdapUser> users = new ArrayList()
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,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")
ldapManager.createLdapUserResponse(_) >>> response1
def domainService = Mock(DomainService)
1 * domainService.getDomain(1L) >> new DomainVO("DOMAIN", 1L, 1L, "DOMAIN", UUID.randomUUID().toString());;
def accountService = Mock(AccountService)
1 * accountService.getActiveAccountByName('ACCOUNT', 0) >> Mock(AccountVO)
1 * accountService.createUser('rmurphy', _ , 'Ryan', 'Murphy', 'rmurphy@test.com', null, 'ACCOUNT', 0, _) >> Mock(UserVO)
0 * accountService.createUserAccount('rmurphy', _, 'Ryan', 'Murphy', 'rmurphy@test.com', null, 'ACCOUNT', 2, 0, 'DOMAIN', null, _, _)
def ldapImportUsersCmd = new LdapImportUsersCmd(ldapManager, domainService, accountService)
ldapImportUsersCmd.accountName = "ACCOUNT"
ldapImportUsersCmd.accountType = 2;
ldapImportUsersCmd.domainId = 1L;
when: "create account is called"
ldapImportUsersCmd.execute()
then: "expect 1 call on accountService createUser and 0 on account service create user account"
}
def "Test create ldap import account for a new cloudstack account"() {
given: "We have an LdapManager, DomainService, two users and a LdapImportUsersCmd"
def ldapManager = Mock(LdapManager)
List<LdapUser> users = new ArrayList()
users.add(new LdapUser("rmurphy", "rmurphy@test.com", "Ryan", "Murphy", "cn=rmurphy,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")
ldapManager.createLdapUserResponse(_) >>> response1
def domainService = Mock(DomainService)
1 * domainService.getDomain(1L) >> new DomainVO("DOMAIN", 1L, 1L, "DOMAIN", UUID.randomUUID().toString());;
def accountService = Mock(AccountService)
1 * accountService.getActiveAccountByName('ACCOUNT', 0) >> null
0 * accountService.createUser('rmurphy', _ , 'Ryan', 'Murphy', 'rmurphy@test.com', null, 'ACCOUNT', 0, _)
1 * accountService.createUserAccount('rmurphy', _, 'Ryan', 'Murphy', 'rmurphy@test.com', null, 'ACCOUNT', 2, 0, 'DOMAIN', null, _, _)
def ldapImportUsersCmd = new LdapImportUsersCmd(ldapManager, domainService, accountService)
ldapImportUsersCmd.accountName = "ACCOUNT"
ldapImportUsersCmd.accountType = 2;
ldapImportUsersCmd.domainId = 1L;
when: "create account is called"
ldapImportUsersCmd.execute()
then: "expect 1 call on accountService createUser and 0 on account service create user account"
}
}

View File

@ -2321,4 +2321,9 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
public UserAccount getUserByApiKey(String apiKey) {
return _userAccountDao.getUserByApiKey(apiKey);
}
@Override
public UserAccount getUserAccountById(Long userId) {
return _userAccountDao.findById(userId);
}
}

View File

@ -225,6 +225,12 @@ public class MockAccountManagerImpl extends ManagerBase implements Manager, Acco
// TODO Auto-generated method stub
}
@Override
public UserAccount getUserAccountById(Long userId) {
// TODO Auto-generated method stub
return null;
}
@Override
public void logoutUser(long userId) {
// TODO Auto-generated method stub

View File

@ -198,10 +198,10 @@
array1.push("&domainid=" + args.data.domainid);
var account = args.data.account;
if (account === null || account.length === 0) {
account = args.username;
if (account !== null && account.length > 0) {
array1.push("&account=" + account);
}
array1.push("&account=" + account);
var accountType = args.data.accounttype;
if (args.data.accounttype == "1" && args.data.domainid != rootDomainId) { //if account type is admin, but domain is not Root domain