From c83323fea77ebbd87adf0f793362f4ba915a007b Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 10 Dec 2012 17:39:25 -0800 Subject: [PATCH] api: Refactoring ListUsersCmd and UserResponse. Signed-off-by: Rohit Yadav --- api/src/com/cloud/user/AccountService.java | 4 +- .../cloudstack/api/ResponseGenerator.java | 3 + .../api/command/admin/user/ListUsersCmd.java | 10 +- .../cloudstack/api/response/UserResponse.java | 31 +- .../api/view/vo/UserAccountJoinVO.java | 302 ++++++++++++++++++ server/src/com/cloud/api/ApiDBUtils.java | 17 + .../src/com/cloud/api/ApiResponseHelper.java | 54 +--- .../DefaultComponentLibrary.java | 2 + .../com/cloud/user/AccountManagerImpl.java | 75 ++--- .../cloud/user/dao/UserAccountJoinDao.java | 38 +++ .../user/dao/UserAccountJoinDaoImpl.java | 122 +++++++ .../cloud/user/MockAccountManagerImpl.java | 8 +- setup/db/create-schema.sql | 31 ++ 13 files changed, 597 insertions(+), 100 deletions(-) create mode 100644 api/src/org/apache/cloudstack/api/view/vo/UserAccountJoinVO.java create mode 100644 server/src/com/cloud/user/dao/UserAccountJoinDao.java create mode 100644 server/src/com/cloud/user/dao/UserAccountJoinDaoImpl.java diff --git a/api/src/com/cloud/user/AccountService.java b/api/src/com/cloud/user/AccountService.java index e9558fc283e..10d666c38f1 100755 --- a/api/src/com/cloud/user/AccountService.java +++ b/api/src/com/cloud/user/AccountService.java @@ -27,6 +27,8 @@ 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.account.UpdateAccountCmd; import org.apache.cloudstack.api.command.user.account.ListAccountsCmd; +import org.apache.cloudstack.api.view.vo.UserAccountJoinVO; + import com.cloud.domain.Domain; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.PermissionDeniedException; @@ -193,7 +195,7 @@ public interface AccountService { Pair, Integer> searchForAccounts(ListAccountsCmd cmd); - Pair, Integer> searchForUsers(ListUsersCmd cmd) + Pair, Integer> searchForUsers(ListUsersCmd cmd) throws PermissionDeniedException; UserAccount getUserByApiKey(String apiKey); diff --git a/api/src/org/apache/cloudstack/api/ResponseGenerator.java b/api/src/org/apache/cloudstack/api/ResponseGenerator.java index 2ccbec54db6..acb548ab0a7 100644 --- a/api/src/org/apache/cloudstack/api/ResponseGenerator.java +++ b/api/src/org/apache/cloudstack/api/ResponseGenerator.java @@ -155,6 +155,7 @@ import org.apache.cloudstack.api.view.vo.EventJoinVO; import org.apache.cloudstack.api.view.vo.InstanceGroupJoinVO; import org.apache.cloudstack.api.view.vo.ResourceTagJoinVO; import org.apache.cloudstack.api.view.vo.SecurityGroupJoinVO; +import org.apache.cloudstack.api.view.vo.UserAccountJoinVO; import org.apache.cloudstack.api.view.vo.UserVmJoinVO; import com.cloud.vm.VirtualMachine; @@ -280,6 +281,8 @@ public interface ResponseGenerator { UserResponse createUserResponse(User user); + List createUserResponse(UserAccountJoinVO... users); + AccountResponse createUserAccountResponse(UserAccount user); Long getSecurityGroupId(String groupName, long accountId); diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/ListUsersCmd.java b/api/src/org/apache/cloudstack/api/command/admin/user/ListUsersCmd.java index c7f0cbbf321..cb480d266ad 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/user/ListUsersCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/user/ListUsersCmd.java @@ -28,6 +28,8 @@ import org.apache.cloudstack.api.Implementation; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.UserResponse; +import org.apache.cloudstack.api.view.vo.UserAccountJoinVO; + import com.cloud.user.UserAccount; import com.cloud.utils.Pair; @@ -86,13 +88,9 @@ public class ListUsersCmd extends BaseListAccountResourcesCmd { @Override public void execute(){ - Pair, Integer> result = _accountService.searchForUsers(this); + Pair, Integer> result = _accountService.searchForUsers(this); ListResponse response = new ListResponse(); - List userResponses = new ArrayList(); - for (UserAccount user : result.first()) { - UserResponse userResponse = _responseGenerator.createUserResponse(user); - userResponses.add(userResponse); - } + List userResponses = _responseGenerator.createUserResponse(result.first().toArray(new UserAccountJoinVO[result.first().size()])); response.setResponses(userResponses, result.second()); response.setResponseName(getCommandName()); this.setResponseObject(response); diff --git a/api/src/org/apache/cloudstack/api/response/UserResponse.java b/api/src/org/apache/cloudstack/api/response/UserResponse.java index 2868be4bbfd..bb161264d12 100644 --- a/api/src/org/apache/cloudstack/api/response/UserResponse.java +++ b/api/src/org/apache/cloudstack/api/response/UserResponse.java @@ -18,14 +18,13 @@ package org.apache.cloudstack.api.response; import java.util.Date; -import com.cloud.utils.IdentityProxy; import com.cloud.serializer.Param; import com.google.gson.annotations.SerializedName; import org.apache.cloudstack.api.BaseResponse; public class UserResponse extends BaseResponse { @SerializedName("id") @Param(description="the user ID") - private IdentityProxy id = new IdentityProxy("user"); + private String id; @SerializedName("username") @Param(description="the user name") private String username; @@ -52,7 +51,7 @@ public class UserResponse extends BaseResponse { private Short accountType; @SerializedName("domainid") @Param(description="the domain ID of the user") - private IdentityProxy domainId = new IdentityProxy("domain"); + private String domainId; @SerializedName("domain") @Param(description="the domain name of the user") private String domainName; @@ -67,15 +66,15 @@ public class UserResponse extends BaseResponse { private String secretKey; @SerializedName("accountid") @Param(description="the account ID of the user") - private IdentityProxy accountId = new IdentityProxy("account"); + private String accountId; - public Long getId() { - return id.getValue(); + public String getId() { + return id; } - public void setId(Long id) { - this.id.setValue(id); + public void setId(String id) { + this.id = id; } public String getUsername() { @@ -142,12 +141,12 @@ public class UserResponse extends BaseResponse { this.accountType = accountType; } - public Long getDomainId() { - return domainId.getValue(); + public String getDomainId() { + return domainId; } - public void setDomainId(Long domainId) { - this.domainId.setValue(domainId); + public void setDomainId(String domainId) { + this.domainId = domainId; } public String getDomainName() { @@ -181,11 +180,11 @@ public class UserResponse extends BaseResponse { public void setSecretKey(String secretKey) { this.secretKey = secretKey; } - public Long getAccountId() { - return accountId.getValue(); + public String getAccountId() { + return accountId; } - public void setAccountId(Long accountId) { - this.accountId.setValue(accountId); + public void setAccountId(String accountId) { + this.accountId = accountId; } } diff --git a/api/src/org/apache/cloudstack/api/view/vo/UserAccountJoinVO.java b/api/src/org/apache/cloudstack/api/view/vo/UserAccountJoinVO.java new file mode 100644 index 00000000000..2cecd2cebfa --- /dev/null +++ b/api/src/org/apache/cloudstack/api/view/vo/UserAccountJoinVO.java @@ -0,0 +1,302 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.api.view.vo; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.Table; + +import com.cloud.utils.db.Encrypt; +import com.cloud.utils.db.GenericDao; +import com.cloud.event.Event.State; + +@Entity +@Table(name="user_view") +public class UserAccountJoinVO extends BaseViewVO { + + @Column(name="uuid") + private String uuid; + + @Column(name="username") + private String username = null; + + @Column(name="password") + private String password = null; + + @Column(name="firstname") + private String firstname = null; + + @Column(name="lastname") + private String lastname = null; + + @Column(name="email") + private String email = null; + + @Column(name="state") + private String state; + + @Column(name="api_key") + private String apiKey = null; + + @Encrypt + @Column(name="secret_key") + private String secretKey = null; + + @Column(name=GenericDao.CREATED_COLUMN) + private Date created; + + @Column(name=GenericDao.REMOVED_COLUMN) + private Date removed; + + @Column(name="timezone") + private String timezone; + + @Column(name="registration_token") + private String registrationToken = null; + + @Column(name="is_registered") + boolean registered; + + @Column (name="incorrect_login_attempts") + int loginAttempts; + + + @Column(name="account_id") + private long accountId; + + @Column(name="account_uuid") + private String accountUuid; + + @Column(name="account_name") + private String accountName = null; + + @Column(name="account_type") + private short accountType; + + @Column(name="domain_id") + private long domainId; + + @Column(name="domain_uuid") + private String domainUuid; + + @Column(name="domain_name") + private String domainName = null; + + @Column(name="domain_path") + private String domainPath = null; + + + public UserAccountJoinVO() { + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + + public long getAccountId() { + return accountId; + } + + public void setAccountId(long accountId) { + this.accountId = accountId; + } + + public String getAccountUuid() { + return accountUuid; + } + + public void setAccountUuid(String accountUuid) { + this.accountUuid = accountUuid; + } + + public String getAccountName() { + return accountName; + } + + public void setAccountName(String accountName) { + this.accountName = accountName; + } + + + public short getAccountType() { + return accountType; + } + + public void setAccountType(short accountType) { + this.accountType = accountType; + } + + + public long getDomainId() { + return domainId; + } + + public void setDomainId(long domainId) { + this.domainId = domainId; + } + + + public String getDomainUuid() { + return domainUuid; + } + + public void setDomainUuid(String domainUuid) { + this.domainUuid = domainUuid; + } + + + public String getDomainName() { + return domainName; + } + + public void setDomainName(String domainName) { + this.domainName = domainName; + } + + + public String getDomainPath() { + return domainPath; + } + + public void setDomainPath(String domainPath) { + this.domainPath = domainPath; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getFirstname() { + return firstname; + } + + public void setFirstname(String firstname) { + this.firstname = firstname; + } + + public String getLastname() { + return lastname; + } + + public void setLastname(String lastname) { + this.lastname = lastname; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public String getApiKey() { + return apiKey; + } + + public void setApiKey(String apiKey) { + this.apiKey = apiKey; + } + + public String getSecretKey() { + return secretKey; + } + + public void setSecretKey(String secretKey) { + this.secretKey = secretKey; + } + + public Date getCreated() { + return created; + } + + public void setCreated(Date created) { + this.created = created; + } + + public Date getRemoved() { + return removed; + } + + public void setRemoved(Date removed) { + this.removed = removed; + } + + public String getTimezone() { + return timezone; + } + + public void setTimezone(String timezone) { + this.timezone = timezone; + } + + public String getRegistrationToken() { + return registrationToken; + } + + public void setRegistrationToken(String registrationToken) { + this.registrationToken = registrationToken; + } + + public boolean isRegistered() { + return registered; + } + + public void setRegistered(boolean registered) { + this.registered = registered; + } + + public int getLoginAttempts() { + return loginAttempts; + } + + public void setLoginAttempts(int loginAttempts) { + this.loginAttempts = loginAttempts; + } + + + +} diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index f3ee0eda7fb..3cebe462c55 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -28,12 +28,14 @@ import org.apache.cloudstack.api.response.EventResponse; import org.apache.cloudstack.api.response.InstanceGroupResponse; import org.apache.cloudstack.api.response.ResourceTagResponse; import org.apache.cloudstack.api.response.SecurityGroupResponse; +import org.apache.cloudstack.api.response.UserResponse; import org.apache.cloudstack.api.response.UserVmResponse; import org.apache.cloudstack.api.view.vo.DomainRouterJoinVO; import org.apache.cloudstack.api.view.vo.EventJoinVO; import org.apache.cloudstack.api.view.vo.InstanceGroupJoinVO; import org.apache.cloudstack.api.view.vo.ResourceTagJoinVO; import org.apache.cloudstack.api.view.vo.SecurityGroupJoinVO; +import org.apache.cloudstack.api.view.vo.UserAccountJoinVO; import org.apache.cloudstack.api.view.vo.UserVmJoinVO; import com.cloud.async.AsyncJobManager; import com.cloud.async.AsyncJobVO; @@ -156,10 +158,12 @@ import com.cloud.user.AccountVO; import com.cloud.user.ResourceLimitService; import com.cloud.user.SSHKeyPairVO; import com.cloud.user.User; +import com.cloud.user.UserAccount; import com.cloud.user.UserStatisticsVO; import com.cloud.user.UserVO; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.SSHKeyPairDao; +import com.cloud.user.dao.UserAccountJoinDao; import com.cloud.user.dao.UserDao; import com.cloud.user.dao.UserStatisticsDao; import com.cloud.uservm.UserVm; @@ -256,6 +260,7 @@ public class ApiDBUtils { private static ResourceTagJoinDao _tagJoinDao; private static EventJoinDao _eventJoinDao; private static InstanceGroupJoinDao _vmGroupJoinDao; + private static UserAccountJoinDao _userAccountJoinDao; static { _ms = (ManagementServer) ComponentLocator.getComponent(ManagementServer.Name); @@ -996,4 +1001,16 @@ public class ApiDBUtils { public static InstanceGroupJoinVO newInstanceGroupView(InstanceGroup e){ return _vmGroupJoinDao.newInstanceGroupView(e); } + + public static UserResponse newUserResponse(UserAccountJoinVO usr) { + return _userAccountJoinDao.newUserResponse(usr); + } + + public static UserAccountJoinVO newUserView(User usr){ + return _userAccountJoinDao.newUserView(usr); + } + + public static UserAccountJoinVO newUserView(UserAccount usr){ + return _userAccountJoinDao.newUserView(usr); + } } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 04a931447b3..c8c78d027fe 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -118,6 +118,7 @@ import org.apache.cloudstack.api.view.vo.EventJoinVO; import org.apache.cloudstack.api.view.vo.InstanceGroupJoinVO; import org.apache.cloudstack.api.view.vo.ResourceTagJoinVO; import org.apache.cloudstack.api.view.vo.SecurityGroupJoinVO; +import org.apache.cloudstack.api.view.vo.UserAccountJoinVO; import org.apache.cloudstack.api.view.vo.UserVmJoinVO; import com.cloud.async.AsyncJob; import com.cloud.capacity.Capacity; @@ -238,27 +239,21 @@ public class ApiResponseHelper implements ResponseGenerator { @Override public UserResponse createUserResponse(User user) { - UserResponse userResponse = new UserResponse(); - Account account = ApiDBUtils.findAccountById(user.getAccountId()); - userResponse.setAccountName(account.getAccountName()); - userResponse.setAccountType(account.getType()); - userResponse.setCreated(user.getCreated()); - userResponse.setDomainId(account.getDomainId()); - userResponse.setDomainName(ApiDBUtils.findDomainById(account.getDomainId()).getName()); - userResponse.setEmail(user.getEmail()); - userResponse.setFirstname(user.getFirstname()); - userResponse.setId(user.getId()); - userResponse.setLastname(user.getLastname()); - userResponse.setState(user.getState().toString()); - userResponse.setTimezone(user.getTimezone()); - userResponse.setUsername(user.getUsername()); - userResponse.setApiKey(user.getApiKey()); - userResponse.setSecretKey(user.getSecretKey()); - userResponse.setObjectName("user"); - - return userResponse; + UserAccountJoinVO vUser = ApiDBUtils.newUserView(user); + return ApiDBUtils.newUserResponse(vUser); } + + @Override + public List createUserResponse(UserAccountJoinVO... users) { + List respList = new ArrayList(); + for (UserAccountJoinVO vt : users){ + respList.add(ApiDBUtils.newUserResponse(vt)); + } + return respList; + } + + // this method is used for response generation via createAccount (which creates an account + user) @Override public AccountResponse createUserAccountResponse(UserAccount user) { @@ -417,25 +412,8 @@ public class ApiResponseHelper implements ResponseGenerator { @Override public UserResponse createUserResponse(UserAccount user) { - UserResponse userResponse = new UserResponse(); - userResponse.setAccountName(user.getAccountName()); - userResponse.setAccountType(user.getType()); - userResponse.setCreated(user.getCreated()); - userResponse.setDomainId(user.getDomainId()); - userResponse.setDomainName(ApiDBUtils.findDomainById(user.getDomainId()).getName()); - userResponse.setEmail(user.getEmail()); - userResponse.setFirstname(user.getFirstname()); - userResponse.setId(user.getId()); - userResponse.setLastname(user.getLastname()); - userResponse.setState(user.getState()); - userResponse.setTimezone(user.getTimezone()); - userResponse.setUsername(user.getUsername()); - userResponse.setApiKey(user.getApiKey()); - userResponse.setSecretKey(user.getSecretKey()); - userResponse.setAccountId((user.getAccountId())); - userResponse.setObjectName("user"); - - return userResponse; + UserAccountJoinVO vUser = ApiDBUtils.newUserView(user); + return ApiDBUtils.newUserResponse(vUser); } @Override diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java index 5dc1c803692..c1703bc3729 100755 --- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java +++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java @@ -183,6 +183,7 @@ import com.cloud.user.DomainManagerImpl; import com.cloud.user.dao.AccountDaoImpl; import com.cloud.user.dao.SSHKeyPairDaoImpl; import com.cloud.user.dao.UserAccountDaoImpl; +import com.cloud.user.dao.UserAccountJoinDaoImpl; import com.cloud.user.dao.UserDaoImpl; import com.cloud.user.dao.UserStatisticsDaoImpl; import com.cloud.user.dao.UserStatsLogDaoImpl; @@ -227,6 +228,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com addDao("SecurityGroupJoinDao", SecurityGroupJoinDaoImpl.class); addDao("ResourceTagJoinDao", ResourceTagJoinDaoImpl.class); addDao("EventJoinDao", EventJoinDaoImpl.class); + addDao("UserAccountJoinDao", UserAccountJoinDaoImpl.class); ComponentInfo> info = addDao("ServiceOfferingDao", ServiceOfferingDaoImpl.class); info.addParameter("cache.size", "50"); info.addParameter("cache.time.to.live", "600"); diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index c0cbe474636..e1b806dc603 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -5,7 +5,7 @@ // 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, @@ -44,6 +44,8 @@ import org.apache.log4j.Logger; import com.cloud.acl.ControlledEntity; import org.apache.cloudstack.api.view.vo.ControlledViewEntity; +import org.apache.cloudstack.api.view.vo.UserAccountJoinVO; + import com.cloud.acl.SecurityChecker; import com.cloud.acl.SecurityChecker.AccessType; import com.cloud.api.ApiDBUtils; @@ -108,6 +110,7 @@ import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.Account.State; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserAccountDao; +import com.cloud.user.dao.UserAccountJoinDao; import com.cloud.user.dao.UserDao; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; @@ -157,6 +160,8 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag @Inject private UserAccountDao _userAccountDao; @Inject + private UserAccountJoinDao _userAccountJoinDao; + @Inject private VolumeDao _volumeDao; @Inject private UserVmDao _userVmDao; @@ -293,7 +298,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag @Override public boolean isAdmin(short accountType) { - return ((accountType == Account.ACCOUNT_TYPE_ADMIN) || (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) + return ((accountType == Account.ACCOUNT_TYPE_ADMIN) || (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) || (accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) || (accountType == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN)); } @@ -491,7 +496,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag @Override public boolean deleteAccount(AccountVO account, long callerUserId, Account caller) { long accountId = account.getId(); - + //delete the account record if (!_accountDao.remove(accountId)) { s_logger.error("Unable to delete account " + accountId); @@ -509,7 +514,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag public boolean cleanupAccount(AccountVO account, long callerUserId, Account caller) { long accountId = account.getId(); boolean accountCleanupNeeded = false; - + try { //cleanup the users from the account List users = _userDao.listByAccount(accountId); @@ -519,10 +524,10 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag accountCleanupNeeded = true; } } - + //delete the account from project accounts _projectAccountDao.removeAccountFromProjects(accountId); - + // delete all vm groups belonging to accont List groups = _vmGroupDao.listByAccountId(accountId); for (InstanceGroupVO group : groups) { @@ -600,7 +605,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag s_logger.warn("Failed to cleanup remote access vpn resources as a part of account id=" + accountId + " cleanup due to Exception: ", ex); accountCleanupNeeded = true; } - + // Cleanup security groups int numRemoved = _securityGroupDao.removeByAccountId(accountId); s_logger.info("deleteAccount: Deleted " + numRemoved + " network groups for account " + accountId); @@ -623,7 +628,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag } } } - + //Delete all VPCs boolean vpcsDeleted = true; s_logger.debug("Deleting vpcs for account " + account.getId()); @@ -774,7 +779,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag if (userName.isEmpty()) { throw new InvalidParameterValueException("Username is empty"); } - + if (firstName.isEmpty()) { throw new InvalidParameterValueException("Firstname is empty"); } @@ -846,7 +851,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag if (account == null || account.getType() == Account.ACCOUNT_TYPE_PROJECT) { throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain id=" + domainId + " to create user"); } - + if (account.getId() == Account.ACCOUNT_ID_SYSTEM) { throw new PermissionDeniedException("Account id : " + account.getId() + " is a system account, can't add a user to it"); } @@ -903,21 +908,21 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag if (firstName.isEmpty()) { throw new InvalidParameterValueException("Firstname is empty"); } - + user.setFirstname(firstName); } if (lastName != null) { if (lastName.isEmpty()) { throw new InvalidParameterValueException("Lastname is empty"); } - + 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 duplicatedUsers = _userDao.findUsersByName(userName); for (UserVO duplicatedUser : duplicatedUsers) { @@ -931,7 +936,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag user.setUsername(userName); } - + if (password != null) { String encodedPassword = null; for (Enumeration en = _userAuthenticators.enumeration(); en.hasMoreElements();) { @@ -1213,7 +1218,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag if (account == null || account.getType() == Account.ACCOUNT_TYPE_PROJECT) { throw new InvalidParameterValueException("Unable to find active account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId); } - + if (account.getId() == Account.ACCOUNT_ID_SYSTEM) { throw new PermissionDeniedException("Account id : " + accountId + " is a system account, lock is not allowed"); } @@ -1242,7 +1247,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag if (account == null || account.getType() == Account.ACCOUNT_TYPE_PROJECT) { throw new InvalidParameterValueException("Unable to find account by accountId: " + accountId + " OR by name: " + accountName + " in domain " + domainId); } - + if (account.getId() == Account.ACCOUNT_ID_SYSTEM) { throw new PermissionDeniedException("Account id : " + accountId + " is a system account, disable is not allowed"); } @@ -1394,7 +1399,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag s_logger.info("Found " + removedAccounts.size() + " removed accounts to cleanup"); for (AccountVO account : removedAccounts) { s_logger.debug("Cleaning up " + account.getId()); - cleanupAccount(account, getSystemUser().getId(), getSystemAccount()); + cleanupAccount(account, getSystemUser().getId(), getSystemAccount()); } // cleanup disabled accounts @@ -1693,7 +1698,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag if (s_logger.isDebugEnabled()) { s_logger.debug("Creating user: " + userName + ", accountId: " + accountId + " timezone:" + timezone); } - + String encodedPassword = null; for (Enumeration en = _userAuthenticators.enumeration(); en.hasMoreElements();) { UserAuthenticator authenticator = en.nextElement(); @@ -1841,7 +1846,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag s_logger.error("Failed to authenticate user: " + username + " in domain " + domainId); return null; } - + if (s_logger.isDebugEnabled()) { s_logger.debug("User: " + username + " in domain " + domainId + " has successfully logged in"); } @@ -1940,10 +1945,10 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag Long userId = cmd.getId(); User user = getUserIncludingRemoved(userId); - if (user == null) { + if (user == null) { throw new InvalidParameterValueException("unable to find user by id"); } - + //don't allow updating system user if (user.getId() == User.UID_SYSTEM) { throw new PermissionDeniedException("user id : " + user.getId() + " is system account, update is not allowed"); @@ -2136,9 +2141,10 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag } @Override - public Pair, Integer> searchForUsers(ListUsersCmd cmd) throws PermissionDeniedException { + public Pair, Integer> searchForUsers(ListUsersCmd cmd) throws PermissionDeniedException { Account caller = UserContext.current().getCaller(); + //TODO: Integrate with ACL checkAccess refactoring Long domainId = cmd.getDomainId(); if (domainId != null) { Domain domain = _domainDao.findById(domainId); @@ -2152,7 +2158,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag domainId = caller.getDomainId(); } - Filter searchFilter = new Filter(UserAccountVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal()); + Filter searchFilter = new Filter(UserAccountJoinVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal()); Long id = cmd.getId(); Object username = cmd.getUsername(); @@ -2161,12 +2167,12 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag Object state = cmd.getState(); Object keyword = cmd.getKeyword(); - SearchBuilder sb = _userAccountDao.createSearchBuilder(); + SearchBuilder sb = _userAccountJoinDao.createSearchBuilder(); sb.and("username", sb.entity().getUsername(), SearchCriteria.Op.LIKE); if (id != null && id == 1) { // system user should NOT be searchable - List emptyList = new ArrayList(); - return new Pair, Integer>(emptyList, 0); + List emptyList = new ArrayList(); + return new Pair, Integer>(emptyList, 0); } else if (id != null) { sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); } else { @@ -2174,20 +2180,18 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag sb.and("id", sb.entity().getId(), SearchCriteria.Op.NEQ); } - sb.and("type", sb.entity().getType(), SearchCriteria.Op.EQ); + sb.and("type", sb.entity().getAccountType(), SearchCriteria.Op.EQ); sb.and("domainId", sb.entity().getDomainId(), SearchCriteria.Op.EQ); sb.and("accountName", sb.entity().getAccountName(), SearchCriteria.Op.EQ); sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ); if ((accountName == null) && (domainId != null)) { - SearchBuilder domainSearch = _domainDao.createSearchBuilder(); - domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE); - sb.join("domainSearch", domainSearch, sb.entity().getDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER); + sb.and("domainPath", sb.entity().getDomainPath(), SearchCriteria.Op.LIKE); } - SearchCriteria sc = sb.create(); + SearchCriteria sc = sb.create(); if (keyword != null) { - SearchCriteria ssc = _userAccountDao.createSearchCriteria(); + SearchCriteria ssc = _userAccountJoinDao.createSearchCriteria(); ssc.addOr("username", SearchCriteria.Op.LIKE, "%" + keyword + "%"); ssc.addOr("firstname", SearchCriteria.Op.LIKE, "%" + keyword + "%"); ssc.addOr("lastname", SearchCriteria.Op.LIKE, "%" + keyword + "%"); @@ -2222,15 +2226,14 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag } } else if (domainId != null) { DomainVO domainVO = _domainDao.findById(domainId); - sc.setJoinParameters("domainSearch", "path", domainVO.getPath() + "%"); + sc.setParameters("domainPath", domainVO.getPath() + "%"); } if (state != null) { sc.setParameters("state", state); } - Pair, Integer> result = _userAccountDao.searchAndCount(sc, searchFilter); - return new Pair, Integer>(result.first(), result.second()); + return _userAccountJoinDao.searchAndCount(sc, searchFilter); } @Override @@ -2301,7 +2304,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag } @Override - public void buildACLSearchParameters(Account caller, Long id, String accountName, Long projectId, List + public void buildACLSearchParameters(Account caller, Long id, String accountName, Long projectId, List permittedAccounts, Ternary domainIdRecursiveListProject, boolean listAll, boolean forProjectInvitation) { Long domainId = domainIdRecursiveListProject.first(); diff --git a/server/src/com/cloud/user/dao/UserAccountJoinDao.java b/server/src/com/cloud/user/dao/UserAccountJoinDao.java new file mode 100644 index 00000000000..05858d022c2 --- /dev/null +++ b/server/src/com/cloud/user/dao/UserAccountJoinDao.java @@ -0,0 +1,38 @@ +// 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.dao; + +import java.util.List; + +import org.apache.cloudstack.api.response.UserResponse; +import org.apache.cloudstack.api.view.vo.UserAccountJoinVO; + +import com.cloud.user.User; +import com.cloud.user.UserAccount; +import com.cloud.utils.db.GenericDao; + +public interface UserAccountJoinDao extends GenericDao { + + UserResponse newUserResponse(UserAccountJoinVO usr); + + UserAccountJoinVO newUserView(User usr); + + UserAccountJoinVO newUserView(UserAccount usr); + + List searchByIds(Long... ids); + +} diff --git a/server/src/com/cloud/user/dao/UserAccountJoinDaoImpl.java b/server/src/com/cloud/user/dao/UserAccountJoinDaoImpl.java new file mode 100644 index 00000000000..8ffff0f82f0 --- /dev/null +++ b/server/src/com/cloud/user/dao/UserAccountJoinDaoImpl.java @@ -0,0 +1,122 @@ +// 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.dao; + +import java.util.List; + +import javax.ejb.Local; + +import org.apache.log4j.Logger; + +import com.cloud.api.ApiDBUtils; +import com.cloud.api.ApiResponseHelper; +import org.apache.cloudstack.api.response.InstanceGroupResponse; +import org.apache.cloudstack.api.response.UserResponse; +import org.apache.cloudstack.api.view.vo.InstanceGroupJoinVO; +import org.apache.cloudstack.api.view.vo.UserAccountJoinVO; + +import com.cloud.user.Account; +import com.cloud.user.User; +import com.cloud.user.UserAccount; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.vm.InstanceGroup; + + +@Local(value={UserAccountJoinDao.class}) +public class UserAccountJoinDaoImpl extends GenericDaoBase implements UserAccountJoinDao { + public static final Logger s_logger = Logger.getLogger(UserAccountJoinDaoImpl.class); + + private SearchBuilder vrSearch; + + private SearchBuilder vrIdSearch; + + + protected UserAccountJoinDaoImpl() { + + vrSearch = createSearchBuilder(); + vrSearch.and("idIN", vrSearch.entity().getId(), SearchCriteria.Op.IN); + vrSearch.done(); + + vrIdSearch = createSearchBuilder(); + vrIdSearch.and("id", vrIdSearch.entity().getId(), SearchCriteria.Op.EQ); + vrIdSearch.done(); + + this._count = "select count(distinct id) from user_view WHERE "; + } + + + + @Override + public UserResponse newUserResponse(UserAccountJoinVO usr) { + UserResponse userResponse = new UserResponse(); + userResponse.setAccountId(usr.getAccountUuid()); + userResponse.setAccountName(usr.getAccountName()); + userResponse.setAccountType(usr.getAccountType()); + userResponse.setCreated(usr.getCreated()); + userResponse.setDomainId(usr.getDomainUuid()); + userResponse.setDomainName(usr.getDomainName()); + userResponse.setEmail(usr.getEmail()); + userResponse.setFirstname(usr.getFirstname()); + userResponse.setId(usr.getUuid()); + userResponse.setLastname(usr.getLastname()); + userResponse.setState(usr.getState().toString()); + userResponse.setTimezone(usr.getTimezone()); + userResponse.setUsername(usr.getUsername()); + userResponse.setApiKey(usr.getApiKey()); + userResponse.setSecretKey(usr.getSecretKey()); + userResponse.setObjectName("user"); + + return userResponse; + } + + + @Override + public UserAccountJoinVO newUserView(User usr) { + SearchCriteria sc = vrIdSearch.create(); + sc.setParameters("id", usr.getId()); + List users = searchIncludingRemoved(sc, null, null, false); + assert users != null && users.size() == 1 : "No user found for user id " + usr.getId(); + return users.get(0); + } + + + + + @Override + public UserAccountJoinVO newUserView(UserAccount usr) { + SearchCriteria sc = vrIdSearch.create(); + sc.setParameters("id", usr.getId()); + List users = searchIncludingRemoved(sc, null, null, false); + assert users != null && users.size() == 1 : "No user found for user id " + usr.getId(); + return users.get(0); + } + + + + @Override + public List searchByIds(Long... ids) { + SearchCriteria sc = vrSearch.create(); + sc.setParameters("idIN", ids); + return searchIncludingRemoved(sc, null, null, false); + } + + + + +} diff --git a/server/test/com/cloud/user/MockAccountManagerImpl.java b/server/test/com/cloud/user/MockAccountManagerImpl.java index 90422c72668..dbe616991c1 100644 --- a/server/test/com/cloud/user/MockAccountManagerImpl.java +++ b/server/test/com/cloud/user/MockAccountManagerImpl.java @@ -31,6 +31,8 @@ import org.apache.cloudstack.api.command.user.account.ListAccountsCmd; import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd; import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd; import org.apache.cloudstack.api.view.vo.ControlledViewEntity; +import org.apache.cloudstack.api.view.vo.UserAccountJoinVO; + import com.cloud.domain.Domain; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.PermissionDeniedException; @@ -305,7 +307,7 @@ public class MockAccountManagerImpl implements Manager, AccountManager, AccountS } @Override - public Pair, Integer> searchForUsers(ListUsersCmd cmd) throws PermissionDeniedException { + public Pair, Integer> searchForUsers(ListUsersCmd cmd) throws PermissionDeniedException { // TODO Auto-generated method stub return null; } @@ -320,14 +322,14 @@ public class MockAccountManagerImpl implements Manager, AccountManager, AccountS public void buildACLSearchBuilder(SearchBuilder sb, Long domainId, boolean isRecursive, List permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria) { // TODO Auto-generated method stub - + } @Override public void buildACLSearchCriteria(SearchCriteria sc, Long domainId, boolean isRecursive, List permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria) { // TODO Auto-generated method stub - + } @Override diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 406145ce2b3..722b31f440f 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -2859,3 +2859,34 @@ from instance_group inner join account on instance_group.account_id=account.id inner join domain on account.domain_id=domain.id left join projects on projects.project_account_id = instance_group.account_id; + +DROP VIEW IF EXISTS `cloud`.`user_view`; +CREATE VIEW user_view AS +select +user.id, +user.uuid, +user.username, +user.password, +user.firstname, +user.lastname, +user.email, +user.state, +user.api_key, +user.secret_key, +user.created, +user.removed, +user.timezone, +user.registration_token, +user.is_registered, +user.incorrect_login_attempts, +account.id account_id, +account.uuid account_uuid, +account.account_name account_name, +account.type account_type, +domain.id domain_id, +domain.uuid domain_uuid, +domain.name domain_name, +domain.path domain_path +from user +inner join account on user.account_id = account.id +inner join domain on account.domain_id=domain.id;