From 1a9ad61694f79ac5249a2caa9e3a6359a78f6280 Mon Sep 17 00:00:00 2001 From: harika-vakadi Date: Fri, 14 Dec 2012 19:12:08 +0530 Subject: [PATCH] Test to GET public-readable container's object Added a test case to "test_object_services.py" which tries to GET public readable object with an empty header. Added a new class "ObjectClientCustomizedHeader" to object_client.py inorder to overwrite the http request with an empty header, which makes the test case to "Make container public-readable, and access the object anonymously without using credentials" with proper verification Change-Id: I407ceffefb6a99cbfa3bb31421189190aa3f8c1c Implements: blueprint add-some-functional-swift-tests --- tempest/openstack.py | 19 ++++---- .../services/object_storage/object_client.py | 43 +++++++++++++++++++ tempest/tests/object_storage/base.py | 1 + .../object_storage/test_object_services.py | 33 ++++++++++++++ 4 files changed, 88 insertions(+), 8 deletions(-) diff --git a/tempest/openstack.py b/tempest/openstack.py index e29ea8e5cf..01b4cc1849 100644 --- a/tempest/openstack.py +++ b/tempest/openstack.py @@ -22,33 +22,33 @@ from tempest import exceptions from tempest.services.boto.clients import APIClientEC2 from tempest.services.boto.clients import ObjectClientS3 from tempest.services.compute.json.extensions_client import \ - ExtensionsClientJSON + ExtensionsClientJSON from tempest.services.compute.json.flavors_client import FlavorsClientJSON from tempest.services.compute.json.floating_ips_client import \ - FloatingIPsClientJSON + FloatingIPsClientJSON from tempest.services.compute.json.images_client import ImagesClientJSON from tempest.services.compute.json.limits_client import LimitsClientJSON from tempest.services.compute.json.servers_client import ServersClientJSON from tempest.services.compute.json.security_groups_client import \ - SecurityGroupsClientJSON + SecurityGroupsClientJSON from tempest.services.compute.json.keypairs_client import KeyPairsClientJSON from tempest.services.compute.json.quotas_client import QuotasClient from tempest.services.compute.json.volumes_extensions_client import \ - VolumesExtensionsClientJSON + VolumesExtensionsClientJSON from tempest.services.compute.json.console_output_client import \ - ConsoleOutputsClient + ConsoleOutputsClient from tempest.services.compute.xml.extensions_client import ExtensionsClientXML from tempest.services.compute.xml.flavors_client import FlavorsClientXML from tempest.services.compute.xml.floating_ips_client import \ - FloatingIPsClientXML + FloatingIPsClientXML from tempest.services.compute.xml.images_client import ImagesClientXML from tempest.services.compute.xml.keypairs_client import KeyPairsClientXML from tempest.services.compute.xml.limits_client import LimitsClientXML from tempest.services.compute.xml.security_groups_client \ -import SecurityGroupsClientXML + import SecurityGroupsClientXML from tempest.services.compute.xml.servers_client import ServersClientXML from tempest.services.compute.xml.volumes_extensions_client import \ - VolumesExtensionsClientXML + VolumesExtensionsClientXML from tempest.services.identity.json.admin_client import AdminClientJSON from tempest.services.identity.json.admin_client import TokenClientJSON from tempest.services.identity.xml.admin_client import AdminClientXML @@ -60,6 +60,8 @@ from tempest.services.object_storage.container_client import ContainerClient from tempest.services.object_storage.object_client import ObjectClient from tempest.services.volume.json.volumes_client import VolumesClientJSON from tempest.services.volume.xml.volumes_client import VolumesClientXML +from tempest.services.object_storage.object_client import \ + ObjectClientCustomizedHeader LOG = logging.getLogger(__name__) @@ -191,6 +193,7 @@ class Manager(object): self.object_client = ObjectClient(*client_args) self.ec2api_client = APIClientEC2(*client_args) self.s3_client = ObjectClientS3(*client_args) + self.custom_object_client = ObjectClientCustomizedHeader(*client_args) class AltManager(Manager): diff --git a/tempest/services/object_storage/object_client.py b/tempest/services/object_storage/object_client.py index c8f63ef2cb..5bf8de07f6 100644 --- a/tempest/services/object_storage/object_client.py +++ b/tempest/services/object_storage/object_client.py @@ -15,6 +15,8 @@ # License for the specific language governing permissions and limitations # under the License. +import httplib2 +import json import re from tempest.common.rest_client import RestClient @@ -116,3 +118,44 @@ class ObjectClient(RestClient): resp, body = self.copy(url, headers=headers) return resp, body + + +class ObjectClientCustomizedHeader(RestClient): + + def __init__(self, config, username, password, auth_url, tenant_name=None): + super(ObjectClientCustomizedHeader, self).__init__(config, username, + password, auth_url, + tenant_name) + #Overwrites json-specific header encoding in RestClient + self.service = self.config.object_storage.catalog_type + self.format = 'json' + + def request(self, method, url, headers=None, body=None, wait=None): + """A simple HTTP request interface.""" + self.http_obj = httplib2.Http() + if headers is None: + headers = {} + if self.base_url is None: + self._set_auth() + + req_url = "%s/%s" % (self.base_url, url) + resp, resp_body = self.http_obj.request(req_url, method, + headers=headers, body=body) + if resp.status in (401, 403): + try: + resp_body = json.loads(resp_body) + raise exceptions.Unauthorized(resp_body['error']['message']) + except ValueError: + pass + return resp, resp_body + + def get_object(self, container, object_name, metadata=None): + """Retrieve object's data.""" + headers = {} + if metadata: + for key in metadata: + headers[str(key)] = metadata[key] + + url = "{0}/{1}".format(container, object_name) + resp, body = self.get(url, headers=headers) + return resp, body diff --git a/tempest/tests/object_storage/base.py b/tempest/tests/object_storage/base.py index 8edb3d2342..f29798f306 100644 --- a/tempest/tests/object_storage/base.py +++ b/tempest/tests/object_storage/base.py @@ -32,6 +32,7 @@ class BaseObjectTest(unittest.TestCase): cls.container_client = cls.os.container_client cls.account_client = cls.os.account_client cls.config = cls.os.config + cls.custom_object_client = cls.os.custom_object_client try: cls.account_client.list_account_containers() diff --git a/tempest/tests/object_storage/test_object_services.py b/tempest/tests/object_storage/test_object_services.py index 3be2beedb6..807a99e3d9 100644 --- a/tempest/tests/object_storage/test_object_services.py +++ b/tempest/tests/object_storage/test_object_services.py @@ -263,3 +263,36 @@ class ObjectTest(base.BaseObjectTest): src_container_name) resp, _ = self.container_client.delete_container( dst_container_name) + + @attr(type='smoke') + def test_access_object_without_using_creds(self): + """Make container public-readable, and access the object + anonymously, e.g. without using credentials""" + + # Update Container Metadata to make public readable + headers = {'X-Container-Read': '.r:*,.rlistings'} + resp, body = \ + self.container_client.update_container_metadata( + self.container_name, metadata=headers, metadata_prefix='') + self.assertIn(resp['status'], '204') + + # Create Object + object_name = rand_name(name='Object') + data = arbitrary_string(size=len(object_name) * 1, + base_text=object_name) + resp, _ = self.object_client.create_object(self.container_name, + object_name, data) + self.assertEqual(resp['status'], '201') + + # List container metadata + resp, _ = \ + self.container_client.list_container_metadata(self.container_name) + self.assertEqual(resp['status'], '204') + self.assertIn('x-container-read', resp) + self.assertEqual(resp['x-container-read'], '.r:*,.rlistings') + + # Trying to Get Object with empty Headers as it is public readable + resp, body = \ + self.custom_object_client.get_object(self.container_name, + object_name, metadata={}) + self.assertEqual(body, data)