DaanHoogland commented on a change in pull request #4774:
URL: https://github.com/apache/cloudstack/pull/4774#discussion_r821695630



##########
File path: test/integration/component/test_template_access_across_domains.py
##########
@@ -0,0 +1,627 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Import Local Modules
+from nose.plugins.attrib import attr
+from marvin.cloudstackTestCase import cloudstackTestCase, unittest
+from marvin.cloudstackAPI import (listZones,
+                                  deleteTemplate,
+                                  listConfigurations,
+                                  updateConfiguration)
+from marvin.lib.utils import (cleanup_resources)
+from marvin.lib.base import (Account,
+                             Domain,
+                             Network,
+                             NetworkOffering,
+                             Template,
+                             ServiceOffering,
+                             VirtualMachine,
+                             Snapshot,
+                             Volume)
+from marvin.lib.common import (get_domain,
+                               get_zone,
+                               get_template,
+                               get_builtin_template_info)
+# Import System modules
+import time
+import logging
+
+class TestTemplateAccessAcrossDomains(cloudstackTestCase):
+    @classmethod
+    def setUpClass(cls):
+        cls.testClient = super(TestTemplateAccessAcrossDomains, 
cls).getClsTestClient()
+        cls.apiclient = cls.testClient.getApiClient()
+
+        cls.services = cls.testClient.getParsedTestDataConfig()
+        # Get Zone, Domain and templates
+        cls.domain = get_domain(cls.apiclient)
+        cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
+        cls.services['mode'] = cls.zone.networktype
+        cls.logger = logging.getLogger("TestRouterResources")
+        cls._cleanup = []
+        cls.unsupportedHypervisor = False
+        cls.hypervisor = cls.testClient.getHypervisorInfo()
+        if cls.hypervisor.lower() in ['lxc']:
+            cls.unsupportedHypervisor = True
+            return
+        cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+
+        # Create new domain1
+        cls.domain1 = Domain.create(
+            cls.apiclient,
+            services=cls.services["acl"]["domain1"],
+            parentdomainid=cls.domain.id)
+        cls._cleanup.append(cls.domain1)
+
+        # Create account1
+        cls.account1 = Account.create(
+            cls.apiclient,
+            cls.services["acl"]["accountD1"],
+            domainid=cls.domain1.id
+        )
+        cls._cleanup.append(cls.account1)
+
+        # Create new sub-domain
+        cls.sub_domain = Domain.create(
+            cls.apiclient,
+            services=cls.services["acl"]["domain11"],
+            parentdomainid=cls.domain1.id)
+        cls._cleanup.append(cls.sub_domain)
+
+        # Create account for sub-domain
+        cls.sub_account = Account.create(
+            cls.apiclient,
+            cls.services["acl"]["accountD11"],
+            domainid=cls.sub_domain.id
+        )
+        cls._cleanup.append(cls.sub_account)
+
+        # Create new domain2
+        cls.domain2 = Domain.create(
+            cls.apiclient,
+            services=cls.services["acl"]["domain2"],
+            parentdomainid=cls.domain.id)
+        cls._cleanup.append(cls.domain2)
+
+        # Create account2
+        cls.account2 = Account.create(
+            cls.apiclient,
+            cls.services["acl"]["accountD2"],
+            domainid=cls.domain2.id
+        )
+        cls._cleanup.append(cls.account2)
+
+        cls.service_offering = ServiceOffering.create(
+            cls.apiclient,
+            cls.services["service_offering"]
+        )
+        cls._cleanup.append(cls.service_offering)
+        if cls.hypervisor.lower() in ['kvm']:
+            # register template under ROOT domain
+            cls.root_template = Template.register(cls.apiclient,
+                                                  
cls.services["test_templates"]["kvm"],
+                                                  zoneid=cls.zone.id,
+                                                  domainid=cls.domain.id,
+                                                  
hypervisor=cls.hypervisor.lower())
+            cls.root_template.download(cls.apiclient)
+            cls._cleanup.append(cls.root_template)
+            cls.services["test_templates"]["kvm"]["name"] = cls.account1.name
+            cls.template1 = Template.register(cls.apiclient,
+                                              
cls.services["test_templates"]["kvm"],
+                                              zoneid=cls.zone.id,
+                                              account=cls.account1.name,
+                                              domainid=cls.domain1.id,
+                                              
hypervisor=cls.hypervisor.lower())
+            cls.template1.download(cls.apiclient)
+            cls._cleanup.append(cls.template1)
+            cls.services["test_templates"]["kvm"]["name"] = 
cls.sub_account.name
+            cls.sub_template = Template.register(cls.apiclient,
+                                                 
cls.services["test_templates"]["kvm"],
+                                                 zoneid=cls.zone.id,
+                                                 account=cls.sub_account.name,
+                                                 domainid=cls.sub_domain.id,
+                                                 
hypervisor=cls.hypervisor.lower())
+            cls.sub_template.download(cls.apiclient)
+            cls._cleanup.append(cls.sub_template)
+            cls.template2 = Template.register(cls.apiclient,
+                                              
cls.services["test_templates"]["kvm"],
+                                              zoneid=cls.zone.id,
+                                              account=cls.account2.name,
+                                              domainid=cls.domain2.id,
+                                              
hypervisor=cls.hypervisor.lower())
+            cls.template2.download(cls.apiclient)
+            cls._cleanup.append(cls.template2)
+        else:
+            return
+
+    @classmethod
+    def tearDownClass(cls):
+        super(TestTemplateAccessAcrossDomains, cls).tearDownClass()
+
+    def setUp(self):
+        self.apiclient = self.testClient.getApiClient()
+        self.domain1_config = 
self.get_restrict_template_configuration(self.domain1.id)
+        self.domain2_config = 
self.get_restrict_template_configuration(self.domain2.id)
+        self.sub_domain_config = 
self.get_restrict_template_configuration(self.sub_domain.id)
+        self.cleanup = []
+        return
+
+    def tearDown(self):
+        try:
+            self.update_restrict_template_configuration(self.domain1.id, 
self.domain1_config)
+            self.update_restrict_template_configuration(self.domain2.id, 
self.domain2_config)
+            self.update_restrict_template_configuration(self.sub_domain.id, 
self.sub_domain_config)
+            cleanup_resources(self.apiclient, self.cleanup)

Review comment:
       please apply this suggestion @soreana . It reverses the cleanup from how 
it was created and thus prevents any blockage due to dependencies in the 
infra/app-scape.

##########
File path: server/src/main/java/com/cloud/acl/DomainChecker.java
##########
@@ -167,6 +168,16 @@ public boolean checkAccess(Account caller, 
ControlledEntity entity, AccessType a
                             throw new PermissionDeniedException("Domain Admin 
and regular users can modify only their own Public templates");
                         }
                     }
+                } else if 
(QueryService.SharePublicTemplatesWithOtherDomains.valueIn(owner.getDomainId()) 
&& caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { // public template can be 
used by other accounts in the same domain or in sub-domains, and domain admin 
of parent domains
+                    if (caller.getDomainId() != owner.getDomainId() && 
!_domainDao.isChildDomain(owner.getDomainId(), caller.getDomainId())) {
+                        if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL || 
caller.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+                            throw new PermissionDeniedException(caller + "is 
not allowed to access the template " + template);
+                        } else if (caller.getType() == 
Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == 
Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) {
+                            if 
(!_domainDao.isChildDomain(caller.getDomainId(), owner.getDomainId())) {
+                                throw new PermissionDeniedException(caller + 
"is not allowed to access the template " + template);
+                            }
+                        }
+                    }

Review comment:
       maybe using 
   ```
   // public template can be used by other accounts in the same domain or in 
sub-domains, and domain admin of parent domains
   ```
   as an inspiration for a method name or a javadoc on it?

##########
File path: server/src/main/java/com/cloud/acl/DomainChecker.java
##########
@@ -167,6 +168,16 @@ public boolean checkAccess(Account caller, 
ControlledEntity entity, AccessType a
                             throw new PermissionDeniedException("Domain Admin 
and regular users can modify only their own Public templates");
                         }
                     }
+                } else if 
(QueryService.SharePublicTemplatesWithOtherDomains.valueIn(owner.getDomainId()) 
&& caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { // public template can be 
used by other accounts in the same domain or in sub-domains, and domain admin 
of parent domains
+                    if (caller.getDomainId() != owner.getDomainId() && 
!_domainDao.isChildDomain(owner.getDomainId(), caller.getDomainId())) {
+                        if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL || 
caller.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+                            throw new PermissionDeniedException(caller + "is 
not allowed to access the template " + template);
+                        } else if (caller.getType() == 
Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == 
Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) {
+                            if 
(!_domainDao.isChildDomain(caller.getDomainId(), owner.getDomainId())) {
+                                throw new PermissionDeniedException(caller + 
"is not allowed to access the template " + template);
+                            }
+                        }
+                    }

Review comment:
       can you put this block in a separate method?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to