diff options
-rw-r--r-- | glance/api/v1/images.py | 26 | ||||
-rw-r--r-- | glance/tests/functional/v1/test_copy_to_file.py | 28 | ||||
-rw-r--r-- | glance/tests/unit/v1/test_api.py | 6 |
3 files changed, 41 insertions, 19 deletions
diff --git a/glance/api/v1/images.py b/glance/api/v1/images.py index 15ec91201..3b460272f 100644 --- a/glance/api/v1/images.py +++ b/glance/api/v1/images.py @@ -417,17 +417,20 @@ class Controller(controller.BaseController): """ External sources (as specified via the location or copy-from headers) are supported only over non-local store types, i.e. S3, Swift, HTTP. - Note the absence of file:// for security reasons, see LP bug #942118. + Note the absence of 'file://' for security reasons, see LP bug #942118. + 'swift+config://' is also absent for security reasons, see LP bug + #1334196. If the above constraint is violated, we reject with 400 "Bad Request". """ if source: pieces = urlparse.urlparse(source) schemes = [scheme for scheme in store.get_known_schemes() - if scheme != 'file'] + if scheme != 'file' and scheme != 'swift+config'] for scheme in schemes: if pieces.scheme == scheme: return source - msg = "External sourcing not supported for store %s" % source + msg = ("External sourcing not supported for " + "store '%s'" % pieces.scheme) LOG.debug(msg) raise HTTPBadRequest(explanation=msg, request=req, @@ -743,18 +746,17 @@ class Controller(controller.BaseController): self.pool.spawn_n(self._upload_and_activate, req, image_meta) else: if location: - try: - store.validate_location(location, context=req.context) - except store.BadStoreUri as bse: - raise HTTPBadRequest(explanation=bse.msg, - request=req) - self._validate_image_for_activation(req, image_id, image_meta) image_size_meta = image_meta.get('size') if image_size_meta: - image_size_store = store.get_size_from_backend( - location, - context=req.context) + try: + image_size_store = store.get_size_from_backend( + location, req.context) + except (store.BadStoreUri, store.UnknownScheme) as e: + LOG.debug(utils.exception_to_str(e)) + raise HTTPBadRequest(explanation=e.msg, + request=req, + content_type="text/plain") # NOTE(zhiyan): A returned size of zero usually means # the driver encountered an error. In this case the # size provided by the client will be used as-is. diff --git a/glance/tests/functional/v1/test_copy_to_file.py b/glance/tests/functional/v1/test_copy_to_file.py index ae2c32051..15bb7081c 100644 --- a/glance/tests/functional/v1/test_copy_to_file.py +++ b/glance/tests/functional/v1/test_copy_to_file.py @@ -250,7 +250,33 @@ class TestCopyToFile(functional.FunctionalTest): response, content = http.request(path, 'POST', headers=headers) self.assertEqual(response.status, 400, content) - expected = 'External sourcing not supported for store ' + copy_from + expected = 'External sourcing not supported for store \'file\'' + msg = 'expected "%s" in "%s"' % (expected, content) + self.assertTrue(expected in content, msg) + + self.stop_servers() + + @skip_if_disabled + def test_copy_from_swift_config(self): + """ + Ensure we can't copy from swift+config + """ + self.cleanup() + + self.start_servers(**self.__dict__.copy()) + + # POST /images with public image copied from file (to file) + headers = {'X-Image-Meta-Name': 'copied', + 'X-Image-Meta-disk_format': 'raw', + 'X-Image-Meta-container_format': 'ovf', + 'X-Image-Meta-Is-Public': 'True', + 'X-Glance-API-Copy-From': 'swift+config://xxx'} + path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port) + http = httplib2.Http() + response, content = http.request(path, 'POST', headers=headers) + self.assertEqual(response.status, 400, content) + + expected = 'External sourcing not supported for store \'swift+config\'' msg = 'expected "%s" in "%s"' % (expected, content) self.assertTrue(expected in content, msg) diff --git a/glance/tests/unit/v1/test_api.py b/glance/tests/unit/v1/test_api.py index 8d2d68951..fa7f220e6 100644 --- a/glance/tests/unit/v1/test_api.py +++ b/glance/tests/unit/v1/test_api.py @@ -91,7 +91,6 @@ class TestGlanceAPI(base.IsolatedUnitTest): 'metadata': {}, 'status': 'active'}], 'properties': {}}] self.context = glance.context.RequestContext(is_admin=True) - store.validate_location = mock.Mock() db_api.get_engine() self.destroy_fixtures() self.create_fixtures() @@ -1009,11 +1008,6 @@ class TestGlanceAPI(base.IsolatedUnitTest): def test_add_location_with_invalid_location(self): """Tests creates an image from location and conflict image size""" - - mock_validate_location = mock.Mock() - store.validate_location = mock_validate_location - mock_validate_location.side_effect = store.BadStoreUri() - fixture_headers = {'x-image-meta-store': 'file', 'x-image-meta-disk-format': 'vhd', 'x-image-meta-location': 'http://a/b/c.tar.gz', |