diff options
author | Tim Burke <tim.burke@gmail.com> | 2020-06-18 09:41:46 -0700 |
---|---|---|
committer | Tim Burke <tim.burke@gmail.com> | 2020-06-18 09:41:46 -0700 |
commit | 481f126e6b59689599f438e5d27f7328f5b3e813 (patch) | |
tree | 14212db13aee782e95ffd36993d74c6bf35df0cb /test/functional/test_object_versioning.py | |
parent | b3fd0bd9d82160305a821e742b2cd968036911b2 (diff) | |
parent | 51a587ed8dd5700b558ad26d70dcb7facc0f91e4 (diff) | |
download | swift-481f126e6b59689599f438e5d27f7328f5b3e813.tar.gz |
Merge remote-tracking branch 'gerrit/master' into feature/losffeature/losf
Change-Id: If9d7c63f3c4c15fbccff31e2b77a6911bb95972a
Diffstat (limited to 'test/functional/test_object_versioning.py')
-rw-r--r-- | test/functional/test_object_versioning.py | 106 |
1 files changed, 88 insertions, 18 deletions
diff --git a/test/functional/test_object_versioning.py b/test/functional/test_object_versioning.py index ebfca68f6..d7db187c0 100644 --- a/test/functional/test_object_versioning.py +++ b/test/functional/test_object_versioning.py @@ -26,6 +26,7 @@ from six.moves.urllib.parse import quote, unquote import test.functional as tf +from swift.common.swob import normalize_etag from swift.common.utils import MD5_OF_EMPTY_STRING, config_true_value from swift.common.middleware.versioned_writes.object_versioning import \ DELETE_MARKER_CONTENT_TYPE @@ -331,6 +332,80 @@ class TestObjectVersioning(TestObjectVersioningBase): # listing, though, we'll only ever have the two entries. self.assertTotalVersions(container, 2) + def test_get_if_match(self): + body = b'data' + oname = Utils.create_name() + obj = self.env.unversioned_container.file(oname) + resp = obj.write(body, return_resp=True) + etag = resp.getheader('etag') + self.assertEqual(md5(body).hexdigest(), normalize_etag(etag)) + + # un-versioned object is cool with with if-match + self.assertEqual(body, obj.read(hdrs={'if-match': etag})) + with self.assertRaises(ResponseError) as cm: + obj.read(hdrs={'if-match': 'not-the-etag'}) + self.assertEqual(412, cm.exception.status) + + v_obj = self.env.container.file(oname) + resp = v_obj.write(body, return_resp=True) + self.assertEqual(resp.getheader('etag'), etag) + + # versioned object is too with with if-match + self.assertEqual(body, v_obj.read(hdrs={ + 'if-match': normalize_etag(etag)})) + # works quoted, too + self.assertEqual(body, v_obj.read(hdrs={ + 'if-match': '"%s"' % normalize_etag(etag)})) + with self.assertRaises(ResponseError) as cm: + v_obj.read(hdrs={'if-match': 'not-the-etag'}) + self.assertEqual(412, cm.exception.status) + + def test_container_acls(self): + if tf.skip3: + raise SkipTest('Username3 not set') + + obj = self.env.container.file(Utils.create_name()) + resp = obj.write(b"data", return_resp=True) + version_id = resp.getheader('x-object-version-id') + self.assertIsNotNone(version_id) + + with self.assertRaises(ResponseError) as cm: + obj.read(hdrs={'X-Auth-Token': self.env.conn3.storage_token}) + self.assertEqual(403, cm.exception.status) + + # Container ACLs work more or less like they always have + self.env.container.update_metadata( + hdrs={'X-Container-Read': self.env.conn3.user_acl}) + self.assertEqual(b"data", obj.read(hdrs={ + 'X-Auth-Token': self.env.conn3.storage_token})) + + # But the version-specifc GET still requires a swift owner + with self.assertRaises(ResponseError) as cm: + obj.read(hdrs={'X-Auth-Token': self.env.conn3.storage_token}, + parms={'version-id': version_id}) + self.assertEqual(403, cm.exception.status) + + # If it's pointing to a symlink that points elsewhere, that still needs + # to be authed + tgt_name = Utils.create_name() + self.env.unversioned_container.file(tgt_name).write(b'link') + sym_tgt_header = quote(unquote('%s/%s' % ( + self.env.unversioned_container.name, tgt_name))) + obj.write(hdrs={'X-Symlink-Target': sym_tgt_header}) + + # So, user1's good... + self.assertEqual(b'link', obj.read()) + # ...but user3 can't + with self.assertRaises(ResponseError) as cm: + obj.read(hdrs={'X-Auth-Token': self.env.conn3.storage_token}) + self.assertEqual(403, cm.exception.status) + + # unless we add the acl to the unversioned_container + self.env.unversioned_container.update_metadata( + hdrs={'X-Container-Read': self.env.conn3.user_acl}) + self.assertEqual(b'link', obj.read( + hdrs={'X-Auth-Token': self.env.conn3.storage_token})) + def _test_overwriting_setup(self, obj_name=None): # sanity container = self.env.container @@ -919,13 +994,13 @@ class TestObjectVersioning(TestObjectVersioningBase): 'Content-Type': 'text/jibberish32' }, return_resp=True) v1_version_id = resp.getheader('x-object-version-id') - v1_etag = resp.getheader('etag') + v1_etag = normalize_etag(resp.getheader('etag')) resp = obj.write(b'version2', hdrs={ 'Content-Type': 'text/jibberish33' }, return_resp=True) v2_version_id = resp.getheader('x-object-version-id') - v2_etag = resp.getheader('etag') + v2_etag = normalize_etag(resp.getheader('etag')) # sanity self.assertEqual(b'version2', obj.read()) @@ -992,7 +1067,7 @@ class TestObjectVersioning(TestObjectVersioningBase): self.assertEqual(b'version1', obj.read()) obj_info = obj.info() self.assertEqual('text/jibberish32', obj_info['content_type']) - self.assertEqual(v1_etag, obj_info['etag']) + self.assertEqual(v1_etag, normalize_etag(obj_info['etag'])) def test_delete_with_version_api_old_object(self): versioned_obj_name = Utils.create_name() @@ -2308,7 +2383,7 @@ class TestSloWithVersioning(TestObjectVersioningBase): expected = { 'bytes': file_info['content_length'], 'content_type': 'application/octet-stream', - 'hash': manifest_info['etag'], + 'hash': normalize_etag(manifest_info['etag']), 'name': 'my-slo-manifest', 'slo_etag': file_info['etag'], 'version_symlink': True, @@ -2340,7 +2415,7 @@ class TestSloWithVersioning(TestObjectVersioningBase): expected = { 'bytes': file_info['content_length'], 'content_type': 'application/octet-stream', - 'hash': manifest_info['etag'], + 'hash': normalize_etag(manifest_info['etag']), 'name': 'my-slo-manifest', 'slo_etag': file_info['etag'], 'version_symlink': True, @@ -2688,16 +2763,11 @@ class TestVersioningContainerTempurl(TestObjectVersioningBase): obj.write(b"version2") # get v2 object (reading from versions container) - # cross container tempurl does not work for container tempurl key - try: - obj.read(parms=get_parms, cfg={'no_auth_token': True}) - except ResponseError as e: - self.assertEqual(e.status, 401) - else: - self.fail('request did not error') - try: - obj.info(parms=get_parms, cfg={'no_auth_token': True}) - except ResponseError as e: - self.assertEqual(e.status, 401) - else: - self.fail('request did not error') + # versioning symlink allows us to bypass the normal + # container-tempurl-key scoping + contents = obj.read(parms=get_parms, cfg={'no_auth_token': True}) + self.assert_status([200]) + self.assertEqual(contents, b"version2") + # HEAD works, too + obj.info(parms=get_parms, cfg={'no_auth_token': True}) + self.assert_status([200]) |