diff --git a/api/src/com/cloud/user/AccountService.java b/api/src/com/cloud/user/AccountService.java index a4103978da4..11062d31cbc 100644 --- a/api/src/com/cloud/user/AccountService.java +++ b/api/src/com/cloud/user/AccountService.java @@ -128,5 +128,9 @@ public interface AccountService { * @throws PermissionDeniedException */ List searchForLimits(ListResourceLimitsCmd cmd) throws InvalidParameterValueException, PermissionDeniedException; + + Account getSystemAccount(); + + User getSystemUser(); } diff --git a/api/src/com/cloud/user/UserContext.java b/api/src/com/cloud/user/UserContext.java index 40e6924aed7..7eb2a403c54 100644 --- a/api/src/com/cloud/user/UserContext.java +++ b/api/src/com/cloud/user/UserContext.java @@ -17,97 +17,43 @@ */ package com.cloud.user; - -import org.apache.log4j.Logger; -import com.cloud.utils.ProcessUtil; +import com.cloud.server.ManagementService; +import com.cloud.utils.component.ComponentLocator; + public class UserContext { - private static final Logger s_logger = Logger.getLogger(UserContext.class); + + private static ThreadLocal s_currentContext = new ThreadLocal(); + private static final ComponentLocator locator = ComponentLocator.getLocator(ManagementService.Name); + private static final AccountService _accountMgr = locator.getManager(AccountService.class); - private static ThreadLocal s_currentContext = new ThreadLocal(); - - private Long userId; - private String accountName; - private Long accountId; - private Long domainId; + private long userId; private String sessionId; - private Account accountObject; - private Long eventId; + private Account accountObject; private boolean apiServer; - private static UserContext s_nullContext = new UserContext(); + private static UserContext s_adminContext = new UserContext(_accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount(), null, false); public UserContext() { } - public UserContext(Long userId, Account accountObject, String accountName, Long accountId, Long domainId, String sessionId, boolean apiServer) { + public UserContext(long userId, Account accountObject, String sessionId, boolean apiServer) { this.userId = userId; this.accountObject = accountObject; - this.accountId = accountId; - this.domainId = domainId; this.sessionId = sessionId; - this.apiServer = apiServer; - this.eventId = null; + this.apiServer = apiServer; } - public Long getUserId() { - if (userId != null) { - return userId; - } - - if (!apiServer) { - s_logger.warn("Null user id in UserContext " + ProcessUtil.dumpStack()); - } - - return null; + public long getUserId() { + return userId; } - public void setEventId(long eventId) { - this.eventId = eventId; - } - - public Long getEventId() { - return eventId; - } - - public void setUserId(Long userId) { + public void setUserId(long userId) { this.userId = userId; } - public String getAccountName() { - return accountName; - } - - public void setAccountName(String accountName) { - this.accountName = accountName; - } - - public Long getAccountId() { - if (accountId != null) { - return accountId; - } - - if (!apiServer) { - s_logger.warn("Null account id in UserContext " + ProcessUtil.dumpStack()); - } - - return null; - } - - public void setAccountId(Long accountId) { - this.accountId = accountId; - } - - public Long getDomainId() { - return domainId; - } - - public void setDomainId(Long domainId) { - this.domainId = domainId; - } - public String getSessionId() { return sessionId; } @@ -135,25 +81,22 @@ public class UserContext { public static UserContext current() { UserContext context = s_currentContext.get(); if (context == null) { - return s_nullContext; + return s_adminContext; } return context; } - public static void updateContext(Long userId, Account accountObject, String accountName, Long accountId, Long domainId, String sessionId) { + public static void updateContext(long userId, Account accountObject, String sessionId) { UserContext context = current(); assert(context != null) : "Context should be already setup before you can call this one"; context.setUserId(userId); context.setAccount(accountObject); - context.setAccountName(accountName); - context.setAccountId(accountId); - context.setDomainId(domainId); context.setSessionKey(sessionId); } - public static void registerContext(Long userId, Account accountObject, String accountName, Long accountId, Long domainId, String sessionId, boolean apiServer) { - s_currentContext.set(new UserContext(userId, accountObject, accountName, accountId, domainId, sessionId, apiServer)); + public static void registerContext(long userId, Account accountObject, String sessionId, boolean apiServer) { + s_currentContext.set(new UserContext(userId, accountObject, sessionId, apiServer)); } public static void unregisterContext() { diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java index 40daf61c2c6..7613b6db72a 100755 --- a/server/src/com/cloud/api/ApiServer.java +++ b/server/src/com/cloud/api/ApiServer.java @@ -91,7 +91,7 @@ import com.cloud.exception.CloudAuthenticationException; import com.cloud.maid.StackMaid; import com.cloud.server.ManagementServer; import com.cloud.user.Account; -import com.cloud.user.AccountManager; +import com.cloud.user.AccountService; import com.cloud.user.User; import com.cloud.user.UserAccount; import com.cloud.user.UserContext; @@ -114,7 +114,7 @@ public class ApiServer implements HttpRequestHandler { private Properties _apiCommands = null; private ApiDispatcher _dispatcher; private ManagementServer _ms = null; - private AccountManager _accountMgr = null; + private AccountService _accountMgr = null; private AsyncJobManager _asyncMgr = null; private Account _systemAccount = null; private User _systemUser = null; @@ -200,7 +200,7 @@ public class ApiServer implements HttpRequestHandler { _ms = (ManagementServer)ComponentLocator.getComponent(ManagementServer.Name); ComponentLocator locator = ComponentLocator.getLocator(ManagementServer.Name); - _accountMgr = locator.getManager(AccountManager.class); + _accountMgr = locator.getManager(AccountService.class); _asyncMgr = locator.getManager(AsyncJobManager.class); _systemAccount = _accountMgr.getSystemAccount(); _systemUser = _accountMgr.getSystemUser(); @@ -263,7 +263,7 @@ public class ApiServer implements HttpRequestHandler { } try { // always trust commands from API port, user context will always be UID_SYSTEM/ACCOUNT_ID_SYSTEM - UserContext.registerContext(_systemUser.getId(), _systemAccount, _systemAccount.getAccountName(), _systemAccount.getId(), null, null, true); + UserContext.registerContext(_systemUser.getId(), _systemAccount, null, true); sb.insert(0,"(userId="+User.UID_SYSTEM+ " accountId="+Account.ACCOUNT_ID_SYSTEM+ " sessionId="+null+ ") " ); String responseText = handleRequest(parameterMap, true, responseType, sb); sb.append(" 200 " + ((responseText == null) ? 0 : responseText.length())); @@ -397,7 +397,7 @@ public class ApiServer implements HttpRequestHandler { AsyncJobVO job = new AsyncJobVO(); job.setUserId(userId); if (account != null) { - job.setAccountId(ctx.getAccountId()); + job.setAccountId(ctx.getAccount().getId()); } else { // Just have SYSTEM own the job for now. Users won't be able to see this job, // but in an admin case (like domain admin) they won't be able to see it anyway @@ -547,7 +547,7 @@ public class ApiServer implements HttpRequestHandler { return false; } - UserContext.updateContext(user.getId(), account, account.getAccountName(), account.getId(), account.getDomainId(), null); + UserContext.updateContext(user.getId(), account, null); if (!isCommandAvailable(account.getType(), commandName)) { return false; diff --git a/server/src/com/cloud/api/ApiServlet.java b/server/src/com/cloud/api/ApiServlet.java index 38d2823e96c..1e6e87eba11 100755 --- a/server/src/com/cloud/api/ApiServlet.java +++ b/server/src/com/cloud/api/ApiServlet.java @@ -33,10 +33,12 @@ import javax.servlet.http.HttpSession; import org.apache.log4j.Logger; import com.cloud.exception.CloudAuthenticationException; -import com.cloud.exception.InvalidParameterValueException; import com.cloud.maid.StackMaid; +import com.cloud.server.ManagementServer; import com.cloud.user.Account; +import com.cloud.user.AccountService; import com.cloud.user.UserContext; +import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.exception.CloudRuntimeException; @SuppressWarnings("serial") @@ -45,13 +47,16 @@ public class ApiServlet extends HttpServlet { private static final Logger s_accessLogger = Logger.getLogger("apiserver." + ApiServer.class.getName()); private ApiServer _apiServer = null; + private AccountService _accountMgr = null; public ApiServlet() { super(); _apiServer = ApiServer.getInstance(); if (_apiServer == null) { throw new CloudRuntimeException("ApiServer not initialized"); - } + } + ComponentLocator locator = ComponentLocator.getLocator(ManagementServer.Name); + _accountMgr = locator.getManager(AccountService.class); } @Override @@ -188,7 +193,7 @@ public class ApiServlet extends HttpServlet { // Initialize an empty context and we will update it after we have verified the request below, // we no longer rely on web-session here, verifyRequest will populate user/account information // if a API key exists - UserContext.registerContext(null, null, null, null, null, null, false); + UserContext.registerContext(_accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount(), null, false); Long userId = null; if (!isNew) { @@ -216,7 +221,7 @@ public class ApiServlet extends HttpServlet { resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "no command specified"); return; } - UserContext.updateContext(userId, (Account)accountObj, account, ((Account)accountObj).getId(), domainId, session.getId()); + UserContext.updateContext(userId, (Account)accountObj, session.getId()); } else { // Invalidate the session to ensure we won't allow a request across management server restarts if the userId was serialized to the // stored session @@ -249,7 +254,7 @@ public class ApiServlet extends HttpServlet { updateUserContext(params, session != null ? session.getId() : null); */ - auditTrailSb.insert(0, "(userId="+UserContext.current().getUserId()+ " accountId="+UserContext.current().getAccountId()+ " sessionId="+(session != null ? session.getId() : null)+ ")" ); + auditTrailSb.insert(0, "(userId="+UserContext.current().getUserId()+ " accountId="+UserContext.current().getAccount().getId()+ " sessionId="+(session != null ? session.getId() : null)+ ")" ); try { String response = _apiServer.handleRequest(params, true, responseType, auditTrailSb); diff --git a/server/src/com/cloud/async/AsyncJobManagerImpl.java b/server/src/com/cloud/async/AsyncJobManagerImpl.java index a22ad00581d..5e87f6a3404 100644 --- a/server/src/com/cloud/async/AsyncJobManagerImpl.java +++ b/server/src/com/cloud/async/AsyncJobManagerImpl.java @@ -369,7 +369,7 @@ public class AsyncJobManagerImpl implements AsyncJobManager { accountObject = _accountDao.findById(Long.parseLong(acctIdStr)); } - UserContext.registerContext(userId, accountObject, null, null, null, null, false); + UserContext.registerContext(userId, accountObject, null, false); // dispatch could ultimately queue the job _dispatcher.dispatch(cmdObj, params); diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index 18ad91c52a4..bca8d2095a8 100644 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -133,7 +133,7 @@ import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.user.Account; -import com.cloud.user.AccountManager; +import com.cloud.user.AccountService; import com.cloud.user.AccountVO; import com.cloud.user.User; import com.cloud.user.UserVO; @@ -243,7 +243,7 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx @Inject private StorageManager _storageMgr; @Inject private HighAvailabilityManager _haMgr; @Inject NetworkManager _networkMgr; - @Inject AccountManager _accountMgr; + @Inject AccountService _accountMgr; @Inject private EventDao _eventDao; @Inject GuestOSDao _guestOSDao = null; @Inject ServiceOfferingDao _offeringDao; @@ -554,8 +554,8 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx return start(proxyVmId, startEventId); } ConsoleProxyVO proxy = _consoleProxyDao.findById(proxyVmId); - AccountVO systemAcct = _accountMgr.getSystemAccount(); - UserVO systemUser = _accountMgr.getSystemUser(); + Account systemAcct = _accountMgr.getSystemAccount(); + User systemUser = _accountMgr.getSystemUser(); return _itMgr.start(proxy, null, systemUser, systemAcct); } @@ -1023,7 +1023,7 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx String vlanGateway = publicIpAndVlan._gateWay; String vlanNetmask = publicIpAndVlan._netMask; - AccountVO systemAccount = _accountMgr.getSystemAccount(); + Account systemAccount = _accountMgr.getSystemAccount(); txn.start(); ConsoleProxyVO proxy; @@ -1061,7 +1061,7 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx long id = _consoleProxyDao.getNextInSequence(Long.class, "id"); String name = VirtualMachineName.getConsoleProxyName(id, _instance); DataCenterVO dc = _dcDao.findById(dataCenterId); - AccountVO systemAcct = _accountMgr.getSystemAccount(); + Account systemAcct = _accountMgr.getSystemAccount(); DataCenterDeployment plan = new DataCenterDeployment(dataCenterId); diff --git a/server/src/com/cloud/network/router/DomainRouterManagerImpl.java b/server/src/com/cloud/network/router/DomainRouterManagerImpl.java index 1fe5c3c4143..aa6a90c51f1 100644 --- a/server/src/com/cloud/network/router/DomainRouterManagerImpl.java +++ b/server/src/com/cloud/network/router/DomainRouterManagerImpl.java @@ -140,6 +140,7 @@ import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; +import com.cloud.user.AccountService; import com.cloud.user.AccountVO; import com.cloud.user.User; import com.cloud.user.UserContext; @@ -209,6 +210,7 @@ public class DomainRouterManagerImpl implements DomainRouterManager, DomainRoute @Inject HighAvailabilityManager _haMgr; @Inject AlertManager _alertMgr; @Inject AccountManager _accountMgr; + @Inject AccountService _accountService; @Inject ConfigurationManager _configMgr; @Inject AsyncJobManager _asyncMgr; @Inject StoragePoolDao _storagePoolDao = null; @@ -247,7 +249,7 @@ public class DomainRouterManagerImpl implements DomainRouterManager, DomainRoute ScheduledExecutorService _executor; - AccountVO _systemAcct; + Account _systemAcct; boolean _useNewNetworking; @Override @@ -1512,7 +1514,7 @@ public class DomainRouterManagerImpl implements DomainRouterManager, DomainRoute _useNewNetworking = Boolean.parseBoolean(configs.get("use.new.networking")); - _systemAcct = _accountMgr.getSystemAccount(); + _systemAcct = _accountService.getSystemAccount(); s_logger.info("DomainRouterManager is configured."); @@ -2090,7 +2092,7 @@ public class DomainRouterManagerImpl implements DomainRouterManager, DomainRoute router = _itMgr.allocate(router, _template, _offering, networks, plan, owner); } - return _itMgr.start(router, null, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount()); + return _itMgr.start(router, null, _accountService.getSystemUser(), _accountService.getSystemAccount()); } @Override @@ -2376,7 +2378,7 @@ public class DomainRouterManagerImpl implements DomainRouterManager, DomainRoute public VirtualRouter stopRouter(long routerId) throws ResourceUnavailableException, ConcurrentOperationException { UserContext context = UserContext.current(); Account account = context.getAccount(); - long accountId = context.getAccountId(); + long accountId = account.getId(); long userId = context.getUserId(); diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index b80238daff4..4ced7f1f5f5 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -3595,7 +3595,7 @@ public class ManagementServerImpl implements ManagementServer { public DomainVO createDomain(CreateDomainCmd cmd) throws InvalidParameterValueException, PermissionDeniedException { String name = cmd.getDomainName(); Long parentId = cmd.getParentDomainId(); - Long ownerId = UserContext.current().getAccountId(); + Long ownerId = UserContext.current().getAccount().getId(); Account account = UserContext.current().getAccount(); if (ownerId == null) { @@ -4277,10 +4277,10 @@ public class ManagementServerImpl implements ManagementServer { } // treat any requests from API server as trusted requests - if (!UserContext.current().isApiServer() && job.getAccountId() != UserContext.current().getAccountId()) { + if (!UserContext.current().isApiServer() && job.getAccountId() != UserContext.current().getAccount().getId()) { if (s_logger.isDebugEnabled()) s_logger.debug("Mismatched account id in job and user context, perform further securty check. job id: " - + jobId + ", job owner account: " + job.getAccountId() + ", accound id in current context: " + UserContext.current().getAccountId()); + + jobId + ", job owner account: " + job.getAccountId() + ", accound id in current context: " + UserContext.current().getAccount().getId()); Account account = UserContext.current().getAccount(); if (account != null) { @@ -4868,7 +4868,7 @@ public class ManagementServerImpl implements ManagementServer { public VirtualMachine startSystemVm(long vmId) { UserContext context = UserContext.current(); long callerId = context.getUserId(); - long callerAccountId = context.getAccountId(); + long callerAccountId = context.getAccount().getId(); VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(vmId, VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm); if (systemVm == null) { @@ -4891,7 +4891,7 @@ public class ManagementServerImpl implements ManagementServer { UserContext context = UserContext.current(); long callerId = context.getUserId(); - long callerAccountId = context.getAccountId(); + long callerAccountId = context.getAccount().getId(); // verify parameters VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(vmId, VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm); diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index a3087dae41d..bd544fc3f05 100644 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -113,10 +113,9 @@ import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.template.TemplateConstants; import com.cloud.user.Account; -import com.cloud.user.AccountManager; +import com.cloud.user.AccountService; import com.cloud.user.AccountVO; import com.cloud.user.User; -import com.cloud.user.UserVO; import com.cloud.user.dao.AccountDao; import com.cloud.utils.DateUtil; import com.cloud.utils.NumbersUtil; @@ -220,7 +219,7 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V @Inject private ConfigurationDao _configDao; @Inject private EventDao _eventDao; @Inject private ServiceOfferingDao _offeringDao; - @Inject private AccountManager _accountMgr; + @Inject private AccountService _accountMgr; @Inject GuestOSDao _guestOSDao = null; @Inject private VmManager _itMgr; @@ -276,8 +275,8 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V public SecondaryStorageVmVO start2(long secStorageVmId, long startEventId) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException { SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findById(secStorageVmId); - AccountVO systemAcct = _accountMgr.getSystemAccount(); - UserVO systemUser = _accountMgr.getSystemUser(); + Account systemAcct = _accountMgr.getSystemAccount(); + User systemUser = _accountMgr.getSystemUser(); return _itMgr.start(secStorageVm, null, systemUser, systemAcct); } @@ -732,7 +731,7 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V long id = _secStorageVmDao.getNextInSequence(Long.class, "id"); String name = VirtualMachineName.getSystemVmName(id, _instance, "s").intern(); - AccountVO systemAcct = _accountMgr.getSystemAccount(); + Account systemAcct = _accountMgr.getSystemAccount(); DataCenterDeployment plan = new DataCenterDeployment(dataCenterId); @@ -831,7 +830,7 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V String vlanGateway = publicIpAndVlan._gateWay; String vlanNetmask = publicIpAndVlan._netMask; - AccountVO systemAcct = _accountMgr.getSystemAccount(); + Account systemAcct = _accountMgr.getSystemAccount(); txn.start(); SecondaryStorageVmVO secStorageVm; String name = VirtualMachineName.getSystemVmName(id, _instance, "s").intern(); diff --git a/server/src/com/cloud/user/AccountManager.java b/server/src/com/cloud/user/AccountManager.java index 1f84b0e16b4..5a2c61c0575 100755 --- a/server/src/com/cloud/user/AccountManager.java +++ b/server/src/com/cloud/user/AccountManager.java @@ -96,13 +96,7 @@ public interface AccountManager extends Manager { List searchForLimits(Criteria c); - void checkAccess(Account account, Domain domain) throws PermissionDeniedException; - - void checkAccess(Account account, ControlledEntity... entities) throws PermissionDeniedException; - - AccountVO getSystemAccount(); - - UserVO getSystemUser(); + /** * Disables an account by accountId @@ -114,4 +108,8 @@ public interface AccountManager extends Manager { boolean deleteAccount(AccountVO account); boolean deleteUserInternal(long userId, long startEventId); + + void checkAccess(Account account, Domain domain) throws PermissionDeniedException; + + void checkAccess(Account account, ControlledEntity... entities) throws PermissionDeniedException; } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 0f9b1bbb33f..bca7e0584b5 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -171,6 +171,7 @@ import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.template.VirtualMachineTemplate.BootloaderType; import com.cloud.user.Account; import com.cloud.user.AccountManager; +import com.cloud.user.AccountService; import com.cloud.user.AccountVO; import com.cloud.user.User; import com.cloud.user.UserContext; @@ -237,6 +238,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, VirtualM @Inject HighAvailabilityManager _haMgr = null; @Inject AlertManager _alertMgr = null; @Inject AccountManager _accountMgr; + @Inject AccountService _accountService; @Inject AsyncJobManager _asyncMgr; @Inject VlanDao _vlanDao; @Inject AccountVlanMapDao _accountVlanMapDao;