diff --git a/server/src/main/java/com/cloud/network/NetworkModelImpl.java b/server/src/main/java/com/cloud/network/NetworkModelImpl.java index 66d79cc35047..c601c13e6ad5 100644 --- a/server/src/main/java/com/cloud/network/NetworkModelImpl.java +++ b/server/src/main/java/com/cloud/network/NetworkModelImpl.java @@ -1659,7 +1659,7 @@ public void checkCapabilityForProvider(Set providers, Service service, } @Override - public void checkNetworkPermissions(Account owner, Network network) { + public void checkNetworkPermissions(Account caller, Network network) { // dahn 20140310: I was thinking of making this an assert but // as we hardly ever test with asserts I think // we better make sure at runtime. @@ -1672,11 +1672,11 @@ public void checkNetworkPermissions(Account owner, Network network) { if (networkOwner == null) throw new PermissionDeniedException("Unable to use network with id= " + ((NetworkVO)network).getUuid() + ", network does not have an owner"); - if (owner.getType() != Account.Type.PROJECT && networkOwner.getType() == Account.Type.PROJECT) { - checkProjectNetworkPermissions(owner, networkOwner, network); + if (!Account.Type.PROJECT.equals(caller.getType()) && Account.Type.PROJECT.equals(networkOwner.getType())) { + checkProjectNetworkPermissions(caller, networkOwner, network); } else { - List networkMap = _networksDao.listBy(owner.getId(), network.getId()); - NetworkPermissionVO networkPermission = _networkPermissionDao.findByNetworkAndAccount(network.getId(), owner.getId()); + List networkMap = _networksDao.listBy(caller.getId(), network.getId()); + NetworkPermissionVO networkPermission = _networkPermissionDao.findByNetworkAndAccount(network.getId(), caller.getId()); if (CollectionUtils.isEmpty(networkMap) && networkPermission == null) { throw new PermissionDeniedException("Unable to use network with id= " + ((NetworkVO)network).getUuid() + ", permission denied"); @@ -1684,13 +1684,13 @@ public void checkNetworkPermissions(Account owner, Network network) { } } else { - if (!isNetworkAvailableInDomain(network.getId(), owner.getDomainId())) { - DomainVO ownerDomain = _domainDao.findById(owner.getDomainId()); - if (ownerDomain == null) { - throw new CloudRuntimeException("cannot check permission on account " + owner.getAccountName() + " whose domain does not exist"); + if (!isNetworkAvailableInDomain(network.getId(), caller.getDomainId())) { + DomainVO callerDomain = _domainDao.findById(caller.getDomainId()); + if (callerDomain == null) { + throw new CloudRuntimeException("cannot check permission on account " + caller.getAccountName() + " whose domain does not exist"); } throw new PermissionDeniedException("Shared network id=" + ((NetworkVO)network).getUuid() + " is not available in domain id=" + - ownerDomain.getUuid()); + callerDomain.getUuid()); } } } diff --git a/server/src/main/java/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java b/server/src/main/java/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java index 1c9af7a334d5..d9f1db616f58 100644 --- a/server/src/main/java/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java +++ b/server/src/main/java/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java @@ -113,7 +113,7 @@ public ApplicationLoadBalancerRule createApplicationLoadBalancer(String name, St } Account caller = CallContext.current().getCallingAccount(); - _accountMgr.checkAccess(caller, AccessType.UseEntry, false, guestNtwk); + _accountMgr.checkAccess(caller, AccessType.OperateEntry, false, guestNtwk); Network sourceIpNtwk = _networkModel.getNetwork(sourceIpNetworkId); if (sourceIpNtwk == null) { diff --git a/server/src/test/java/com/cloud/network/NetworkModelTest.java b/server/src/test/java/com/cloud/network/NetworkModelTest.java index af14cbd7adc0..b52335035fd8 100644 --- a/server/src/test/java/com/cloud/network/NetworkModelTest.java +++ b/server/src/test/java/com/cloud/network/NetworkModelTest.java @@ -31,34 +31,49 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Set; + +import org.apache.cloudstack.network.NetworkPermissionVO; +import org.apache.cloudstack.network.dao.NetworkPermissionDao; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.Spy; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenterVO; +import com.cloud.dc.VlanVO; import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.VlanDao; +import com.cloud.domain.DomainVO; +import com.cloud.domain.dao.DomainDao; import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.PermissionDeniedException; +import com.cloud.network.Network.Provider; +import com.cloud.network.dao.IPAddressDao; +import com.cloud.network.dao.IPAddressVO; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkDomainDao; +import com.cloud.network.dao.NetworkDomainVO; +import com.cloud.network.dao.NetworkVO; import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; import com.cloud.network.dao.PhysicalNetworkServiceProviderVO; import com.cloud.network.dao.PhysicalNetworkVO; -import junit.framework.Assert; - -import org.junit.Before; -import org.junit.Test; - -import com.cloud.dc.VlanVO; -import com.cloud.dc.dao.VlanDao; -import com.cloud.network.dao.IPAddressDao; -import com.cloud.network.dao.IPAddressVO; +import com.cloud.projects.dao.ProjectDao; import com.cloud.user.Account; +import com.cloud.user.AccountVO; +import com.cloud.user.DomainManager; +import com.cloud.user.dao.AccountDao; import com.cloud.utils.db.Filter; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.Ip; -import com.cloud.network.Network.Provider; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.mockito.Spy; + +import junit.framework.Assert; public class NetworkModelTest { @@ -85,6 +100,20 @@ public class NetworkModelTest { private PhysicalNetworkVO physicalNetworkZone2; @Mock private PhysicalNetworkServiceProviderVO providerVO; + @Mock + private AccountDao accountDao; + @Mock + private NetworkDao networkDao; + @Mock + private NetworkPermissionDao networkPermissionDao; + @Mock + private NetworkDomainDao networkDomainDao; + @Mock + private DomainManager domainManager; + @Mock + private DomainDao domainDao; + @Mock + private ProjectDao projectDao; private static final long ZONE_1_ID = 1L; private static final long ZONE_2_ID = 2L; @@ -263,4 +292,116 @@ public void checkIp6ParametersTestNullStartAndEndIpv6() { networkModel.checkIp6Parameters(null, null, IPV6_GATEWAY,IPV6_CIDR); } + @Test + public void testCheckNetworkPermissions() { + long accountId = 1L; + AccountVO caller = mock(AccountVO.class); + when(caller.getId()).thenReturn(accountId); + when(caller.getType()).thenReturn(Account.Type.NORMAL); + NetworkVO network = mock(NetworkVO.class); + when(network.getGuestType()).thenReturn(Network.GuestType.Isolated); + when(network.getAccountId()).thenReturn(accountId); + when(accountDao.findById(accountId)).thenReturn(caller); + when(networkDao.listBy(caller.getId(), network.getId())).thenReturn(List.of(network)); + when(networkPermissionDao.findByNetworkAndAccount(network.getId(), caller.getId())).thenReturn(mock(NetworkPermissionVO.class)); + networkModel.checkNetworkPermissions(caller, network); + } + + @Test(expected = CloudRuntimeException.class) + public void testCheckNetworkPermissionsNullNetwork() { + AccountVO caller = mock(AccountVO.class); + NetworkVO network = null; + networkModel.checkNetworkPermissions(caller, network); + } + + @Test(expected = PermissionDeniedException.class) + public void testCheckNetworkPermissionsNoOwner() { + long accountId = 1L; + AccountVO caller = mock(AccountVO.class); + when(caller.getId()).thenReturn(accountId); + when(caller.getType()).thenReturn(Account.Type.NORMAL); + NetworkVO network = mock(NetworkVO.class); + when(network.getGuestType()).thenReturn(Network.GuestType.Isolated); + when(network.getAccountId()).thenReturn(accountId); + when(accountDao.findById(accountId)).thenReturn(null); + networkModel.checkNetworkPermissions(caller, network); + } + + @Test(expected = PermissionDeniedException.class) + public void testCheckNetworkPermissionsNoPermission() { + long accountId = 1L; + AccountVO caller = mock(AccountVO.class); + when(caller.getId()).thenReturn(accountId); + when(caller.getType()).thenReturn(Account.Type.NORMAL); + NetworkVO network = mock(NetworkVO.class); + when(network.getGuestType()).thenReturn(Network.GuestType.Isolated); + when(network.getAccountId()).thenReturn(accountId); + when(accountDao.findById(accountId)).thenReturn(caller); + when(networkDao.listBy(caller.getId(), network.getId())).thenReturn(null); + when(networkPermissionDao.findByNetworkAndAccount(network.getId(), caller.getId())).thenReturn(null); + networkModel.checkNetworkPermissions(caller, network); + } + + @Test + public void testCheckNetworkPermissionsSharedNetwork() { + long id = 1L; + long subDomainId = 2L; + AccountVO caller = mock(AccountVO.class); + when(caller.getId()).thenReturn(id); + when(caller.getDomainId()).thenReturn(id); + when(caller.getType()).thenReturn(Account.Type.NORMAL); + NetworkVO network = mock(NetworkVO.class); + when(network.getGuestType()).thenReturn(Network.GuestType.Shared); + when(network.getId()).thenReturn(id); + when(networkDao.findById(network.getId())).thenReturn(network); + NetworkDomainVO networkDomainVO = mock(NetworkDomainVO.class); + when(networkDomainVO.getDomainId()).thenReturn(id); + when(networkDomainDao.getDomainNetworkMapByNetworkId(id)).thenReturn(networkDomainVO); + networkModel.checkNetworkPermissions(caller, network); + when(caller.getDomainId()).thenReturn(subDomainId); + networkDomainVO.subdomainAccess = Boolean.TRUE; + when(domainManager.getDomainParentIds(subDomainId)).thenReturn(Set.of(id)); + networkModel.checkNetworkPermissions(caller, network); + } + + @Test(expected = PermissionDeniedException.class) + public void testCheckNetworkPermissionsSharedNetworkNoSubDomainAccess() { + long id = 1L; + long subDomainId = 2L; + AccountVO caller = mock(AccountVO.class); + when(caller.getId()).thenReturn(id); + when(caller.getDomainId()).thenReturn(subDomainId); + when(caller.getType()).thenReturn(Account.Type.NORMAL); + NetworkVO network = mock(NetworkVO.class); + when(network.getGuestType()).thenReturn(Network.GuestType.Shared); + when(network.getId()).thenReturn(id); + when(networkDao.findById(network.getId())).thenReturn(network); + when(domainDao.findById(caller.getDomainId())).thenReturn(mock(DomainVO.class)); + NetworkDomainVO networkDomainVO = mock(NetworkDomainVO.class); + when(networkDomainVO.getDomainId()).thenReturn(id); + networkDomainVO.subdomainAccess = Boolean.FALSE; + when(networkDomainDao.getDomainNetworkMapByNetworkId(id)).thenReturn(networkDomainVO); + networkModel.checkNetworkPermissions(caller, network); + } + + @Test(expected = PermissionDeniedException.class) + public void testCheckNetworkPermissionsSharedNetworkNotSubDomain() { + long id = 1L; + long subDomainId = 2L; + AccountVO caller = mock(AccountVO.class); + when(caller.getId()).thenReturn(id); + when(caller.getDomainId()).thenReturn(subDomainId); + when(caller.getType()).thenReturn(Account.Type.NORMAL); + NetworkVO network = mock(NetworkVO.class); + when(network.getGuestType()).thenReturn(Network.GuestType.Shared); + when(network.getId()).thenReturn(id); + when(networkDao.findById(network.getId())).thenReturn(network); + when(domainDao.findById(caller.getDomainId())).thenReturn(mock(DomainVO.class)); + NetworkDomainVO networkDomainVO = mock(NetworkDomainVO.class); + when(networkDomainVO.getDomainId()).thenReturn(id); + networkDomainVO.subdomainAccess = Boolean.TRUE; + when(networkDomainDao.getDomainNetworkMapByNetworkId(id)).thenReturn(networkDomainVO); + when(domainManager.getDomainParentIds(subDomainId)).thenReturn(Set.of(0L)); + networkModel.checkNetworkPermissions(caller, network); + } }