diff --git a/api/src/com/cloud/api/commands/ListPortForwardingRulesCmd.java b/api/src/com/cloud/api/commands/ListPortForwardingRulesCmd.java index 3d0ce6d3c81..bb012859a13 100644 --- a/api/src/com/cloud/api/commands/ListPortForwardingRulesCmd.java +++ b/api/src/com/cloud/api/commands/ListPortForwardingRulesCmd.java @@ -42,6 +42,12 @@ public class ListPortForwardingRulesCmd extends BaseListCmd { @Parameter(name=ApiConstants.IP_ADDRESS, type=CommandType.STRING, description="the IP address of the port forwarding services") private String ipAddress; + + @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="account. Must be used with the domainId parameter.") + private String accountName; + + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="the domain ID. If used with the account parameter, lists port forwarding rules for the specified account in this domain.") + private Long domainId; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -50,6 +56,14 @@ public class ListPortForwardingRulesCmd extends BaseListCmd { public String getIpAddress() { return ipAddress; } + + public String getAccountName() { + return accountName; + } + + public Long getDomainId() { + return domainId; + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// diff --git a/api/src/com/cloud/user/AccountService.java b/api/src/com/cloud/user/AccountService.java index 839abac4864..20019cbfa12 100644 --- a/api/src/com/cloud/user/AccountService.java +++ b/api/src/com/cloud/user/AccountService.java @@ -33,10 +33,12 @@ 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.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.utils.Pair; public interface AccountService { @@ -143,6 +145,8 @@ public interface AccountService { Account finalizeOwner(Account caller, String accountName, Long domainId); + Pair finalizeAccountDomainForList(Account caller, String accountName, Long domainId); + Account getActiveAccount(String accountName, Long domainId); Account getActiveAccount(Long accountId); @@ -150,5 +154,7 @@ public interface AccountService { Account getAccount(Long accountId); User getActiveUser(long userId); + + Domain getDomain(long id); } diff --git a/server/src/com/cloud/network/rules/RulesManagerImpl.java b/server/src/com/cloud/network/rules/RulesManagerImpl.java index 6001f4e4ce2..3005037d344 100644 --- a/server/src/com/cloud/network/rules/RulesManagerImpl.java +++ b/server/src/com/cloud/network/rules/RulesManagerImpl.java @@ -27,6 +27,8 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import com.cloud.api.commands.ListPortForwardingRulesCmd; +import com.cloud.domain.Domain; +import com.cloud.domain.DomainVO; import com.cloud.event.EventVO; import com.cloud.event.dao.EventDao; import com.cloud.exception.InvalidParameterValueException; @@ -51,6 +53,10 @@ import com.cloud.utils.Pair; import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; import com.cloud.utils.db.DB; +import com.cloud.utils.db.Filter; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.Ip; @@ -337,9 +343,12 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { @Override public List listPortForwardingRules(ListPortForwardingRulesCmd cmd) { - Account caller = UserContext.current().getCaller(); - - List rules = null; + Account caller = UserContext.current().getCaller(); + String ip = cmd.getIpAddress(); + + Pair accountDomainPair = _accountMgr.finalizeAccountDomainForList(caller, cmd.getAccountName(), cmd.getDomainId()); + String accountName = accountDomainPair.first(); + Long domainId = accountDomainPair.second(); if(cmd.getIpAddress() != null){ Ip ipAddress = new Ip(cmd.getIpAddress()); @@ -347,13 +356,30 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { if (ipAddressVO == null || !ipAddressVO.readyToUse()) { throw new InvalidParameterValueException("Ip address not ready for port forwarding rules yet: " + ipAddress); } - - rules = _forwardingDao.listByIp(ipAddress); - _accountMgr.checkAccess(caller, rules.toArray(new PortForwardingRuleVO[rules.size()])); - } else { - rules = _forwardingDao.listByAccount(caller.getAccountId()); + _accountMgr.checkAccess(caller, ipAddressVO); } - return rules; + + Filter filter = new Filter(PortForwardingRuleVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal()); + SearchBuilder sb = _forwardingDao.createSearchBuilder(); + sb.and("ip", sb.entity().getSourceIpAddress(), Op.EQ); + sb.and("accountId", sb.entity().getAccountId(), Op.EQ); + sb.and("domainId", sb.entity().getDomainId(), Op.EQ); + + SearchCriteria sc = sb.create(); + + if (ip != null) { + sc.setParameters("ip", ip); + } + + if (domainId != null) { + sc.setParameters("domainId", domainId); + if (accountName != null) { + Account account = _accountMgr.getActiveAccount(accountName, domainId); + sc.setParameters("accountId", account.getId()); + } + } + + return _forwardingDao.search(sc, filter); } @Override diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index 6d93131346d..655d6de54fe 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -1488,28 +1488,30 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag } public Account finalizeOwner(Account caller, String accountName, Long domainId) { - if (isAdmin(caller.getType())) { - if (domainId != null) { - DomainVO domain = _domainDao.findById(domainId); - if (domain == null) { - throw new InvalidParameterValueException("Unable to find the domain by id=" + domainId); - } + if (isAdmin(caller.getType()) && accountName != null && domainId != null) { + DomainVO domain = _domainDao.findById(domainId); + if (domain == null) { + throw new InvalidParameterValueException("Unable to find the domain by id=" + domainId); + } - if (accountName != null) { - Account owner = _accountDao.findActiveAccount(accountName, domainId); - if (owner == null) { - throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId); - } - checkAccess(caller, domain); - return owner; - } else { - throw new InvalidParameterValueException("Account have to be specified along with domainId"); - } + Account owner = _accountDao.findActiveAccount(accountName, domainId); + if (owner == null) { + throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId); + } + checkAccess(caller, domain); + + return owner; + } else if (!isAdmin(caller.getType()) && accountName != null && domainId != null) { + if (!accountName.equals(caller.getAccountName()) || domainId.longValue() != caller.getDomainId()) { + throw new PermissionDeniedException("Can't create/list resources for account " + accountName + " in domain " + domainId + ", permission denied"); } else { return caller; } } else { - //regular user can't create resources for other people + if (accountName == null || domainId == null) { + throw new InvalidParameterValueException("AccountName and domainId must be specified together"); + } + //regular user can't create/list resources for other people return caller; } } @@ -1546,4 +1548,41 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag public User getActiveUser(long userId) { return _userDao.findById(userId); } + + @Override + public Domain getDomain(long domainId) { + return _domainDao.findById(domainId); + } + + @Override + public Pair finalizeAccountDomainForList(Account caller, String accountName, Long domainId) { + if (isAdmin(caller.getType())) { + if (domainId == null && accountName != null) { + throw new InvalidParameterValueException("accountName and domainId might be specified together"); + } else if (domainId != null){ + Domain domain = getDomain(domainId); + if (domain == null) { + throw new InvalidParameterValueException("Unable to find the domain by id=" + domainId); + } + + checkAccess(caller, domain); + + if (accountName != null) { + Account owner = getActiveAccount(accountName, domainId); + if (owner == null) { + throw new InvalidParameterValueException("Unable to find account with name " + accountName + " in domain id=" + domainId); + } + } + } + } else if (accountName != null && domainId != null) { + if (!accountName.equals(caller.getAccountName()) || domainId.longValue() != caller.getDomainId()) { + throw new PermissionDeniedException("Can't list port forwarding rules for account " + accountName + " in domain " + domainId + ", permission denied"); + } + } else { + accountName = caller.getAccountName(); + domainId = caller.getDomainId(); + } + + return new Pair(accountName, domainId); + } }