mirror of https://github.com/apache/cloudstack.git
[CLOUDSTACK-5235] ask users current password when they are executing a password update (#2574)
* [CLOUDSTACK-5235] Force users to enter old password when updating password * Formatting for checkstyle * Remove an unused import in AccountManagerImpl * Apply Nitin's suggestions * Change 'oldPassword' to 'currentPassword' * Second review of Resmo * Fix typos found by Nitin
This commit is contained in:
parent
5df580ef64
commit
3adc2b8485
|
|
@ -23,53 +23,28 @@ import org.apache.cloudstack.acl.RoleType;
|
||||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||||
import org.apache.cloudstack.api.command.admin.user.GetUserKeysCmd;
|
import org.apache.cloudstack.api.command.admin.user.GetUserKeysCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.user.RegisterCmd;
|
import org.apache.cloudstack.api.command.admin.user.RegisterCmd;
|
||||||
|
import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
|
||||||
|
|
||||||
import com.cloud.domain.Domain;
|
import com.cloud.domain.Domain;
|
||||||
import com.cloud.exception.PermissionDeniedException;
|
import com.cloud.exception.PermissionDeniedException;
|
||||||
import com.cloud.offering.DiskOffering;
|
import com.cloud.offering.DiskOffering;
|
||||||
import com.cloud.offering.ServiceOffering;
|
import com.cloud.offering.ServiceOffering;
|
||||||
|
|
||||||
|
|
||||||
public interface AccountService {
|
public interface AccountService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new user and account, stores the password as is so encrypted passwords are recommended.
|
* Creates a new user and account, stores the password as is so encrypted passwords are recommended.
|
||||||
*
|
|
||||||
* @param userName
|
|
||||||
* TODO
|
|
||||||
* @param password
|
|
||||||
* TODO
|
|
||||||
* @param firstName
|
|
||||||
* TODO
|
|
||||||
* @param lastName
|
|
||||||
* TODO
|
|
||||||
* @param email
|
|
||||||
* TODO
|
|
||||||
* @param timezone
|
|
||||||
* TODO
|
|
||||||
* @param accountName
|
|
||||||
* TODO
|
|
||||||
* @param accountType
|
|
||||||
* TODO
|
|
||||||
* @param domainId
|
|
||||||
* TODO
|
|
||||||
* @param networkDomain
|
|
||||||
* TODO
|
|
||||||
*
|
|
||||||
* @return the user if created successfully, null otherwise
|
* @return the user if created successfully, null otherwise
|
||||||
*/
|
*/
|
||||||
UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName,
|
UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName, short accountType, Long roleId, Long domainId,
|
||||||
short accountType, Long roleId, Long domainId, String networkDomain, Map<String, String> details, String accountUUID, String userUUID);
|
String networkDomain, Map<String, String> details, String accountUUID, String userUUID);
|
||||||
|
|
||||||
UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName, short accountType, Long roleId, Long domainId, String networkDomain,
|
UserAccount createUserAccount(String userName, String password, String firstName, String lastName, String email, String timezone, String accountName, short accountType, Long roleId, Long domainId,
|
||||||
Map<String, String> details, String accountUUID, String userUUID, User.Source source);
|
String networkDomain, Map<String, String> details, String accountUUID, String userUUID, User.Source source);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Locks a user by userId. A locked user cannot access the API, but will still have running VMs/IP addresses
|
* Locks a user by userId. A locked user cannot access the API, but will still have running VMs/IP addresses
|
||||||
* allocated/etc.
|
* allocated/etc.
|
||||||
*
|
|
||||||
* @param userId
|
|
||||||
* @return UserAccount object
|
|
||||||
*/
|
*/
|
||||||
UserAccount lockUser(long userId);
|
UserAccount lockUser(long userId);
|
||||||
|
|
||||||
|
|
@ -79,8 +54,7 @@ public interface AccountService {
|
||||||
|
|
||||||
User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID);
|
User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID);
|
||||||
|
|
||||||
User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID,
|
User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID, User.Source source);
|
||||||
User.Source source);
|
|
||||||
|
|
||||||
boolean isAdmin(Long accountId);
|
boolean isAdmin(Long accountId);
|
||||||
|
|
||||||
|
|
@ -90,7 +64,7 @@ public interface AccountService {
|
||||||
|
|
||||||
UserAccount getActiveUserAccount(String username, Long domainId);
|
UserAccount getActiveUserAccount(String username, Long domainId);
|
||||||
|
|
||||||
UserAccount updateUser(Long userId, String firstName, String lastName, String email, String userName, String password, String apiKey, String secretKey, String timeZone);
|
UserAccount updateUser(UpdateUserCmd updateUserCmd);
|
||||||
|
|
||||||
Account getActiveAccountById(long accountId);
|
Account getActiveAccountById(long accountId);
|
||||||
|
|
||||||
|
|
@ -128,15 +102,14 @@ public interface AccountService {
|
||||||
|
|
||||||
void checkAccess(User user, ControlledEntity entity);
|
void checkAccess(User user, ControlledEntity entity);
|
||||||
|
|
||||||
void checkAccess(Account account, AccessType accessType, boolean sameOwner, String apiName,
|
void checkAccess(Account account, AccessType accessType, boolean sameOwner, String apiName, ControlledEntity... entities) throws PermissionDeniedException;
|
||||||
ControlledEntity... entities) throws PermissionDeniedException;
|
|
||||||
|
|
||||||
Long finalyzeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly);
|
Long finalyzeAccountId(String accountName, Long domainId, Long projectId, boolean enabledOnly);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns the user account object for a given user id
|
* returns the user account object for a given user id
|
||||||
* @param userId user id
|
* @param userId user id
|
||||||
* @return useraccount object if it exists else null
|
* @return {@link UserAccount} object if it exists else null
|
||||||
*/
|
*/
|
||||||
UserAccount getUserAccountById(Long userId);
|
UserAccount getUserAccountById(Long userId);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -215,8 +215,8 @@ public class ApiConstants {
|
||||||
public static final String PARENT_DOMAIN_ID = "parentdomainid";
|
public static final String PARENT_DOMAIN_ID = "parentdomainid";
|
||||||
public static final String PARENT_TEMPLATE_ID = "parenttemplateid";
|
public static final String PARENT_TEMPLATE_ID = "parenttemplateid";
|
||||||
public static final String PASSWORD = "password";
|
public static final String PASSWORD = "password";
|
||||||
|
public static final String CURRENT_PASSWORD = "currentpassword";
|
||||||
public static final String SHOULD_UPDATE_PASSWORD = "update_passwd_on_host";
|
public static final String SHOULD_UPDATE_PASSWORD = "update_passwd_on_host";
|
||||||
public static final String NEW_PASSWORD = "new_password";
|
|
||||||
public static final String PASSWORD_ENABLED = "passwordenabled";
|
public static final String PASSWORD_ENABLED = "passwordenabled";
|
||||||
public static final String SSHKEY_ENABLED = "sshkeyenabled";
|
public static final String SSHKEY_ENABLED = "sshkeyenabled";
|
||||||
public static final String PATH = "path";
|
public static final String PATH = "path";
|
||||||
|
|
@ -729,4 +729,4 @@ public class ApiConstants {
|
||||||
public enum DomainDetails {
|
public enum DomainDetails {
|
||||||
all, resource, min;
|
all, resource, min;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -34,7 +34,7 @@ import com.cloud.user.User;
|
||||||
import com.cloud.user.UserAccount;
|
import com.cloud.user.UserAccount;
|
||||||
|
|
||||||
@APICommand(name = "updateUser", description = "Updates a user account", responseObject = UserResponse.class,
|
@APICommand(name = "updateUser", description = "Updates a user account", responseObject = UserResponse.class,
|
||||||
requestHasSensitiveInfo = true, responseHasSensitiveInfo = true)
|
requestHasSensitiveInfo = true, responseHasSensitiveInfo = true)
|
||||||
public class UpdateUserCmd extends BaseCmd {
|
public class UpdateUserCmd extends BaseCmd {
|
||||||
public static final Logger s_logger = Logger.getLogger(UpdateUserCmd.class.getName());
|
public static final Logger s_logger = Logger.getLogger(UpdateUserCmd.class.getName());
|
||||||
|
|
||||||
|
|
@ -65,20 +65,22 @@ public class UpdateUserCmd extends BaseCmd {
|
||||||
acceptedOnAdminPort = false)
|
acceptedOnAdminPort = false)
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
|
@Parameter(name = ApiConstants.CURRENT_PASSWORD, type = CommandType.STRING, description = "Current password that was being used by the user. You must inform the current password when updating the password.", acceptedOnAdminPort = false)
|
||||||
|
private String currentPassword;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.SECRET_KEY, type = CommandType.STRING, description = "The secret key for the user. Must be specified with userApiKey")
|
@Parameter(name = ApiConstants.SECRET_KEY, type = CommandType.STRING, description = "The secret key for the user. Must be specified with userApiKey")
|
||||||
private String secretKey;
|
private String secretKey;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.TIMEZONE,
|
@Parameter(name = ApiConstants.TIMEZONE,
|
||||||
type = CommandType.STRING,
|
type = CommandType.STRING,
|
||||||
description = "Specifies a timezone for this command. For more information on the timezone parameter, see Time Zone Format.")
|
description = "Specifies a timezone for this command. For more information on the timezone parameter, see Time Zone Format.")
|
||||||
private String timezone;
|
private String timezone;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, description = "Unique username")
|
@Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, description = "Unique username")
|
||||||
private String username;
|
private String username;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
RegionService _regionService;
|
private RegionService _regionService;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
/////////////////// Accessors ///////////////////////
|
/////////////////// Accessors ///////////////////////
|
||||||
|
|
@ -108,6 +110,10 @@ public class UpdateUserCmd extends BaseCmd {
|
||||||
return password;
|
return password;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getCurrentPassword() {
|
||||||
|
return currentPassword;
|
||||||
|
}
|
||||||
|
|
||||||
public String getSecretKey() {
|
public String getSecretKey() {
|
||||||
return secretKey;
|
return secretKey;
|
||||||
}
|
}
|
||||||
|
|
@ -152,4 +158,20 @@ public class UpdateUserCmd extends BaseCmd {
|
||||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update user");
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update user");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstname(String firstname) {
|
||||||
|
this.firstname = firstname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastname(String lastname) {
|
||||||
|
this.lastname = lastname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(String email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -167,13 +167,6 @@ public class MockAccountManager extends ManagerBase implements AccountManager {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserAccount updateUser(Long userId, String firstName, String lastName, String email, String userName, String password, String apiKey, String secretKey,
|
|
||||||
String timeZone) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public User getActiveUser(long arg0) {
|
public User getActiveUser(long arg0) {
|
||||||
return _systemUser;
|
return _systemUser;
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,6 @@ import java.util.UUID;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import com.cloud.user.Account;
|
|
||||||
import com.cloud.user.User;
|
|
||||||
import com.cloud.user.UserAccount;
|
|
||||||
import org.apache.cloudstack.acl.RoleType;
|
import org.apache.cloudstack.acl.RoleType;
|
||||||
import org.apache.cloudstack.api.APICommand;
|
import org.apache.cloudstack.api.APICommand;
|
||||||
import org.apache.cloudstack.api.ApiConstants;
|
import org.apache.cloudstack.api.ApiConstants;
|
||||||
|
|
@ -36,6 +33,7 @@ import org.apache.cloudstack.api.ApiErrorCode;
|
||||||
import org.apache.cloudstack.api.BaseListCmd;
|
import org.apache.cloudstack.api.BaseListCmd;
|
||||||
import org.apache.cloudstack.api.Parameter;
|
import org.apache.cloudstack.api.Parameter;
|
||||||
import org.apache.cloudstack.api.ServerApiException;
|
import org.apache.cloudstack.api.ServerApiException;
|
||||||
|
import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
|
||||||
import org.apache.cloudstack.api.response.DomainResponse;
|
import org.apache.cloudstack.api.response.DomainResponse;
|
||||||
import org.apache.cloudstack.api.response.LdapUserResponse;
|
import org.apache.cloudstack.api.response.LdapUserResponse;
|
||||||
import org.apache.cloudstack.api.response.ListResponse;
|
import org.apache.cloudstack.api.response.ListResponse;
|
||||||
|
|
@ -54,25 +52,23 @@ import com.cloud.exception.InvalidParameterValueException;
|
||||||
import com.cloud.exception.NetworkRuleConflictException;
|
import com.cloud.exception.NetworkRuleConflictException;
|
||||||
import com.cloud.exception.ResourceAllocationException;
|
import com.cloud.exception.ResourceAllocationException;
|
||||||
import com.cloud.exception.ResourceUnavailableException;
|
import com.cloud.exception.ResourceUnavailableException;
|
||||||
|
import com.cloud.user.Account;
|
||||||
import com.cloud.user.AccountService;
|
import com.cloud.user.AccountService;
|
||||||
import com.cloud.user.DomainService;
|
import com.cloud.user.DomainService;
|
||||||
|
import com.cloud.user.User;
|
||||||
|
import com.cloud.user.UserAccount;
|
||||||
|
|
||||||
@APICommand(name = "importLdapUsers", description = "Import LDAP users", responseObject = LdapUserResponse.class, since = "4.3.0",
|
@APICommand(name = "importLdapUsers", description = "Import LDAP users", responseObject = LdapUserResponse.class, since = "4.3.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
|
||||||
public class LdapImportUsersCmd extends BaseListCmd {
|
public class LdapImportUsersCmd extends BaseListCmd {
|
||||||
|
|
||||||
public static final Logger s_logger = Logger.getLogger(LdapImportUsersCmd.class.getName());
|
public static final Logger s_logger = Logger.getLogger(LdapImportUsersCmd.class.getName());
|
||||||
|
|
||||||
private static final String s_name = "ldapuserresponse";
|
private static final String s_name = "ldapuserresponse";
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.TIMEZONE,
|
@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.")
|
||||||
type = CommandType.STRING,
|
|
||||||
description = "Specifies a timezone for this command. For more information on the timezone parameter, see Time Zone Format.")
|
|
||||||
private String timezone;
|
private String timezone;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.ACCOUNT_TYPE,
|
@Parameter(name = ApiConstants.ACCOUNT_TYPE, type = CommandType.SHORT, description = "Type of the account. Specify 0 for user, 1 for root admin, and 2 for domain admin")
|
||||||
type = CommandType.SHORT,
|
|
||||||
description = "Type of the account. Specify 0 for user, 1 for root admin, and 2 for domain admin")
|
|
||||||
private Short accountType;
|
private Short accountType;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.ROLE_ID, type = CommandType.UUID, entityType = RoleResponse.class, description = "Creates the account under the specified role.")
|
@Parameter(name = ApiConstants.ROLE_ID, type = CommandType.UUID, entityType = RoleResponse.class, description = "Creates the account under the specified role.")
|
||||||
|
|
@ -81,16 +77,13 @@ public class LdapImportUsersCmd extends BaseListCmd {
|
||||||
@Parameter(name = ApiConstants.ACCOUNT_DETAILS, type = CommandType.MAP, description = "details for account used to store specific parameters")
|
@Parameter(name = ApiConstants.ACCOUNT_DETAILS, type = CommandType.MAP, description = "details for account used to store specific parameters")
|
||||||
private Map<String, String> details;
|
private Map<String, String> details;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.DOMAIN_ID,
|
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "Specifies the domain to which the ldap users are to be "
|
||||||
type = CommandType.UUID,
|
+ "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 "
|
||||||
entityType = DomainResponse.class,
|
+ "created. If no OU hierarchy exists, will be defaulted to ROOT domain")
|
||||||
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;
|
private Long domainId;
|
||||||
|
|
||||||
@Parameter(name = ApiConstants.GROUP, type = CommandType.STRING, description = "Specifies the group name from which the ldap users are to 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.")
|
+ "If no group is specified, all the users will be imported.")
|
||||||
private String groupName;
|
private String groupName;
|
||||||
|
|
||||||
private Domain _domain;
|
private Domain _domain;
|
||||||
|
|
@ -121,20 +114,27 @@ public class LdapImportUsersCmd extends BaseListCmd {
|
||||||
} else {
|
} else {
|
||||||
// check if the user exists. if yes, call update
|
// check if the user exists. if yes, call update
|
||||||
UserAccount csuser = _accountService.getActiveUserAccount(user.getUsername(), domain.getId());
|
UserAccount csuser = _accountService.getActiveUserAccount(user.getUsername(), domain.getId());
|
||||||
if(csuser == null) {
|
if (csuser == null) {
|
||||||
s_logger.debug("No user exists with name: " + user.getUsername() + " creating a user in the account: " + accountName);
|
s_logger.debug("No user exists with name: " + user.getUsername() + " creating a user in the account: " + accountName);
|
||||||
_accountService.createUser(user.getUsername(), generatePassword(), user.getFirstname(), user.getLastname(), user.getEmail(), timezone, accountName, domain.getId(),
|
_accountService.createUser(user.getUsername(), generatePassword(), user.getFirstname(), user.getLastname(), user.getEmail(), timezone, accountName, domain.getId(),
|
||||||
UUID.randomUUID().toString(), User.Source.LDAP);
|
UUID.randomUUID().toString(), User.Source.LDAP);
|
||||||
} else {
|
} else {
|
||||||
s_logger.debug("account with name: " + accountName + " exist and user with name: " + user.getUsername() + " exists in the account. Updating the account.");
|
s_logger.debug("Account [name=%s] and user [name=%s] already exist in CloudStack. Executing the user update.");
|
||||||
_accountService.updateUser(csuser.getId(), user.getFirstname(), user.getLastname(), user.getEmail(), null, null, null, null, null);
|
|
||||||
|
UpdateUserCmd updateUserCmd = new UpdateUserCmd();
|
||||||
|
updateUserCmd.setId(csuser.getId());
|
||||||
|
updateUserCmd.setFirstname(user.getFirstname());
|
||||||
|
updateUserCmd.setLastname(user.getLastname());
|
||||||
|
updateUserCmd.setEmail(user.getEmail());
|
||||||
|
|
||||||
|
_accountService.updateUser(updateUserCmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
|
public void execute()
|
||||||
ResourceAllocationException, NetworkRuleConflictException {
|
throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
|
||||||
if (getAccountType() == null && getRoleId() == null) {
|
if (getAccountType() == null && getRoleId() == null) {
|
||||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Both account type and role ID are not provided");
|
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Both account type and role ID are not provided");
|
||||||
}
|
}
|
||||||
|
|
@ -177,7 +177,7 @@ public class LdapImportUsersCmd extends BaseListCmd {
|
||||||
|
|
||||||
private String getAccountName(LdapUser user) {
|
private String getAccountName(LdapUser user) {
|
||||||
String finalAccountName = accountName;
|
String finalAccountName = accountName;
|
||||||
if(finalAccountName == null ) {
|
if (finalAccountName == null) {
|
||||||
finalAccountName = user.getUsername();
|
finalAccountName = user.getUsername();
|
||||||
}
|
}
|
||||||
return finalAccountName;
|
return finalAccountName;
|
||||||
|
|
@ -244,7 +244,7 @@ public class LdapImportUsersCmd extends BaseListCmd {
|
||||||
final byte bytes[] = new byte[20];
|
final byte bytes[] = new byte[20];
|
||||||
randomGen.nextBytes(bytes);
|
randomGen.nextBytes(bytes);
|
||||||
return new String(Base64.encode(bytes), "UTF-8");
|
return new String(Base64.encode(bytes), "UTF-8");
|
||||||
} catch ( NoSuchAlgorithmException | UnsupportedEncodingException e) {
|
} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
|
||||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to generate random password");
|
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to generate random password");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,15 +16,17 @@
|
||||||
// under the License.
|
// under the License.
|
||||||
package com.cloud.user;
|
package com.cloud.user;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.net.InetAddress;
|
|
||||||
|
|
||||||
import org.apache.cloudstack.acl.ControlledEntity;
|
import org.apache.cloudstack.acl.ControlledEntity;
|
||||||
import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd;
|
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.DeleteUserCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.user.MoveUserCmd;
|
import org.apache.cloudstack.api.command.admin.user.MoveUserCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
|
import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
|
||||||
|
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||||
|
import org.apache.cloudstack.framework.config.Configurable;
|
||||||
|
|
||||||
import com.cloud.api.query.vo.ControlledViewEntity;
|
import com.cloud.api.query.vo.ControlledViewEntity;
|
||||||
import com.cloud.exception.ConcurrentOperationException;
|
import com.cloud.exception.ConcurrentOperationException;
|
||||||
|
|
@ -34,17 +36,14 @@ import com.cloud.utils.Pair;
|
||||||
import com.cloud.utils.Ternary;
|
import com.cloud.utils.Ternary;
|
||||||
import com.cloud.utils.db.SearchBuilder;
|
import com.cloud.utils.db.SearchBuilder;
|
||||||
import com.cloud.utils.db.SearchCriteria;
|
import com.cloud.utils.db.SearchCriteria;
|
||||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
|
||||||
import org.apache.cloudstack.framework.config.Configurable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AccountManager includes logic that deals with accounts, domains, and users.
|
* AccountManager includes logic that deals with accounts, domains, and users.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public interface AccountManager extends AccountService, Configurable{
|
public interface AccountManager extends AccountService, Configurable {
|
||||||
/**
|
/**
|
||||||
* Disables an account by accountId
|
* Disables an account by accountId
|
||||||
* @param accountId
|
|
||||||
* @return true if disable was successful, false otherwise
|
* @return true if disable was successful, false otherwise
|
||||||
*/
|
*/
|
||||||
boolean disableAccount(long accountId) throws ConcurrentOperationException, ResourceUnavailableException;
|
boolean disableAccount(long accountId) throws ConcurrentOperationException, ResourceUnavailableException;
|
||||||
|
|
@ -57,24 +56,23 @@ public interface AccountManager extends AccountService, Configurable{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs out a user
|
* Logs out a user
|
||||||
* @param userId
|
|
||||||
*/
|
*/
|
||||||
void logoutUser(long userId);
|
void logoutUser(long userId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Authenticates a user when s/he logs in.
|
* Authenticates a user when s/he logs in.
|
||||||
*
|
*
|
||||||
* @param username
|
* @param username
|
||||||
* required username for authentication
|
* required username for authentication
|
||||||
* @param password
|
* @param password
|
||||||
* password to use for authentication, can be null for single sign-on case
|
* password to use for authentication, can be null for single sign-on case
|
||||||
* @param domainId
|
* @param domainId
|
||||||
* id of domain where user with username resides
|
* id of domain where user with username resides
|
||||||
* @param requestParameters
|
* @param requestParameters
|
||||||
* the request parameters of the login request, which should contain timestamp of when the request signature is
|
* the request parameters of the login request, which should contain timestamp of when the request signature is
|
||||||
* made, and the signature itself in the single sign-on case
|
* made, and the signature itself in the single sign-on case
|
||||||
* @return a user object, null if the user failed to authenticate
|
* @return a user object, null if the user failed to authenticate
|
||||||
*/
|
*/
|
||||||
UserAccount authenticateUser(String username, String password, Long domainId, InetAddress loginIpAddress, Map<String, Object[]> requestParameters);
|
UserAccount authenticateUser(String username, String password, Long domainId, InetAddress loginIpAddress, Map<String, Object[]> requestParameters);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -88,23 +86,20 @@ public interface AccountManager extends AccountService, Configurable{
|
||||||
|
|
||||||
boolean enableAccount(long accountId);
|
boolean enableAccount(long accountId);
|
||||||
|
|
||||||
|
void buildACLSearchBuilder(SearchBuilder<? extends ControlledEntity> sb, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
|
||||||
|
ListProjectResourcesCriteria listProjectResourcesCriteria);
|
||||||
|
|
||||||
void buildACLSearchBuilder(SearchBuilder<? extends ControlledEntity> sb, Long domainId,
|
void buildACLViewSearchBuilder(SearchBuilder<? extends ControlledViewEntity> sb, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
|
||||||
boolean isRecursive, List<Long> permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria);
|
ListProjectResourcesCriteria listProjectResourcesCriteria);
|
||||||
|
|
||||||
void buildACLViewSearchBuilder(SearchBuilder<? extends ControlledViewEntity> sb, Long domainId,
|
void buildACLSearchCriteria(SearchCriteria<? extends ControlledEntity> sc, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
|
||||||
boolean isRecursive, List<Long> permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria);
|
ListProjectResourcesCriteria listProjectResourcesCriteria);
|
||||||
|
|
||||||
void buildACLSearchCriteria(SearchCriteria<? extends ControlledEntity> sc,
|
void buildACLSearchParameters(Account caller, Long id, String accountName, Long projectId, List<Long> permittedAccounts,
|
||||||
Long domainId, boolean isRecursive, List<Long> permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria);
|
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject, boolean listAll, boolean forProjectInvitation);
|
||||||
|
|
||||||
void buildACLSearchParameters(Account caller, Long id,
|
|
||||||
String accountName, Long projectId, List<Long> permittedAccounts, Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject, boolean listAll,
|
|
||||||
boolean forProjectInvitation);
|
|
||||||
|
|
||||||
void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledViewEntity> sc,
|
|
||||||
Long domainId, boolean isRecursive, List<Long> permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria);
|
|
||||||
|
|
||||||
|
void buildACLViewSearchCriteria(SearchCriteria<? extends ControlledViewEntity> sc, Long domainId, boolean isRecursive, List<Long> permittedAccounts,
|
||||||
|
ListProjectResourcesCriteria listProjectResourcesCriteria);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes a user by userId
|
* Deletes a user by userId
|
||||||
|
|
@ -127,10 +122,6 @@ public interface AccountManager extends AccountService, Configurable{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disables an account by accountName and domainId
|
* Disables an account by accountName and domainId
|
||||||
*
|
|
||||||
* @param accountName
|
|
||||||
* @param domainId
|
|
||||||
* @param accountId
|
|
||||||
* @param disabled
|
* @param disabled
|
||||||
* account if success
|
* account if success
|
||||||
* @return true if disable was successful, false otherwise
|
* @return true if disable was successful, false otherwise
|
||||||
|
|
@ -142,33 +133,21 @@ public interface AccountManager extends AccountService, Configurable{
|
||||||
*
|
*
|
||||||
* @param accountName
|
* @param accountName
|
||||||
* - the enableAccount command defining the accountId to be deleted.
|
* - the enableAccount command defining the accountId to be deleted.
|
||||||
* @param domainId
|
|
||||||
* TODO
|
|
||||||
* @param accountId
|
|
||||||
* @return account object
|
|
||||||
*/
|
*/
|
||||||
Account enableAccount(String accountName, Long domainId, Long accountId);
|
Account enableAccount(String accountName, Long domainId, Long accountId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes user by Id
|
* Deletes user by Id
|
||||||
* @param deleteUserCmd
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
boolean deleteUser(DeleteUserCmd deleteUserCmd);
|
boolean deleteUser(DeleteUserCmd deleteUserCmd);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* moves a user to another account within the same domain
|
* moves a user to another account within the same domain
|
||||||
* @param moveUserCmd
|
|
||||||
* @return true if the user was successfully moved
|
* @return true if the user was successfully moved
|
||||||
*/
|
*/
|
||||||
boolean moveUser(MoveUserCmd moveUserCmd);
|
boolean moveUser(MoveUserCmd moveUserCmd);
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Update a user by userId
|
|
||||||
*
|
|
||||||
* @param cmd
|
|
||||||
* @return UserAccount object
|
|
||||||
*/
|
|
||||||
UserAccount updateUser(UpdateUserCmd cmd);
|
UserAccount updateUser(UpdateUserCmd cmd);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -196,10 +175,6 @@ public interface AccountManager extends AccountService, Configurable{
|
||||||
*
|
*
|
||||||
* @param accountName
|
* @param accountName
|
||||||
* - the LockAccount command defining the accountId to be locked.
|
* - the LockAccount command defining the accountId to be locked.
|
||||||
* @param domainId
|
|
||||||
* TODO
|
|
||||||
* @param accountId
|
|
||||||
* @return account object
|
|
||||||
*/
|
*/
|
||||||
Account lockAccount(String accountName, Long domainId, Long accountId);
|
Account lockAccount(String accountName, Long domainId, Long accountId);
|
||||||
|
|
||||||
|
|
@ -208,13 +183,8 @@ public interface AccountManager extends AccountService, Configurable{
|
||||||
public static final String MESSAGE_ADD_ACCOUNT_EVENT = "Message.AddAccount.Event";
|
public static final String MESSAGE_ADD_ACCOUNT_EVENT = "Message.AddAccount.Event";
|
||||||
|
|
||||||
public static final String MESSAGE_REMOVE_ACCOUNT_EVENT = "Message.RemoveAccount.Event";
|
public static final String MESSAGE_REMOVE_ACCOUNT_EVENT = "Message.RemoveAccount.Event";
|
||||||
public static final ConfigKey<Boolean> UseSecretKeyInResponse = new ConfigKey<Boolean>(
|
public static final ConfigKey<Boolean> UseSecretKeyInResponse = new ConfigKey<Boolean>("Advanced", Boolean.class, "use.secret.key.in.response", "false",
|
||||||
"Advanced",
|
"This parameter allows the users to enable or disable of showing secret key as a part of response for various APIs. By default it is set to false.", true);
|
||||||
Boolean.class,
|
|
||||||
"use.secret.key.in.response",
|
|
||||||
"false",
|
|
||||||
"This parameter allows the users to enable or disable of showing secret key as a part of response for various APIs. By default it is set to false.",
|
|
||||||
true);
|
|
||||||
|
|
||||||
boolean moveUser(long id, Long domainId, long accountId);
|
boolean moveUser(long id, Long domainId, long accountId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
@ -38,10 +37,6 @@ import javax.crypto.spec.SecretKeySpec;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
import org.apache.commons.codec.binary.Base64;
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
|
|
||||||
import org.apache.cloudstack.acl.ControlledEntity;
|
import org.apache.cloudstack.acl.ControlledEntity;
|
||||||
import org.apache.cloudstack.acl.QuerySelector;
|
import org.apache.cloudstack.acl.QuerySelector;
|
||||||
import org.apache.cloudstack.acl.RoleType;
|
import org.apache.cloudstack.acl.RoleType;
|
||||||
|
|
@ -55,6 +50,7 @@ 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.MoveUserCmd;
|
||||||
import org.apache.cloudstack.api.command.admin.user.RegisterCmd;
|
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.user.UpdateUserCmd;
|
||||||
|
import org.apache.cloudstack.config.ApiServiceConfiguration;
|
||||||
import org.apache.cloudstack.context.CallContext;
|
import org.apache.cloudstack.context.CallContext;
|
||||||
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
||||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||||
|
|
@ -64,6 +60,11 @@ import org.apache.cloudstack.framework.messagebus.PublishScope;
|
||||||
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
|
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
|
||||||
import org.apache.cloudstack.region.gslb.GlobalLoadBalancerRuleDao;
|
import org.apache.cloudstack.region.gslb.GlobalLoadBalancerRuleDao;
|
||||||
import org.apache.cloudstack.utils.baremetal.BaremetalUtils;
|
import org.apache.cloudstack.utils.baremetal.BaremetalUtils;
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import com.cloud.api.ApiDBUtils;
|
import com.cloud.api.ApiDBUtils;
|
||||||
import com.cloud.api.query.vo.ControlledViewEntity;
|
import com.cloud.api.query.vo.ControlledViewEntity;
|
||||||
|
|
@ -172,8 +173,6 @@ import com.cloud.vm.snapshot.VMSnapshot;
|
||||||
import com.cloud.vm.snapshot.VMSnapshotManager;
|
import com.cloud.vm.snapshot.VMSnapshotManager;
|
||||||
import com.cloud.vm.snapshot.VMSnapshotVO;
|
import com.cloud.vm.snapshot.VMSnapshotVO;
|
||||||
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
|
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
|
||||||
import org.apache.cloudstack.config.ApiServiceConfiguration;
|
|
||||||
|
|
||||||
|
|
||||||
public class AccountManagerImpl extends ManagerBase implements AccountManager, Manager {
|
public class AccountManagerImpl extends ManagerBase implements AccountManager, Manager {
|
||||||
public static final Logger s_logger = Logger.getLogger(AccountManagerImpl.class);
|
public static final Logger s_logger = Logger.getLogger(AccountManagerImpl.class);
|
||||||
|
|
@ -540,8 +539,8 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
Account account = ApiDBUtils.findAccountById(entity.getAccountId());
|
Account account = ApiDBUtils.findAccountById(entity.getAccountId());
|
||||||
domainId = account != null ? account.getDomainId() : -1;
|
domainId = account != null ? account.getDomainId() : -1;
|
||||||
}
|
}
|
||||||
if (entity.getAccountId() != -1 && domainId != -1 && !(entity instanceof VirtualMachineTemplate)
|
if (entity.getAccountId() != -1 && domainId != -1 && !(entity instanceof VirtualMachineTemplate) && !(entity instanceof Network && accessType != null && accessType == AccessType.UseEntry)
|
||||||
&& !(entity instanceof Network && accessType != null && accessType == AccessType.UseEntry) && !(entity instanceof AffinityGroup)) {
|
&& !(entity instanceof AffinityGroup)) {
|
||||||
List<ControlledEntity> toBeChecked = domains.get(entity.getDomainId());
|
List<ControlledEntity> toBeChecked = domains.get(entity.getDomainId());
|
||||||
// for templates, we don't have to do cross domains check
|
// for templates, we don't have to do cross domains check
|
||||||
if (toBeChecked == null) {
|
if (toBeChecked == null) {
|
||||||
|
|
@ -563,7 +562,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
|
|
||||||
if (!granted) {
|
if (!granted) {
|
||||||
assert false : "How can all of the security checkers pass on checking this check: " + entity;
|
assert false : "How can all of the security checkers pass on checking this check: " + entity;
|
||||||
throw new PermissionDeniedException("There's no way to confirm " + caller + " has access to " + entity);
|
throw new PermissionDeniedException("There's no way to confirm " + caller + " has access to " + entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -590,26 +589,27 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
public Long checkAccessAndSpecifyAuthority(Account caller, Long zoneId) {
|
public Long checkAccessAndSpecifyAuthority(Account caller, Long zoneId) {
|
||||||
// We just care for resource domain admin for now. He should be permitted to see only his zone.
|
// We just care for resource domain admin for now. He should be permitted to see only his zone.
|
||||||
if (isResourceDomainAdmin(caller.getAccountId())) {
|
if (isResourceDomainAdmin(caller.getAccountId())) {
|
||||||
if (zoneId == null)
|
if (zoneId == null) {
|
||||||
return getZoneIdForAccount(caller);
|
return getZoneIdForAccount(caller);
|
||||||
else if (zoneId.compareTo(getZoneIdForAccount(caller)) != 0)
|
} else if (zoneId.compareTo(getZoneIdForAccount(caller)) != 0) {
|
||||||
throw new PermissionDeniedException("Caller " + caller + "is not allowed to access the zone " + zoneId);
|
throw new PermissionDeniedException("Caller " + caller + "is not allowed to access the zone " + zoneId);
|
||||||
else
|
} else {
|
||||||
return zoneId;
|
return zoneId;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
else
|
|
||||||
return zoneId;
|
return zoneId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Long getZoneIdForAccount(Account account) {
|
private Long getZoneIdForAccount(Account account) {
|
||||||
|
|
||||||
// Currently just for resource domain admin
|
// Currently just for resource domain admin
|
||||||
List<DataCenterVO> dcList = _dcDao.findZonesByDomainId(account.getDomainId());
|
List<DataCenterVO> dcList = _dcDao.findZonesByDomainId(account.getDomainId());
|
||||||
if (dcList != null && dcList.size() != 0)
|
if (dcList != null && dcList.size() != 0) {
|
||||||
return dcList.get(0).getId();
|
return dcList.get(0).getId();
|
||||||
else
|
} else {
|
||||||
throw new CloudRuntimeException("Failed to find any private zone for Resource domain admin.");
|
throw new CloudRuntimeException("Failed to find any private zone for Resource domain admin.");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1011,13 +1011,12 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ActionEvents({@ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_CREATE, eventDescription = "creating Account"),
|
@ActionEvents({@ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_CREATE, eventDescription = "creating Account"),
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User")})
|
@ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User")})
|
||||||
public UserAccount createUserAccount(final String userName, final String password, final String firstName, final String lastName, final String email, final String timezone,
|
public UserAccount createUserAccount(final String userName, final String password, final String firstName, final String lastName, final String email, final String timezone, String accountName,
|
||||||
String accountName, final short accountType, final Long roleId, Long domainId, final String networkDomain, final Map<String, String> details, String accountUUID,
|
final short accountType, final Long roleId, Long domainId, final String networkDomain, final Map<String, String> details, String accountUUID, final String userUUID) {
|
||||||
final String userUUID) {
|
|
||||||
|
|
||||||
return createUserAccount(userName, password, firstName, lastName, email, timezone, accountName, accountType, roleId, domainId, networkDomain, details, accountUUID,
|
return createUserAccount(userName, password, firstName, lastName, email, timezone, accountName, accountType, roleId, domainId, networkDomain, details, accountUUID, userUUID,
|
||||||
userUUID, User.Source.UNKNOWN);
|
User.Source.UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ///////////////////////////////////////////////////
|
// ///////////////////////////////////////////////////
|
||||||
|
|
@ -1027,10 +1026,10 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
@Override
|
@Override
|
||||||
@DB
|
@DB
|
||||||
@ActionEvents({@ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_CREATE, eventDescription = "creating Account"),
|
@ActionEvents({@ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_CREATE, eventDescription = "creating Account"),
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User")})
|
@ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User")})
|
||||||
public UserAccount createUserAccount(final String userName, final String password, final String firstName, final String lastName, final String email, final String timezone,
|
public UserAccount createUserAccount(final String userName, final String password, final String firstName, final String lastName, final String email, final String timezone, String accountName,
|
||||||
String accountName, final short accountType, final Long roleId, Long domainId, final String networkDomain, final Map<String, String> details, String accountUUID,
|
final short accountType, final Long roleId, Long domainId, final String networkDomain, final Map<String, String> details, String accountUUID, final String userUUID,
|
||||||
final String userUUID, final User.Source source) {
|
final User.Source source) {
|
||||||
|
|
||||||
if (accountName == null) {
|
if (accountName == null) {
|
||||||
accountName = userName;
|
accountName = userName;
|
||||||
|
|
@ -1058,7 +1057,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check permissions
|
// Check permissions
|
||||||
checkAccess(CallContext.current().getCallingAccount(), domain);
|
checkAccess(getCurrentCallingAccount(), domain);
|
||||||
|
|
||||||
if (!_userAccountDao.validateUsernameInDomain(userName, domainId)) {
|
if (!_userAccountDao.validateUsernameInDomain(userName, domainId)) {
|
||||||
throw new InvalidParameterValueException("The user " + userName + " already exists in domain " + domainId);
|
throw new InvalidParameterValueException("The user " + userName + " already exists in domain " + domainId);
|
||||||
|
|
@ -1132,7 +1131,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
throw new CloudRuntimeException("The user cannot be created as domain " + domain.getName() + " is being deleted");
|
throw new CloudRuntimeException("The user cannot be created as domain " + domain.getName() + " is being deleted");
|
||||||
}
|
}
|
||||||
|
|
||||||
checkAccess(CallContext.current().getCallingAccount(), domain);
|
checkAccess(getCurrentCallingAccount(), domain);
|
||||||
|
|
||||||
Account account = _accountDao.findEnabledAccount(accountName, domainId);
|
Account account = _accountDao.findEnabledAccount(accountName, domainId);
|
||||||
if (account == null || account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
|
if (account == null || account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
|
||||||
|
|
@ -1153,157 +1152,246 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User")
|
@ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User")
|
||||||
public UserVO createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId,
|
public UserVO createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID) {
|
||||||
String userUUID) {
|
|
||||||
|
|
||||||
return createUser(userName, password, firstName, lastName, email, timeZone, accountName, domainId, userUUID, User.Source.UNKNOWN);
|
return createUser(userName, password, firstName, lastName, email, timeZone, accountName, domainId, userUUID, User.Source.UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_USER_UPDATE, eventDescription = "updating User")
|
@ActionEvent(eventType = EventTypes.EVENT_USER_UPDATE, eventDescription = "Updating User")
|
||||||
public UserAccount updateUser(Long userId, String firstName, String lastName, String email, String userName, String password, String apiKey, String secretKey,
|
public UserAccount updateUser(UpdateUserCmd updateUserCmd) {
|
||||||
String timeZone) {
|
UserVO user = retrieveAndValidateUser(updateUserCmd);
|
||||||
// Input validation
|
s_logger.debug("Updating user with Id: " + user.getUuid());
|
||||||
UserVO user = _userDao.getUser(userId);
|
|
||||||
|
|
||||||
if (user == null) {
|
validateAndUpdatApiAndSecretKeyIfNeeded(updateUserCmd, user);
|
||||||
throw new InvalidParameterValueException("unable to find user by id");
|
Account account = retrieveAndValidateAccount(user);
|
||||||
|
|
||||||
|
validateAndUpdateFirstNameIfNeeded(updateUserCmd, user);
|
||||||
|
validateAndUpdateLastNameIfNeeded(updateUserCmd, user);
|
||||||
|
validateAndUpdateUsernameIfNeeded(updateUserCmd, user, account);
|
||||||
|
|
||||||
|
validateUserPasswordAndUpdateIfNeeded(updateUserCmd.getPassword(), user, updateUserCmd.getCurrentPassword());
|
||||||
|
String email = updateUserCmd.getEmail();
|
||||||
|
if (StringUtils.isNotBlank(email)) {
|
||||||
|
user.setEmail(email);
|
||||||
}
|
}
|
||||||
|
String timezone = updateUserCmd.getTimezone();
|
||||||
if ((apiKey == null && secretKey != null) || (apiKey != null && secretKey == null)) {
|
if (StringUtils.isNotBlank(timezone)) {
|
||||||
throw new InvalidParameterValueException("Please provide an userApiKey/userSecretKey pair");
|
user.setTimezone(timezone);
|
||||||
}
|
}
|
||||||
|
_userDao.update(user.getId(), user);
|
||||||
|
return _userAccountDao.findById(user.getId());
|
||||||
|
}
|
||||||
|
|
||||||
// If the account is an admin type, return an error. We do not allow this
|
/**
|
||||||
Account account = _accountDao.findById(user.getAccountId());
|
* Updates the password in the user POJO if needed. If no password is provided, then the password is not updated.
|
||||||
if (account == null) {
|
* The following validations are executed if 'password' is not null. Admins (root admins or domain admins) can execute password updates without entering the current password.
|
||||||
throw new InvalidParameterValueException("unable to find user account " + user.getAccountId());
|
* <ul>
|
||||||
|
* <li> If 'password' is blank, we throw an {@link InvalidParameterValueException};
|
||||||
|
* <li> If 'current password' is not provided and user is not an Admin, we throw an {@link InvalidParameterValueException};
|
||||||
|
* <li> If a normal user is calling this method, we use {@link #validateCurrentPassword(UserVO, String)} to check if the provided old password matches the database one;
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* If all checks pass, we encode the given password with the most preferable password mechanism given in {@link #_userPasswordEncoders}.
|
||||||
|
*/
|
||||||
|
protected void validateUserPasswordAndUpdateIfNeeded(String newPassword, UserVO user, String currentPassword) {
|
||||||
|
if (newPassword == null) {
|
||||||
|
s_logger.trace("No new password to update for user: " + user.getUuid());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
if (StringUtils.isBlank(newPassword)) {
|
||||||
// don't allow updating project account
|
throw new InvalidParameterValueException("Password cannot be empty or blank.");
|
||||||
if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
|
|
||||||
throw new InvalidParameterValueException("unable to find user by id");
|
|
||||||
}
|
}
|
||||||
|
Account callingAccount = getCurrentCallingAccount();
|
||||||
// don't allow updating system account
|
boolean isRootAdminExecutingPasswordUpdate = callingAccount.getId() == Account.ACCOUNT_ID_SYSTEM || isRootAdmin(callingAccount.getId());
|
||||||
if (account.getId() == Account.ACCOUNT_ID_SYSTEM) {
|
boolean isDomainAdmin = isDomainAdmin(callingAccount.getId());
|
||||||
throw new PermissionDeniedException("user id : " + userId + " is system account, update is not allowed");
|
boolean isAdmin = isDomainAdmin || isRootAdminExecutingPasswordUpdate;
|
||||||
|
if (isAdmin) {
|
||||||
|
s_logger.trace(String.format("Admin account [uuid=%s] executing password update for user [%s] ", callingAccount.getUuid(), user.getUuid()));
|
||||||
}
|
}
|
||||||
|
if (!isAdmin && StringUtils.isBlank(currentPassword)) {
|
||||||
|
throw new InvalidParameterValueException("To set a new password the current password must be provided.");
|
||||||
|
}
|
||||||
|
if (CollectionUtils.isEmpty(_userPasswordEncoders)) {
|
||||||
|
throw new CloudRuntimeException("No user authenticators configured!");
|
||||||
|
}
|
||||||
|
if (!isAdmin) {
|
||||||
|
validateCurrentPassword(user, currentPassword);
|
||||||
|
}
|
||||||
|
UserAuthenticator userAuthenticator = _userPasswordEncoders.get(0);
|
||||||
|
String newPasswordEncoded = userAuthenticator.encode(newPassword);
|
||||||
|
user.setPassword(newPasswordEncoded);
|
||||||
|
}
|
||||||
|
|
||||||
checkAccess(CallContext.current().getCallingAccount(), AccessType.OperateEntry, true, account);
|
/**
|
||||||
|
* Iterates over all configured user authenticators and tries to authenticate the user using the current password.
|
||||||
if (firstName != null) {
|
* If the user is authenticated with success, we have nothing else to do here; otherwise, an {@link InvalidParameterValueException} is thrown.
|
||||||
if (firstName.isEmpty()) {
|
*/
|
||||||
throw new InvalidParameterValueException("Firstname is empty");
|
protected void validateCurrentPassword(UserVO user, String currentPassword) {
|
||||||
|
AccountVO userAccount = _accountDao.findById(user.getAccountId());
|
||||||
|
boolean currentPasswordMatchesDataBasePassword = false;
|
||||||
|
for (UserAuthenticator userAuthenticator : _userPasswordEncoders) {
|
||||||
|
Pair<Boolean, ActionOnFailedAuthentication> authenticationResult = userAuthenticator.authenticate(user.getUsername(), currentPassword, userAccount.getDomainId(), null);
|
||||||
|
if (authenticationResult == null) {
|
||||||
|
s_logger.trace(String.format("Authenticator [%s] is returning null for the authenticate mehtod.", userAuthenticator.getClass()));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (BooleanUtils.toBoolean(authenticationResult.first())) {
|
||||||
|
s_logger.debug(String.format("User [id=%s] re-authenticated [authenticator=%s] during password update.", user.getUuid(), userAuthenticator.getName()));
|
||||||
|
currentPasswordMatchesDataBasePassword = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
user.setFirstname(firstName);
|
|
||||||
}
|
}
|
||||||
|
if (!currentPasswordMatchesDataBasePassword) {
|
||||||
|
throw new InvalidParameterValueException("Current password is incorrect.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the user 'username' if provided. The 'username' cannot be blank (when provided).
|
||||||
|
* <ul>
|
||||||
|
* <li> If the 'username' is not provided, we do not update it (setting to null) in the User POJO.
|
||||||
|
* <li> If the 'username' is blank, we throw an {@link InvalidParameterValueException}.
|
||||||
|
* <li> The username must be unique in each domain. Therefore, if there is already another user with the same username, an {@link InvalidParameterValueException} is thrown.
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
protected void validateAndUpdateUsernameIfNeeded(UpdateUserCmd updateUserCmd, UserVO user, Account account) {
|
||||||
|
String userName = updateUserCmd.getUsername();
|
||||||
|
if (userName == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (StringUtils.isBlank(userName)) {
|
||||||
|
throw new InvalidParameterValueException("Username cannot be empty.");
|
||||||
|
}
|
||||||
|
List<UserVO> duplicatedUsers = _userDao.findUsersByName(userName);
|
||||||
|
for (UserVO duplicatedUser : duplicatedUsers) {
|
||||||
|
if (duplicatedUser.getId() == user.getId()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Account duplicatedUserAccountWithUserThatHasTheSameUserName = _accountDao.findById(duplicatedUser.getAccountId());
|
||||||
|
if (duplicatedUserAccountWithUserThatHasTheSameUserName.getDomainId() == account.getDomainId()) {
|
||||||
|
DomainVO domain = _domainDao.findById(duplicatedUserAccountWithUserThatHasTheSameUserName.getDomainId());
|
||||||
|
throw new InvalidParameterValueException(String.format("Username [%s] already exists in domain [id=%s,name=%s]", duplicatedUser.getUsername(), domain.getUuid(), domain.getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
user.setUsername(userName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the user 'lastName' if provided. The 'lastName' cannot be blank (when provided).
|
||||||
|
* <ul>
|
||||||
|
* <li> If the 'lastName' is not provided, we do not update it (setting to null) in the User POJO.
|
||||||
|
* <li> If the 'lastName' is blank, we throw an {@link InvalidParameterValueException}.
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
protected void validateAndUpdateLastNameIfNeeded(UpdateUserCmd updateUserCmd, UserVO user) {
|
||||||
|
String lastName = updateUserCmd.getLastname();
|
||||||
if (lastName != null) {
|
if (lastName != null) {
|
||||||
if (lastName.isEmpty()) {
|
if (StringUtils.isBlank(lastName)) {
|
||||||
throw new InvalidParameterValueException("Lastname is empty");
|
throw new InvalidParameterValueException("Lastname cannot be empty.");
|
||||||
}
|
}
|
||||||
|
|
||||||
user.setLastname(lastName);
|
user.setLastname(lastName);
|
||||||
}
|
}
|
||||||
if (userName != null) {
|
|
||||||
if (userName.isEmpty()) {
|
|
||||||
throw new InvalidParameterValueException("Username is empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
// don't allow to have same user names in the same domain
|
|
||||||
List<UserVO> duplicatedUsers = _userDao.findUsersByName(userName);
|
|
||||||
for (UserVO duplicatedUser : duplicatedUsers) {
|
|
||||||
if (duplicatedUser.getId() != user.getId()) {
|
|
||||||
Account duplicatedUserAccount = _accountDao.findById(duplicatedUser.getAccountId());
|
|
||||||
if (duplicatedUserAccount.getDomainId() == account.getDomainId()) {
|
|
||||||
throw new InvalidParameterValueException("User with name " + userName + " already exists in domain " + duplicatedUserAccount.getDomainId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
user.setUsername(userName);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (password != null) {
|
|
||||||
if (password.isEmpty()) {
|
|
||||||
throw new InvalidParameterValueException("Password cannot be empty");
|
|
||||||
}
|
|
||||||
String encodedPassword = null;
|
|
||||||
for (Iterator<UserAuthenticator> en = _userPasswordEncoders.iterator(); en.hasNext();) {
|
|
||||||
UserAuthenticator authenticator = en.next();
|
|
||||||
encodedPassword = authenticator.encode(password);
|
|
||||||
if (encodedPassword != null) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (encodedPassword == null) {
|
|
||||||
throw new CloudRuntimeException("Failed to encode password");
|
|
||||||
}
|
|
||||||
user.setPassword(encodedPassword);
|
|
||||||
}
|
|
||||||
if (email != null) {
|
|
||||||
user.setEmail(email);
|
|
||||||
}
|
|
||||||
if (timeZone != null) {
|
|
||||||
user.setTimezone(timeZone);
|
|
||||||
}
|
|
||||||
if (apiKey != null) {
|
|
||||||
user.setApiKey(apiKey);
|
|
||||||
}
|
|
||||||
if (secretKey != null) {
|
|
||||||
user.setSecretKey(secretKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s_logger.isDebugEnabled()) {
|
|
||||||
s_logger.debug("updating user with id: " + userId);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
// check if the apiKey and secretKey are globally unique
|
|
||||||
if (apiKey != null && secretKey != null) {
|
|
||||||
Pair<User, Account> apiKeyOwner = _accountDao.findUserAccountByApiKey(apiKey);
|
|
||||||
|
|
||||||
if (apiKeyOwner != null) {
|
|
||||||
User usr = apiKeyOwner.first();
|
|
||||||
if (usr.getId() != userId) {
|
|
||||||
throw new InvalidParameterValueException("The api key:" + apiKey + " exists in the system for user id:" + userId + " ,please provide a unique key");
|
|
||||||
} else {
|
|
||||||
// allow the updation to take place
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_userDao.update(userId, user);
|
|
||||||
} catch (Throwable th) {
|
|
||||||
s_logger.error("error updating user", th);
|
|
||||||
throw new CloudRuntimeException("Unable to update user " + userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
CallContext.current().putContextParameter(User.class, user.getUuid());
|
|
||||||
|
|
||||||
return _userAccountDao.findById(userId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_USER_UPDATE, eventDescription = "updating User")
|
* Validates the user 'firstName' if provided. The 'firstName' cannot be blank (when provided).
|
||||||
public UserAccount updateUser(UpdateUserCmd cmd) {
|
* <ul>
|
||||||
Long id = cmd.getId();
|
* <li> If the 'firstName' is not provided, we do not update it (setting to null) in the User POJO.
|
||||||
String apiKey = cmd.getApiKey();
|
* <li> If the 'firstName' is blank, we throw an {@link InvalidParameterValueException}.
|
||||||
String firstName = cmd.getFirstname();
|
* </ul>
|
||||||
String email = cmd.getEmail();
|
*/
|
||||||
String lastName = cmd.getLastname();
|
protected void validateAndUpdateFirstNameIfNeeded(UpdateUserCmd updateUserCmd, UserVO user) {
|
||||||
String password = cmd.getPassword();
|
String firstName = updateUserCmd.getFirstname();
|
||||||
String secretKey = cmd.getSecretKey();
|
if (firstName != null) {
|
||||||
String timeZone = cmd.getTimezone();
|
if (StringUtils.isBlank(firstName)) {
|
||||||
String userName = cmd.getUsername();
|
throw new InvalidParameterValueException("Firstname cannot be empty.");
|
||||||
|
}
|
||||||
|
user.setFirstname(firstName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return updateUser(id, firstName, lastName, email, userName, password, apiKey, secretKey, timeZone);
|
/**
|
||||||
|
* Searches an account for the given users. Then, we validate it as follows:
|
||||||
|
* <ul>
|
||||||
|
* <li>If no account is found for the given user, we throw a {@link CloudRuntimeException}. There must be something wrong in the database for this case.
|
||||||
|
* <li>If the account is of {@link Account#ACCOUNT_TYPE_PROJECT}, we throw an {@link InvalidParameterValueException}.
|
||||||
|
* <li>If the account is of {@link Account#ACCOUNT_ID_SYSTEM}, we throw an {@link InvalidParameterValueException}.
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* Afterwards, we check if the logged user has access to the user being updated via {@link #checkAccess(Account, AccessType, boolean, ControlledEntity...)}
|
||||||
|
*/
|
||||||
|
protected Account retrieveAndValidateAccount(UserVO user) {
|
||||||
|
Account account = _accountDao.findById(user.getAccountId());
|
||||||
|
if (account == null) {
|
||||||
|
throw new CloudRuntimeException("Unable to find user account with ID: " + user.getAccountId());
|
||||||
|
}
|
||||||
|
if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
|
||||||
|
throw new InvalidParameterValueException("Unable to find user with ID: " + user.getUuid());
|
||||||
|
}
|
||||||
|
if (account.getId() == Account.ACCOUNT_ID_SYSTEM) {
|
||||||
|
throw new PermissionDeniedException("user UUID : " + user.getUuid() + " is a system account; update is not allowed.");
|
||||||
|
}
|
||||||
|
checkAccess(getCurrentCallingAccount(), AccessType.OperateEntry, true, account);
|
||||||
|
return account;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the calling account using the method {@link CallContext#getCallingAccount()}.
|
||||||
|
* We are introducing this method to avoid using 'PowerMockRunner' in unit tests. Then, we can mock the calls to this method, which facilitates the development of test cases.
|
||||||
|
*/
|
||||||
|
protected Account getCurrentCallingAccount() {
|
||||||
|
return CallContext.current().getCallingAccount();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates user API and Secret keys. If a new pair of keys is provided, we update them in the user POJO.
|
||||||
|
* <ul>
|
||||||
|
* <li>When updating the keys, it must be provided a pair (API and Secret keys); otherwise, an {@link InvalidParameterValueException} is thrown.
|
||||||
|
* <li>If a pair of keys is provided, we validate to see if there is an user already using the provided API key. If there is someone else using, we throw an {@link InvalidParameterValueException} because two users cannot have the same API key.
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
protected void validateAndUpdatApiAndSecretKeyIfNeeded(UpdateUserCmd updateUserCmd, UserVO user) {
|
||||||
|
String apiKey = updateUserCmd.getApiKey();
|
||||||
|
String secretKey = updateUserCmd.getSecretKey();
|
||||||
|
|
||||||
|
boolean isApiKeyBlank = StringUtils.isBlank(apiKey);
|
||||||
|
boolean isSecretKeyBlank = StringUtils.isBlank(secretKey);
|
||||||
|
if (isApiKeyBlank ^ isSecretKeyBlank) {
|
||||||
|
throw new InvalidParameterValueException("Please provide a userApiKey/userSecretKey pair");
|
||||||
|
}
|
||||||
|
if (isApiKeyBlank && isSecretKeyBlank) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Pair<User, Account> apiKeyOwner = _accountDao.findUserAccountByApiKey(apiKey);
|
||||||
|
if (apiKeyOwner != null) {
|
||||||
|
User userThatHasTheProvidedApiKey = apiKeyOwner.first();
|
||||||
|
if (userThatHasTheProvidedApiKey.getId() != user.getId()) {
|
||||||
|
throw new InvalidParameterValueException(String.format("The API key [%s] already exists in the system. Please provide a unique key.", apiKey));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
user.setApiKey(apiKey);
|
||||||
|
user.setSecretKey(secretKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches for a user with the given userId. If no user is found we throw an {@link InvalidParameterValueException}.
|
||||||
|
*/
|
||||||
|
protected UserVO retrieveAndValidateUser(UpdateUserCmd updateUserCmd) {
|
||||||
|
Long userId = updateUserCmd.getId();
|
||||||
|
|
||||||
|
UserVO user = _userDao.getUser(userId);
|
||||||
|
if (user == null) {
|
||||||
|
throw new InvalidParameterValueException("Unable to find user with id: " + userId);
|
||||||
|
}
|
||||||
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_USER_DISABLE, eventDescription = "disabling User", async = true)
|
@ActionEvent(eventType = EventTypes.EVENT_USER_DISABLE, eventDescription = "disabling User", async = true)
|
||||||
public UserAccount disableUser(long userId) {
|
public UserAccount disableUser(long userId) {
|
||||||
Account caller = CallContext.current().getCallingAccount();
|
Account caller = getCurrentCallingAccount();
|
||||||
|
|
||||||
// Check if user exists in the system
|
// Check if user exists in the system
|
||||||
User user = _userDao.findById(userId);
|
User user = _userDao.findById(userId);
|
||||||
|
|
@ -1345,7 +1433,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_USER_ENABLE, eventDescription = "enabling User")
|
@ActionEvent(eventType = EventTypes.EVENT_USER_ENABLE, eventDescription = "enabling User")
|
||||||
public UserAccount enableUser(final long userId) {
|
public UserAccount enableUser(final long userId) {
|
||||||
|
|
||||||
Account caller = CallContext.current().getCallingAccount();
|
Account caller = getCurrentCallingAccount();
|
||||||
|
|
||||||
// Check if user exists in the system
|
// Check if user exists in the system
|
||||||
final User user = _userDao.findById(userId);
|
final User user = _userDao.findById(userId);
|
||||||
|
|
@ -1396,7 +1484,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
@Override
|
@Override
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_USER_LOCK, eventDescription = "locking User")
|
@ActionEvent(eventType = EventTypes.EVENT_USER_LOCK, eventDescription = "locking User")
|
||||||
public UserAccount lockUser(long userId) {
|
public UserAccount lockUser(long userId) {
|
||||||
Account caller = CallContext.current().getCallingAccount();
|
Account caller = getCurrentCallingAccount();
|
||||||
|
|
||||||
// Check if user with id exists in the system
|
// Check if user with id exists in the system
|
||||||
User user = _userDao.findById(userId);
|
User user = _userDao.findById(userId);
|
||||||
|
|
@ -1462,7 +1550,6 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_DELETE, eventDescription = "deleting account", async = true)
|
@ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_DELETE, eventDescription = "deleting account", async = true)
|
||||||
// This method deletes the account
|
|
||||||
public boolean deleteUserAccount(long accountId) {
|
public boolean deleteUserAccount(long accountId) {
|
||||||
|
|
||||||
CallContext ctx = CallContext.current();
|
CallContext ctx = CallContext.current();
|
||||||
|
|
@ -1528,7 +1615,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if user performing the action is allowed to modify this account
|
// Check if user performing the action is allowed to modify this account
|
||||||
Account caller = CallContext.current().getCallingAccount();
|
Account caller = getCurrentCallingAccount();
|
||||||
checkAccess(caller, AccessType.OperateEntry, true, account);
|
checkAccess(caller, AccessType.OperateEntry, true, account);
|
||||||
|
|
||||||
boolean success = enableAccount(account.getId());
|
boolean success = enableAccount(account.getId());
|
||||||
|
|
@ -1545,7 +1632,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
@Override
|
@Override
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_DISABLE, eventDescription = "locking account", async = true)
|
@ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_DISABLE, eventDescription = "locking account", async = true)
|
||||||
public AccountVO lockAccount(String accountName, Long domainId, Long accountId) {
|
public AccountVO lockAccount(String accountName, Long domainId, Long accountId) {
|
||||||
Account caller = CallContext.current().getCallingAccount();
|
Account caller = getCurrentCallingAccount();
|
||||||
|
|
||||||
Account account = null;
|
Account account = null;
|
||||||
if (accountId != null) {
|
if (accountId != null) {
|
||||||
|
|
@ -1575,7 +1662,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
@Override
|
@Override
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_DISABLE, eventDescription = "disabling account", async = true)
|
@ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_DISABLE, eventDescription = "disabling account", async = true)
|
||||||
public AccountVO disableAccount(String accountName, Long domainId, Long accountId) throws ConcurrentOperationException, ResourceUnavailableException {
|
public AccountVO disableAccount(String accountName, Long domainId, Long accountId) throws ConcurrentOperationException, ResourceUnavailableException {
|
||||||
Account caller = CallContext.current().getCallingAccount();
|
Account caller = getCurrentCallingAccount();
|
||||||
|
|
||||||
Account account = null;
|
Account account = null;
|
||||||
if (accountId != null) {
|
if (accountId != null) {
|
||||||
|
|
@ -1633,16 +1720,11 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if user performing the action is allowed to modify this account
|
// Check if user performing the action is allowed to modify this account
|
||||||
checkAccess(CallContext.current().getCallingAccount(), _domainMgr.getDomain(account.getDomainId()));
|
checkAccess(getCurrentCallingAccount(), _domainMgr.getDomain(account.getDomainId()));
|
||||||
|
|
||||||
// check if the given account name is unique in this domain for updating
|
// check if the given account name is unique in this domain for updating
|
||||||
Account duplicateAcccount = _accountDao.findActiveAccount(newAccountName, domainId);
|
Account duplicateAcccount = _accountDao.findActiveAccount(newAccountName, domainId);
|
||||||
if (duplicateAcccount != null && duplicateAcccount.getId() != account.getId()) {// allow
|
if (duplicateAcccount != null && duplicateAcccount.getId() != account.getId()) {
|
||||||
// same
|
|
||||||
// account
|
|
||||||
// to
|
|
||||||
// update
|
|
||||||
// itself
|
|
||||||
throw new InvalidParameterValueException(
|
throw new InvalidParameterValueException(
|
||||||
"There already exists an account with the name:" + newAccountName + " in the domain:" + domainId + " with existing account id:" + duplicateAcccount.getId());
|
"There already exists an account with the name:" + newAccountName + " in the domain:" + domainId + " with existing account id:" + duplicateAcccount.getId());
|
||||||
}
|
}
|
||||||
|
|
@ -1700,6 +1782,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
return _userDao.remove(deleteUserCmd.getId());
|
return _userDao.remove(deleteUserCmd.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_USER_MOVE, eventDescription = "moving User to a new account")
|
@ActionEvent(eventType = EventTypes.EVENT_USER_MOVE, eventDescription = "moving User to a new account")
|
||||||
public boolean moveUser(MoveUserCmd cmd) {
|
public boolean moveUser(MoveUserCmd cmd) {
|
||||||
final Long id = cmd.getId();
|
final Long id = cmd.getId();
|
||||||
|
|
@ -1713,17 +1796,18 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
return moveUser(user, newAccountId);
|
return moveUser(user, newAccountId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean moveUser(long id, Long domainId, long accountId) {
|
public boolean moveUser(long id, Long domainId, long accountId) {
|
||||||
UserVO user = getValidUserVO(id);
|
UserVO user = getValidUserVO(id);
|
||||||
Account oldAccount = _accountDao.findById(user.getAccountId());
|
Account oldAccount = _accountDao.findById(user.getAccountId());
|
||||||
checkAccountAndAccess(user, oldAccount);
|
checkAccountAndAccess(user, oldAccount);
|
||||||
Account newAccount = _accountDao.findById(accountId);
|
Account newAccount = _accountDao.findById(accountId);
|
||||||
checkIfNotMovingAcrossDomains(domainId, newAccount);
|
checkIfNotMovingAcrossDomains(domainId, newAccount);
|
||||||
return moveUser(user , accountId);
|
return moveUser(user, accountId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean moveUser(UserVO user, long newAccountId) {
|
private boolean moveUser(UserVO user, long newAccountId) {
|
||||||
if(newAccountId == user.getAccountId()) {
|
if (newAccountId == user.getAccountId()) {
|
||||||
// could do a not silent fail but the objective of the user is reached
|
// 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 true; // no need to create a new user object for this user
|
||||||
}
|
}
|
||||||
|
|
@ -1734,7 +1818,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
UserVO newUser = new UserVO(user);
|
UserVO newUser = new UserVO(user);
|
||||||
user.setExternalEntity(user.getUuid());
|
user.setExternalEntity(user.getUuid());
|
||||||
user.setUuid(UUID.randomUUID().toString());
|
user.setUuid(UUID.randomUUID().toString());
|
||||||
_userDao.update(user.getId(),user);
|
_userDao.update(user.getId(), user);
|
||||||
newUser.setAccountId(newAccountId);
|
newUser.setAccountId(newAccountId);
|
||||||
boolean success = _userDao.remove(user.getId());
|
boolean success = _userDao.remove(user.getId());
|
||||||
UserVO persisted = _userDao.persist(newUser);
|
UserVO persisted = _userDao.persist(newUser);
|
||||||
|
|
@ -1746,7 +1830,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
private long getNewAccountId(long domainId, String accountName, Long accountId) {
|
private long getNewAccountId(long domainId, String accountName, Long accountId) {
|
||||||
Account newAccount = null;
|
Account newAccount = null;
|
||||||
if (StringUtils.isNotBlank(accountName)) {
|
if (StringUtils.isNotBlank(accountName)) {
|
||||||
if(s_logger.isDebugEnabled()) {
|
if (s_logger.isDebugEnabled()) {
|
||||||
s_logger.debug("Getting id for account by name '" + accountName + "' in domain " + domainId);
|
s_logger.debug("Getting id for account by name '" + accountName + "' in domain " + domainId);
|
||||||
}
|
}
|
||||||
newAccount = _accountDao.findEnabledAccount(accountName, domainId);
|
newAccount = _accountDao.findEnabledAccount(accountName, domainId);
|
||||||
|
|
@ -1763,7 +1847,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkIfNotMovingAcrossDomains(long domainId, Account newAccount) {
|
private void checkIfNotMovingAcrossDomains(long domainId, Account newAccount) {
|
||||||
if(newAccount.getDomainId() != domainId) {
|
if (newAccount.getDomainId() != domainId) {
|
||||||
// not in scope
|
// not in scope
|
||||||
throw new InvalidParameterValueException("moving a user from an account in one domain to an account in annother domain is not supported!");
|
throw new InvalidParameterValueException("moving a user from an account in one domain to an account in annother domain is not supported!");
|
||||||
}
|
}
|
||||||
|
|
@ -1775,7 +1859,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
throw new InvalidParameterValueException("Project users cannot be deleted or moved.");
|
throw new InvalidParameterValueException("Project users cannot be deleted or moved.");
|
||||||
}
|
}
|
||||||
|
|
||||||
checkAccess(CallContext.current().getCallingAccount(), AccessType.OperateEntry, true, account);
|
checkAccess(getCurrentCallingAccount(), AccessType.OperateEntry, true, account);
|
||||||
CallContext.current().putContextParameter(User.class, user.getUuid());
|
CallContext.current().putContextParameter(User.class, user.getUuid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1995,8 +2079,8 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@DB
|
@DB
|
||||||
public AccountVO createAccount(final String accountName, final short accountType, final Long roleId, final Long domainId, final String networkDomain,
|
public AccountVO createAccount(final String accountName, final short accountType, final Long roleId, final Long domainId, final String networkDomain, final Map<String, String> details,
|
||||||
final Map<String, String> details, final String uuid) {
|
final String uuid) {
|
||||||
// Validate domain
|
// Validate domain
|
||||||
Domain domain = _domainMgr.getDomain(domainId);
|
Domain domain = _domainMgr.getDomain(domainId);
|
||||||
if (domain == null) {
|
if (domain == null) {
|
||||||
|
|
@ -2064,8 +2148,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected UserVO createUser(long accountId, String userName, String password, String firstName, String lastName, String email, String timezone, String userUUID,
|
protected UserVO createUser(long accountId, String userName, String password, String firstName, String lastName, String email, String timezone, String userUUID, User.Source source) {
|
||||||
User.Source source) {
|
|
||||||
if (s_logger.isDebugEnabled()) {
|
if (s_logger.isDebugEnabled()) {
|
||||||
s_logger.debug("Creating user: " + userName + ", accountId: " + accountId + " timezone:" + timezone);
|
s_logger.debug("Creating user: " + userName + ", accountId: " + accountId + " timezone:" + timezone);
|
||||||
}
|
}
|
||||||
|
|
@ -2098,8 +2181,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserAccount authenticateUser(final String username, final String password, final Long domainId, final InetAddress loginIpAddress, final Map<String, Object[]>
|
public UserAccount authenticateUser(final String username, final String password, final Long domainId, final InetAddress loginIpAddress, final Map<String, Object[]> requestParameters) {
|
||||||
requestParameters) {
|
|
||||||
UserAccount user = null;
|
UserAccount user = null;
|
||||||
if (password != null && !password.isEmpty()) {
|
if (password != null && !password.isEmpty()) {
|
||||||
user = getUserAccount(username, password, domainId, requestParameters);
|
user = getUserAccount(username, password, domainId, requestParameters);
|
||||||
|
|
@ -2211,10 +2293,10 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
|
|
||||||
// We authenticated successfully by now, let's check if we are allowed to login from the ip address the reqest comes from
|
// We authenticated successfully by now, let's check if we are allowed to login from the ip address the reqest comes from
|
||||||
final Account account = _accountMgr.getAccount(user.getAccountId());
|
final Account account = _accountMgr.getAccount(user.getAccountId());
|
||||||
final DomainVO domain = (DomainVO) _domainMgr.getDomain(account.getDomainId());
|
final DomainVO domain = (DomainVO)_domainMgr.getDomain(account.getDomainId());
|
||||||
|
|
||||||
// Get the CIDRs from where this account is allowed to make calls
|
// Get the CIDRs from where this account is allowed to make calls
|
||||||
final String accessAllowedCidrs = ApiServiceConfiguration.ApiAllowedSourceCidrList.valueIn(account.getId()).replaceAll("\\s","");
|
final String accessAllowedCidrs = ApiServiceConfiguration.ApiAllowedSourceCidrList.valueIn(account.getId()).replaceAll("\\s", "");
|
||||||
final Boolean ApiSourceCidrChecksEnabled = ApiServiceConfiguration.ApiSourceCidrChecksEnabled.value();
|
final Boolean ApiSourceCidrChecksEnabled = ApiServiceConfiguration.ApiSourceCidrChecksEnabled.value();
|
||||||
|
|
||||||
if (ApiSourceCidrChecksEnabled) {
|
if (ApiSourceCidrChecksEnabled) {
|
||||||
|
|
@ -2222,10 +2304,9 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
|
|
||||||
// Block when is not in the list of allowed IPs
|
// Block when is not in the list of allowed IPs
|
||||||
if (!NetUtils.isIpInCidrList(loginIpAddress, accessAllowedCidrs.split(","))) {
|
if (!NetUtils.isIpInCidrList(loginIpAddress, accessAllowedCidrs.split(","))) {
|
||||||
s_logger.warn("Request by account '" + account.toString() + "' was denied since " + loginIpAddress.toString().replaceAll("/","")
|
s_logger.warn("Request by account '" + account.toString() + "' was denied since " + loginIpAddress.toString().replaceAll("/", "") + " does not match " + accessAllowedCidrs);
|
||||||
+ " does not match " + accessAllowedCidrs);
|
|
||||||
throw new CloudAuthenticationException("Failed to authenticate user '" + username + "' in domain '" + domain.getPath() + "' from ip "
|
throw new CloudAuthenticationException("Failed to authenticate user '" + username + "' in domain '" + domain.getPath() + "' from ip "
|
||||||
+ loginIpAddress.toString().replaceAll("/","") + "; please provide valid credentials");
|
+ loginIpAddress.toString().replaceAll("/", "") + "; please provide valid credentials");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2234,8 +2315,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
s_logger.debug("User: " + username + " in domain " + domainId + " has successfully logged in");
|
s_logger.debug("User: " + username + " in domain " + domainId + " has successfully logged in");
|
||||||
}
|
}
|
||||||
|
|
||||||
ActionEventUtils.onActionEvent(user.getId(), user.getAccountId(), user.getDomainId(), EventTypes.EVENT_USER_LOGIN,
|
ActionEventUtils.onActionEvent(user.getId(), user.getAccountId(), user.getDomainId(), EventTypes.EVENT_USER_LOGIN, "user has logged in from IP Address " + loginIpAddress);
|
||||||
"user has logged in from IP Address " + loginIpAddress);
|
|
||||||
|
|
||||||
return user;
|
return user;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2285,12 +2365,12 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
if (s_logger.isInfoEnabled()) {
|
if (s_logger.isInfoEnabled()) {
|
||||||
s_logger.info("User " + username + " in domain " + domainName + " is disabled/locked (or account is disabled/locked)");
|
s_logger.info("User " + username + " in domain " + domainName + " is disabled/locked (or account is disabled/locked)");
|
||||||
}
|
}
|
||||||
throw new CloudAuthenticationException(
|
throw new CloudAuthenticationException("User " + username + " (or their account) in domain " + domainName + " is disabled/locked. Please contact the administrator.");
|
||||||
"User " + username + " (or their account) in domain " + domainName + " is disabled/locked. Please contact the administrator.");
|
|
||||||
}
|
}
|
||||||
// Whenever the user is able to log in successfully, reset the login attempts to zero
|
// Whenever the user is able to log in successfully, reset the login attempts to zero
|
||||||
if (!isInternalAccount(userAccount.getId()))
|
if (!isInternalAccount(userAccount.getId())) {
|
||||||
updateLoginAttempts(userAccount.getId(), 0, false);
|
updateLoginAttempts(userAccount.getId(), 0, false);
|
||||||
|
}
|
||||||
|
|
||||||
return userAccount;
|
return userAccount;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2351,7 +2431,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
@DB
|
@DB
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_REGISTER_FOR_SECRET_API_KEY, eventDescription = "register for the developer API keys")
|
@ActionEvent(eventType = EventTypes.EVENT_REGISTER_FOR_SECRET_API_KEY, eventDescription = "register for the developer API keys")
|
||||||
public String[] createApiKeyAndSecretKey(RegisterCmd cmd) {
|
public String[] createApiKeyAndSecretKey(RegisterCmd cmd) {
|
||||||
Account caller = CallContext.current().getCallingAccount();
|
Account caller = getCurrentCallingAccount();
|
||||||
final Long userId = cmd.getId();
|
final Long userId = cmd.getId();
|
||||||
|
|
||||||
User user = getUserIncludingRemoved(userId);
|
User user = getUserIncludingRemoved(userId);
|
||||||
|
|
@ -2668,8 +2748,9 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> listAclGroupsByAccount(Long accountId) {
|
public List<String> listAclGroupsByAccount(Long accountId) {
|
||||||
if (_querySelectors == null || _querySelectors.size() == 0)
|
if (_querySelectors == null || _querySelectors.size() == 0) {
|
||||||
return new ArrayList<String>();
|
return new ArrayList<String>();
|
||||||
|
}
|
||||||
|
|
||||||
QuerySelector qs = _querySelectors.get(0);
|
QuerySelector qs = _querySelectors.get(0);
|
||||||
return qs.listAclGroupsByAccount(accountId);
|
return qs.listAclGroupsByAccount(accountId);
|
||||||
|
|
@ -2692,8 +2773,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||||
if (!enabledOnly || account.getState() == Account.State.enabled) {
|
if (!enabledOnly || account.getState() == Account.State.enabled) {
|
||||||
return account.getId();
|
return account.getId();
|
||||||
} else {
|
} else {
|
||||||
throw new PermissionDeniedException(
|
throw new PermissionDeniedException("Can't add resources to the account id=" + account.getId() + " in state=" + account.getState() + " as it's no longer active");
|
||||||
"Can't add resources to the account id=" + account.getId() + " in state=" + account.getState() + " as it's no longer active");
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// idList is not used anywhere, so removed it now
|
// idList is not used anywhere, so removed it now
|
||||||
|
|
|
||||||
|
|
@ -22,67 +22,100 @@ import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.cloud.acl.DomainChecker;
|
|
||||||
import com.cloud.exception.PermissionDeniedException;
|
|
||||||
import com.cloud.server.auth.UserAuthenticator;
|
|
||||||
import com.cloud.utils.Pair;
|
|
||||||
|
|
||||||
import org.apache.cloudstack.api.command.admin.user.GetUserKeysCmd;
|
|
||||||
import org.apache.cloudstack.context.CallContext;
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.apache.cloudstack.acl.ControlledEntity;
|
import org.apache.cloudstack.acl.ControlledEntity;
|
||||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||||
import com.cloud.vm.snapshot.VMSnapshotVO;
|
import org.apache.cloudstack.api.command.admin.user.GetUserKeysCmd;
|
||||||
|
import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
|
||||||
|
import org.apache.cloudstack.context.CallContext;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.InOrder;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import com.cloud.acl.DomainChecker;
|
||||||
import com.cloud.domain.Domain;
|
import com.cloud.domain.Domain;
|
||||||
import com.cloud.domain.DomainVO;
|
import com.cloud.domain.DomainVO;
|
||||||
import com.cloud.exception.ConcurrentOperationException;
|
import com.cloud.exception.ConcurrentOperationException;
|
||||||
|
import com.cloud.exception.InvalidParameterValueException;
|
||||||
|
import com.cloud.exception.PermissionDeniedException;
|
||||||
import com.cloud.exception.ResourceUnavailableException;
|
import com.cloud.exception.ResourceUnavailableException;
|
||||||
|
import com.cloud.server.auth.UserAuthenticator;
|
||||||
|
import com.cloud.server.auth.UserAuthenticator.ActionOnFailedAuthentication;
|
||||||
import com.cloud.user.Account.State;
|
import com.cloud.user.Account.State;
|
||||||
|
import com.cloud.utils.Pair;
|
||||||
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
import com.cloud.vm.UserVmManagerImpl;
|
import com.cloud.vm.UserVmManagerImpl;
|
||||||
import com.cloud.vm.UserVmVO;
|
import com.cloud.vm.UserVmVO;
|
||||||
import com.cloud.vm.VMInstanceVO;
|
import com.cloud.vm.VMInstanceVO;
|
||||||
|
import com.cloud.vm.snapshot.VMSnapshotVO;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class AccountManagerImplTest extends AccountManagetImplTestBase {
|
public class AccountManagerImplTest extends AccountManagetImplTestBase {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private UserVmManagerImpl _vmMgr;
|
||||||
|
@Mock
|
||||||
|
private AccountVO callingAccount;
|
||||||
|
@Mock
|
||||||
|
private DomainChecker domainChecker;
|
||||||
|
@Mock
|
||||||
|
private AccountService accountService;
|
||||||
|
@Mock
|
||||||
|
private GetUserKeysCmd _listkeyscmd;
|
||||||
|
@Mock
|
||||||
|
private User _user;
|
||||||
|
@Mock
|
||||||
|
private UserAccountVO userAccountVO;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
UserVmManagerImpl _vmMgr;
|
private UpdateUserCmd UpdateUserCmdMock;
|
||||||
|
|
||||||
@Test
|
private long userVoIdMock = 111l;
|
||||||
public void disableAccountNotexisting()
|
@Mock
|
||||||
throws ConcurrentOperationException, ResourceUnavailableException {
|
private UserVO userVoMock;
|
||||||
Mockito.when(_accountDao.findById(42l)).thenReturn(null);
|
|
||||||
Assert.assertTrue(accountManager.disableAccount(42));
|
private long accountMockId = 100l;
|
||||||
|
@Mock
|
||||||
|
private Account accountMock;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void beforeTest() {
|
||||||
|
Mockito.doReturn(accountMockId).when(accountMock).getId();
|
||||||
|
Mockito.doReturn(accountMock).when(accountManagerImpl).getCurrentCallingAccount();
|
||||||
|
|
||||||
|
Mockito.doReturn(accountMockId).when(userVoMock).getAccountId();
|
||||||
|
|
||||||
|
Mockito.doReturn(userVoIdMock).when(userVoMock).getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void disableAccountDisabled() throws ConcurrentOperationException,
|
public void disableAccountNotexisting() throws ConcurrentOperationException, ResourceUnavailableException {
|
||||||
ResourceUnavailableException {
|
Mockito.when(accountDaoMock.findById(42l)).thenReturn(null);
|
||||||
|
Assert.assertTrue(accountManagerImpl.disableAccount(42));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void disableAccountDisabled() throws ConcurrentOperationException, ResourceUnavailableException {
|
||||||
AccountVO disabledAccount = new AccountVO();
|
AccountVO disabledAccount = new AccountVO();
|
||||||
disabledAccount.setState(State.disabled);
|
disabledAccount.setState(State.disabled);
|
||||||
Mockito.when(_accountDao.findById(42l)).thenReturn(disabledAccount);
|
Mockito.when(accountDaoMock.findById(42l)).thenReturn(disabledAccount);
|
||||||
Assert.assertTrue(accountManager.disableAccount(42));
|
Assert.assertTrue(accountManagerImpl.disableAccount(42));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void disableAccount() throws ConcurrentOperationException,
|
public void disableAccount() throws ConcurrentOperationException, ResourceUnavailableException {
|
||||||
ResourceUnavailableException {
|
|
||||||
AccountVO account = new AccountVO();
|
AccountVO account = new AccountVO();
|
||||||
account.setState(State.enabled);
|
account.setState(State.enabled);
|
||||||
Mockito.when(_accountDao.findById(42l)).thenReturn(account);
|
Mockito.when(accountDaoMock.findById(42l)).thenReturn(account);
|
||||||
Mockito.when(_accountDao.createForUpdate()).thenReturn(new AccountVO());
|
Mockito.when(accountDaoMock.createForUpdate()).thenReturn(new AccountVO());
|
||||||
Mockito.when(
|
Mockito.when(accountDaoMock.update(Mockito.eq(42l), Mockito.any(AccountVO.class))).thenReturn(true);
|
||||||
_accountDao.update(Mockito.eq(42l),
|
Mockito.when(_vmDao.listByAccountId(42l)).thenReturn(Arrays.asList(Mockito.mock(VMInstanceVO.class)));
|
||||||
Mockito.any(AccountVO.class))).thenReturn(true);
|
Assert.assertTrue(accountManagerImpl.disableAccount(42));
|
||||||
Mockito.when(_vmDao.listByAccountId(42l)).thenReturn(
|
Mockito.verify(accountDaoMock, Mockito.atLeastOnce()).update(Mockito.eq(42l), Mockito.any(AccountVO.class));
|
||||||
Arrays.asList(Mockito.mock(VMInstanceVO.class)));
|
|
||||||
Assert.assertTrue(accountManager.disableAccount(42));
|
|
||||||
Mockito.verify(_accountDao, Mockito.atLeastOnce()).update(
|
|
||||||
Mockito.eq(42l), Mockito.any(AccountVO.class));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -90,20 +123,12 @@ public class AccountManagerImplTest extends AccountManagetImplTestBase {
|
||||||
AccountVO account = new AccountVO();
|
AccountVO account = new AccountVO();
|
||||||
account.setId(42l);
|
account.setId(42l);
|
||||||
DomainVO domain = new DomainVO();
|
DomainVO domain = new DomainVO();
|
||||||
Mockito.when(_accountDao.findById(42l)).thenReturn(account);
|
Mockito.when(accountDaoMock.findById(42l)).thenReturn(account);
|
||||||
Mockito.when(
|
Mockito.when(securityChecker.checkAccess(Mockito.any(Account.class), Mockito.any(ControlledEntity.class), Mockito.any(AccessType.class), Mockito.anyString())).thenReturn(true);
|
||||||
securityChecker.checkAccess(Mockito.any(Account.class),
|
Mockito.when(accountDaoMock.remove(42l)).thenReturn(true);
|
||||||
Mockito.any(ControlledEntity.class), Mockito.any(AccessType.class),
|
Mockito.when(_configMgr.releaseAccountSpecificVirtualRanges(42l)).thenReturn(true);
|
||||||
Mockito.anyString()))
|
|
||||||
.thenReturn(true);
|
|
||||||
Mockito.when(_accountDao.remove(42l)).thenReturn(true);
|
|
||||||
Mockito.when(_configMgr.releaseAccountSpecificVirtualRanges(42l))
|
|
||||||
.thenReturn(true);
|
|
||||||
Mockito.when(_domainMgr.getDomain(Mockito.anyLong())).thenReturn(domain);
|
Mockito.when(_domainMgr.getDomain(Mockito.anyLong())).thenReturn(domain);
|
||||||
Mockito.when(
|
Mockito.when(securityChecker.checkAccess(Mockito.any(Account.class), Mockito.any(Domain.class))).thenReturn(true);
|
||||||
securityChecker.checkAccess(Mockito.any(Account.class),
|
|
||||||
Mockito.any(Domain.class)))
|
|
||||||
.thenReturn(true);
|
|
||||||
Mockito.when(_vmSnapshotDao.listByAccountId(Mockito.anyLong())).thenReturn(new ArrayList<VMSnapshotVO>());
|
Mockito.when(_vmSnapshotDao.listByAccountId(Mockito.anyLong())).thenReturn(new ArrayList<VMSnapshotVO>());
|
||||||
|
|
||||||
List<SSHKeyPairVO> sshkeyList = new ArrayList<SSHKeyPairVO>();
|
List<SSHKeyPairVO> sshkeyList = new ArrayList<SSHKeyPairVO>();
|
||||||
|
|
@ -113,10 +138,9 @@ public class AccountManagerImplTest extends AccountManagetImplTestBase {
|
||||||
Mockito.when(_sshKeyPairDao.listKeyPairs(Mockito.anyLong(), Mockito.anyLong())).thenReturn(sshkeyList);
|
Mockito.when(_sshKeyPairDao.listKeyPairs(Mockito.anyLong(), Mockito.anyLong())).thenReturn(sshkeyList);
|
||||||
Mockito.when(_sshKeyPairDao.remove(Mockito.anyLong())).thenReturn(true);
|
Mockito.when(_sshKeyPairDao.remove(Mockito.anyLong())).thenReturn(true);
|
||||||
|
|
||||||
Assert.assertTrue(accountManager.deleteUserAccount(42));
|
Assert.assertTrue(accountManagerImpl.deleteUserAccount(42));
|
||||||
// assert that this was a clean delete
|
// assert that this was a clean delete
|
||||||
Mockito.verify(_accountDao, Mockito.never()).markForCleanup(
|
Mockito.verify(accountDaoMock, Mockito.never()).markForCleanup(Mockito.eq(42l));
|
||||||
Mockito.eq(42l));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -124,33 +148,20 @@ public class AccountManagerImplTest extends AccountManagetImplTestBase {
|
||||||
AccountVO account = new AccountVO();
|
AccountVO account = new AccountVO();
|
||||||
account.setId(42l);
|
account.setId(42l);
|
||||||
DomainVO domain = new DomainVO();
|
DomainVO domain = new DomainVO();
|
||||||
Mockito.when(_accountDao.findById(42l)).thenReturn(account);
|
Mockito.when(accountDaoMock.findById(42l)).thenReturn(account);
|
||||||
Mockito.when(
|
Mockito.when(securityChecker.checkAccess(Mockito.any(Account.class), Mockito.any(ControlledEntity.class), Mockito.any(AccessType.class), Mockito.anyString())).thenReturn(true);
|
||||||
securityChecker.checkAccess(Mockito.any(Account.class),
|
Mockito.when(accountDaoMock.remove(42l)).thenReturn(true);
|
||||||
Mockito.any(ControlledEntity.class), Mockito.any(AccessType.class),
|
Mockito.when(_configMgr.releaseAccountSpecificVirtualRanges(42l)).thenReturn(true);
|
||||||
Mockito.anyString()))
|
Mockito.when(_userVmDao.listByAccountId(42l)).thenReturn(Arrays.asList(Mockito.mock(UserVmVO.class)));
|
||||||
.thenReturn(true);
|
Mockito.when(_vmMgr.expunge(Mockito.any(UserVmVO.class), Mockito.anyLong(), Mockito.any(Account.class))).thenReturn(false);
|
||||||
Mockito.when(_accountDao.remove(42l)).thenReturn(true);
|
|
||||||
Mockito.when(_configMgr.releaseAccountSpecificVirtualRanges(42l))
|
|
||||||
.thenReturn(true);
|
|
||||||
Mockito.when(_userVmDao.listByAccountId(42l)).thenReturn(
|
|
||||||
Arrays.asList(Mockito.mock(UserVmVO.class)));
|
|
||||||
Mockito.when(
|
|
||||||
_vmMgr.expunge(Mockito.any(UserVmVO.class), Mockito.anyLong(),
|
|
||||||
Mockito.any(Account.class))).thenReturn(false);
|
|
||||||
Mockito.when(_domainMgr.getDomain(Mockito.anyLong())).thenReturn(domain);
|
Mockito.when(_domainMgr.getDomain(Mockito.anyLong())).thenReturn(domain);
|
||||||
Mockito.when(
|
Mockito.when(securityChecker.checkAccess(Mockito.any(Account.class), Mockito.any(Domain.class))).thenReturn(true);
|
||||||
securityChecker.checkAccess(Mockito.any(Account.class),
|
|
||||||
Mockito.any(Domain.class)))
|
|
||||||
.thenReturn(true);
|
|
||||||
|
|
||||||
Assert.assertTrue(accountManager.deleteUserAccount(42));
|
Assert.assertTrue(accountManagerImpl.deleteUserAccount(42));
|
||||||
// assert that this was NOT a clean delete
|
// assert that this was NOT a clean delete
|
||||||
Mockito.verify(_accountDao, Mockito.atLeastOnce()).markForCleanup(
|
Mockito.verify(accountDaoMock, Mockito.atLeastOnce()).markForCleanup(Mockito.eq(42l));
|
||||||
Mockito.eq(42l));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAuthenticateUser() throws UnknownHostException {
|
public void testAuthenticateUser() throws UnknownHostException {
|
||||||
Pair<Boolean, UserAuthenticator.ActionOnFailedAuthentication> successAuthenticationPair = new Pair<>(true, null);
|
Pair<Boolean, UserAuthenticator.ActionOnFailedAuthentication> successAuthenticationPair = new Pair<>(true, null);
|
||||||
|
|
@ -160,21 +171,21 @@ public class AccountManagerImplTest extends AccountManagetImplTestBase {
|
||||||
UserAccountVO userAccountVO = new UserAccountVO();
|
UserAccountVO userAccountVO = new UserAccountVO();
|
||||||
userAccountVO.setSource(User.Source.UNKNOWN);
|
userAccountVO.setSource(User.Source.UNKNOWN);
|
||||||
userAccountVO.setState(Account.State.disabled.toString());
|
userAccountVO.setState(Account.State.disabled.toString());
|
||||||
Mockito.when(_userAccountDao.getUserAccount("test", 1L)).thenReturn(userAccountVO);
|
Mockito.when(userAccountDaoMock.getUserAccount("test", 1L)).thenReturn(userAccountVO);
|
||||||
Mockito.when(userAuthenticator.authenticate("test", "fail", 1L, null)).thenReturn(failureAuthenticationPair);
|
Mockito.when(userAuthenticator.authenticate("test", "fail", 1L, null)).thenReturn(failureAuthenticationPair);
|
||||||
Mockito.when(userAuthenticator.authenticate("test", null, 1L, null)).thenReturn(successAuthenticationPair);
|
Mockito.when(userAuthenticator.authenticate("test", null, 1L, null)).thenReturn(successAuthenticationPair);
|
||||||
Mockito.when(userAuthenticator.authenticate("test", "", 1L, null)).thenReturn(successAuthenticationPair);
|
Mockito.when(userAuthenticator.authenticate("test", "", 1L, null)).thenReturn(successAuthenticationPair);
|
||||||
|
|
||||||
//Test for incorrect password. authentication should fail
|
//Test for incorrect password. authentication should fail
|
||||||
UserAccount userAccount = accountManager.authenticateUser("test", "fail", 1L, InetAddress.getByName("127.0.0.1"), null);
|
UserAccount userAccount = accountManagerImpl.authenticateUser("test", "fail", 1L, InetAddress.getByName("127.0.0.1"), null);
|
||||||
Assert.assertNull(userAccount);
|
Assert.assertNull(userAccount);
|
||||||
|
|
||||||
//Test for null password. authentication should fail
|
//Test for null password. authentication should fail
|
||||||
userAccount = accountManager.authenticateUser("test", null, 1L, InetAddress.getByName("127.0.0.1"), null);
|
userAccount = accountManagerImpl.authenticateUser("test", null, 1L, InetAddress.getByName("127.0.0.1"), null);
|
||||||
Assert.assertNull(userAccount);
|
Assert.assertNull(userAccount);
|
||||||
|
|
||||||
//Test for empty password. authentication should fail
|
//Test for empty password. authentication should fail
|
||||||
userAccount = accountManager.authenticateUser("test", "", 1L, InetAddress.getByName("127.0.0.1"), null);
|
userAccount = accountManagerImpl.authenticateUser("test", "", 1L, InetAddress.getByName("127.0.0.1"), null);
|
||||||
Assert.assertNull(userAccount);
|
Assert.assertNull(userAccount);
|
||||||
|
|
||||||
//Verifying that the authentication method is only called when password is specified
|
//Verifying that the authentication method is only called when password is specified
|
||||||
|
|
@ -183,38 +194,509 @@ public class AccountManagerImplTest extends AccountManagetImplTestBase {
|
||||||
Mockito.verify(userAuthenticator, Mockito.never()).authenticate("test", "", 1L, null);
|
Mockito.verify(userAuthenticator, Mockito.never()).authenticate("test", "", 1L, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Mock
|
@Test(expected = PermissionDeniedException.class)
|
||||||
AccountVO callingAccount;
|
public void testgetUserCmd() {
|
||||||
@Mock
|
|
||||||
DomainChecker domainChecker;
|
|
||||||
@Mock
|
|
||||||
AccountService accountService;
|
|
||||||
@Mock
|
|
||||||
private GetUserKeysCmd _listkeyscmd;
|
|
||||||
@Mock
|
|
||||||
private Account _account;
|
|
||||||
@Mock
|
|
||||||
private User _user;
|
|
||||||
@Mock
|
|
||||||
private UserAccountVO userAccountVO;
|
|
||||||
|
|
||||||
|
|
||||||
@Test (expected = PermissionDeniedException.class)
|
|
||||||
public void testgetUserCmd(){
|
|
||||||
CallContext.register(callingUser, callingAccount); // Calling account is user account i.e normal account
|
CallContext.register(callingUser, callingAccount); // Calling account is user account i.e normal account
|
||||||
Mockito.when(_listkeyscmd.getID()).thenReturn(1L);
|
Mockito.when(_listkeyscmd.getID()).thenReturn(1L);
|
||||||
Mockito.when(accountManager.getActiveUser(1L)).thenReturn(_user);
|
Mockito.when(accountManagerImpl.getActiveUser(1L)).thenReturn(_user);
|
||||||
Mockito.when(accountManager.getUserAccountById(1L)).thenReturn(userAccountVO);
|
Mockito.when(accountManagerImpl.getUserAccountById(1L)).thenReturn(userAccountVO);
|
||||||
Mockito.when(userAccountVO.getAccountId()).thenReturn(1L);
|
Mockito.when(userAccountVO.getAccountId()).thenReturn(1L);
|
||||||
Mockito.when(accountManager.getAccount(Mockito.anyLong())).thenReturn(_account); // Queried account - admin account
|
Mockito.when(accountManagerImpl.getAccount(Mockito.anyLong())).thenReturn(accountMock); // Queried account - admin account
|
||||||
|
|
||||||
Mockito.when(callingUser.getAccountId()).thenReturn(1L);
|
Mockito.when(callingUser.getAccountId()).thenReturn(1L);
|
||||||
Mockito.when(_accountDao.findById(1L)).thenReturn(callingAccount);
|
Mockito.when(accountDaoMock.findById(1L)).thenReturn(callingAccount);
|
||||||
|
|
||||||
Mockito.when(accountService.isNormalUser(Mockito.anyLong())).thenReturn(Boolean.TRUE);
|
Mockito.when(accountService.isNormalUser(Mockito.anyLong())).thenReturn(Boolean.TRUE);
|
||||||
Mockito.when(_account.getAccountId()).thenReturn(2L);
|
Mockito.when(accountMock.getAccountId()).thenReturn(2L);
|
||||||
|
|
||||||
accountManager.getKeys(_listkeyscmd);
|
accountManagerImpl.getKeys(_listkeyscmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updateUserTestTimeZoneAndEmailNull() {
|
||||||
|
prepareMockAndExecuteUpdateUserTest(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updateUserTestTimeZoneAndEmailNotNull() {
|
||||||
|
Mockito.when(UpdateUserCmdMock.getEmail()).thenReturn("email");
|
||||||
|
Mockito.when(UpdateUserCmdMock.getTimezone()).thenReturn("timezone");
|
||||||
|
prepareMockAndExecuteUpdateUserTest(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepareMockAndExecuteUpdateUserTest(int numberOfExpectedCallsForSetEmailAndSetTimeZone) {
|
||||||
|
Mockito.doReturn(userVoMock).when(accountManagerImpl).retrieveAndValidateUser(UpdateUserCmdMock);
|
||||||
|
Mockito.doNothing().when(accountManagerImpl).validateAndUpdatApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||||
|
Mockito.doReturn(accountMock).when(accountManagerImpl).retrieveAndValidateAccount(userVoMock);
|
||||||
|
|
||||||
|
Mockito.doNothing().when(accountManagerImpl).validateAndUpdateFirstNameIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||||
|
Mockito.doNothing().when(accountManagerImpl).validateAndUpdateLastNameIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||||
|
Mockito.doNothing().when(accountManagerImpl).validateAndUpdateUsernameIfNeeded(UpdateUserCmdMock, userVoMock, accountMock);
|
||||||
|
Mockito.doNothing().when(accountManagerImpl).validateUserPasswordAndUpdateIfNeeded(Mockito.anyString(), Mockito.eq(userVoMock), Mockito.anyString());
|
||||||
|
|
||||||
|
Mockito.doReturn(true).when(userDaoMock).update(Mockito.anyLong(), Mockito.eq(userVoMock));
|
||||||
|
Mockito.doReturn(Mockito.mock(UserAccountVO.class)).when(userAccountDaoMock).findById(Mockito.anyLong());
|
||||||
|
|
||||||
|
accountManagerImpl.updateUser(UpdateUserCmdMock);
|
||||||
|
|
||||||
|
InOrder inOrder = Mockito.inOrder(userVoMock, accountManagerImpl, userDaoMock, userAccountDaoMock);
|
||||||
|
|
||||||
|
inOrder.verify(accountManagerImpl).retrieveAndValidateUser(UpdateUserCmdMock);
|
||||||
|
inOrder.verify(accountManagerImpl).validateAndUpdatApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||||
|
inOrder.verify(accountManagerImpl).retrieveAndValidateAccount(userVoMock);
|
||||||
|
|
||||||
|
inOrder.verify(accountManagerImpl).validateAndUpdateFirstNameIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||||
|
inOrder.verify(accountManagerImpl).validateAndUpdateLastNameIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||||
|
inOrder.verify(accountManagerImpl).validateAndUpdateUsernameIfNeeded(UpdateUserCmdMock, userVoMock, accountMock);
|
||||||
|
inOrder.verify(accountManagerImpl).validateUserPasswordAndUpdateIfNeeded(Mockito.anyString(), Mockito.eq(userVoMock), Mockito.anyString());
|
||||||
|
|
||||||
|
inOrder.verify(userVoMock, Mockito.times(numberOfExpectedCallsForSetEmailAndSetTimeZone)).setEmail(Mockito.anyString());
|
||||||
|
inOrder.verify(userVoMock, Mockito.times(numberOfExpectedCallsForSetEmailAndSetTimeZone)).setTimezone(Mockito.anyString());
|
||||||
|
|
||||||
|
inOrder.verify(userDaoMock).update(Mockito.anyLong(), Mockito.eq(userVoMock));
|
||||||
|
inOrder.verify(userAccountDaoMock).findById(Mockito.anyLong());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void retrieveAndValidateUserTestNoUserFound() {
|
||||||
|
Mockito.doReturn(null).when(userDaoMock).getUser(Mockito.anyLong());
|
||||||
|
|
||||||
|
accountManagerImpl.retrieveAndValidateUser(UpdateUserCmdMock);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void retrieveAndValidateUserTestUserIsFound() {
|
||||||
|
Mockito.doReturn(userVoMock).when(userDaoMock).getUser(Mockito.anyLong());
|
||||||
|
|
||||||
|
UserVO receivedUser = accountManagerImpl.retrieveAndValidateUser(UpdateUserCmdMock);
|
||||||
|
|
||||||
|
Assert.assertEquals(userVoMock, receivedUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void validateAndUpdatApiAndSecretKeyIfNeededTestNoKeys() {
|
||||||
|
accountManagerImpl.validateAndUpdatApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||||
|
|
||||||
|
Mockito.verify(accountDaoMock, Mockito.times(0)).findUserAccountByApiKey(Mockito.anyString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void validateAndUpdatApiAndSecretKeyIfNeededTestOnlyApiKeyInformed() {
|
||||||
|
Mockito.doReturn("apiKey").when(UpdateUserCmdMock).getApiKey();
|
||||||
|
|
||||||
|
accountManagerImpl.validateAndUpdatApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void validateAndUpdatApiAndSecretKeyIfNeededTestOnlySecretKeyInformed() {
|
||||||
|
Mockito.doReturn("secretKey").when(UpdateUserCmdMock).getSecretKey();
|
||||||
|
|
||||||
|
accountManagerImpl.validateAndUpdatApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void validateAndUpdatApiAndSecretKeyIfNeededTestApiKeyAlreadyUsedBySomeoneElse() {
|
||||||
|
String apiKey = "apiKey";
|
||||||
|
Mockito.doReturn(apiKey).when(UpdateUserCmdMock).getApiKey();
|
||||||
|
Mockito.doReturn("secretKey").when(UpdateUserCmdMock).getSecretKey();
|
||||||
|
|
||||||
|
Mockito.doReturn(1L).when(userVoMock).getId();
|
||||||
|
|
||||||
|
User otherUserMock = Mockito.mock(User.class);
|
||||||
|
Mockito.doReturn(2L).when(otherUserMock).getId();
|
||||||
|
|
||||||
|
Pair<User, Account> pairUserAccountMock = new Pair<User, Account>(otherUserMock, Mockito.mock(Account.class));
|
||||||
|
Mockito.doReturn(pairUserAccountMock).when(accountDaoMock).findUserAccountByApiKey(apiKey);
|
||||||
|
|
||||||
|
accountManagerImpl.validateAndUpdatApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void validateAndUpdatApiAndSecretKeyIfNeededTest() {
|
||||||
|
String apiKey = "apiKey";
|
||||||
|
Mockito.doReturn(apiKey).when(UpdateUserCmdMock).getApiKey();
|
||||||
|
|
||||||
|
String secretKey = "secretKey";
|
||||||
|
Mockito.doReturn(secretKey).when(UpdateUserCmdMock).getSecretKey();
|
||||||
|
|
||||||
|
Mockito.doReturn(1L).when(userVoMock).getId();
|
||||||
|
|
||||||
|
User otherUserMock = Mockito.mock(User.class);
|
||||||
|
Mockito.doReturn(1L).when(otherUserMock).getId();
|
||||||
|
|
||||||
|
Pair<User, Account> pairUserAccountMock = new Pair<User, Account>(otherUserMock, Mockito.mock(Account.class));
|
||||||
|
Mockito.doReturn(pairUserAccountMock).when(accountDaoMock).findUserAccountByApiKey(apiKey);
|
||||||
|
|
||||||
|
accountManagerImpl.validateAndUpdatApiAndSecretKeyIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||||
|
|
||||||
|
Mockito.verify(accountDaoMock).findUserAccountByApiKey(apiKey);
|
||||||
|
Mockito.verify(userVoMock).setApiKey(apiKey);
|
||||||
|
Mockito.verify(userVoMock).setSecretKey(secretKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = CloudRuntimeException.class)
|
||||||
|
public void retrieveAndValidateAccountTestAccountNotFound() {
|
||||||
|
Mockito.doReturn(accountMockId).when(userVoMock).getAccountId();
|
||||||
|
|
||||||
|
Mockito.doReturn(null).when(accountDaoMock).findById(accountMockId);
|
||||||
|
|
||||||
|
accountManagerImpl.retrieveAndValidateAccount(userVoMock);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void retrieveAndValidateAccountTestAccountTypeEqualsProjectType() {
|
||||||
|
Mockito.doReturn(accountMockId).when(userVoMock).getAccountId();
|
||||||
|
Mockito.doReturn(Account.ACCOUNT_TYPE_PROJECT).when(accountMock).getType();
|
||||||
|
Mockito.doReturn(accountMock).when(accountDaoMock).findById(accountMockId);
|
||||||
|
|
||||||
|
accountManagerImpl.retrieveAndValidateAccount(userVoMock);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = PermissionDeniedException.class)
|
||||||
|
public void retrieveAndValidateAccountTestAccountTypeEqualsSystemType() {
|
||||||
|
Mockito.doReturn(Account.ACCOUNT_ID_SYSTEM).when(userVoMock).getAccountId();
|
||||||
|
Mockito.doReturn(Account.ACCOUNT_ID_SYSTEM).when(accountMock).getId();
|
||||||
|
Mockito.doReturn(accountMock).when(accountDaoMock).findById(Account.ACCOUNT_ID_SYSTEM);
|
||||||
|
|
||||||
|
accountManagerImpl.retrieveAndValidateAccount(userVoMock);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void retrieveAndValidateAccountTest() {
|
||||||
|
Mockito.doReturn(accountMockId).when(userVoMock).getAccountId();
|
||||||
|
Mockito.doReturn(accountMock).when(accountDaoMock).findById(accountMockId);
|
||||||
|
|
||||||
|
Mockito.doNothing().when(accountManagerImpl).checkAccess(Mockito.eq(accountMock), Mockito.eq(AccessType.OperateEntry), Mockito.anyBoolean(), Mockito.any(Account.class));
|
||||||
|
accountManagerImpl.retrieveAndValidateAccount(userVoMock);
|
||||||
|
|
||||||
|
Mockito.verify(accountManagerImpl).getCurrentCallingAccount();
|
||||||
|
Mockito.verify(accountManagerImpl).checkAccess(Mockito.eq(accountMock), Mockito.eq(AccessType.OperateEntry), Mockito.anyBoolean(), Mockito.any(Account.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void validateAndUpdateFirstNameIfNeededTestFirstNameBlank() {
|
||||||
|
Mockito.doReturn(" ").when(UpdateUserCmdMock).getFirstname();
|
||||||
|
|
||||||
|
accountManagerImpl.validateAndUpdateFirstNameIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void validateAndUpdateFirstNameIfNeededTestFirstNameNull() {
|
||||||
|
Mockito.doReturn(null).when(UpdateUserCmdMock).getFirstname();
|
||||||
|
|
||||||
|
accountManagerImpl.validateAndUpdateFirstNameIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||||
|
|
||||||
|
Mockito.verify(userVoMock, Mockito.times(0)).setFirstname(Mockito.anyString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void validateAndUpdateFirstNameIfNeededTest() {
|
||||||
|
String firstname = "firstName";
|
||||||
|
Mockito.doReturn(firstname).when(UpdateUserCmdMock).getFirstname();
|
||||||
|
|
||||||
|
accountManagerImpl.validateAndUpdateFirstNameIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||||
|
|
||||||
|
Mockito.verify(userVoMock).setFirstname(firstname);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void validateAndUpdateLastNameIfNeededTestLastNameBlank() {
|
||||||
|
Mockito.doReturn(" ").when(UpdateUserCmdMock).getLastname();
|
||||||
|
|
||||||
|
accountManagerImpl.validateAndUpdateLastNameIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void validateAndUpdateLastNameIfNeededTestLastNameNull() {
|
||||||
|
Mockito.doReturn(null).when(UpdateUserCmdMock).getLastname();
|
||||||
|
|
||||||
|
accountManagerImpl.validateAndUpdateLastNameIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||||
|
|
||||||
|
Mockito.verify(userVoMock, Mockito.times(0)).setLastname(Mockito.anyString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void validateAndUpdateLastNameIfNeededTest() {
|
||||||
|
String lastName = "lastName";
|
||||||
|
Mockito.doReturn(lastName).when(UpdateUserCmdMock).getLastname();
|
||||||
|
|
||||||
|
accountManagerImpl.validateAndUpdateLastNameIfNeeded(UpdateUserCmdMock, userVoMock);
|
||||||
|
|
||||||
|
Mockito.verify(userVoMock).setLastname(lastName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void validateAndUpdateUsernameIfNeededTestNullUsername() {
|
||||||
|
Mockito.doReturn(null).when(UpdateUserCmdMock).getUsername();
|
||||||
|
|
||||||
|
accountManagerImpl.validateAndUpdateUsernameIfNeeded(UpdateUserCmdMock, userVoMock, accountMock);
|
||||||
|
|
||||||
|
Mockito.verify(userVoMock, Mockito.times(0)).setUsername(Mockito.anyString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void validateAndUpdateUsernameIfNeededTestBlankUsername() {
|
||||||
|
Mockito.doReturn(" ").when(UpdateUserCmdMock).getUsername();
|
||||||
|
|
||||||
|
accountManagerImpl.validateAndUpdateUsernameIfNeeded(UpdateUserCmdMock, userVoMock, accountMock);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void validateAndUpdateUsernameIfNeededTestDuplicatedUserSameDomainThisUser() {
|
||||||
|
long domanIdCurrentUser = 22l;
|
||||||
|
|
||||||
|
String userName = "username";
|
||||||
|
Mockito.doReturn(userName).when(UpdateUserCmdMock).getUsername();
|
||||||
|
Mockito.doReturn(userName).when(userVoMock).getUsername();
|
||||||
|
Mockito.doReturn(domanIdCurrentUser).when(accountMock).getDomainId();
|
||||||
|
|
||||||
|
long userVoDuplicatedMockId = 67l;
|
||||||
|
UserVO userVoDuplicatedMock = Mockito.mock(UserVO.class);
|
||||||
|
Mockito.doReturn(userName).when(userVoDuplicatedMock).getUsername();
|
||||||
|
Mockito.doReturn(userVoDuplicatedMockId).when(userVoDuplicatedMock).getId();
|
||||||
|
|
||||||
|
long accountIdUserDuplicated = 98l;
|
||||||
|
Mockito.doReturn(accountIdUserDuplicated).when(userVoDuplicatedMock).getAccountId();
|
||||||
|
|
||||||
|
Account accountUserDuplicatedMock = Mockito.mock(Account.class);
|
||||||
|
Mockito.doReturn(accountIdUserDuplicated).when(accountUserDuplicatedMock).getId();
|
||||||
|
Mockito.doReturn(domanIdCurrentUser).when(accountUserDuplicatedMock).getDomainId();
|
||||||
|
|
||||||
|
List<UserVO> usersWithSameUserName = new ArrayList<>();
|
||||||
|
usersWithSameUserName.add(userVoMock);
|
||||||
|
usersWithSameUserName.add(userVoDuplicatedMock);
|
||||||
|
|
||||||
|
Mockito.doReturn(usersWithSameUserName).when(userDaoMock).findUsersByName(userName);
|
||||||
|
|
||||||
|
Mockito.doReturn(accountMock).when(accountDaoMock).findById(accountMockId);
|
||||||
|
Mockito.doReturn(accountUserDuplicatedMock).when(accountDaoMock).findById(accountIdUserDuplicated);
|
||||||
|
|
||||||
|
Mockito.doReturn(Mockito.mock(DomainVO.class)).when(_domainDao).findById(Mockito.anyLong());
|
||||||
|
|
||||||
|
accountManagerImpl.validateAndUpdateUsernameIfNeeded(UpdateUserCmdMock, userVoMock, accountMock);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void validateAndUpdateUsernameIfNeededTestDuplicatedUserButInDifferentDomains() {
|
||||||
|
long domanIdCurrentUser = 22l;
|
||||||
|
|
||||||
|
String userName = "username";
|
||||||
|
Mockito.doReturn(userName).when(UpdateUserCmdMock).getUsername();
|
||||||
|
Mockito.doReturn(userName).when(userVoMock).getUsername();
|
||||||
|
Mockito.doReturn(domanIdCurrentUser).when(accountMock).getDomainId();
|
||||||
|
|
||||||
|
long userVoDuplicatedMockId = 67l;
|
||||||
|
UserVO userVoDuplicatedMock = Mockito.mock(UserVO.class);
|
||||||
|
Mockito.doReturn(userName).when(userVoDuplicatedMock).getUsername();
|
||||||
|
Mockito.doReturn(userVoDuplicatedMockId).when(userVoDuplicatedMock).getId();
|
||||||
|
|
||||||
|
long accountIdUserDuplicated = 98l;
|
||||||
|
Mockito.doReturn(accountIdUserDuplicated).when(userVoDuplicatedMock).getAccountId();
|
||||||
|
|
||||||
|
Account accountUserDuplicatedMock = Mockito.mock(Account.class);
|
||||||
|
Mockito.doReturn(accountIdUserDuplicated).when(accountUserDuplicatedMock).getId();
|
||||||
|
Mockito.doReturn(45l).when(accountUserDuplicatedMock).getDomainId();
|
||||||
|
|
||||||
|
List<UserVO> usersWithSameUserName = new ArrayList<>();
|
||||||
|
usersWithSameUserName.add(userVoMock);
|
||||||
|
usersWithSameUserName.add(userVoDuplicatedMock);
|
||||||
|
|
||||||
|
Mockito.doReturn(usersWithSameUserName).when(userDaoMock).findUsersByName(userName);
|
||||||
|
|
||||||
|
Mockito.doReturn(accountMock).when(accountDaoMock).findById(accountMockId);
|
||||||
|
Mockito.doReturn(accountUserDuplicatedMock).when(accountDaoMock).findById(accountIdUserDuplicated);
|
||||||
|
|
||||||
|
accountManagerImpl.validateAndUpdateUsernameIfNeeded(UpdateUserCmdMock, userVoMock, accountMock);
|
||||||
|
|
||||||
|
Mockito.verify(userVoMock).setUsername(userName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void validateAndUpdateUsernameIfNeededTestNoDuplicatedUserNames() {
|
||||||
|
long domanIdCurrentUser = 22l;
|
||||||
|
|
||||||
|
String userName = "username";
|
||||||
|
Mockito.doReturn(userName).when(UpdateUserCmdMock).getUsername();
|
||||||
|
Mockito.doReturn(userName).when(userVoMock).getUsername();
|
||||||
|
Mockito.doReturn(domanIdCurrentUser).when(accountMock).getDomainId();
|
||||||
|
|
||||||
|
List<UserVO> usersWithSameUserName = new ArrayList<>();
|
||||||
|
|
||||||
|
Mockito.doReturn(usersWithSameUserName).when(userDaoMock).findUsersByName(userName);
|
||||||
|
|
||||||
|
Mockito.doReturn(accountMock).when(accountDaoMock).findById(accountMockId);
|
||||||
|
|
||||||
|
accountManagerImpl.validateAndUpdateUsernameIfNeeded(UpdateUserCmdMock, userVoMock, accountMock);
|
||||||
|
|
||||||
|
Mockito.verify(userVoMock).setUsername(userName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void valiateUserPasswordAndUpdateIfNeededTestPasswordNull() {
|
||||||
|
accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(null, userVoMock, null);
|
||||||
|
|
||||||
|
Mockito.verify(userVoMock, Mockito.times(0)).setPassword(Mockito.anyString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void valiateUserPasswordAndUpdateIfNeededTestBlankPassword() {
|
||||||
|
accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(" ", userVoMock, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void valiateUserPasswordAndUpdateIfNeededTestNoAdminAndNoCurrentPasswordProvided() {
|
||||||
|
Mockito.doReturn(accountMock).when(accountManagerImpl).getCurrentCallingAccount();
|
||||||
|
Mockito.doReturn(false).when(accountManagerImpl).isRootAdmin(accountMockId);
|
||||||
|
Mockito.doReturn(false).when(accountManagerImpl).isDomainAdmin(accountMockId);
|
||||||
|
Mockito.doReturn(true).when(accountManagerImpl).isResourceDomainAdmin(accountMockId);
|
||||||
|
|
||||||
|
accountManagerImpl.validateUserPasswordAndUpdateIfNeeded("newPassword", userVoMock, " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = CloudRuntimeException.class)
|
||||||
|
public void valiateUserPasswordAndUpdateIfNeededTestNoUserAuthenticatorsConfigured() {
|
||||||
|
Mockito.doReturn(accountMock).when(accountManagerImpl).getCurrentCallingAccount();
|
||||||
|
Mockito.doReturn(true).when(accountManagerImpl).isRootAdmin(accountMockId);
|
||||||
|
Mockito.doReturn(false).when(accountManagerImpl).isDomainAdmin(accountMockId);
|
||||||
|
|
||||||
|
Mockito.doNothing().when(accountManagerImpl).validateCurrentPassword(Mockito.eq(userVoMock), Mockito.anyString());
|
||||||
|
|
||||||
|
accountManagerImpl.validateUserPasswordAndUpdateIfNeeded("newPassword", userVoMock, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void validateUserPasswordAndUpdateIfNeededTestRootAdminUpdatingUserPassword() {
|
||||||
|
Mockito.doReturn(accountMock).when(accountManagerImpl).getCurrentCallingAccount();
|
||||||
|
Mockito.doReturn(true).when(accountManagerImpl).isRootAdmin(accountMockId);
|
||||||
|
Mockito.doReturn(false).when(accountManagerImpl).isDomainAdmin(accountMockId);
|
||||||
|
|
||||||
|
String newPassword = "newPassword";
|
||||||
|
|
||||||
|
String expectedUserPasswordAfterEncoded = configureUserMockAuthenticators(newPassword);
|
||||||
|
|
||||||
|
Mockito.doNothing().when(accountManagerImpl).validateCurrentPassword(Mockito.eq(userVoMock), Mockito.anyString());
|
||||||
|
|
||||||
|
accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(newPassword, userVoMock, null);
|
||||||
|
|
||||||
|
Mockito.verify(accountManagerImpl, Mockito.times(0)).validateCurrentPassword(Mockito.eq(userVoMock), Mockito.anyString());
|
||||||
|
Mockito.verify(userVoMock, Mockito.times(1)).setPassword(expectedUserPasswordAfterEncoded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void validateUserPasswordAndUpdateIfNeededTestDomainAdminUpdatingUserPassword() {
|
||||||
|
Mockito.doReturn(accountMock).when(accountManagerImpl).getCurrentCallingAccount();
|
||||||
|
Mockito.doReturn(false).when(accountManagerImpl).isRootAdmin(accountMockId);
|
||||||
|
Mockito.doReturn(true).when(accountManagerImpl).isDomainAdmin(accountMockId);
|
||||||
|
|
||||||
|
String newPassword = "newPassword";
|
||||||
|
|
||||||
|
String expectedUserPasswordAfterEncoded = configureUserMockAuthenticators(newPassword);
|
||||||
|
|
||||||
|
Mockito.doNothing().when(accountManagerImpl).validateCurrentPassword(Mockito.eq(userVoMock), Mockito.anyString());
|
||||||
|
|
||||||
|
accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(newPassword, userVoMock, null);
|
||||||
|
|
||||||
|
Mockito.verify(accountManagerImpl, Mockito.times(0)).validateCurrentPassword(Mockito.eq(userVoMock), Mockito.anyString());
|
||||||
|
Mockito.verify(userVoMock, Mockito.times(1)).setPassword(expectedUserPasswordAfterEncoded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void validateUserPasswordAndUpdateIfNeededTestUserUpdatingHisPassword() {
|
||||||
|
Mockito.doReturn(accountMock).when(accountManagerImpl).getCurrentCallingAccount();
|
||||||
|
Mockito.doReturn(false).when(accountManagerImpl).isRootAdmin(accountMockId);
|
||||||
|
Mockito.doReturn(false).when(accountManagerImpl).isDomainAdmin(accountMockId);
|
||||||
|
|
||||||
|
String newPassword = "newPassword";
|
||||||
|
String expectedUserPasswordAfterEncoded = configureUserMockAuthenticators(newPassword);
|
||||||
|
|
||||||
|
Mockito.doNothing().when(accountManagerImpl).validateCurrentPassword(Mockito.eq(userVoMock), Mockito.anyString());
|
||||||
|
|
||||||
|
String currentPassword = "theCurrentPassword";
|
||||||
|
accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(newPassword, userVoMock, currentPassword);
|
||||||
|
|
||||||
|
Mockito.verify(accountManagerImpl, Mockito.times(1)).validateCurrentPassword(userVoMock, currentPassword);
|
||||||
|
Mockito.verify(userVoMock, Mockito.times(1)).setPassword(expectedUserPasswordAfterEncoded);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String configureUserMockAuthenticators(String newPassword) {
|
||||||
|
accountManagerImpl._userPasswordEncoders = new ArrayList<>();
|
||||||
|
UserAuthenticator authenticatorMock1 = Mockito.mock(UserAuthenticator.class);
|
||||||
|
String expectedUserPasswordAfterEncoded = "passwordEncodedByAuthenticator1";
|
||||||
|
Mockito.doReturn(expectedUserPasswordAfterEncoded).when(authenticatorMock1).encode(newPassword);
|
||||||
|
|
||||||
|
UserAuthenticator authenticatorMock2 = Mockito.mock(UserAuthenticator.class);
|
||||||
|
Mockito.doReturn("passwordEncodedByAuthenticator2").when(authenticatorMock2).encode(newPassword);
|
||||||
|
|
||||||
|
accountManagerImpl._userPasswordEncoders.add(authenticatorMock1);
|
||||||
|
accountManagerImpl._userPasswordEncoders.add(authenticatorMock2);
|
||||||
|
return expectedUserPasswordAfterEncoded;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = InvalidParameterValueException.class)
|
||||||
|
public void validateCurrentPasswordTestUserNotAuthenticatedWithProvidedCurrentPassword() {
|
||||||
|
Mockito.doReturn(Mockito.mock(AccountVO.class)).when(accountDaoMock).findById(accountMockId);
|
||||||
|
String newPassword = "newPassword";
|
||||||
|
configureUserMockAuthenticators(newPassword);
|
||||||
|
|
||||||
|
accountManagerImpl.validateCurrentPassword(userVoMock, "currentPassword");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void validateCurrentPasswordTestUserAuthenticatedWithProvidedCurrentPasswordViaFirstAuthenticator() {
|
||||||
|
AccountVO accountVoMock = Mockito.mock(AccountVO.class);
|
||||||
|
long domainId = 14l;
|
||||||
|
Mockito.doReturn(domainId).when(accountVoMock).getDomainId();
|
||||||
|
|
||||||
|
Mockito.doReturn(accountVoMock).when(accountDaoMock).findById(accountMockId);
|
||||||
|
String username = "username";
|
||||||
|
Mockito.doReturn(username).when(userVoMock).getUsername();
|
||||||
|
|
||||||
|
accountManagerImpl._userPasswordEncoders = new ArrayList<>();
|
||||||
|
UserAuthenticator authenticatorMock1 = Mockito.mock(UserAuthenticator.class);
|
||||||
|
UserAuthenticator authenticatorMock2 = Mockito.mock(UserAuthenticator.class);
|
||||||
|
|
||||||
|
accountManagerImpl._userPasswordEncoders.add(authenticatorMock1);
|
||||||
|
accountManagerImpl._userPasswordEncoders.add(authenticatorMock2);
|
||||||
|
|
||||||
|
Pair<Boolean, ActionOnFailedAuthentication> authenticationResult = new Pair<Boolean, UserAuthenticator.ActionOnFailedAuthentication>(true,
|
||||||
|
UserAuthenticator.ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT);
|
||||||
|
|
||||||
|
String currentPassword = "currentPassword";
|
||||||
|
Mockito.doReturn(authenticationResult).when(authenticatorMock1).authenticate(username, currentPassword, domainId, null);
|
||||||
|
|
||||||
|
accountManagerImpl.validateCurrentPassword(userVoMock, currentPassword);
|
||||||
|
|
||||||
|
Mockito.verify(authenticatorMock1, Mockito.times(1)).authenticate(username, currentPassword, domainId, null);
|
||||||
|
Mockito.verify(authenticatorMock2, Mockito.times(0)).authenticate(username, currentPassword, domainId, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void validateCurrentPasswordTestUserAuthenticatedWithProvidedCurrentPasswordViaSecondAuthenticator() {
|
||||||
|
AccountVO accountVoMock = Mockito.mock(AccountVO.class);
|
||||||
|
long domainId = 14l;
|
||||||
|
Mockito.doReturn(domainId).when(accountVoMock).getDomainId();
|
||||||
|
|
||||||
|
Mockito.doReturn(accountVoMock).when(accountDaoMock).findById(accountMockId);
|
||||||
|
String username = "username";
|
||||||
|
Mockito.doReturn(username).when(userVoMock).getUsername();
|
||||||
|
|
||||||
|
accountManagerImpl._userPasswordEncoders = new ArrayList<>();
|
||||||
|
UserAuthenticator authenticatorMock1 = Mockito.mock(UserAuthenticator.class);
|
||||||
|
UserAuthenticator authenticatorMock2 = Mockito.mock(UserAuthenticator.class);
|
||||||
|
|
||||||
|
accountManagerImpl._userPasswordEncoders.add(authenticatorMock1);
|
||||||
|
accountManagerImpl._userPasswordEncoders.add(authenticatorMock2);
|
||||||
|
|
||||||
|
Pair<Boolean, ActionOnFailedAuthentication> authenticationResult = new Pair<Boolean, UserAuthenticator.ActionOnFailedAuthentication>(true,
|
||||||
|
UserAuthenticator.ActionOnFailedAuthentication.INCREMENT_INCORRECT_LOGIN_ATTEMPT_COUNT);
|
||||||
|
|
||||||
|
String currentPassword = "currentPassword";
|
||||||
|
Mockito.doReturn(authenticationResult).when(authenticatorMock2).authenticate(username, currentPassword, domainId, null);
|
||||||
|
|
||||||
|
accountManagerImpl.validateCurrentPassword(userVoMock, currentPassword);
|
||||||
|
|
||||||
|
Mockito.verify(authenticatorMock1, Mockito.times(1)).authenticate(username, currentPassword, domainId, null);
|
||||||
|
Mockito.verify(authenticatorMock2, Mockito.times(1)).authenticate(username, currentPassword, domainId, null);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,12 @@
|
||||||
// under the License.
|
// under the License.
|
||||||
package com.cloud.user;
|
package com.cloud.user;
|
||||||
|
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Matchers.anyBoolean;
|
||||||
|
import static org.mockito.Matchers.anyLong;
|
||||||
|
import static org.mockito.Matchers.anyString;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.when;
|
||||||
import static org.mockito.Mockito.anyLong;
|
|
||||||
import static org.mockito.Mockito.anyString;
|
|
||||||
import static org.mockito.Mockito.anyBoolean;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
|
@ -52,13 +52,12 @@ import com.cloud.exception.AgentUnavailableException;
|
||||||
import com.cloud.exception.CloudException;
|
import com.cloud.exception.CloudException;
|
||||||
import com.cloud.exception.ConcurrentOperationException;
|
import com.cloud.exception.ConcurrentOperationException;
|
||||||
import com.cloud.service.ServiceOfferingVO;
|
import com.cloud.service.ServiceOfferingVO;
|
||||||
import com.cloud.storage.VolumeVO;
|
|
||||||
import com.cloud.storage.Volume.Type;
|
import com.cloud.storage.Volume.Type;
|
||||||
|
import com.cloud.storage.VolumeVO;
|
||||||
import com.cloud.vm.UserVmManagerImpl;
|
import com.cloud.vm.UserVmManagerImpl;
|
||||||
import com.cloud.vm.UserVmVO;
|
import com.cloud.vm.UserVmVO;
|
||||||
import com.cloud.vm.VirtualMachine;
|
import com.cloud.vm.VirtualMachine;
|
||||||
|
|
||||||
|
|
||||||
public class AccountManagerImplVolumeDeleteEventTest extends AccountManagetImplTestBase {
|
public class AccountManagerImplVolumeDeleteEventTest extends AccountManagetImplTestBase {
|
||||||
|
|
||||||
private static final Long ACCOUNT_ID = 1l;
|
private static final Long ACCOUNT_ID = 1l;
|
||||||
|
|
@ -70,12 +69,10 @@ public class AccountManagerImplVolumeDeleteEventTest extends AccountManagetImplT
|
||||||
Map<String, Object> oldFields = new HashMap<>();
|
Map<String, Object> oldFields = new HashMap<>();
|
||||||
UserVmVO vm = mock(UserVmVO.class);
|
UserVmVO vm = mock(UserVmVO.class);
|
||||||
|
|
||||||
|
|
||||||
// Configures the static fields of the UsageEventUtils class, Storing the
|
// Configures the static fields of the UsageEventUtils class, Storing the
|
||||||
// previous values to be restored during the cleanup phase, to avoid
|
// previous values to be restored during the cleanup phase, to avoid
|
||||||
// interference with other unit tests.
|
// interference with other unit tests.
|
||||||
protected UsageEventUtils setupUsageUtils() throws NoSuchMethodException, SecurityException, IllegalAccessException,
|
protected UsageEventUtils setupUsageUtils() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||||
IllegalArgumentException, InvocationTargetException {
|
|
||||||
|
|
||||||
_usageEventDao = new MockUsageEventDao();
|
_usageEventDao = new MockUsageEventDao();
|
||||||
UsageEventUtils utils = new UsageEventUtils();
|
UsageEventUtils utils = new UsageEventUtils();
|
||||||
|
|
@ -93,8 +90,7 @@ public class AccountManagerImplVolumeDeleteEventTest extends AccountManagetImplT
|
||||||
Field staticField = UsageEventUtils.class.getDeclaredField("s_" + fieldName);
|
Field staticField = UsageEventUtils.class.getDeclaredField("s_" + fieldName);
|
||||||
staticField.setAccessible(true);
|
staticField.setAccessible(true);
|
||||||
oldFields.put(f.getName(), staticField.get(null));
|
oldFields.put(f.getName(), staticField.get(null));
|
||||||
f.set(utils,
|
f.set(utils, this.getClass().getSuperclass().getDeclaredField("_" + fieldName).get(this));
|
||||||
this.getClass().getSuperclass().getDeclaredField("_" + fieldName).get(this));
|
|
||||||
} catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
|
} catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
@ -106,14 +102,12 @@ public class AccountManagerImplVolumeDeleteEventTest extends AccountManagetImplT
|
||||||
return utils;
|
return utils;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void defineMocksBehavior() throws AgentUnavailableException, ConcurrentOperationException, CloudException {
|
||||||
protected void defineMocksBehavior()
|
|
||||||
throws AgentUnavailableException, ConcurrentOperationException, CloudException {
|
|
||||||
|
|
||||||
AccountVO account = new AccountVO();
|
AccountVO account = new AccountVO();
|
||||||
account.setId(ACCOUNT_ID);
|
account.setId(ACCOUNT_ID);
|
||||||
when(_accountDao.remove(ACCOUNT_ID)).thenReturn(true);
|
when(accountDaoMock.remove(ACCOUNT_ID)).thenReturn(true);
|
||||||
when(_accountDao.findById(ACCOUNT_ID)).thenReturn(account);
|
when(accountDaoMock.findById(ACCOUNT_ID)).thenReturn(account);
|
||||||
|
|
||||||
DomainVO domain = new DomainVO();
|
DomainVO domain = new DomainVO();
|
||||||
VirtualMachineEntity vmEntity = mock(VirtualMachineEntity.class);
|
VirtualMachineEntity vmEntity = mock(VirtualMachineEntity.class);
|
||||||
|
|
@ -128,8 +122,7 @@ public class AccountManagerImplVolumeDeleteEventTest extends AccountManagetImplT
|
||||||
List<VolumeVO> volumes = new ArrayList<>();
|
List<VolumeVO> volumes = new ArrayList<>();
|
||||||
volumes.add(vol);
|
volumes.add(vol);
|
||||||
|
|
||||||
when(securityChecker.checkAccess(any(Account.class), any(ControlledEntity.class), any(AccessType.class),
|
when(securityChecker.checkAccess(any(Account.class), any(ControlledEntity.class), any(AccessType.class), anyString())).thenReturn(true);
|
||||||
anyString())).thenReturn(true);
|
|
||||||
|
|
||||||
when(_userVmDao.findById(anyLong())).thenReturn(vm);
|
when(_userVmDao.findById(anyLong())).thenReturn(vm);
|
||||||
when(_userVmDao.listByAccountId(ACCOUNT_ID)).thenReturn(Arrays.asList(vm));
|
when(_userVmDao.listByAccountId(ACCOUNT_ID)).thenReturn(Arrays.asList(vm));
|
||||||
|
|
@ -142,8 +135,7 @@ public class AccountManagerImplVolumeDeleteEventTest extends AccountManagetImplT
|
||||||
when(offering.getId()).thenReturn(1l);
|
when(offering.getId()).thenReturn(1l);
|
||||||
when(offering.getCpu()).thenReturn(500);
|
when(offering.getCpu()).thenReturn(500);
|
||||||
when(offering.getRamSize()).thenReturn(500);
|
when(offering.getRamSize()).thenReturn(500);
|
||||||
when(_serviceOfferingDao.findByIdIncludingRemoved(anyLong(), anyLong()))
|
when(_serviceOfferingDao.findByIdIncludingRemoved(anyLong(), anyLong())).thenReturn(offering);
|
||||||
.thenReturn(offering);
|
|
||||||
|
|
||||||
when(_domainMgr.getDomain(anyLong())).thenReturn(domain);
|
when(_domainMgr.getDomain(anyLong())).thenReturn(domain);
|
||||||
|
|
||||||
|
|
@ -152,9 +144,8 @@ public class AccountManagerImplVolumeDeleteEventTest extends AccountManagetImplT
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void init()
|
public void init() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, AgentUnavailableException,
|
||||||
throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,
|
ConcurrentOperationException, CloudException {
|
||||||
InvocationTargetException, AgentUnavailableException, ConcurrentOperationException, CloudException {
|
|
||||||
|
|
||||||
setupUsageUtils();
|
setupUsageUtils();
|
||||||
defineMocksBehavior();
|
defineMocksBehavior();
|
||||||
|
|
@ -175,22 +166,19 @@ public class AccountManagerImplVolumeDeleteEventTest extends AccountManagetImplT
|
||||||
method.invoke(utils);
|
method.invoke(utils);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
protected List<UsageEventVO> deleteUserAccountRootVolumeUsageEvents(boolean vmDestroyedPrior) throws AgentUnavailableException, ConcurrentOperationException, CloudException {
|
||||||
protected List<UsageEventVO> deleteUserAccountRootVolumeUsageEvents(boolean vmDestroyedPrior)
|
|
||||||
throws AgentUnavailableException, ConcurrentOperationException, CloudException {
|
|
||||||
|
|
||||||
when(vm.getState())
|
when(vm.getState()).thenReturn(vmDestroyedPrior ? VirtualMachine.State.Destroyed : VirtualMachine.State.Running);
|
||||||
.thenReturn(vmDestroyedPrior ? VirtualMachine.State.Destroyed : VirtualMachine.State.Running);
|
|
||||||
when(vm.getRemoved()).thenReturn(vmDestroyedPrior ? new Date() : null);
|
when(vm.getRemoved()).thenReturn(vmDestroyedPrior ? new Date() : null);
|
||||||
accountManager.deleteUserAccount(ACCOUNT_ID);
|
accountManagerImpl.deleteUserAccount(ACCOUNT_ID);
|
||||||
|
|
||||||
return _usageEventDao.listAll();
|
return _usageEventDao.listAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
// If the VM is alerady destroyed, no events should get emitted
|
// If the VM is alerady destroyed, no events should get emitted
|
||||||
public void destroyedVMRootVolumeUsageEvent() throws SecurityException, IllegalArgumentException,
|
public void destroyedVMRootVolumeUsageEvent()
|
||||||
ReflectiveOperationException, AgentUnavailableException, ConcurrentOperationException, CloudException {
|
throws SecurityException, IllegalArgumentException, ReflectiveOperationException, AgentUnavailableException, ConcurrentOperationException, CloudException {
|
||||||
List<UsageEventVO> emittedEvents = deleteUserAccountRootVolumeUsageEvents(true);
|
List<UsageEventVO> emittedEvents = deleteUserAccountRootVolumeUsageEvents(true);
|
||||||
Assert.assertEquals(0, emittedEvents.size());
|
Assert.assertEquals(0, emittedEvents.size());
|
||||||
}
|
}
|
||||||
|
|
@ -198,8 +186,8 @@ public class AccountManagerImplVolumeDeleteEventTest extends AccountManagetImplT
|
||||||
@Test
|
@Test
|
||||||
// If the VM is running, we should see one emitted event for the root
|
// If the VM is running, we should see one emitted event for the root
|
||||||
// volume.
|
// volume.
|
||||||
public void runningVMRootVolumeUsageEvent() throws SecurityException, IllegalArgumentException,
|
public void runningVMRootVolumeUsageEvent()
|
||||||
ReflectiveOperationException, AgentUnavailableException, ConcurrentOperationException, CloudException {
|
throws SecurityException, IllegalArgumentException, ReflectiveOperationException, AgentUnavailableException, ConcurrentOperationException, CloudException {
|
||||||
List<UsageEventVO> emittedEvents = deleteUserAccountRootVolumeUsageEvents(false);
|
List<UsageEventVO> emittedEvents = deleteUserAccountRootVolumeUsageEvents(false);
|
||||||
Assert.assertEquals(1, emittedEvents.size());
|
Assert.assertEquals(1, emittedEvents.size());
|
||||||
UsageEventVO event = emittedEvents.get(0);
|
UsageEventVO event = emittedEvents.get(0);
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,6 @@ import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import org.apache.cloudstack.acl.SecurityChecker;
|
import org.apache.cloudstack.acl.SecurityChecker;
|
||||||
import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
|
import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
|
||||||
import org.apache.cloudstack.context.CallContext;
|
import org.apache.cloudstack.context.CallContext;
|
||||||
|
|
@ -34,9 +32,10 @@ import org.apache.cloudstack.region.gslb.GlobalLoadBalancerRuleDao;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Spy;
|
||||||
import org.mockito.runners.MockitoJUnitRunner;
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
import org.springframework.test.util.ReflectionTestUtils;
|
|
||||||
|
|
||||||
import com.cloud.configuration.ConfigurationManager;
|
import com.cloud.configuration.ConfigurationManager;
|
||||||
import com.cloud.configuration.dao.ResourceCountDao;
|
import com.cloud.configuration.dao.ResourceCountDao;
|
||||||
|
|
@ -84,17 +83,17 @@ import com.cloud.vm.snapshot.dao.VMSnapshotDao;
|
||||||
public class AccountManagetImplTestBase {
|
public class AccountManagetImplTestBase {
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
AccountDao _accountDao;
|
AccountDao accountDaoMock;
|
||||||
@Mock
|
@Mock
|
||||||
ConfigurationDao _configDao;
|
ConfigurationDao _configDao;
|
||||||
@Mock
|
@Mock
|
||||||
ResourceCountDao _resourceCountDao;
|
ResourceCountDao _resourceCountDao;
|
||||||
@Mock
|
@Mock
|
||||||
UserDao _userDao;
|
UserDao userDaoMock;
|
||||||
@Mock
|
@Mock
|
||||||
InstanceGroupDao _vmGroupDao;
|
InstanceGroupDao _vmGroupDao;
|
||||||
@Mock
|
@Mock
|
||||||
UserAccountDao _userAccountDao;
|
UserAccountDao userAccountDaoMock;
|
||||||
@Mock
|
@Mock
|
||||||
VolumeDao _volumeDao;
|
VolumeDao _volumeDao;
|
||||||
@Mock
|
@Mock
|
||||||
|
|
@ -193,27 +192,16 @@ public class AccountManagetImplTestBase {
|
||||||
@Mock
|
@Mock
|
||||||
SSHKeyPairDao _sshKeyPairDao;
|
SSHKeyPairDao _sshKeyPairDao;
|
||||||
|
|
||||||
AccountManagerImpl accountManager;
|
@Spy
|
||||||
|
@InjectMocks
|
||||||
UsageEventDao _usageEventDao = new MockUsageEventDao();
|
AccountManagerImpl accountManagerImpl;
|
||||||
|
@Mock
|
||||||
|
UsageEventDao _usageEventDao;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup()
|
public void setup() {
|
||||||
throws NoSuchFieldException, SecurityException,
|
accountManagerImpl.setUserAuthenticators(Arrays.asList(userAuthenticator));
|
||||||
IllegalArgumentException, IllegalAccessException {
|
accountManagerImpl.setSecurityCheckers(Arrays.asList(securityChecker));
|
||||||
accountManager = new AccountManagerImpl();
|
|
||||||
Map<String, Field> declaredFields = getInheritedFields(this.getClass());
|
|
||||||
for (Field field : AccountManagerImpl.class.getDeclaredFields()) {
|
|
||||||
if (field.getAnnotation(Inject.class) != null) {
|
|
||||||
field.setAccessible(true);
|
|
||||||
if (declaredFields.containsKey(field.getName())) {
|
|
||||||
Field mockField = declaredFields.get(field.getName());
|
|
||||||
field.set(accountManager, mockField.get(this));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ReflectionTestUtils.setField(accountManager, "_userAuthenticators", Arrays.asList(userAuthenticator));
|
|
||||||
accountManager.setSecurityCheckers(Arrays.asList(securityChecker));
|
|
||||||
CallContext.register(callingUser, callingAccount);
|
CallContext.register(callingUser, callingAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -231,14 +219,4 @@ public class AccountManagetImplTestBase {
|
||||||
}
|
}
|
||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map<Class<?>, Field> getInheritedFieldsByClass(Class<?> type) {
|
|
||||||
Map<Class<?>, Field> fields = new HashMap<>();
|
|
||||||
for (Class<?> c = type; c != null; c = c.getSuperclass()) {
|
|
||||||
for (Field f : c.getDeclaredFields()) {
|
|
||||||
fields.put(f.getType(), f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fields;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -157,13 +157,6 @@ public class MockAccountManagerImpl extends ManagerBase implements Manager, Acco
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserAccount updateUser(Long userId, String firstName, String lastName, String email, String userName, String password, String apiKey, String secretKey,
|
|
||||||
String timeZone) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Account getActiveAccountById(long accountId) {
|
public Account getActiveAccountById(long accountId) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
|
||||||
|
|
@ -1,164 +0,0 @@
|
||||||
// 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 com.cloud.user;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.naming.ConfigurationException;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import org.apache.cloudstack.api.command.admin.domain.ListDomainChildrenCmd;
|
|
||||||
import org.apache.cloudstack.api.command.admin.domain.ListDomainsCmd;
|
|
||||||
import org.apache.cloudstack.api.command.admin.domain.UpdateDomainCmd;
|
|
||||||
|
|
||||||
import com.cloud.domain.Domain;
|
|
||||||
import com.cloud.domain.DomainVO;
|
|
||||||
import com.cloud.exception.PermissionDeniedException;
|
|
||||||
import com.cloud.utils.Pair;
|
|
||||||
import com.cloud.utils.component.ManagerBase;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class MockDomainManagerImpl extends ManagerBase implements DomainManager, DomainService {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Domain getDomain(long id) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Domain getDomain(String uuid) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Domain getDomainByName(String name, long parentId) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isChildDomain(Long parentId, Long childId) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean deleteDomain(long domainId, Boolean cleanup) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Pair<List<? extends Domain>, Integer> searchForDomains(ListDomainsCmd cmd) throws PermissionDeniedException {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Pair<List<? extends Domain>, Integer> searchForDomainChildren(ListDomainChildrenCmd cmd) throws PermissionDeniedException {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<Long> getDomainChildrenIds(String parentDomainPath) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DomainVO findDomainByPath(String domainPath) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DomainVO findDomainByIdOrPath(Long id, String domainPath) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<Long> getDomainParentIds(long domainId) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean removeDomain(long domainId) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<? extends Domain> findInactiveDomains() {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean deleteDomain(DomainVO domain, Boolean cleanup) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean start() {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean stop() {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Domain createDomain(String name, Long parentId, String networkDomain, String domainUUID) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Domain updateDomain(UpdateDomainCmd cmd) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Domain createDomain(String name, Long parentId, Long ownerId, String networkDomain, String domainUUID) {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1151,6 +1151,7 @@ var dictionary = {
|
||||||
"label.networks": "الشبكات",
|
"label.networks": "الشبكات",
|
||||||
"label.new": "جديد",
|
"label.new": "جديد",
|
||||||
"label.new.password": "New Password",
|
"label.new.password": "New Password",
|
||||||
|
"label.current.password": "Current Password",
|
||||||
"label.new.project": "مشروع جديد",
|
"label.new.project": "مشروع جديد",
|
||||||
"label.new.ssh.key.pair": "New SSH Key Pair",
|
"label.new.ssh.key.pair": "New SSH Key Pair",
|
||||||
"label.new.vm": "New VM",
|
"label.new.vm": "New VM",
|
||||||
|
|
|
||||||
|
|
@ -1151,6 +1151,7 @@ var dictionary = {
|
||||||
"label.networks": "Xarxes",
|
"label.networks": "Xarxes",
|
||||||
"label.new": "Nou",
|
"label.new": "Nou",
|
||||||
"label.new.password": "New Password",
|
"label.new.password": "New Password",
|
||||||
|
"label.current.password": "Current Password",
|
||||||
"label.new.project": "Nou projecte",
|
"label.new.project": "Nou projecte",
|
||||||
"label.new.ssh.key.pair": "New SSH Key Pair",
|
"label.new.ssh.key.pair": "New SSH Key Pair",
|
||||||
"label.new.vm": "Nova MV",
|
"label.new.vm": "Nova MV",
|
||||||
|
|
|
||||||
|
|
@ -1151,6 +1151,7 @@ var dictionary = {
|
||||||
"label.networks": "Netzwerke",
|
"label.networks": "Netzwerke",
|
||||||
"label.new": "Neu",
|
"label.new": "Neu",
|
||||||
"label.new.password": "Neues Passwort",
|
"label.new.password": "Neues Passwort",
|
||||||
|
"label.current.password": "Current Password",
|
||||||
"label.new.project": "Neues Projekt",
|
"label.new.project": "Neues Projekt",
|
||||||
"label.new.ssh.key.pair": "Neues SSH-Schlüsselpaar",
|
"label.new.ssh.key.pair": "Neues SSH-Schlüsselpaar",
|
||||||
"label.new.vm": "Neue VM",
|
"label.new.vm": "Neue VM",
|
||||||
|
|
|
||||||
|
|
@ -1186,6 +1186,7 @@ var dictionary = {
|
||||||
"label.networks":"Networks",
|
"label.networks":"Networks",
|
||||||
"label.new":"New",
|
"label.new":"New",
|
||||||
"label.new.password":"New Password",
|
"label.new.password":"New Password",
|
||||||
|
"label.current.password": "Current Password",
|
||||||
"label.new.project":"New Project",
|
"label.new.project":"New Project",
|
||||||
"label.new.ssh.key.pair":"New SSH Key Pair",
|
"label.new.ssh.key.pair":"New SSH Key Pair",
|
||||||
"label.new.vm":"New VM",
|
"label.new.vm":"New VM",
|
||||||
|
|
|
||||||
|
|
@ -1151,6 +1151,7 @@ var dictionary = {
|
||||||
"label.networks": "Redes",
|
"label.networks": "Redes",
|
||||||
"label.new": "Nuevo",
|
"label.new": "Nuevo",
|
||||||
"label.new.password": "Nueva contraseña",
|
"label.new.password": "Nueva contraseña",
|
||||||
|
"label.current.password": "Current Password",
|
||||||
"label.new.project": "Nuevo Proyecto",
|
"label.new.project": "Nuevo Proyecto",
|
||||||
"label.new.ssh.key.pair": "Nuevo Par de Claves SSH",
|
"label.new.ssh.key.pair": "Nuevo Par de Claves SSH",
|
||||||
"label.new.vm": "Nueva MV",
|
"label.new.vm": "Nueva MV",
|
||||||
|
|
|
||||||
|
|
@ -1151,6 +1151,7 @@ var dictionary = {
|
||||||
"label.networks": "Réseaux",
|
"label.networks": "Réseaux",
|
||||||
"label.new": "Nouveau",
|
"label.new": "Nouveau",
|
||||||
"label.new.password": "Nouveau mot de passe",
|
"label.new.password": "Nouveau mot de passe",
|
||||||
|
"label.current.password": "Current Password",
|
||||||
"label.new.project": "Nouveau projet",
|
"label.new.project": "Nouveau projet",
|
||||||
"label.new.ssh.key.pair": "Nouvelle bi-clé SSH",
|
"label.new.ssh.key.pair": "Nouvelle bi-clé SSH",
|
||||||
"label.new.vm": "Nouvelle VM",
|
"label.new.vm": "Nouvelle VM",
|
||||||
|
|
|
||||||
|
|
@ -1151,6 +1151,7 @@ var dictionary = {
|
||||||
"label.networks": "Hálózatok",
|
"label.networks": "Hálózatok",
|
||||||
"label.new": "Új",
|
"label.new": "Új",
|
||||||
"label.new.password": "Új jelszó",
|
"label.new.password": "Új jelszó",
|
||||||
|
"label.current.password": "Current Password",
|
||||||
"label.new.project": "Új projekt",
|
"label.new.project": "Új projekt",
|
||||||
"label.new.ssh.key.pair": "Új SSH kulcspár",
|
"label.new.ssh.key.pair": "Új SSH kulcspár",
|
||||||
"label.new.vm": "Új VM",
|
"label.new.vm": "Új VM",
|
||||||
|
|
|
||||||
|
|
@ -1151,6 +1151,7 @@ var dictionary = {
|
||||||
"label.networks": "Reti",
|
"label.networks": "Reti",
|
||||||
"label.new": "Nuovo",
|
"label.new": "Nuovo",
|
||||||
"label.new.password": "New Password",
|
"label.new.password": "New Password",
|
||||||
|
"label.current.password": "Current Password",
|
||||||
"label.new.project": "Nuovo Progetto",
|
"label.new.project": "Nuovo Progetto",
|
||||||
"label.new.ssh.key.pair": "New SSH Key Pair",
|
"label.new.ssh.key.pair": "New SSH Key Pair",
|
||||||
"label.new.vm": "Nuova VM",
|
"label.new.vm": "Nuova VM",
|
||||||
|
|
|
||||||
|
|
@ -1151,6 +1151,7 @@ var dictionary = {
|
||||||
"label.networks": "ネットワーク",
|
"label.networks": "ネットワーク",
|
||||||
"label.new": "新規",
|
"label.new": "新規",
|
||||||
"label.new.password": "新しいパスワード",
|
"label.new.password": "新しいパスワード",
|
||||||
|
"label.current.password": "Current Password",
|
||||||
"label.new.project": "新しいプロジェクト",
|
"label.new.project": "新しいプロジェクト",
|
||||||
"label.new.ssh.key.pair": "新しい SSH キーペア",
|
"label.new.ssh.key.pair": "新しい SSH キーペア",
|
||||||
"label.new.vm": "新しい VM",
|
"label.new.vm": "新しい VM",
|
||||||
|
|
|
||||||
|
|
@ -1151,6 +1151,7 @@ var dictionary = {
|
||||||
"label.networks": "네트워크",
|
"label.networks": "네트워크",
|
||||||
"label.new": "신규",
|
"label.new": "신규",
|
||||||
"label.new.password": "새로운 암호",
|
"label.new.password": "새로운 암호",
|
||||||
|
"label.current.password": "Current Password",
|
||||||
"label.new.project": "새 프로젝트",
|
"label.new.project": "새 프로젝트",
|
||||||
"label.new.ssh.key.pair": "New SSH Key Pair",
|
"label.new.ssh.key.pair": "New SSH Key Pair",
|
||||||
"label.new.vm": "새 VM",
|
"label.new.vm": "새 VM",
|
||||||
|
|
|
||||||
|
|
@ -1151,6 +1151,7 @@ var dictionary = {
|
||||||
"label.networks": "Nettverk",
|
"label.networks": "Nettverk",
|
||||||
"label.new": "Ny",
|
"label.new": "Ny",
|
||||||
"label.new.password": "Nytt passord",
|
"label.new.password": "Nytt passord",
|
||||||
|
"label.current.password": "Current Password",
|
||||||
"label.new.project": "Nytt prosjekt",
|
"label.new.project": "Nytt prosjekt",
|
||||||
"label.new.ssh.key.pair": "Nytt SSH-nøkkelpar",
|
"label.new.ssh.key.pair": "Nytt SSH-nøkkelpar",
|
||||||
"label.new.vm": "Ny VM",
|
"label.new.vm": "Ny VM",
|
||||||
|
|
|
||||||
|
|
@ -1151,6 +1151,7 @@ var dictionary = {
|
||||||
"label.networks": "Netwerken",
|
"label.networks": "Netwerken",
|
||||||
"label.new": "Nieuw",
|
"label.new": "Nieuw",
|
||||||
"label.new.password": "Nieuw wachtwoord",
|
"label.new.password": "Nieuw wachtwoord",
|
||||||
|
"label.current.password": "Current Password",
|
||||||
"label.new.project": "Nieuw Project",
|
"label.new.project": "Nieuw Project",
|
||||||
"label.new.ssh.key.pair": "nieuw SSH sleutelpaar",
|
"label.new.ssh.key.pair": "nieuw SSH sleutelpaar",
|
||||||
"label.new.vm": "Nieuwe VM",
|
"label.new.vm": "Nieuwe VM",
|
||||||
|
|
|
||||||
|
|
@ -1151,6 +1151,7 @@ var dictionary = {
|
||||||
"label.networks": "Sieci",
|
"label.networks": "Sieci",
|
||||||
"label.new": "Nowy",
|
"label.new": "Nowy",
|
||||||
"label.new.password": "New Password",
|
"label.new.password": "New Password",
|
||||||
|
"label.current.password": "Current Password",
|
||||||
"label.new.project": "Nowy projekt",
|
"label.new.project": "Nowy projekt",
|
||||||
"label.new.ssh.key.pair": "New SSH Key Pair",
|
"label.new.ssh.key.pair": "New SSH Key Pair",
|
||||||
"label.new.vm": "New VM",
|
"label.new.vm": "New VM",
|
||||||
|
|
|
||||||
|
|
@ -1151,6 +1151,7 @@ var dictionary = {
|
||||||
"label.networks": "Redes",
|
"label.networks": "Redes",
|
||||||
"label.new": "Novo",
|
"label.new": "Novo",
|
||||||
"label.new.password": "Nova Senha",
|
"label.new.password": "Nova Senha",
|
||||||
|
"label.current.password": "Senha Antiga",
|
||||||
"label.new.project": "Novo Projeto",
|
"label.new.project": "Novo Projeto",
|
||||||
"label.new.ssh.key.pair": "Novo par de chaves SSH",
|
"label.new.ssh.key.pair": "Novo par de chaves SSH",
|
||||||
"label.new.vm": "Nova VM",
|
"label.new.vm": "Nova VM",
|
||||||
|
|
|
||||||
|
|
@ -1151,6 +1151,7 @@ var dictionary = {
|
||||||
"label.networks": "Сети",
|
"label.networks": "Сети",
|
||||||
"label.new": "Создать",
|
"label.new": "Создать",
|
||||||
"label.new.password": "Новый пароль",
|
"label.new.password": "Новый пароль",
|
||||||
|
"label.current.password": "Current Password",
|
||||||
"label.new.project": "Новый проект",
|
"label.new.project": "Новый проект",
|
||||||
"label.new.ssh.key.pair": "New SSH Key Pair",
|
"label.new.ssh.key.pair": "New SSH Key Pair",
|
||||||
"label.new.vm": "Новая ВМ",
|
"label.new.vm": "Новая ВМ",
|
||||||
|
|
|
||||||
|
|
@ -1151,6 +1151,7 @@ var dictionary = {
|
||||||
"label.networks": "网络",
|
"label.networks": "网络",
|
||||||
"label.new": "新建",
|
"label.new": "新建",
|
||||||
"label.new.password": "新密码",
|
"label.new.password": "新密码",
|
||||||
|
"label.current.password": "Current Password",
|
||||||
"label.new.project": "新建项目",
|
"label.new.project": "新建项目",
|
||||||
"label.new.ssh.key.pair": "新SSH密钥对",
|
"label.new.ssh.key.pair": "新SSH密钥对",
|
||||||
"label.new.vm": "新建 VM",
|
"label.new.vm": "新建 VM",
|
||||||
|
|
|
||||||
|
|
@ -1476,6 +1476,14 @@
|
||||||
form: {
|
form: {
|
||||||
title: 'label.action.change.password',
|
title: 'label.action.change.password',
|
||||||
fields: {
|
fields: {
|
||||||
|
currentPassword: {
|
||||||
|
label: 'label.current.password',
|
||||||
|
isPassword: true,
|
||||||
|
validation: {
|
||||||
|
required: !(isAdmin() || isDomainAdmin())
|
||||||
|
},
|
||||||
|
id: 'currentPassword'
|
||||||
|
},
|
||||||
newPassword: {
|
newPassword: {
|
||||||
label: 'label.new.password',
|
label: 'label.new.password',
|
||||||
isPassword: true,
|
isPassword: true,
|
||||||
|
|
@ -1496,13 +1504,13 @@
|
||||||
},
|
},
|
||||||
after: function(args) {
|
after: function(args) {
|
||||||
start();
|
start();
|
||||||
|
var currentPassword = args.data.currentPassword;
|
||||||
var password = args.data.newPassword;
|
var password = args.data.newPassword;
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: createURL('updateUser'),
|
url: createURL('updateUser'),
|
||||||
data: {
|
data: {
|
||||||
id: context.users[0].id,
|
id: context.users[0].id,
|
||||||
|
currentPassword: currentPassword,
|
||||||
password: password
|
password: password
|
||||||
},
|
},
|
||||||
type: "POST",
|
type: "POST",
|
||||||
|
|
@ -1515,6 +1523,9 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if(isAdmin() || isDomainAdmin()){
|
||||||
|
$('div[rel=currentPassword]').hide();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
cloudStack.dialog.notice({ message: _l('error.could.not.change.your.password.because.non.native.user') });
|
cloudStack.dialog.notice({ message: _l('error.could.not.change.your.password.because.non.native.user') });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue