From 8b4f955a7ad356bc15f0ff450fc0dea42b2451af Mon Sep 17 00:00:00 2001 From: Ryan Selden Date: Fri, 15 Jul 2016 17:52:28 +0000 Subject: [PATCH] Properly validate metadef objects Metadef objects were not being properly validated when they had 1 or more properties. This adds validation for any and all properties attached to a metadef object being created. Additionally, invalid metadef objects resulted in a 500 internal server error rather than a 400 bad request, this fixes that so that the error is useful. Change-Id: I6e6d97d54660710cf829a603b0741a23d248146b Closes-Bug: #1413209 Co-Authored-By: Rebecca Finn --- glance/api/v2/metadef_objects.py | 5 +++++ glance/api/v2/metadef_properties.py | 7 ++++--- .../tests/unit/v2/test_metadef_resources.py | 21 +++++++++++++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/glance/api/v2/metadef_objects.py b/glance/api/v2/metadef_objects.py index c42d69f394..efb931ffda 100644 --- a/glance/api/v2/metadef_objects.py +++ b/glance/api/v2/metadef_objects.py @@ -23,6 +23,7 @@ from wsme.rest import json from glance.api import policy from glance.api.v2 import metadef_namespaces as namespaces +import glance.api.v2.metadef_properties as properties from glance.api.v2.model.metadef_object import MetadefObject from glance.api.v2.model.metadef_object import MetadefObjects from glance.common import exception @@ -250,6 +251,10 @@ class RequestDeserializer(wsgi.JSONRequestDeserializer): self._check_allowed(body) try: self.schema.validate(body) + if 'properties' in body: + for propertyname in body['properties']: + schema = properties.get_schema(require_name=False) + schema.validate(body['properties'][propertyname]) except exception.InvalidObject as e: raise webob.exc.HTTPBadRequest(explanation=e.msg) metadata_object = json.fromjson(MetadefObject, body) diff --git a/glance/api/v2/metadef_properties.py b/glance/api/v2/metadef_properties.py index c8685e2c86..7385f1c18f 100644 --- a/glance/api/v2/metadef_properties.py +++ b/glance/api/v2/metadef_properties.py @@ -283,12 +283,13 @@ def _get_base_properties(): return base_def['property']['additionalProperties']['properties'] -def get_schema(): +def get_schema(require_name=True): definitions = _get_base_definitions() properties = _get_base_properties() mandatory_attrs = PropertyType.get_mandatory_attrs() - # name is required attribute when use as single property type - mandatory_attrs.append('name') + if require_name: + # name is required attribute when use as single property type + mandatory_attrs.append('name') schema = glance.schema.Schema( 'property', properties, diff --git a/glance/tests/unit/v2/test_metadef_resources.py b/glance/tests/unit/v2/test_metadef_resources.py index 1b45c168eb..7563545c64 100644 --- a/glance/tests/unit/v2/test_metadef_resources.py +++ b/glance/tests/unit/v2/test_metadef_resources.py @@ -1344,6 +1344,27 @@ class TestMetadefsControllers(base.IsolatedUnitTest): self.assertEqual([], object.required) self.assertEqual({}, object.properties) + def test_object_create_invalid_properties(self): + request = unit_test_utils.get_fake_request('/metadefs/namespaces/' + 'Namespace3/' + 'objects') + body = { + "name": "My Object", + "description": "object1 description.", + "properties": { + "property1": { + "type": "integer", + "title": "property", + "description": "property description", + "test-key": "test-value", + } + } + } + request.body = jsonutils.dump_as_bytes(body) + self.assertRaises(webob.exc.HTTPBadRequest, + self.deserializer.create, + request) + def test_object_create_overlimit_name(self): request = unit_test_utils.get_fake_request('/metadefs/namespaces/' 'Namespace3/'