Add cross-project tests for Containers

Depends-On: I821b4f5998be5b40327311039979f5e00ea9cefc
Change-Id: I4ef2f68d9070da0c56c4e2370cf66bc813829cd5
diff --git a/barbican_tempest_plugin/services/key_manager/json/container_client.py b/barbican_tempest_plugin/services/key_manager/json/container_client.py
index ef2ebf8..812e722 100644
--- a/barbican_tempest_plugin/services/key_manager/json/container_client.py
+++ b/barbican_tempest_plugin/services/key_manager/json/container_client.py
@@ -81,5 +81,33 @@
         self.expected_success(204, response.status)
         return
 
+    def get_container_acl(self, container_id):
+        headers = {
+            'Accept': 'application/json'
+        }
+        resp, body = self.get('v1/containers/{}/acl'.format(container_id),
+                              headers=headers)
+        self.expected_success(200, resp.status)
+        return json.loads(body)
+
+    def put_container_acl(self, container_id, acl):
+        req_body = json.dumps(acl)
+        resp, body = self.put('v1/containers/{}/acl'.format(container_id),
+                              req_body)
+        self.expected_success(200, resp.status)
+        return json.loads(body)
+
+    def patch_container_acl(self, container_id, acl):
+        req_body = json.dumps(acl)
+        resp, body = self.patch('v1/containers/{}/acl'.format(container_id),
+                                req_body)
+        self.expected_success(200, resp.status)
+        return json.loads(body)
+
+    def delete_container_acl(self, container_id):
+        resp, body = self.delete('v1/containers/{}/acl'.format(container_id))
+        self.expected_success(200, resp.status)
+        return json.loads(body)
+
     def queue_for_cleanup(self, container_id):
         raise NotImplementedError
diff --git a/barbican_tempest_plugin/tests/rbac/v1/base.py b/barbican_tempest_plugin/tests/rbac/v1/base.py
index 4c3ad32..07639ef 100644
--- a/barbican_tempest_plugin/tests/rbac/v1/base.py
+++ b/barbican_tempest_plugin/tests/rbac/v1/base.py
@@ -239,6 +239,16 @@
             name=container_name,
             type=container_type)
 
+    def add_consumer_to_container_admin(self,
+                                        consumer_name,
+                                        consumer_url,
+                                        container_id):
+        """add consumer to container as admin user"""
+        return self.admin_consumer_client.add_consumer_to_container(
+            name=consumer_name,
+            URL=consumer_url,
+            container_id=container_id)
+
     def create_aes_secret_admin(self, secret_name):
         key = create_aes_key()
         expire_time = (datetime.utcnow() + timedelta(days=5))
@@ -300,3 +310,17 @@
         }
         resp = client.create_order(**kwargs)
         return client.ref_to_uuid(resp['order_ref'])
+
+    def create_test_container(self, client, name):
+        """Create a generic container for testing
+
+        The new container is created using the given client.
+
+        :returns: the uuid for the new container
+        """
+        container = {
+            "type": "generic",
+            "name": name,
+        }
+        resp = client.create_container(**container)
+        return client.ref_to_uuid(resp['container_ref'])
diff --git a/barbican_tempest_plugin/tests/rbac/v1/test_containers.py b/barbican_tempest_plugin/tests/rbac/v1/test_containers.py
index 4615656..951a9a5 100644
--- a/barbican_tempest_plugin/tests/rbac/v1/test_containers.py
+++ b/barbican_tempest_plugin/tests/rbac/v1/test_containers.py
@@ -12,6 +12,7 @@
 import abc
 
 from tempest import config
+from tempest.lib.common.utils import data_utils
 from tempest.lib import exceptions
 
 from barbican_tempest_plugin.tests.rbac.v1 import base
@@ -96,7 +97,7 @@
     def test_delete_container_acl(self):
         """Test delete_container_acl policy
 
-        Testing: DELETE /v1/containers/{container-id}
+        Testing: DELETE /v1/containers/{container-id}/acl
         This test must check:
           * whether the persona can delete a containers acl
         """
@@ -123,24 +124,26 @@
         raise NotImplementedError
 
     @abc.abstractmethod
-    def test_get_container_consumer(self):
-        """Test get_container_consumer policy
+    def test_delete_container_consumer(self):
+        """Test delete_container_consumer policy
 
-        Testing: GET /v1/containers/{container-id}/consumers/{consumer-id}
+        Testing: DELETE /v1/containers/{container-id}/consumers
         This test must check:
-          * whether the persona can get a containers consumer by id
+          * whether the persona can delete a consumer of the container
         """
         raise NotImplementedError
 
     @abc.abstractmethod
-    def test_delete_container_consumer(self):
-        """Test delete_container_consumer policy
+    def test_get_container_consumer(self):
+        """Test GET /v1/containers/{container-id}/consumers/{consumer-id}
 
-        Testing: DELETE /v1/containers/{container-id}/consumers/{consumer-id}
         This test must check:
-          * whether the persona can delete a containers consumer by id
+          * whether the persona can get a containers consumer by id
+
+        NOTE: This route is undocumented, also there's no way to get a
+        consumer-id back from the API.
         """
-        raise NotImplementedError
+        pass
 
     @abc.abstractmethod
     def test_add_secret_to_container(self):
@@ -169,9 +172,17 @@
     def setup_clients(cls):
         super().setup_clients()
         cls.client = cls.os_project_reader.secret_v1.ContainerClient()
-        cls.secret_client = cls.os_project_reader.secret_v1.SecretClient()
-        cls.consumer_client = cls.os_project_reader.secret_v1.ConsumerClient(
-            service='key-manager')
+
+    def setUp(self):
+        super().setUp()
+        self.secret_id = self.create_test_secret(
+            self.secret_client,
+            data_utils.rand_name('test-containers'),
+            'SECRET_PASSPHRASE'
+        )
+        self.container_id = self.create_test_container(
+            self.container_client,
+            data_utils.rand_name('test-containers'))
 
     def test_list_containers(self):
         self.assertRaises(
@@ -184,21 +195,16 @@
             self.client.create_container)
 
     def test_get_container(self):
-        resp = self.create_empty_container_admin('test_reader_get_container')
-        container_id = self.ref_to_uuid(resp['container_ref'])
         self.assertRaises(
             exceptions.Forbidden,
             self.client.get_container,
-            container_id=container_id)
+            container_id=self.container_id)
 
     def test_delete_container(self):
-        resp = self.create_empty_container_admin(
-            'test_reader_delete_container')
-        container_id = self.ref_to_uuid(resp['container_ref'])
         self.assertRaises(
             exceptions.Forbidden,
             self.client.delete_container,
-            container_id=container_id)
+            container_id=self.container_id)
 
     def test_get_container_acl(self):
         pass
@@ -213,10 +219,31 @@
         pass
 
     def test_list_container_consumers(self):
-        pass
+        resp = self.create_empty_container_admin(
+            'test_reader_list_container_consumers')
+        container_id = self.ref_to_uuid(resp['container_ref'])
+
+        resp = self.add_consumer_to_container_admin(
+            consumer_name='test_reader_list_container_consumer',
+            consumer_url=resp['container_ref'],
+            container_id=container_id)
+
+        self.assertRaises(
+            exceptions.Forbidden,
+            self.consumer_client.list_consumers_in_container,
+            container_id=container_id)
 
     def test_create_container_consumer(self):
-        pass
+        resp = self.create_empty_container_admin(
+            'test_reader_create_container_consumer_container')
+        container_id = self.ref_to_uuid(resp['container_ref'])
+
+        self.assertRaises(
+            exceptions.Forbidden,
+            self.consumer_client.add_consumer_to_container,
+            name='test_reader_create_container_consumer',
+            URL=resp['container_ref'],
+            container_id=container_id)
 
     def test_get_container_consumer(self):
         pass
@@ -225,34 +252,18 @@
         pass
 
     def test_add_secret_to_container(self):
-        resp = self.create_empty_container_admin(
-            'test_reader_add_secret_to_container_container')
-        container_id = self.ref_to_uuid(resp['container_ref'])
-
-        resp = self.create_empty_secret_admin(
-            'test_reader_add_secret_to_container_secret')
-        secret_id = self.ref_to_uuid(resp['secret_ref'])
-
         self.assertRaises(
             exceptions.Forbidden,
             self.client.add_secret_to_container,
-            container_id=container_id,
-            secret_id=secret_id)
+            container_id=self.container_id,
+            secret_id=self.secret_id)
 
     def test_delete_secret_from_container(self):
-        resp = self.create_empty_container_admin(
-            'test_reader_delete_secret_from_container_container')
-        container_id = self.ref_to_uuid(resp['container_ref'])
-
-        resp = self.create_empty_secret_admin(
-            'test_reader_delete_secret_from_container_secret')
-        secret_id = self.ref_to_uuid(resp['secret_ref'])
-
         self.assertRaises(
             exceptions.Forbidden,
             self.client.delete_secret_from_container,
-            container_id=container_id,
-            secret_id=secret_id)
+            container_id=self.container_id,
+            secret_id=self.secret_id)
 
 
 class ProjectMemberTests(ProjectReaderTests):
@@ -260,80 +271,63 @@
     @classmethod
     def setup_clients(cls):
         super().setup_clients()
-        cls.client = cls.os_project_member.secret_v1.ContainerClient()
-        cls.secret_client = cls.os_project_member.secret_v1.SecretClient()
-        cls.consumer_client = cls.os_project_member.secret_v1.ConsumerClient()
+        cls.client = cls.container_client
 
     def test_list_containers(self):
-        self.client.create_container(
-            name='test_list_containers',
-            type='generic')
-        resp = self.client.list_containers(name='test_list_containers')
+        resp = self.client.list_containers()
         containers = resp['containers']
 
         self.assertGreaterEqual(len(containers), 1)
 
     def test_create_container(self):
-        self.client.create_container(
-            name='test_create_containers',
-            type='generic')
+        container_id = self.create_test_container(
+            self.client,
+            'test-create-container')
+
+        _ = self.container_client.get_container(container_id)
 
     def test_get_container(self):
-        resp = self.client.create_container(
-            name='get_container',
-            type='generic')
-        container_id = self.ref_to_uuid(resp['container_ref'])
-        resp = self.client.get_container(container_id=container_id)
+        resp = self.client.get_container(self.container_id)
 
-        self.assertEqual(container_id, self.ref_to_uuid(resp['container_ref']))
+        self.assertEqual(
+            self.container_id,
+            self.client.ref_to_uuid(resp['container_ref']))
 
     def test_delete_container(self):
-        resp = self.client.create_container(
-            name='delete_container',
-            type='generic')
-        container_id = self.ref_to_uuid(resp['container_ref'])
+        self.client.delete_container(self.container_id)
 
-        self.client.delete_container(container_id)
+        resp = self.container_client.list_containers()
+        container_ids = [self.client.ref_to_uuid(c['container_ref'])
+                         for c in resp['containers']]
+        self.assertNotIn(self.container_id, container_ids)
 
     def test_add_secret_to_container(self):
-        resp = self.client.create_container(
-            name='add_secret_to_container_c',
-            type='generic')
-        container_id = self.ref_to_uuid(resp['container_ref'])
-
-        resp = self.secret_client.create_secret(
-            cleanup='secret',
-            name='add_secret_to_container_s',
-            secret_type='passphrase',
-            payload='shhh... secret',
-            payload_content_type='text/plain')
-
-        secret_id = self.ref_to_uuid(resp['secret_ref'])
         self.client.add_secret_to_container(
-            container_id=container_id,
-            secret_id=secret_id)
+            container_id=self.container_id,
+            secret_id=self.secret_id)
+
+        resp = self.client.get_container(self.container_id)
+        secret_ids = [self.client.ref_to_uuid(sr['secret_ref'])
+                      for sr in resp['secret_refs']]
+        self.assertIn(self.secret_id, secret_ids)
 
     def test_delete_secret_from_container(self):
-        resp = self.client.create_container(
-            name='add_secret_to_container_c',
-            type='generic')
-        container_id = self.ref_to_uuid(resp['container_ref'])
-
-        resp = self.secret_client.create_secret(
-            cleanup='secret',
-            name='add_secret_to_container_s',
-            secret_type='passphrase',
-            payload='shhh... secret',
-            payload_content_type='text/plain')
-        secret_id = self.ref_to_uuid(resp['secret_ref'])
-
         self.client.add_secret_to_container(
-            container_id=container_id,
-            secret_id=secret_id)
+            self.container_id,
+            self.secret_id)
+        resp = self.client.get_container(self.container_id)
+        secret_ids = [self.client.ref_to_uuid(sr['secret_ref'])
+                      for sr in resp['secret_refs']]
+        self.assertIn(self.secret_id, secret_ids)
 
         self.client.delete_secret_from_container(
-            container_id=container_id,
-            secret_id=secret_id)
+            self.container_id,
+            self.secret_id)
+
+        resp = self.client.get_container(self.container_id)
+        secret_ids = [self.client.ref_to_uuid(sr['secret_ref'])
+                      for sr in resp['secret_refs']]
+        self.assertNotIn(self.secret_id, secret_ids)
 
 
 class ProjectAdminTests(ProjectMemberTests):
@@ -341,6 +335,58 @@
     @classmethod
     def setup_clients(cls):
         super().setup_clients()
-        cls.client = cls.os_project_admin.secret_v1.ContainerClient()
-        cls.secret_client = cls.os_project_admin.secret_v1.SecretClient()
-        cls.consumer_client = cls.os_project_member.secret_v1.ConsumerClient()
+        cls.client = cls.admin_container_client
+
+
+class ProjectReaderTestsAcrossProjects(ProjectReaderTests):
+    """Tests for Project Reader across Projects
+
+    Tests for Project Reader Persona using containers/secrets
+    that belong to a different project.
+
+    This class overrides setUp to create self.secret_id and
+    self.container_id to use objects that belong to a different
+    project.
+
+    We re-use most of the tests in ProjectReaderTests because
+    we also expect these to be Forbidden.
+
+    The only exception is the two tests we've overridden to
+    pass because it is not possible to list or create containers
+    on a different project.
+    """
+
+    def setUp(self):
+        super().setUp()
+        self.secret_id = self.create_test_secret(
+            self.other_secret_client,
+            data_utils.rand_name('test-containers'),
+            'SECRET_PASSPHRASE'
+        )
+        self.container_id = self.create_test_container(
+            self.other_container_client,
+            data_utils.rand_name('test-containers'))
+
+    def test_list_containers(self):
+        """This is not possible across projects"""
+        pass
+
+    def test_create_container(self):
+        """This is not possible across projects"""
+        pass
+
+
+class ProjectMemberTestsAcrossProjects(ProjectReaderTestsAcrossProjects):
+
+    @classmethod
+    def setup_clients(cls):
+        super().setup_clients()
+        cls.client = cls.container_client
+
+
+class ProjectAdminTestsAcrossProjects(ProjectMemberTestsAcrossProjects):
+
+    @classmethod
+    def setup_clients(cls):
+        super().setup_clients()
+        cls.client = cls.admin_container_client