Return BadRequest for 4 byte unicode characters

Various create and update apis are returning 500 error
when you pass 4 byte unicode characters in the request.

This patch fixes the issue to return HTTP 400 Bad Request.

1. md-namespace-create
2. md-namespace-update
3. md-property-create
4. md-property-update
5. md-object-create
6. md-object-update
7. md-tag-create
8. md-tag-update

APIImpact: For all of the above APIs, it will return 400 error instead
of 500 if user passes 4 byte unicode characters in the request.

Closes-Bug: #1570789
Change-Id:  I8233cf95310aa2671ebc62995c58208024fc38a3
This commit is contained in:
bhagyashris 2016-03-24 10:01:59 +00:00
parent bf56e4e40c
commit 6e10f1b4c9
7 changed files with 132 additions and 1 deletions

View File

@ -162,7 +162,10 @@ class NamespaceController(object):
**self._to_property_dict(name, value)
))
prop_repo.add(new_property_type)
except exception.Invalid as e:
msg = (_("Couldn't create metadata namespace: %s")
% encodeutils.exception_to_unicode(e))
raise webob.exc.HTTPBadRequest(explanation=msg)
except exception.Forbidden as e:
self._cleanup_namespace(ns_repo, namespace, namespace_created)
LOG.debug("User not permitted to create metadata namespace")
@ -285,6 +288,10 @@ class NamespaceController(object):
ns_obj.owner = (
wsme_utils._get_value(user_ns.owner) or req.context.owner)
updated_namespace = namespace_repo.save(ns_obj)
except exception.Invalid as e:
msg = (_("Couldn't update metadata namespace: %s")
% encodeutils.exception_to_unicode(e))
raise webob.exc.HTTPBadRequest(explanation=msg)
except exception.Forbidden as e:
LOG.debug("User not permitted to update metadata namespace "
"'%s'", namespace)

View File

@ -61,6 +61,10 @@ class MetadefObjectsController(object):
LOG.debug("User not permitted to create metadata object within "
"'%s' namespace", namespace)
raise webob.exc.HTTPForbidden(explanation=e.msg)
except exception.Invalid as e:
msg = (_("Couldn't create metadata object: %s")
% encodeutils.exception_to_unicode(e))
raise webob.exc.HTTPBadRequest(explanation=msg)
except exception.NotFound as e:
raise webob.exc.HTTPNotFound(explanation=e.msg)
except exception.Duplicate as e:
@ -132,6 +136,10 @@ class MetadefObjectsController(object):
metadef_object.properties = wsme_utils._get_value(
metadata_object.properties)
updated_metadata_obj = meta_repo.save(metadef_object)
except exception.Invalid as e:
msg = (_("Couldn't update metadata object: %s")
% encodeutils.exception_to_unicode(e))
raise webob.exc.HTTPBadRequest(explanation=msg)
except exception.Forbidden as e:
LOG.debug("User not permitted to update metadata object '%s' "
"within '%s' namespace ", object_name, namespace)

View File

@ -123,6 +123,10 @@ class NamespacePropertiesController(object):
LOG.debug("User not permitted to create metadata property within "
"'%s' namespace", namespace)
raise webob.exc.HTTPForbidden(explanation=e.msg)
except exception.Invalid as e:
msg = (_("Couldn't create metadata property: %s")
% encodeutils.exception_to_unicode(e))
raise webob.exc.HTTPBadRequest(explanation=msg)
except exception.NotFound as e:
raise webob.exc.HTTPNotFound(explanation=e.msg)
except exception.Duplicate as e:
@ -140,6 +144,10 @@ class NamespacePropertiesController(object):
db_property_type.name = property_type.name
db_property_type.schema = (self._to_dict(property_type))['schema']
updated_property_type = prop_repo.save(db_property_type)
except exception.Invalid as e:
msg = (_("Couldn't update metadata property: %s")
% encodeutils.exception_to_unicode(e))
raise webob.exc.HTTPBadRequest(explanation=msg)
except exception.Forbidden as e:
LOG.debug("User not permitted to update metadata property '%s' "
"within '%s' namespace", property_name, namespace)

View File

@ -56,6 +56,10 @@ class TagsController(object):
namespace=namespace,
**tag_name_as_dict)
tag_repo.add(new_meta_tag)
except exception.Invalid as e:
msg = (_("Couldn't create metadata tag: %s")
% encodeutils.exception_to_unicode(e))
raise webob.exc.HTTPBadRequest(explanation=msg)
except exception.Forbidden as e:
LOG.debug("User not permitted to create metadata tag within "
"'%s' namespace", namespace)
@ -152,6 +156,10 @@ class TagsController(object):
metadef_tag.name = wsme_utils._get_value(
metadata_tag.name)
updated_metadata_tag = meta_repo.save(metadef_tag)
except exception.Invalid as e:
msg = (_("Couldn't update metadata tag: %s")
% encodeutils.exception_to_unicode(e))
raise webob.exc.HTTPBadRequest(explanation=msg)
except exception.Forbidden as e:
LOG.debug("User not permitted to update metadata tag '%s' "
"within '%s' namespace", tag_name, namespace)

View File

@ -1107,6 +1107,7 @@ def _metadef_delete_namespace_content(get_func, key, context, namespace_name):
@log_call
@utils.no_4byte_params
def metadef_namespace_create(context, values):
"""Create a namespace object"""
global DATA
@ -1140,6 +1141,7 @@ def metadef_namespace_create(context, values):
@log_call
@utils.no_4byte_params
def metadef_namespace_update(context, namespace_id, values):
"""Update a namespace object"""
global DATA
@ -1327,6 +1329,7 @@ def metadef_object_get_all(context, namespace_name):
@log_call
@utils.no_4byte_params
def metadef_object_create(context, namespace_name, values):
"""Create a metadef object"""
global DATA
@ -1367,6 +1370,7 @@ def metadef_object_create(context, namespace_name, values):
@log_call
@utils.no_4byte_params
def metadef_object_update(context, namespace_name, object_id, values):
"""Update a metadef object"""
global DATA
@ -1450,6 +1454,7 @@ def metadef_property_count(context, namespace_name):
@log_call
@utils.no_4byte_params
def metadef_property_create(context, namespace_name, values):
"""Create a metadef property"""
global DATA
@ -1493,6 +1498,7 @@ def metadef_property_create(context, namespace_name, values):
@log_call
@utils.no_4byte_params
def metadef_property_update(context, namespace_name, property_id, values):
"""Update a metadef property"""
global DATA
@ -1785,6 +1791,7 @@ def metadef_tag_get_all(context, namespace_name, filters=None, marker=None,
@log_call
@utils.no_4byte_params
def metadef_tag_create(context, namespace_name, values):
"""Create a metadef tag"""
global DATA
@ -1867,6 +1874,7 @@ def metadef_tag_create_tags(context, namespace_name, tag_list):
@log_call
@utils.no_4byte_params
def metadef_tag_update(context, namespace_name, id, values):
"""Update a metadef tag"""
global DATA

View File

@ -1591,12 +1591,14 @@ def metadef_namespace_get(context, namespace_name, session=None):
context, namespace_name, session)
@utils.no_4byte_params
def metadef_namespace_create(context, values, session=None):
"""Create a namespace or raise if it already exists."""
session = session or get_session()
return metadef_namespace_api.create(context, values, session)
@utils.no_4byte_params
def metadef_namespace_update(context, namespace_id, namespace_dict,
session=None):
"""Update a namespace or raise if it does not exist or not visible"""
@ -1626,6 +1628,7 @@ def metadef_object_get(context, namespace_name, object_name, session=None):
context, namespace_name, object_name, session)
@utils.no_4byte_params
def metadef_object_create(context, namespace_name, object_dict,
session=None):
"""Create a metadata-schema object or raise if it already exists."""
@ -1634,6 +1637,7 @@ def metadef_object_create(context, namespace_name, object_dict,
context, namespace_name, object_dict, session)
@utils.no_4byte_params
def metadef_object_update(context, namespace_name, object_id, object_dict,
session=None):
"""Update an object or raise if it does not exist or not visible."""
@ -1678,6 +1682,7 @@ def metadef_property_get(context, namespace_name,
context, namespace_name, property_name, session)
@utils.no_4byte_params
def metadef_property_create(context, namespace_name, property_dict,
session=None):
"""Create a metadef property or raise if it already exists."""
@ -1686,6 +1691,7 @@ def metadef_property_create(context, namespace_name, property_dict,
context, namespace_name, property_dict, session)
@utils.no_4byte_params
def metadef_property_update(context, namespace_name, property_id,
property_dict, session=None):
"""Update an object or raise if it does not exist or not visible."""
@ -1788,6 +1794,7 @@ def metadef_tag_get(context, namespace_name, name, session=None):
context, namespace_name, name, session)
@utils.no_4byte_params
def metadef_tag_create(context, namespace_name, tag_dict,
session=None):
"""Create a metadata-schema tag or raise if it already exists."""
@ -1804,6 +1811,7 @@ def metadef_tag_create_tags(context, namespace_name, tag_list,
context, namespace_name, tag_list, session)
@utils.no_4byte_params
def metadef_tag_update(context, namespace_name, id, tag_dict,
session=None):
"""Update an tag or raise if it does not exist or not visible."""

View File

@ -606,6 +606,16 @@ class TestMetadefsControllers(base.IsolatedUnitTest):
namespace = self.namespace_controller.show(request, NAMESPACE4)
self.assertEqual(NAMESPACE4, namespace.namespace)
def test_namespace_create_with_4byte_character(self):
request = unit_test_utils.get_fake_request()
namespace = namespaces.Namespace()
namespace.namespace = u'\U0001f693'
self.assertRaises(webob.exc.HTTPBadRequest,
self.namespace_controller.create, request,
namespace)
def test_namespace_create_duplicate(self):
request = unit_test_utils.get_fake_request()
@ -810,6 +820,16 @@ class TestMetadefsControllers(base.IsolatedUnitTest):
self.assertRaises(webob.exc.HTTPNotFound,
self.namespace_controller.show, request, NAMESPACE1)
def test_namespace_update_with_4byte_character(self):
request = unit_test_utils.get_fake_request()
namespace = self.namespace_controller.show(request, NAMESPACE1)
namespace.namespace = u'\U0001f693'
self.assertRaises(webob.exc.HTTPBadRequest,
self.namespace_controller.update, request,
namespace, NAMESPACE1)
def test_namespace_update_name_conflict(self):
request = unit_test_utils.get_fake_request()
namespace = self.namespace_controller.show(request, NAMESPACE1)
@ -964,6 +984,18 @@ class TestMetadefsControllers(base.IsolatedUnitTest):
self.assertEqual('string', property.type)
self.assertEqual('title', property.title)
def test_property_create_with_4byte_character(self):
request = unit_test_utils.get_fake_request()
property = properties.PropertyType()
property.name = u'\U0001f693'
property.type = 'string'
property.title = 'title'
self.assertRaises(webob.exc.HTTPBadRequest,
self.property_controller.create,
request, NAMESPACE1, property)
def test_property_create_with_operators(self):
request = unit_test_utils.get_fake_request()
@ -1131,6 +1163,19 @@ class TestMetadefsControllers(base.IsolatedUnitTest):
PROPERTY1, property)
self.assertNotificationsLog([])
def test_property_update_with_4byte_character(self):
request = unit_test_utils.get_fake_request(tenant=TENANT3)
property = self.property_controller.show(request, NAMESPACE3,
PROPERTY1)
property.name = u'\U0001f693'
property.type = 'string'
property.title = 'title'
self.assertRaises(webob.exc.HTTPBadRequest,
self.property_controller.update, request,
NAMESPACE3, PROPERTY1, property)
def test_property_update_non_existing(self):
request = unit_test_utils.get_fake_request(tenant=TENANT3)
@ -1313,6 +1358,18 @@ class TestMetadefsControllers(base.IsolatedUnitTest):
NAMESPACE1)
self.assertNotificationsLog([])
def test_object_create_with_4byte_character(self):
request = unit_test_utils.get_fake_request()
object = objects.MetadefObject()
object.name = u'\U0001f693'
object.required = []
object.properties = {}
self.assertRaises(webob.exc.HTTPBadRequest,
self.object_controller.create, request,
object, NAMESPACE1)
def test_object_create_non_existing_namespace(self):
request = unit_test_utils.get_fake_request()
@ -1416,6 +1473,16 @@ class TestMetadefsControllers(base.IsolatedUnitTest):
object = self.object_controller.show(request, NAMESPACE1, OBJECT2)
self.assertEqual(OBJECT2, object.name)
def test_object_update_with_4byte_character(self):
request = unit_test_utils.get_fake_request()
object = self.object_controller.show(request, NAMESPACE1, OBJECT1)
object.name = u'\U0001f693'
self.assertRaises(webob.exc.HTTPBadRequest,
self.object_controller.update, request,
object, NAMESPACE1, OBJECT1)
def test_object_update_conflict(self):
request = unit_test_utils.get_fake_request(tenant=TENANT3)
@ -1745,6 +1812,13 @@ class TestMetadefsControllers(base.IsolatedUnitTest):
tag = self.tag_controller.show(request, NAMESPACE1, TAG2)
self.assertEqual(TAG2, tag.name)
def test_tag_create_with_4byte_character(self):
request = unit_test_utils.get_fake_request()
self.assertRaises(webob.exc.HTTPBadRequest,
self.tag_controller.create,
request, NAMESPACE1, u'\U0001f693')
def test_tag_create_tags(self):
request = unit_test_utils.get_fake_request()
@ -1872,6 +1946,16 @@ class TestMetadefsControllers(base.IsolatedUnitTest):
tag = self.tag_controller.show(request, NAMESPACE1, TAG2)
self.assertEqual(TAG2, tag.name)
def test_tag_update_with_4byte_character(self):
request = unit_test_utils.get_fake_request()
tag = self.tag_controller.show(request, NAMESPACE1, TAG1)
tag.name = u'\U0001f693'
self.assertRaises(webob.exc.HTTPBadRequest,
self.tag_controller.update, request, tag,
NAMESPACE1, TAG1)
def test_tag_update_conflict(self):
request = unit_test_utils.get_fake_request(tenant=TENANT3)