http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/14bd345f/server/src/com/cloud/projects/ProjectManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/projects/ProjectManagerImpl.java b/server/src/com/cloud/projects/ProjectManagerImpl.java index ab7b7b1..00b7716 100755 --- a/server/src/com/cloud/projects/ProjectManagerImpl.java +++ b/server/src/com/cloud/projects/ProjectManagerImpl.java @@ -38,10 +38,10 @@ import javax.mail.URLName; import javax.mail.internet.InternetAddress; import javax.naming.ConfigurationException; +import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; -import org.apache.cloudstack.acl.SecurityChecker.AccessType; import com.cloud.api.query.dao.ProjectAccountJoinDao; import com.cloud.api.query.dao.ProjectInvitationJoinDao; import com.cloud.api.query.dao.ProjectJoinDao; @@ -73,7 +73,6 @@ import com.cloud.user.UserContext; import com.cloud.user.dao.AccountDao; import com.cloud.utils.DateUtil; import com.cloud.utils.NumbersUtil; -import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.db.DB; @@ -89,7 +88,7 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ public static final Logger s_logger = Logger.getLogger(ProjectManagerImpl.class); private String _name; private EmailInvite _emailInvite; - + @Inject private DomainDao _domainDao; @Inject @@ -118,24 +117,24 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ private ProjectInvitationJoinDao _projectInvitationJoinDao; @Inject protected ResourceTagDao _resourceTagDao; - + protected boolean _invitationRequired = false; protected long _invitationTimeOut = 86400000; protected boolean _allowUserToCreateProject = true; protected ScheduledExecutorService _executor; protected int _projectCleanupExpInvInterval = 60; //Interval defining how often project invitation cleanup thread is running - - + + @Override public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException { _name = name; - + Map<String, String> configs = _configDao.getConfiguration(params); _invitationRequired = Boolean.valueOf(configs.get(Config.ProjectInviteRequired.key())); _invitationTimeOut = Long.valueOf(configs.get(Config.ProjectInvitationExpirationTime.key()))*1000; _allowUserToCreateProject = Boolean.valueOf(configs.get(Config.AllowUserToCreateProject.key())); - - + + // set up the email system for project invitations String smtpHost = configs.get("project.smtp.host"); @@ -153,13 +152,13 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ _emailInvite = new EmailInvite(smtpHost, smtpPort, useAuth, smtpUsername, smtpPassword, emailSender, smtpDebug); _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Project-ExpireInvitations")); - + return true; } - + @Override public boolean start() { - _executor.scheduleWithFixedDelay(new ExpiredInvitationsCleanup(), _projectCleanupExpInvInterval, _projectCleanupExpInvInterval, TimeUnit.SECONDS); + _executor.scheduleWithFixedDelay(new ExpiredInvitationsCleanup(), _projectCleanupExpInvInterval, _projectCleanupExpInvInterval, TimeUnit.SECONDS); return true; } @@ -172,98 +171,98 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ public String getName() { return _name; } - + @Override @ActionEvent(eventType = EventTypes.EVENT_PROJECT_CREATE, eventDescription = "creating project", create=true) @DB public Project createProject(String name, String displayText, String accountName, Long domainId) throws ResourceAllocationException{ Account caller = UserContext.current().getCaller(); Account owner = caller; - + //check if the user authorized to create the project if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL && !_allowUserToCreateProject) { - throw new PermissionDeniedException("Regular user is not permitted to create a project"); + throw new PermissionDeniedException("Regular user is not permitted to create a project"); } - + //Verify request parameters if ((accountName != null && domainId == null) || (domainId != null && accountName == null)) { throw new InvalidParameterValueException("Account name and domain id must be specified together"); } - + if (accountName != null) { owner = _accountMgr.finalizeOwner(caller, accountName, domainId, null); } - + //don't allow 2 projects with the same name inside the same domain if (_projectDao.findByNameAndDomain(name, owner.getDomainId()) != null) { throw new InvalidParameterValueException("Project with name " + name + " already exists in domain id=" + owner.getDomainId()); } - + //do resource limit check _resourceLimitMgr.checkResourceLimit(owner, ResourceType.project); - + Transaction txn = Transaction.currentTxn(); txn.start(); - + //Create an account associated with the project StringBuilder acctNm = new StringBuilder("PrjAcct-"); acctNm.append(name).append("-").append(owner.getDomainId()); - + Account projectAccount = _accountMgr.createAccount(acctNm.toString(), Account.ACCOUNT_TYPE_PROJECT, domainId, null, null); - + Project project = _projectDao.persist(new ProjectVO(name, displayText, owner.getDomainId(), projectAccount.getId())); - + //assign owner to the project assignAccountToProject(project, owner.getId(), ProjectAccount.Role.Admin); - + if (project != null) { UserContext.current().setEventDetails("Project id=" + project.getId()); } - + //Increment resource count _resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.project); - + txn.commit(); - + return project; } - - + + @Override @ActionEvent(eventType = EventTypes.EVENT_PROJECT_CREATE, eventDescription = "creating project", async=true) @DB public Project enableProject(long projectId){ Account caller = UserContext.current().getCaller(); - + ProjectVO project= getProject(projectId); //verify input parameters if (project == null) { throw new InvalidParameterValueException("Unable to find project by id " + projectId); } - + _accountMgr.checkAccess(caller,AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId())); - + //at this point enabling project doesn't require anything, so just update the state project.setState(State.Active); _projectDao.update(projectId, project); - + return project; } - - + + @Override @ActionEvent(eventType = EventTypes.EVENT_PROJECT_DELETE, eventDescription = "deleting project", async = true) public boolean deleteProject(long projectId) { UserContext ctx = UserContext.current(); - + ProjectVO project= getProject(projectId); //verify input parameters if (project == null) { throw new InvalidParameterValueException("Unable to find project by id " + projectId); } - + _accountMgr.checkAccess(ctx.getCaller(),AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId())); - + return deleteProject(ctx.getCaller(), ctx.getCallerUserId(), project); } @@ -281,9 +280,9 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ if (projectOwner != null) { _resourceLimitMgr.decrementResourceCount(projectOwner.getId(), ResourceType.project); } - + txn.commit(); - + if (updateResult) { //pass system caller when clenaup projects account if (!cleanupProject(project, _accountDao.findById(Account.ACCOUNT_ID_SYSTEM), User.UID_SYSTEM)) { @@ -297,31 +296,31 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ return false; } } - + @DB private boolean cleanupProject(Project project, AccountVO caller, Long callerUserId) { boolean result=true; //Delete project's account AccountVO account = _accountDao.findById(project.getProjectAccountId()); s_logger.debug("Deleting projects " + project + " internal account id=" + account.getId() + " as a part of project cleanup..."); - + result = result && _accountMgr.deleteAccount(account, callerUserId, caller); - + if (result) { //Unassign all users from the project - + Transaction txn = Transaction.currentTxn(); txn.start(); - + s_logger.debug("Unassigning all accounts from project " + project + " as a part of project cleanup..."); List<? extends ProjectAccount> projectAccounts = _projectAccountDao.listByProjectId(project.getId()); for (ProjectAccount projectAccount : projectAccounts) { result = result && unassignAccountFromProject(projectAccount.getProjectId(), projectAccount.getAccountId()); } - + s_logger.debug("Removing all invitations for the project " + project + " as a part of project cleanup..."); - _projectInvitationDao.cleanupInvitations(project.getId()); - + _projectInvitationDao.cleanupInvitations(project.getId()); + txn.commit(); if (result) { s_logger.debug("Accounts are unassign successfully from project " + project + " as a part of project cleanup..."); @@ -329,10 +328,10 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ } else { s_logger.warn("Failed to cleanup project's internal account"); } - + return result; } - + @Override public boolean unassignAccountFromProject(long projectId, long accountId) { ProjectAccountVO projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, accountId); @@ -340,7 +339,7 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ s_logger.debug("Account id=" + accountId + " is not assigned to project id=" + projectId + " so no need to unassign"); return true; } - + if ( _projectAccountDao.remove(projectAccount.getId())) { return true; } else { @@ -348,34 +347,34 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ return false; } } - + @Override public ProjectVO getProject (long projectId) { return _projectDao.findById(projectId); } - - + + @Override public long getInvitationTimeout() { return _invitationTimeOut; - } - - + } + + @Override public ProjectAccount assignAccountToProject(Project project, long accountId, ProjectAccount.Role accountRole) { return _projectAccountDao.persist(new ProjectAccountVO(project, accountId, accountRole)); } - + @Override @DB public boolean deleteAccountFromProject(long projectId, long accountId) { boolean success = true; Transaction txn = Transaction.currentTxn(); txn.start(); - + //remove account ProjectAccountVO projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, accountId); success = _projectAccountDao.remove(projectAccount.getId()); - + //remove all invitations for account if (success) { s_logger.debug("Removed account " + accountId + " from project " + projectId + " , cleaning up old invitations for account/project..."); @@ -384,36 +383,36 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ success = success && _projectInvitationDao.remove(invite.getId()); } } - + txn.commit(); return success; } - + @Override public Account getProjectOwner(long projectId) { ProjectAccount prAcct = _projectAccountDao.getProjectOwner(projectId); if (prAcct != null) { return _accountMgr.getAccount(prAcct.getAccountId()); } - + return null; } - + @Override public ProjectVO findByProjectAccountId(long projectAccountId) { return _projectDao.findByProjectAccountId(projectAccountId); } - + @Override public ProjectVO findByProjectAccountIdIncludingRemoved(long projectAccountId) { return _projectDao.findByProjectAccountIdIncludingRemoved(projectAccountId); } - + @Override public Project findByNameAndDomainId(String name, long domainId) { return _projectDao.findByNameAndDomain(name, domainId); } - + @Override public boolean canAccessProjectAccount(Account caller, long accountId) { //ROOT admin always can access the project @@ -424,10 +423,11 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ _accountMgr.checkAccess(caller, _domainDao.findById(owner.getDomainId())); return true; } - + return _projectAccountDao.canAccessProjectAccount(caller.getId(), accountId); } - + + @Override public boolean canModifyProjectAccount(Account caller, long accountId) { //ROOT admin always can access the project if (caller.getType() == Account.ACCOUNT_TYPE_ADMIN) { @@ -439,29 +439,29 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ } return _projectAccountDao.canModifyProjectAccount(caller.getId(), accountId); } - + @Override @DB @ActionEvent(eventType = EventTypes.EVENT_PROJECT_UPDATE, eventDescription = "updating project", async=true) public Project updateProject(long projectId, String displayText, String newOwnerName) throws ResourceAllocationException{ Account caller = UserContext.current().getCaller(); - + //check that the project exists ProjectVO project = getProject(projectId); - + if (project == null) { throw new InvalidParameterValueException("Unable to find the project id=" + projectId); } - + //verify permissions _accountMgr.checkAccess(caller,AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId())); - + Transaction txn = Transaction.currentTxn(); txn.start(); if (displayText != null) { project.setDisplayText(displayText); _projectDao.update(projectId, project); } - + if (newOwnerName != null) { //check that the new owner exists Account futureOwnerAccount = _accountMgr.getActiveAccountByName(newOwnerName, project.getDomainId()); @@ -474,68 +474,68 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ if (futureOwner == null) { throw new InvalidParameterValueException("Account " + newOwnerName + " doesn't belong to the project. Add it to the project first and then change the project's ownership"); } - + //do resource limit check _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(futureOwnerAccount.getId()), ResourceType.project); - + //unset the role for the old owner ProjectAccountVO currentOwner = _projectAccountDao.findByProjectIdAccountId(projectId, currentOwnerAccount.getId()); currentOwner.setAccountRole(Role.Regular); _projectAccountDao.update(currentOwner.getId(), currentOwner); _resourceLimitMgr.decrementResourceCount(currentOwnerAccount.getId(), ResourceType.project); - + //set new owner futureOwner.setAccountRole(Role.Admin); _projectAccountDao.update(futureOwner.getId(), futureOwner); _resourceLimitMgr.incrementResourceCount(futureOwnerAccount.getId(), ResourceType.project); - + } else { s_logger.trace("Future owner " + newOwnerName + "is already the owner of the project id=" + projectId); } } - + txn.commit(); - + return _projectDao.findById(projectId); - + } - + @Override @ActionEvent(eventType = EventTypes.EVENT_PROJECT_ACCOUNT_ADD, eventDescription = "adding account to project", async=true) public boolean addAccountToProject(long projectId, String accountName, String email) { Account caller = UserContext.current().getCaller(); - + //check that the project exists Project project = getProject(projectId); - + if (project == null) { - InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id"); - ex.addProxyObject(project, projectId, "projectId"); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id"); + ex.addProxyObject(project, projectId, "projectId"); throw ex; } - + //User can be added to Active project only if (project.getState() != Project.State.Active) { - InvalidParameterValueException ex = new InvalidParameterValueException("Can't add account to the specified project id in state=" + project.getState() + " as it's no longer active"); - ex.addProxyObject(project, projectId, "projectId"); + InvalidParameterValueException ex = new InvalidParameterValueException("Can't add account to the specified project id in state=" + project.getState() + " as it's no longer active"); + ex.addProxyObject(project, projectId, "projectId"); throw ex; } - + //check that account-to-add exists Account account = null; if (accountName != null) { account = _accountMgr.getActiveAccountByName(accountName, project.getDomainId()); if (account == null) { - InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find account name=" + accountName + " in specified domain id"); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find account name=" + accountName + " in specified domain id"); // We don't have a DomainVO object with us, so just pass the tablename "domain" manually. ex.addProxyObject("domain", project.getDomainId(), "domainId"); throw ex; } - + //verify permissions - only project owner can assign _accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId())); - + //Check if the account already added to the project ProjectAccount projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, account.getId()); if (projectAccount != null) { @@ -543,7 +543,7 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ return true; } } - + if (_invitationRequired) { return inviteAccountToProject(project, account, email); } else { @@ -558,7 +558,7 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ } } } - + private boolean inviteAccountToProject(Project project, Account account, String email) { if (account != null) { if (createAccountInvitation(project, account.getId()) != null) { @@ -568,94 +568,94 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ return false; } } - + if (email != null) { //generate the token String token = generateToken(10); if (generateTokenBasedInvitation(project, email, token) != null) { return true; } else { - s_logger.warn("Failed to generate invitation for email " + email + " to project id=" + project); - return false; + s_logger.warn("Failed to generate invitation for email " + email + " to project id=" + project); + return false; } } - + return false; } - + @Override @ActionEvent(eventType = EventTypes.EVENT_PROJECT_ACCOUNT_REMOVE, eventDescription = "removing account from project", async=true) public boolean deleteAccountFromProject(long projectId, String accountName) { Account caller = UserContext.current().getCaller(); - + //check that the project exists Project project = getProject(projectId); - + if (project == null) { - InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id"); - ex.addProxyObject(project, projectId, "projectId"); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id"); + ex.addProxyObject(project, projectId, "projectId"); throw ex; } - + //check that account-to-remove exists Account account = _accountMgr.getActiveAccountByName(accountName, project.getDomainId()); if (account == null) { - InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find account name=" + accountName + " in domain id=" + project.getDomainId()); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find account name=" + accountName + " in domain id=" + project.getDomainId()); // Since we don't have a domainVO object, pass the table name manually. ex.addProxyObject("domain", project.getDomainId(), "domainId"); } - + //verify permissions _accountMgr.checkAccess(caller,AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId())); - + //Check if the account exists in the project ProjectAccount projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, account.getId()); if (projectAccount == null) { - InvalidParameterValueException ex = new InvalidParameterValueException("Account " + accountName + " is not assigned to the project with specified id"); - // Use the projectVO object and not the projectAccount object to inject the projectId. - ex.addProxyObject(project, projectId, "projectId"); + InvalidParameterValueException ex = new InvalidParameterValueException("Account " + accountName + " is not assigned to the project with specified id"); + // Use the projectVO object and not the projectAccount object to inject the projectId. + ex.addProxyObject(project, projectId, "projectId"); throw ex; } - + //can't remove the owner of the project if (projectAccount.getAccountRole() == Role.Admin) { - InvalidParameterValueException ex = new InvalidParameterValueException("Unable to delete account " + accountName + " from the project with specified id as the account is the owner of the project"); - ex.addProxyObject(project, projectId, "projectId"); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to delete account " + accountName + " from the project with specified id as the account is the owner of the project"); + ex.addProxyObject(project, projectId, "projectId"); throw ex; } - + return deleteAccountFromProject(projectId, account.getId()); } - - - - + + + + public ProjectInvitation createAccountInvitation(Project project, Long accountId) { if (activeInviteExists(project, accountId, null)) { throw new InvalidParameterValueException("There is already a pending invitation for account id=" + accountId + " to the project id=" + project); } - + ProjectInvitation invitation= _projectInvitationDao.persist(new ProjectInvitationVO(project.getId(), accountId, project.getDomainId(), null, null)); - + return invitation; } @DB - public boolean activeInviteExists(Project project, Long accountId, String email) { - Transaction txn = Transaction.currentTxn(); - txn.start(); - //verify if the invitation was already generated - ProjectInvitationVO invite = null; - if (accountId != null) { - invite = _projectInvitationDao.findByAccountIdProjectId(accountId, project.getId()); - } else if (email != null) { - invite = _projectInvitationDao.findByEmailAndProjectId(email, project.getId()); - } - + public boolean activeInviteExists(Project project, Long accountId, String email) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + //verify if the invitation was already generated + ProjectInvitationVO invite = null; + if (accountId != null) { + invite = _projectInvitationDao.findByAccountIdProjectId(accountId, project.getId()); + } else if (email != null) { + invite = _projectInvitationDao.findByEmailAndProjectId(email, project.getId()); + } + if (invite != null) { if (invite.getState() == ProjectInvitation.State.Completed || (invite.getState() == ProjectInvitation.State.Pending && _projectInvitationDao.isActive(invite.getId(), _invitationTimeOut))) { - return true; + return true; } else { if (invite.getState() == ProjectInvitation.State.Pending) { expireInvitation(invite); @@ -664,7 +664,7 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ if (accountId != null) { s_logger.debug("Removing invitation in state " + invite.getState() + " for account id=" + accountId + " to project " + project); } else if (email != null) { - s_logger.debug("Removing invitation in state " + invite.getState() + " for email " + email + " to project " + project); + s_logger.debug("Removing invitation in state " + invite.getState() + " for email " + email + " to project " + project); } _projectInvitationDao.expunge(invite.getId()); @@ -672,14 +672,14 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ } txn.commit(); return false; - } - + } + public ProjectInvitation generateTokenBasedInvitation(Project project, String email, String token) { //verify if the invitation was already generated - if (activeInviteExists(project, null, email)) { - throw new InvalidParameterValueException("There is already a pending invitation for email " + email + " to the project id=" + project); - } - + if (activeInviteExists(project, null, email)) { + throw new InvalidParameterValueException("There is already a pending invitation for email " + email + " to the project id=" + project); + } + ProjectInvitation projectInvitation = _projectInvitationDao.persist(new ProjectInvitationVO(project.getId(), null, project.getDomainId(), email, token)); try { _emailInvite.sendInvite(token, email, project.getId()); @@ -688,52 +688,52 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ _projectInvitationDao.remove(projectInvitation.getId()); return null; } - + return projectInvitation; } - + private boolean expireInvitation(ProjectInvitationVO invite) { s_logger.debug("Expiring invitation id=" + invite.getId()); invite.setState(ProjectInvitation.State.Expired); return _projectInvitationDao.update(invite.getId(), invite); } - - + + @Override @DB @ActionEvent(eventType = EventTypes.EVENT_PROJECT_INVITATION_UPDATE, eventDescription = "updating project invitation", async=true) public boolean updateInvitation(long projectId, String accountName, String token, boolean accept) { Account caller = UserContext.current().getCaller(); Long accountId = null; boolean result = true; - + //if accountname and token are null, default accountname to caller's account name if (accountName == null && token == null) { accountName = caller.getAccountName(); } - + //check that the project exists Project project = getProject(projectId); - + if (project == null) { throw new InvalidParameterValueException("Unable to find the project id=" + projectId); } - + if (accountName != null) { //check that account-to-remove exists Account account = _accountMgr.getActiveAccountByName(accountName, project.getDomainId()); if (account == null) { throw new InvalidParameterValueException("Unable to find account name=" + accountName + " in domain id=" + project.getDomainId()); } - + //verify permissions _accountMgr.checkAccess(caller, null, true, account); - + accountId = account.getId(); } else { accountId = caller.getId(); } - + //check that invitation exists ProjectInvitationVO invite = null; if (token == null) { @@ -741,7 +741,7 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ } else { invite = _projectInvitationDao.findPendingByTokenAndProjectId(token, projectId, ProjectInvitation.State.Pending); } - + if (invite != null) { if (!_projectInvitationDao.isActive(invite.getId(), _invitationTimeOut) && accept) { expireInvitation(invite); @@ -749,116 +749,116 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ } else { Transaction txn = Transaction.currentTxn(); txn.start(); - + ProjectInvitation.State newState = accept ? ProjectInvitation.State.Completed : ProjectInvitation.State.Declined; - - //update invitation - s_logger.debug("Marking invitation " + invite + " with state " + newState); - invite.setState(newState); - result = _projectInvitationDao.update(invite.getId(), invite); - - if (result && accept) { - //check if account already exists for the project (was added before invitation got accepted) - ProjectAccount projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, accountId); - if (projectAccount != null) { - s_logger.debug("Account " + accountName + " already added to the project id=" + projectId); - } else { - assignAccountToProject(project, accountId, ProjectAccount.Role.Regular); - } - } else { - s_logger.warn("Failed to update project invitation " + invite + " with state " + newState); - } - - txn.commit(); + + //update invitation + s_logger.debug("Marking invitation " + invite + " with state " + newState); + invite.setState(newState); + result = _projectInvitationDao.update(invite.getId(), invite); + + if (result && accept) { + //check if account already exists for the project (was added before invitation got accepted) + ProjectAccount projectAccount = _projectAccountDao.findByProjectIdAccountId(projectId, accountId); + if (projectAccount != null) { + s_logger.debug("Account " + accountName + " already added to the project id=" + projectId); + } else { + assignAccountToProject(project, accountId, ProjectAccount.Role.Regular); + } + } else { + s_logger.warn("Failed to update project invitation " + invite + " with state " + newState); + } + + txn.commit(); } } else { throw new InvalidParameterValueException("Unable to find invitation for account name=" + accountName + " to the project id=" + projectId); } - + return result; } - + @Override public List<Long> listPermittedProjectAccounts(long accountId) { return _projectAccountDao.listPermittedAccountIds(accountId); } - + @Override @ActionEvent(eventType = EventTypes.EVENT_PROJECT_ACTIVATE, eventDescription = "activating project") @DB public Project activateProject(long projectId) { Account caller = UserContext.current().getCaller(); - + //check that the project exists ProjectVO project = getProject(projectId); - + if (project == null) { - InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id"); - ex.addProxyObject(project, projectId, "projectId"); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id"); + ex.addProxyObject(project, projectId, "projectId"); throw ex; } - + //verify permissions _accountMgr.checkAccess(caller,AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId())); - + //allow project activation only when it's in Suspended state Project.State currentState = project.getState(); - + if (currentState == State.Active) { s_logger.debug("The project id=" + projectId + " is already active, no need to activate it again"); return project; } - + if (currentState != State.Suspended) { throw new InvalidParameterValueException("Can't activate the project in " + currentState + " state"); } - + Transaction txn = Transaction.currentTxn(); txn.start(); - + project.setState(Project.State.Active); _projectDao.update(projectId, project); - + _accountMgr.enableAccount(project.getProjectAccountId()); - + txn.commit(); - + return _projectDao.findById(projectId); } - - + + @Override @ActionEvent(eventType = EventTypes.EVENT_PROJECT_SUSPEND, eventDescription = "suspending project", async = true) public Project suspendProject (long projectId) throws ConcurrentOperationException, ResourceUnavailableException { Account caller = UserContext.current().getCaller(); - + ProjectVO project= getProject(projectId); //verify input parameters if (project == null) { - InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id"); - ex.addProxyObject(project, projectId, "projectId"); + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find project with specified id"); + ex.addProxyObject(project, projectId, "projectId"); throw ex; } - + _accountMgr.checkAccess(caller,AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId())); - + if (suspendProject(project)) { s_logger.debug("Successfully suspended project id=" + projectId); return _projectDao.findById(projectId); } else { - CloudRuntimeException ex = new CloudRuntimeException("Failed to suspend project with specified id"); - ex.addProxyObject(project, projectId, "projectId"); + CloudRuntimeException ex = new CloudRuntimeException("Failed to suspend project with specified id"); + ex.addProxyObject(project, projectId, "projectId"); throw ex; } - + } - + private boolean suspendProject(ProjectVO project) throws ConcurrentOperationException, ResourceUnavailableException { - + s_logger.debug("Marking project " + project + " with state " + State.Suspended + " as a part of project suspend..."); project.setState(State.Suspended); boolean updateResult = _projectDao.update(project.getId(), project); - + if (updateResult) { long projectAccountId = project.getProjectAccountId(); if (!_accountMgr.disableAccount(projectAccountId)) { @@ -869,8 +869,8 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ } return true; } - - + + public static String generateToken(int length) { String charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; Random rand = new Random(System.currentTimeMillis()); @@ -881,7 +881,7 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ } return sb.toString(); } - + class EmailInvite { private Session _smtpSession; private final String _smtpHost; @@ -941,9 +941,9 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ s_logger.error("Exception creating address for: " + email, ex); } } - + String content = "You've been invited to join the CloudStack project id=" + projectId + ". Please use token " + token + " to complete registration"; - + SMTPMessage msg = new SMTPMessage(_smtpSession); msg.setSender(new InternetAddress(_emailSender, _emailSender)); msg.setFrom(new InternetAddress(_emailSender, _emailSender)); @@ -967,24 +967,24 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ } } } - - + + @Override @DB @ActionEvent(eventType = EventTypes.EVENT_PROJECT_INVITATION_REMOVE, eventDescription = "removing project invitation", async=true) public boolean deleteProjectInvitation(long id) { Account caller = UserContext.current().getCaller(); - + ProjectInvitation invitation = _projectInvitationDao.findById(id); if (invitation == null) { throw new InvalidParameterValueException("Unable to find project invitation by id " + id); } - + //check that the project exists Project project = getProject(invitation.getProjectId()); - + //check permissions - only project owner can remove the invitations _accountMgr.checkAccess(caller, AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId())); - + if (_projectInvitationDao.remove(id)) { s_logger.debug("Project Invitation id=" + id + " is removed"); return true; @@ -993,35 +993,35 @@ public class ProjectManagerImpl implements ProjectManager, Manager{ return false; } } - + public class ExpiredInvitationsCleanup implements Runnable { - @Override - public void run() { - try { - TimeZone.getDefault(); - List<ProjectInvitationVO> invitationsToExpire = _projectInvitationDao.listInvitationsToExpire(_invitationTimeOut); - if (!invitationsToExpire.isEmpty()) { - s_logger.debug("Found " + invitationsToExpire.size() + " projects to expire"); - for (ProjectInvitationVO invitationToExpire : invitationsToExpire) { - invitationToExpire.setState(ProjectInvitation.State.Expired); - _projectInvitationDao.update(invitationToExpire.getId(), invitationToExpire); - s_logger.trace("Expired project invitation id=" + invitationToExpire.getId()); - } - } - } catch (Exception ex) { - s_logger.warn("Exception while running expired invitations cleanup", ex); - } - } + @Override + public void run() { + try { + TimeZone.getDefault(); + List<ProjectInvitationVO> invitationsToExpire = _projectInvitationDao.listInvitationsToExpire(_invitationTimeOut); + if (!invitationsToExpire.isEmpty()) { + s_logger.debug("Found " + invitationsToExpire.size() + " projects to expire"); + for (ProjectInvitationVO invitationToExpire : invitationsToExpire) { + invitationToExpire.setState(ProjectInvitation.State.Expired); + _projectInvitationDao.update(invitationToExpire.getId(), invitationToExpire); + s_logger.trace("Expired project invitation id=" + invitationToExpire.getId()); + } + } + } catch (Exception ex) { + s_logger.warn("Exception while running expired invitations cleanup", ex); + } + } } @Override - public boolean projectInviteRequired() { - return _invitationRequired; - } + public boolean projectInviteRequired() { + return _invitationRequired; + } @Override public boolean allowUserToCreateProject() { - return _allowUserToCreateProject; + return _allowUserToCreateProject; } - + }
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/14bd345f/server/src/com/cloud/server/ConfigurationServerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java index 28f28cb..4999ffe 100755 --- a/server/src/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/com/cloud/server/ConfigurationServerImpl.java @@ -16,6 +16,35 @@ // under the License. package com.cloud.server; +import java.io.DataInputStream; +import java.io.EOFException; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.security.NoSuchAlgorithmException; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.UUID; +import java.util.regex.Pattern; + +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import javax.inject.Inject; + +import org.apache.commons.codec.binary.Base64; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationVO; import com.cloud.configuration.Resource; @@ -45,7 +74,11 @@ import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.Mode; import com.cloud.network.Networks.TrafficType; import com.cloud.network.dao.NetworkDao; -import com.cloud.network.guru.*; +import com.cloud.network.guru.ControlNetworkGuru; +import com.cloud.network.guru.DirectPodBasedNetworkGuru; +import com.cloud.network.guru.PodBasedNetworkGuru; +import com.cloud.network.guru.PublicNetworkGuru; +import com.cloud.network.guru.StorageNetworkGuru; import com.cloud.offering.NetworkOffering; import com.cloud.offering.NetworkOffering.Availability; import com.cloud.offerings.NetworkOfferingServiceMapVO; @@ -63,7 +96,6 @@ import com.cloud.user.User; import com.cloud.user.dao.AccountDao; import com.cloud.utils.PasswordGenerator; import com.cloud.utils.PropertiesUtil; -import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.crypt.DBEncryptionUtil; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; @@ -71,20 +103,6 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.cloud.utils.script.Script; import com.cloud.uuididentity.dao.IdentityDao; -import org.apache.commons.codec.binary.Base64; -import org.apache.log4j.Logger; - -import javax.crypto.KeyGenerator; -import javax.crypto.SecretKey; -import java.io.*; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.security.NoSuchAlgorithmException; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; -import java.util.regex.Pattern; @Component public class ConfigurationServerImpl implements ConfigurationServer { @@ -230,7 +248,7 @@ public class ConfigurationServerImpl implements ConfigurationServer { // store the public and private keys in the database updateKeyPairs(); - + // generate a random password for system vm updateSystemvmPassword(); @@ -504,29 +522,29 @@ public class ConfigurationServerImpl implements ConfigurationServer { if (!userid.startsWith("cloud")) { return; } - + if (!Boolean.valueOf(_configDao.getValue("system.vm.random.password"))) { - return; + return; + } + + String already = _configDao.getValue("system.vm.password"); + if (already == null) { + Transaction txn = Transaction.currentTxn(); + try { + String rpassword = PasswordGenerator.generatePresharedKey(8); + String wSql = "INSERT INTO `cloud`.`configuration` (category, instance, component, name, value, description) " + + "VALUES ('Hidden','DEFAULT', 'management-server','system.vm.password', '" + rpassword + + "','randmon password generated each management server starts for system vm')"; + PreparedStatement stmt = txn.prepareAutoCloseStatement(wSql); + stmt.executeUpdate(wSql); + s_logger.info("Updated systemvm password in database"); + } catch (SQLException e) { + s_logger.error("Cannot retrieve systemvm password", e); + } } - String already = _configDao.getValue("system.vm.password"); - if (already == null) { - Transaction txn = Transaction.currentTxn(); - try { - String rpassword = PasswordGenerator.generatePresharedKey(8); - String wSql = "INSERT INTO `cloud`.`configuration` (category, instance, component, name, value, description) " - + "VALUES ('Hidden','DEFAULT', 'management-server','system.vm.password', '" + rpassword - + "','randmon password generated each management server starts for system vm')"; - PreparedStatement stmt = txn.prepareAutoCloseStatement(wSql); - stmt.executeUpdate(wSql); - s_logger.info("Updated systemvm password in database"); - } catch (SQLException e) { - s_logger.error("Cannot retrieve systemvm password", e); - } - } - - } - + } + @Override @DB public void updateKeyPairs() { @@ -541,10 +559,10 @@ public class ConfigurationServerImpl implements ConfigurationServer { String already = _configDao.getValue("ssh.privatekey"); String homeDir = null; homeDir = Script.runSimpleBashScript("echo ~" + username); - if (homeDir == null) { + if (homeDir == null) { throw new CloudRuntimeException("Cannot get home directory for account: " + username); } - + if (s_logger.isInfoEnabled()) { s_logger.info("Processing updateKeyPairs"); } @@ -622,11 +640,11 @@ public class ConfigurationServerImpl implements ConfigurationServer { } s_logger.info("Going to update systemvm iso with generated keypairs if needed"); try { - injectSshKeysIntoSystemVmIsoPatch(pubkeyfile.getAbsolutePath(), privkeyfile.getAbsolutePath()); + injectSshKeysIntoSystemVmIsoPatch(pubkeyfile.getAbsolutePath(), privkeyfile.getAbsolutePath()); } catch (CloudRuntimeException e) { - if (!devel) { - throw new CloudRuntimeException(e.getMessage()); - } + if (!devel) { + throw new CloudRuntimeException(e.getMessage()); + } } } @@ -892,7 +910,7 @@ public class ConfigurationServerImpl implements ConfigurationServer { defaultSharedSGNetworkOffering.setState(NetworkOffering.State.Enabled); defaultSharedSGNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultSharedSGNetworkOffering); - + for (Service service : defaultSharedSGNetworkOfferingProviders.keySet()) { NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO(defaultSharedSGNetworkOffering.getId(), service, defaultSharedSGNetworkOfferingProviders.get(service)); _ntwkOfferingServiceMapDao.persist(offService); @@ -967,7 +985,7 @@ public class ConfigurationServerImpl implements ConfigurationServer { _ntwkOfferingServiceMapDao.persist(offService); s_logger.trace("Added service for the network offering: " + offService); } - + // Offering #6 NetworkOfferingVO defaultNetworkOfferingForVpcNetworks = new NetworkOfferingVO( NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks, @@ -978,7 +996,7 @@ public class ConfigurationServerImpl implements ConfigurationServer { defaultNetworkOfferingForVpcNetworks.setState(NetworkOffering.State.Enabled); defaultNetworkOfferingForVpcNetworks = _networkOfferingDao.persistDefaultNetworkOffering(defaultNetworkOfferingForVpcNetworks); - + Map<Network.Service, Network.Provider> defaultVpcNetworkOfferingProviders = new HashMap<Network.Service, Network.Provider>(); defaultVpcNetworkOfferingProviders.put(Service.Dhcp, Provider.VPCVirtualRouter); defaultVpcNetworkOfferingProviders.put(Service.Dns, Provider.VPCVirtualRouter); @@ -990,14 +1008,14 @@ public class ConfigurationServerImpl implements ConfigurationServer { defaultVpcNetworkOfferingProviders.put(Service.StaticNat, Provider.VPCVirtualRouter); defaultVpcNetworkOfferingProviders.put(Service.PortForwarding, Provider.VPCVirtualRouter); defaultVpcNetworkOfferingProviders.put(Service.Vpn, Provider.VPCVirtualRouter); - + for (Service service : defaultVpcNetworkOfferingProviders.keySet()) { NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO (defaultNetworkOfferingForVpcNetworks.getId(), service, defaultVpcNetworkOfferingProviders.get(service)); _ntwkOfferingServiceMapDao.persist(offService); s_logger.trace("Added service for the network offering: " + offService); } - + // Offering #7 NetworkOfferingVO defaultNetworkOfferingForVpcNetworksNoLB = new NetworkOfferingVO( NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksNoLB, @@ -1008,7 +1026,7 @@ public class ConfigurationServerImpl implements ConfigurationServer { defaultNetworkOfferingForVpcNetworksNoLB.setState(NetworkOffering.State.Enabled); defaultNetworkOfferingForVpcNetworksNoLB = _networkOfferingDao.persistDefaultNetworkOffering(defaultNetworkOfferingForVpcNetworksNoLB); - + Map<Network.Service, Network.Provider> defaultVpcNetworkOfferingProvidersNoLB = new HashMap<Network.Service, Network.Provider>(); defaultVpcNetworkOfferingProvidersNoLB.put(Service.Dhcp, Provider.VPCVirtualRouter); defaultVpcNetworkOfferingProvidersNoLB.put(Service.Dns, Provider.VPCVirtualRouter); @@ -1019,16 +1037,16 @@ public class ConfigurationServerImpl implements ConfigurationServer { defaultVpcNetworkOfferingProvidersNoLB.put(Service.StaticNat, Provider.VPCVirtualRouter); defaultVpcNetworkOfferingProvidersNoLB.put(Service.PortForwarding, Provider.VPCVirtualRouter); defaultVpcNetworkOfferingProvidersNoLB.put(Service.Vpn, Provider.VPCVirtualRouter); - + for (Service service : defaultVpcNetworkOfferingProvidersNoLB.keySet()) { NetworkOfferingServiceMapVO offService = new NetworkOfferingServiceMapVO (defaultNetworkOfferingForVpcNetworksNoLB.getId(), service, defaultVpcNetworkOfferingProvidersNoLB.get(service)); _ntwkOfferingServiceMapDao.persist(offService); s_logger.trace("Added service for the network offering: " + offService); } - - - + + + txn.commit(); }
