mirror of https://github.com/apache/cloudstack.git
CLOUDSTACK-10121 moveUser (#2301)
* internal service call for moveUser * expose moveUser as API * move uuid to external entity
This commit is contained in:
parent
e27b3e120d
commit
6724a47122
|
|
@ -56,6 +56,11 @@
|
|||
<artifactId>cloud-framework-ca</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${cs.commons-lang3.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
|
|
|
|||
|
|
@ -198,6 +198,7 @@ public class EventTypes {
|
|||
public static final String EVENT_USER_CREATE = "USER.CREATE";
|
||||
public static final String EVENT_USER_DELETE = "USER.DELETE";
|
||||
public static final String EVENT_USER_DISABLE = "USER.DISABLE";
|
||||
public static final String EVENT_USER_MOVE = "USER.MOVE";
|
||||
public static final String EVENT_USER_UPDATE = "USER.UPDATE";
|
||||
public static final String EVENT_USER_ENABLE = "USER.ENABLE";
|
||||
public static final String EVENT_USER_LOCK = "USER.LOCK";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,126 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.admin.user;
|
||||
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.User;
|
||||
import com.google.common.base.Preconditions;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.AccountResponse;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.api.response.UserResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.region.RegionService;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@APICommand(name = "moveUser",
|
||||
description = "Moves a user to another account",
|
||||
responseObject = SuccessResponse.class,
|
||||
requestHasSensitiveInfo = false,
|
||||
responseHasSensitiveInfo = false,
|
||||
since = "4.11",
|
||||
authorized = {RoleType.Admin})
|
||||
public class MoveUserCmd extends BaseCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(UpdateUserCmd.class.getName());
|
||||
|
||||
public static final String APINAME = "moveUser";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@Parameter(name = ApiConstants.ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = UserResponse.class,
|
||||
required = true,
|
||||
description = "id of the user to be deleted")
|
||||
private Long id;
|
||||
|
||||
@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;
|
||||
|
||||
@Parameter(name = ApiConstants.ACCOUNT_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = AccountResponse.class,
|
||||
description = "Creates the user under the specified domain. Has to be accompanied with the account parameter")
|
||||
private Long accountId;
|
||||
|
||||
@Inject
|
||||
RegionService _regionService;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getAccountName() {
|
||||
return accountName;
|
||||
}
|
||||
|
||||
public Long getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
User user = _entityMgr.findById(User.class, getId());
|
||||
if (user != null) {
|
||||
return user.getAccountId();
|
||||
}
|
||||
|
||||
return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
Preconditions.checkNotNull(getId(),"I have to have an user to move!");
|
||||
Preconditions.checkState(ObjectUtils.anyNotNull(getAccountId(),getAccountName()),"provide either an account name or an account id!");
|
||||
|
||||
CallContext.current().setEventDetails("UserId: " + getId());
|
||||
boolean result =
|
||||
_regionService.moveUser(this);
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to move the user to a new account");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -27,6 +27,7 @@ import org.apache.cloudstack.api.command.admin.domain.UpdateDomainCmd;
|
|||
import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.DisableUserCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.EnableUserCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.MoveUserCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
|
||||
import org.apache.cloudstack.api.command.user.region.ListRegionsCmd;
|
||||
|
||||
|
|
@ -110,10 +111,17 @@ public interface RegionService {
|
|||
*/
|
||||
boolean deleteUser(DeleteUserCmd deleteUserCmd);
|
||||
|
||||
/**
|
||||
* Deletes user by Id
|
||||
* @param moveUserCmd
|
||||
* @return true if delete was successful, false otherwise
|
||||
*/
|
||||
boolean moveUser(MoveUserCmd moveUserCmd);
|
||||
|
||||
/**
|
||||
* update an existing domain
|
||||
*
|
||||
* @param cmd
|
||||
* @param updateDomainCmd
|
||||
* - the command containing domainId and new domainName
|
||||
* @return Domain object if the command succeeded
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -127,7 +127,25 @@ public class UserVO implements User, Identity, InternalIdentity {
|
|||
this.source = source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserVO(UserVO user) {
|
||||
this.setAccountId(user.getAccountId());
|
||||
this.setUsername(user.getUsername());
|
||||
this.setPassword(user.getPassword());
|
||||
this.setFirstname(user.getFirstname());
|
||||
this.setLastname(user.getLastname());
|
||||
this.setEmail(user.getEmail());
|
||||
this.setTimezone(user.getTimezone());
|
||||
this.setUuid(user.getUuid());
|
||||
this.setSource(user.getSource());
|
||||
this.setApiKey(user.getApiKey());
|
||||
this.setSecretKey(user.getSecretKey());
|
||||
this.setExternalEntity(user.getExternalEntity());
|
||||
this.setRegistered(user.isRegistered());
|
||||
this.setRegistrationToken(user.getRegistrationToken());
|
||||
this.setState(user.getState());
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import javax.inject.Inject;
|
|||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.api.command.admin.user.GetUserKeysCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.MoveUserCmd;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
|
|
@ -316,6 +317,10 @@ public class MockAccountManager extends ManagerBase implements AccountManager {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override public boolean moveUser(MoveUserCmd moveUserCmd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteUserAccount(long arg0) {
|
||||
// TODO Auto-generated method stub
|
||||
|
|
|
|||
2
pom.xml
2
pom.xml
|
|
@ -94,7 +94,7 @@
|
|||
<cs.aws.sdk.version>1.11.213</cs.aws.sdk.version>
|
||||
<cs.jackson.version>2.9.2</cs.jackson.version>
|
||||
<cs.lang.version>2.6</cs.lang.version>
|
||||
<cs.commons-lang3.version>3.4</cs.commons-lang3.version>
|
||||
<cs.commons-lang3.version>3.6</cs.commons-lang3.version>
|
||||
<cs.commons-io.version>2.6</cs.commons-io.version>
|
||||
<cs.commons-fileupload.version>1.3.3</cs.commons-fileupload.version>
|
||||
<cs.commons-collections.version>4.1</cs.commons-collections.version>
|
||||
|
|
|
|||
|
|
@ -229,6 +229,7 @@ import org.apache.cloudstack.api.command.admin.user.GetUserCmd;
|
|||
import org.apache.cloudstack.api.command.admin.user.GetUserKeysCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.ListUsersCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.LockUserCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.MoveUserCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.RegisterCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vlan.CreateVlanIpRangeCmd;
|
||||
|
|
@ -2672,6 +2673,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||
cmdList.add(GetUserCmd.class);
|
||||
cmdList.add(ListUsersCmd.class);
|
||||
cmdList.add(LockUserCmd.class);
|
||||
cmdList.add(MoveUserCmd.class);
|
||||
cmdList.add(RegisterCmd.class);
|
||||
cmdList.add(UpdateUserCmd.class);
|
||||
cmdList.add(CreateVlanIpRangeCmd.class);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import java.net.InetAddress;
|
|||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.MoveUserCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
|
||||
|
||||
import com.cloud.api.query.vo.ControlledViewEntity;
|
||||
|
|
@ -155,10 +156,17 @@ public interface AccountManager extends AccountService, Configurable{
|
|||
*/
|
||||
boolean deleteUser(DeleteUserCmd deleteUserCmd);
|
||||
|
||||
/**
|
||||
* moves a user to another account within the same domain
|
||||
* @param moveUserCmd
|
||||
* @return true if the user was successfully moved
|
||||
*/
|
||||
boolean moveUser(MoveUserCmd moveUserCmd);
|
||||
|
||||
/**
|
||||
* Update a user by userId
|
||||
*
|
||||
* @param userId
|
||||
* @param cmd
|
||||
* @return UserAccount object
|
||||
*/
|
||||
UserAccount updateUser(UpdateUserCmd cmd);
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
|
|||
import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.GetUserKeysCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.MoveUserCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.RegisterCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
|
@ -1686,29 +1687,89 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_USER_DELETE, eventDescription = "deleting User")
|
||||
public boolean deleteUser(DeleteUserCmd deleteUserCmd) {
|
||||
long id = deleteUserCmd.getId();
|
||||
|
||||
UserVO user = _userDao.findById(id);
|
||||
|
||||
if (user == null) {
|
||||
throw new InvalidParameterValueException("The specified user doesn't exist in the system");
|
||||
}
|
||||
UserVO user = getValidUserVO(deleteUserCmd.getId());
|
||||
|
||||
Account account = _accountDao.findById(user.getAccountId());
|
||||
|
||||
// don't allow to delete the user from the account of type Project
|
||||
checkAccountAndAccess(user, account);
|
||||
return _userDao.remove(deleteUserCmd.getId());
|
||||
}
|
||||
|
||||
@ActionEvent(eventType = EventTypes.EVENT_USER_MOVE, eventDescription = "moving User to a new account")
|
||||
public boolean moveUser(MoveUserCmd cmd) {
|
||||
UserVO user = getValidUserVO(cmd.getId());
|
||||
Account oldAccount = _accountDao.findById(user.getAccountId());
|
||||
checkAccountAndAccess(user, oldAccount);
|
||||
long domainId = oldAccount.getDomainId();
|
||||
|
||||
long newAccountId = getNewAccountId(cmd, domainId);
|
||||
|
||||
if(newAccountId == user.getAccountId()) {
|
||||
// could do a not silent fail but the objective of the user is reached
|
||||
return true; // no need to create a new user object for this user
|
||||
}
|
||||
return Transaction.execute(new TransactionCallback<Boolean>() {
|
||||
@Override
|
||||
public Boolean doInTransaction(TransactionStatus status) {
|
||||
UserVO newUser = new UserVO(user);
|
||||
user.setExternalEntity(user.getUuid());
|
||||
user.setUuid(UUID.randomUUID().toString());
|
||||
_userDao.update(user.getId(),user);
|
||||
newUser.setAccountId(newAccountId);
|
||||
boolean success = _userDao.remove(cmd.getId());
|
||||
UserVO persisted = _userDao.persist(newUser);
|
||||
return success && persisted.getUuid().equals(user.getExternalEntity());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private long getNewAccountId(MoveUserCmd cmd, long domainId) {
|
||||
Account newAccount = null;
|
||||
if (StringUtils.isNotBlank(cmd.getAccountName())) {
|
||||
if(s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Getting id for account by name '" + cmd.getAccountName() + "' in domain " + domainId);
|
||||
}
|
||||
newAccount = _accountDao.findEnabledAccount(cmd.getAccountName(), domainId);
|
||||
}
|
||||
if (newAccount == null && cmd.getAccountId() != null) {
|
||||
newAccount = _accountDao.findById(cmd.getAccountId());
|
||||
}
|
||||
if (newAccount == null) {
|
||||
throw new CloudRuntimeException("no account name or account id. this should have been caught before this point");
|
||||
}
|
||||
long newAccountId = newAccount.getAccountId();
|
||||
|
||||
if(newAccount.getDomainId() != domainId) {
|
||||
// not in scope
|
||||
throw new InvalidParameterValueException("moving a user from an account in one domain to an account in annother domain is not supported!");
|
||||
}
|
||||
return newAccountId;
|
||||
}
|
||||
|
||||
private void checkAccountAndAccess(UserVO user, Account account) {
|
||||
// don't allow to delete the user from the account of type Project
|
||||
if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
|
||||
throw new InvalidParameterValueException("Project users cannot be deleted or moved.");
|
||||
}
|
||||
|
||||
checkAccess(CallContext.current().getCallingAccount(), AccessType.OperateEntry, true, account);
|
||||
CallContext.current().putContextParameter(User.class, user.getUuid());
|
||||
}
|
||||
|
||||
private UserVO getValidUserVO(long id) {
|
||||
UserVO user = _userDao.findById(id);
|
||||
|
||||
if (user == null || user.getRemoved() != null) {
|
||||
throw new InvalidParameterValueException("The specified user doesn't exist in the system");
|
||||
}
|
||||
|
||||
// don't allow to delete default user (system and admin users)
|
||||
if (user.isDefault()) {
|
||||
throw new InvalidParameterValueException("The user is default and can't be removed");
|
||||
throw new InvalidParameterValueException("The user is default and can't be (re)moved");
|
||||
}
|
||||
|
||||
checkAccess(CallContext.current().getCallingAccount(), AccessType.OperateEntry, true, account);
|
||||
CallContext.current().putContextParameter(User.class, user.getUuid());
|
||||
return _userDao.remove(id);
|
||||
return user;
|
||||
}
|
||||
|
||||
protected class AccountCleanupTask extends ManagedContextRunnable {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import java.util.List;
|
|||
import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd;
|
||||
import org.apache.cloudstack.api.command.admin.domain.UpdateDomainCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.MoveUserCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
|
||||
|
||||
import com.cloud.domain.Domain;
|
||||
|
|
@ -122,10 +123,17 @@ public interface RegionManager {
|
|||
*/
|
||||
boolean deleteUser(DeleteUserCmd deleteUserCmd);
|
||||
|
||||
/**
|
||||
* Deletes user by Id
|
||||
* @param moveUserCmd
|
||||
* @return
|
||||
*/
|
||||
boolean moveUser(MoveUserCmd moveUserCmd);
|
||||
|
||||
/**
|
||||
* update an existing domain
|
||||
*
|
||||
* @param cmd
|
||||
* @param updateDomainCmd
|
||||
* - the command containing domainId and new domainName
|
||||
* @return Domain object if the command succeeded
|
||||
*/
|
||||
|
|
@ -142,7 +150,7 @@ public interface RegionManager {
|
|||
/**
|
||||
* Update a user by userId
|
||||
*
|
||||
* @param userId
|
||||
* @param updateUserCmd
|
||||
* @return UserAccount object
|
||||
*/
|
||||
UserAccount updateUser(UpdateUserCmd updateUserCmd);
|
||||
|
|
@ -150,7 +158,7 @@ public interface RegionManager {
|
|||
/**
|
||||
* Disables a user by userId
|
||||
*
|
||||
* @param userId
|
||||
* @param id
|
||||
* - the userId
|
||||
* @return UserAccount object
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import java.util.Properties;
|
|||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.api.command.admin.user.MoveUserCmd;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
|
@ -224,6 +225,14 @@ public class RegionManagerImpl extends ManagerBase implements RegionManager, Man
|
|||
return _accountMgr.deleteUser(cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean moveUser(MoveUserCmd cmd) {
|
||||
return _accountMgr.moveUser(cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import org.apache.cloudstack.api.command.admin.domain.UpdateDomainCmd;
|
|||
import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.DisableUserCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.EnableUserCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.MoveUserCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
|
||||
import org.apache.cloudstack.api.command.user.region.ListRegionsCmd;
|
||||
|
||||
|
|
@ -151,6 +152,14 @@ public class RegionServiceImpl extends ManagerBase implements RegionService, Man
|
|||
return _regionMgr.deleteUser(cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean moveUser(MoveUserCmd cmd) {
|
||||
return _regionMgr.moveUser(cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import java.net.InetAddress;
|
|||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.api.command.admin.user.GetUserKeysCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.MoveUserCmd;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
|
@ -122,6 +123,10 @@ public class MockAccountManagerImpl extends ManagerBase implements Manager, Acco
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override public boolean moveUser(MoveUserCmd moveUserCmd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAdmin(Long accountId) {
|
||||
// TODO Auto-generated method stub
|
||||
|
|
|
|||
|
|
@ -2086,3 +2086,140 @@ class TestDomainForceRemove(cloudstackTestCase):
|
|||
domain.delete(self.apiclient, cleanup=False)
|
||||
return
|
||||
|
||||
class TestMoveUser(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.testClient = super(TestMoveUser, cls).getClsTestClient()
|
||||
cls.api_client = cls.testClient.getApiClient()
|
||||
cls.testdata = cls.testClient.getParsedTestDataConfig()
|
||||
|
||||
cls.domain = get_domain(cls.api_client)
|
||||
cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
|
||||
cls.testdata['mode'] = cls.zone.networktype
|
||||
|
||||
cls.template = get_test_template(
|
||||
cls.api_client,
|
||||
cls.zone.id,
|
||||
cls.testdata["ostype"]
|
||||
)
|
||||
|
||||
cls.testdata["virtual_machine"]["zoneid"] = cls.zone.id
|
||||
cls._cleanup = []
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
# Clean up, terminate the created resources
|
||||
cleanup_resources(cls.api_client, cls._cleanup)
|
||||
except Exception as e:
|
||||
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def setUp(self):
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
self.cleanup = []
|
||||
self.testdata = self.testClient.getParsedTestDataConfig()
|
||||
self.account1 = Account.create(
|
||||
self.apiclient,
|
||||
self.testdata["acl"]["accountD1"],
|
||||
domainid=self.domain.id
|
||||
)
|
||||
self.cleanup.append(self.account1)
|
||||
|
||||
self.account2 = Account.create(
|
||||
self.apiclient,
|
||||
self.testdata["acl"]["accountD1A"],
|
||||
domainid=self.domain.id
|
||||
)
|
||||
self.cleanup.append(self.account2)
|
||||
|
||||
self.user = User.create(
|
||||
self.apiclient,
|
||||
self.testdata["user"],
|
||||
account=self.account1.name,
|
||||
domainid=self.account1.domainid
|
||||
)
|
||||
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
# Clean up, terminate the created resources
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
@attr(tags=["domains", "advanced", "advancedns", "simulator","dvs"], required_hardware="false")
|
||||
def test_move_user_to_accountID(self):
|
||||
|
||||
self.user.move(self.api_client, dest_accountid=self.account2.id)
|
||||
|
||||
self.assertEqual(
|
||||
self.account2.name,
|
||||
self.user.list(self.apiclient, id=self.user.id)[0].account,
|
||||
"Check user source of created user"
|
||||
)
|
||||
return
|
||||
|
||||
@attr(tags=["domains", "advanced", "advancedns", "simulator","dvs"], required_hardware="false")
|
||||
def test_move_user_to_account_name(self):
|
||||
|
||||
self.user.move(self.api_client, dest_account=self.account2.name)
|
||||
|
||||
self.assertEqual(
|
||||
self.account2.name,
|
||||
self.user.list(self.apiclient, id=self.user.id)[0].account,
|
||||
"Check user source of created user"
|
||||
)
|
||||
return
|
||||
|
||||
@attr(tags=["domains", "advanced", "advancedns", "simulator","dvs"], required_hardware="false")
|
||||
def test_move_user_to_different_domain(self):
|
||||
domain2 = Domain.create(self.api_client,
|
||||
self.testdata["domain"],
|
||||
parentdomainid=self.domain.id
|
||||
)
|
||||
self.cleanup.append(domain2)
|
||||
|
||||
account_different_domain = Account.create(
|
||||
self.apiclient,
|
||||
self.testdata["acl"]["accountD1B"],
|
||||
domainid=domain2.id
|
||||
)
|
||||
self.cleanup.append(account_different_domain)
|
||||
try:
|
||||
self.user.move(self.api_client, dest_account=account_different_domain.name)
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
self.fail("It should not be allowed to move users across accounts in different domains, failing")
|
||||
|
||||
account_different_domain.delete(self.api_client)
|
||||
return
|
||||
|
||||
@attr(tags=["domains", "advanced", "advancedns", "simulator","dvs"], required_hardware="false")
|
||||
def test_move_user_incorrect_account_id(self):
|
||||
|
||||
try:
|
||||
self.user.move(self.api_client, dest_accountid='incorrect-account-id')
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
self.fail("moving to non-existing account should not be possible, failing")
|
||||
return
|
||||
|
||||
@attr(tags=["domains", "advanced", "advancedns", "simulator","dvs"], required_hardware="false")
|
||||
def test_move_user_incorrect_account_name(self):
|
||||
|
||||
try:
|
||||
self.user.move(self.api_client, dest_account='incorrect-account-name')
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
self.fail("moving to non-existing account should not be possible, failing")
|
||||
return
|
||||
|
|
|
|||
|
|
@ -71,6 +71,15 @@ test_data = {
|
|||
"username": "test-account2",
|
||||
"password": "password"
|
||||
},
|
||||
"user": {
|
||||
"email": "user@test.com",
|
||||
"firstname": "User",
|
||||
"lastname": "User",
|
||||
"username": "User",
|
||||
# Random characters are appended for unique
|
||||
# username
|
||||
"password": "fr3sca",
|
||||
},
|
||||
"small": {
|
||||
"displayname": "testserver",
|
||||
"username": "root",
|
||||
|
|
|
|||
|
|
@ -267,6 +267,19 @@ class User:
|
|||
cmd.id = self.id
|
||||
apiclient.deleteUser(cmd)
|
||||
|
||||
def move(self, api_client, dest_accountid = None, dest_account = None, domain= None):
|
||||
|
||||
if all([dest_account, dest_accountid]) is None:
|
||||
raise Exception("Please add either destination account or destination account ID.")
|
||||
|
||||
cmd = moveUser.moveUserCmd()
|
||||
cmd.id = self.id
|
||||
cmd.accountid = dest_accountid
|
||||
cmd.account = dest_account
|
||||
cmd.domain = domain
|
||||
|
||||
return api_client.moveUser(cmd)
|
||||
|
||||
@classmethod
|
||||
def list(cls, apiclient, **kwargs):
|
||||
"""Lists users and provides detailed account information for
|
||||
|
|
|
|||
Loading…
Reference in New Issue