- Merge all CloudZones Registration feature into master

This commit is contained in:
will 2011-04-28 15:42:49 -07:00
parent 2aa280ed14
commit 633d024b7c
13 changed files with 1370 additions and 1081 deletions

View File

@ -1,178 +1,181 @@
/**
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.user;
import java.util.List;
import com.cloud.api.commands.CreateAccountCmd;
import com.cloud.api.commands.CreateUserCmd;
import com.cloud.api.commands.DeleteAccountCmd;
import com.cloud.api.commands.DeleteUserCmd;
import com.cloud.api.commands.DisableAccountCmd;
import com.cloud.api.commands.DisableUserCmd;
import com.cloud.api.commands.EnableAccountCmd;
import com.cloud.api.commands.EnableUserCmd;
import com.cloud.api.commands.ListResourceLimitsCmd;
import com.cloud.api.commands.LockUserCmd;
import com.cloud.api.commands.UpdateAccountCmd;
import com.cloud.api.commands.UpdateResourceLimitCmd;
import com.cloud.api.commands.UpdateUserCmd;
import com.cloud.configuration.ResourceLimit;
import com.cloud.domain.Domain;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.utils.Pair;
public interface AccountService {
/**
* Creates a new user, stores the password as is so encrypted passwords are recommended.
*
* @param cmd
* the create command that has the username, email, password, account name, domain, timezone, etc. for creating
* the user.
* @return the user if created successfully, null otherwise
*/
UserAccount createAccount(CreateAccountCmd cmd);
/**
* Deletes a user by userId
*
* @param cmd
* - the delete command defining the id of the user to be deleted.
* @return true if delete was successful, false otherwise
*/
boolean deleteUserAccount(DeleteAccountCmd cmd);
/**
* Disables a user by userId
*
* @param cmd
* the command wrapping the userId parameter
* @return UserAccount object
*/
UserAccount disableUser(DisableUserCmd cmd);
/**
* Enables a user
*
* @param cmd
* - the command containing userId
* @return UserAccount object
*/
UserAccount enableUser(EnableUserCmd cmd);
/**
* Locks a user by userId. A locked user cannot access the API, but will still have running VMs/IP addresses allocated/etc.
*
* @param userId
* @return UserAccount object
*/
UserAccount lockUser(LockUserCmd cmd);
/**
* Update a user by userId
*
* @param userId
* @return UserAccount object
*/
UserAccount updateUser(UpdateUserCmd cmd);
/**
* Disables an account by accountName and domainId
*
* @param disabled
* account if success
* @return true if disable was successful, false otherwise
*/
Account disableAccount(DisableAccountCmd cmd) throws ConcurrentOperationException, ResourceUnavailableException;
/**
* Enables an account by accountId
*
* @param cmd
* - the enableAccount command defining the accountId to be deleted.
* @return account object
*/
Account enableAccount(EnableAccountCmd cmd);
/**
* Locks an account by accountId. A locked account cannot access the API, but will still have running VMs/IP addresses
* allocated/etc.
*
* @param cmd
* - the LockAccount command defining the accountId to be locked.
* @return account object
*/
Account lockAccount(DisableAccountCmd cmd);
/**
* Updates an account name
*
* @param cmd
* - the parameter containing accountId
* @return updated account object
*/
Account updateAccount(UpdateAccountCmd cmd);
/**
* Updates an existing resource limit with the specified details. If a limit doesn't exist, will create one.
*
* @param cmd
* the command that wraps the domainId, accountId, type, and max parameters
* @return the updated/created resource limit
*/
ResourceLimit updateResourceLimit(UpdateResourceLimitCmd cmd);
/**
* Search for resource limits for the given id and/or account and/or type and/or domain.
*
* @param cmd
* the command wrapping the id, type, account, and domain
* @return a list of limits that match the criteria
*/
List<? extends ResourceLimit> searchForLimits(ListResourceLimitsCmd cmd);
Account getSystemAccount();
User getSystemUser();
User createUser(CreateUserCmd cmd);
boolean deleteUser(DeleteUserCmd deleteUserCmd);
boolean isAdmin(short accountType);
Account finalizeOwner(Account caller, String accountName, Long domainId);
Pair<String, Long> finalizeAccountDomainForList(Account caller, String accountName, Long domainId);
Account getActiveAccount(String accountName, Long domainId);
Account getActiveAccount(Long accountId);
Account getAccount(Long accountId);
User getActiveUser(long userId);
Domain getDomain(long id);
boolean isRootAdmin(short accountType);
}
/**
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.user;
import java.util.List;
import com.cloud.api.commands.CreateAccountCmd;
import com.cloud.api.commands.CreateUserCmd;
import com.cloud.api.commands.DeleteAccountCmd;
import com.cloud.api.commands.DeleteUserCmd;
import com.cloud.api.commands.DisableAccountCmd;
import com.cloud.api.commands.DisableUserCmd;
import com.cloud.api.commands.EnableAccountCmd;
import com.cloud.api.commands.EnableUserCmd;
import com.cloud.api.commands.ListResourceLimitsCmd;
import com.cloud.api.commands.LockUserCmd;
import com.cloud.api.commands.UpdateAccountCmd;
import com.cloud.api.commands.UpdateResourceLimitCmd;
import com.cloud.api.commands.UpdateUserCmd;
import com.cloud.configuration.ResourceLimit;
import com.cloud.domain.Domain;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.utils.Pair;
public interface AccountService {
/**
* Creates a new user, stores the password as is so encrypted passwords are recommended.
*
* @param cmd
* the create command that has the username, email, password, account name, domain, timezone, etc. for creating
* the user.
* @return the user if created successfully, null otherwise
*/
UserAccount createAccount(CreateAccountCmd cmd);
/**
* Deletes a user by userId
*
* @param cmd
* - the delete command defining the id of the user to be deleted.
* @return true if delete was successful, false otherwise
*/
boolean deleteUserAccount(DeleteAccountCmd cmd);
/**
* Disables a user by userId
*
* @param cmd
* the command wrapping the userId parameter
* @return UserAccount object
*/
UserAccount disableUser(DisableUserCmd cmd);
/**
* Enables a user
*
* @param cmd
* - the command containing userId
* @return UserAccount object
*/
UserAccount enableUser(EnableUserCmd cmd);
/**
* Locks a user by userId. A locked user cannot access the API, but will still have running VMs/IP addresses allocated/etc.
*
* @param userId
* @return UserAccount object
*/
UserAccount lockUser(LockUserCmd cmd);
/**
* Update a user by userId
*
* @param userId
* @return UserAccount object
*/
UserAccount updateUser(UpdateUserCmd cmd);
/**
* Disables an account by accountName and domainId
*
* @param disabled
* account if success
* @return true if disable was successful, false otherwise
*/
Account disableAccount(DisableAccountCmd cmd) throws ConcurrentOperationException, ResourceUnavailableException;
/**
* Enables an account by accountId
*
* @param cmd
* - the enableAccount command defining the accountId to be deleted.
* @return account object
*/
Account enableAccount(EnableAccountCmd cmd);
/**
* Locks an account by accountId. A locked account cannot access the API, but will still have running VMs/IP addresses
* allocated/etc.
*
* @param cmd
* - the LockAccount command defining the accountId to be locked.
* @return account object
*/
Account lockAccount(DisableAccountCmd cmd);
/**
* Updates an account name
*
* @param cmd
* - the parameter containing accountId
* @return updated account object
*/
Account updateAccount(UpdateAccountCmd cmd);
/**
* Updates an existing resource limit with the specified details. If a limit doesn't exist, will create one.
*
* @param cmd
* the command that wraps the domainId, accountId, type, and max parameters
* @return the updated/created resource limit
*/
ResourceLimit updateResourceLimit(UpdateResourceLimitCmd cmd);
/**
* Search for resource limits for the given id and/or account and/or type and/or domain.
*
* @param cmd
* the command wrapping the id, type, account, and domain
* @return a list of limits that match the criteria
*/
List<? extends ResourceLimit> searchForLimits(ListResourceLimitsCmd cmd);
Account getSystemAccount();
User getSystemUser();
User createUser(CreateUserCmd cmd);
boolean deleteUser(DeleteUserCmd deleteUserCmd);
boolean isAdmin(short accountType);
Account finalizeOwner(Account caller, String accountName, Long domainId);
Pair<String, Long> finalizeAccountDomainForList(Account caller, String accountName, Long domainId);
Account getActiveAccount(String accountName, Long domainId);
Account getActiveAccount(Long accountId);
Account getAccount(Long accountId);
User getActiveUser(long userId);
Domain getDomain(long id);
boolean isRootAdmin(short accountType);
User getActiveUserByRegistrationToken(String registrationToken);
void markUserRegistered(long userId);
}

View File

@ -66,5 +66,9 @@ public interface User extends OwnedBy {
public String getTimezone();
public void setTimezone(String timezone);
String getRegistrationToken();
boolean isRegistered();
}

View File

@ -53,5 +53,9 @@ public interface UserAccount {
String getAccountState();
String getTimezone();
String getTimezone();
String getRegistrationToken();
boolean isRegistered();
}

View File

@ -42,6 +42,11 @@
<servlet-name>consoleServlet</servlet-name>
<servlet-class>com.cloud.servlet.ConsoleProxyServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>registerCompleteServlet</servlet-name>
<servlet-class>com.cloud.servlet.RegisterCompleteServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>apiServlet</servlet-name>
@ -52,4 +57,9 @@
<servlet-name>consoleServlet</servlet-name>
<url-pattern>/console</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>registerCompleteServlet</servlet-name>
<url-pattern>/cloudkit/complete</url-pattern>
</servlet-mapping>
</web-app>

View File

@ -76,6 +76,12 @@ public class UserAccountVO implements UserAccount {
@Column(name="timezone")
private String timezone;
@Column(name="registration_token")
private String registrationToken = null;
@Column(name="is_registered")
boolean registered;
@Column(name="account_name", table="account", insertable=false, updatable=false)
private String accountName = null;
@ -243,5 +249,24 @@ public class UserAccountVO implements UserAccount {
public void setTimezone(String timezone)
{
this.timezone = timezone;
}
@Override
public String getRegistrationToken(){
return registrationToken;
}
public void setRegistrationToken(String registrationToken)
{
this.registrationToken = registrationToken;
}
@Override
public boolean isRegistered() {
return registered;
}
public void setRegistered(boolean registered) {
this.registered = registered;
}
}

View File

@ -82,6 +82,12 @@ public class UserVO implements User {
@Column(name = "timezone")
private String timezone;
@Column(name="registration_token")
private String registrationToken = null;
@Column(name="is_registered")
boolean registered;
public UserVO() {
}
@ -204,6 +210,25 @@ public class UserVO implements User {
public void setTimezone(String timezone) {
this.timezone = timezone;
}
@Override
public String getRegistrationToken(){
return registrationToken;
}
public void setRegistrationToken(String registrationToken)
{
this.registrationToken = registrationToken;
}
@Override
public boolean isRegistered() {
return registered;
}
public void setRegistered(boolean registered) {
this.registered = registered;
}
@Override
public String toString() {

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,122 @@
/**
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.servlet;
import java.util.List;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import com.cloud.configuration.Configuration;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.server.ManagementServer;
import com.cloud.user.Account;
import com.cloud.user.AccountService;
import com.cloud.user.User;
import com.cloud.user.UserVO;
import com.cloud.user.dao.UserDao;
import com.cloud.utils.SerialVersionUID;
import com.cloud.utils.component.ComponentLocator;
public class RegisterCompleteServlet extends HttpServlet implements ServletContextListener {
public static final Logger s_logger = Logger.getLogger(RegisterCompleteServlet.class.getName());
static final long serialVersionUID = SerialVersionUID.CloudStartupServlet;
protected static AccountService _accountSvc = null;
protected static ConfigurationDao _configDao = null;
protected static UserDao _userDao = null;
@Override
public void init() throws ServletException {
ComponentLocator locator = ComponentLocator.getLocator(ManagementServer.Name);
_accountSvc = locator.getManager(AccountService.class);
_configDao = locator.getDao(ConfigurationDao.class);
_userDao = locator.getDao(UserDao.class);
}
@Override
public void contextInitialized(ServletContextEvent sce) {
try {
init();
} catch (ServletException e) {
s_logger.error("Exception starting management server ", e);
throw new RuntimeException(e);
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
doGet(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
String registrationToken = req.getParameter("token");
if (registrationToken == null || registrationToken.trim().length() == 0) {
// Return an error code
}
User resourceAdminUser = _accountSvc.getActiveUserByRegistrationToken(registrationToken);
if (resourceAdminUser == null) {
// Return an error code
}
if(!resourceAdminUser.isRegistered()){
_accountSvc.markUserRegistered(resourceAdminUser.getId());
}
Account resourceAdminAccount = _accountSvc.getActiveAccount(resourceAdminUser.getAccountId());
Account rsUserAccount = _accountSvc.getActiveAccount(resourceAdminAccount.getAccountName()+"-user", resourceAdminAccount.getDomainId());
List<UserVO> users = _userDao.listByAccount(rsUserAccount.getId());
User rsUser = users.get(0);
Configuration config = _configDao.findByName("endpointe.url");
StringBuffer sb = new StringBuffer();
sb.append("{ \"registration_info\" : { \"endpoint_url\" : \""+config.getValue()+"\", ");
sb.append("\"domain_id\" : \""+resourceAdminAccount.getDomainId()+"\", ");
sb.append("\"admin_account\" : \""+resourceAdminUser.getUsername()+"\", ");
sb.append("\"admin_account_api_key\" : \""+resourceAdminUser.getApiKey()+"\", ");
sb.append("\"admin_account_secret_key\" : \""+resourceAdminUser.getSecretKey()+"\", ");
sb.append("\"user_account\" : \""+rsUser.getUsername()+"\", ");
sb.append("\"user_account_api_key\" : \""+rsUser.getApiKey()+"\", ");
sb.append("\"user_account_secret_key\" : \""+rsUser.getSecretKey()+"\" ");
sb.append("} }");
try {
resp.setContentType("text/javascript; charset=UTF-8");
resp.setStatus(HttpServletResponse.SC_OK);
resp.getWriter().print(sb.toString());
} catch (Exception ex) {
s_logger.error("unknown exception writing register complete response", ex);
}
}
}

View File

@ -22,6 +22,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@ -1144,6 +1145,13 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag
user.setAccountId(accountId.longValue());
user.setEmail(email);
user.setTimezone(timezone);
if(userType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN){
//set registration token
byte[] bytes = (domainId + accountName + username + System.currentTimeMillis()).getBytes();
String registrationToken = UUID.nameUUIDFromBytes(bytes).toString();
user.setRegistrationToken(registrationToken);
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Creating user: " + username + ", account: " + accountName + " (id:" + accountId + "), domain: " + domainId + " timezone:" + timezone);
}
@ -1767,4 +1775,16 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag
return new Pair<String, Long>(accountName, domainId);
}
@Override
public User getActiveUserByRegistrationToken(String registrationToken) {
return _userDao.findUserByRegistrationToken(registrationToken);
}
@Override
public void markUserRegistered(long userId) {
UserVO userForUpdate = _userDao.createForUpdate();
userForUpdate.setRegistered(true);
_userDao.update(Long.valueOf(userId), userForUpdate);
}
}

View File

@ -55,5 +55,13 @@ public interface UserDao extends GenericDao<UserVO, Long>{
* @param secretKey
* @return
*/
UserVO findUserBySecretKey(String secretKey);
UserVO findUserBySecretKey(String secretKey);
/**
* Finds a user based on the registration token provided.
* @param registrationToken
* @return
*/
UserVO findUserByRegistrationToken(String registrationToken);
}

View File

@ -41,7 +41,8 @@ public class UserDaoImpl extends GenericDaoBase<UserVO, Long> implements UserDao
protected SearchBuilder<UserVO> UsernameLikeSearch;
protected SearchBuilder<UserVO> UserIdSearch;
protected SearchBuilder<UserVO> AccountIdSearch;
protected SearchBuilder<UserVO> SecretKeySearch;
protected SearchBuilder<UserVO> SecretKeySearch;
protected SearchBuilder<UserVO> RegistrationTokenSearch;
protected UserDaoImpl () {
UsernameSearch = createSearchBuilder();
@ -67,7 +68,11 @@ public class UserDaoImpl extends GenericDaoBase<UserVO, Long> implements UserDao
SecretKeySearch = createSearchBuilder();
SecretKeySearch.and("secretKey", SecretKeySearch.entity().getSecretKey(), SearchCriteria.Op.EQ);
SecretKeySearch.done();
SecretKeySearch.done();
RegistrationTokenSearch = createSearchBuilder();
RegistrationTokenSearch.and("registrationToken", RegistrationTokenSearch.entity().getRegistrationToken(), SearchCriteria.Op.EQ);
RegistrationTokenSearch.done();
}
@Override
@ -134,5 +139,12 @@ public class UserDaoImpl extends GenericDaoBase<UserVO, Long> implements UserDao
{
throw new CloudRuntimeException("unable to update user -- a user with that name exists");
}
}
}
@Override
public UserVO findUserByRegistrationToken(String registrationToken) {
SearchCriteria<UserVO> sc = RegistrationTokenSearch.create();
sc.setParameters("registrationToken", registrationToken);
return findOneBy(sc);
}
}

View File

@ -698,6 +698,8 @@ CREATE TABLE `cloud`.`user` (
`created` datetime NOT NULL COMMENT 'date created',
`removed` datetime COMMENT 'date removed',
`timezone` varchar(30) default NULL,
`registration_token` varchar(255) default NULL,
`is_registered` tinyint NOT NULL DEFAULT 0 COMMENT '1: yes, 0: no',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

View File

@ -0,0 +1,52 @@
/**
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
var g_loginResponse = null;
$.urlParam = function(name){ var results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(window.location.href); if (!results) { return 0; } return results[1] || 0;}
function logout() {
window.location='/client/cloudkit/login.jsp';
g_loginResponse = null;
return true;
}
$(document).ready(function() {
var url = $.urlParam("loginUrl");
if (url != undefined && url != null && url.length > 0) {
url = unescape("/client/api?"+url);
$.ajax({
url: url,
dataType: "json",
async: false,
success: function(json) {
g_loginResponse = json.loginresponse;
$("#registration_complete_link").attr("href","https://my.rightscale.com/cloud_registrations/cloudkit/new?callback_url="+encodeURIComponent("http://localhost:8080/client/cloudkit/complete?token="+g_loginResponse.registrationtoken));
},
error: function() {
logout();
},
beforeSend: function(XMLHttpRequest) {
return true;
}
});
} else {
logout();
}
});