From a753af1e4a6b4b42dc4a0b4238f4b0ca6175c2d7 Mon Sep 17 00:00:00 2001 From: Davanum Srinivas Date: Thu, 7 Mar 2013 22:17:56 -0500 Subject: [PATCH] Do not accept invalid keys in quota-update Check if the keys are valid and respond with HTTPBadRequest when they are not. Found a spot in wsgi where we were trying to use xml namespace as data for the payload, we need to skip them when converting to json Fix for LP# 1064864 Change-Id: Ic4a68047adf3ccf2dbac669b1b66d73bfe4d58de --- nova/api/openstack/compute/contrib/quotas.py | 43 ++++++++++++------- nova/api/openstack/wsgi.py | 3 +- .../openstack/compute/contrib/test_quotas.py | 11 +++++ 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/nova/api/openstack/compute/contrib/quotas.py b/nova/api/openstack/compute/contrib/quotas.py index ddfe5bf0861d..c7fe87a1ff76 100644 --- a/nova/api/openstack/compute/contrib/quotas.py +++ b/nova/api/openstack/compute/contrib/quotas.py @@ -88,23 +88,34 @@ class QuotaSetsController(object): context = req.environ['nova.context'] authorize_update(context) project_id = id + + bad_keys = [] for key in body['quota_set'].keys(): - if key in QUOTAS: - try: - value = int(body['quota_set'][key]) - except (ValueError, TypeError): - LOG.warn(_("Quota for %s should be integer.") % key) - # NOTE(hzzhoushaoyu): Do not prevent valid value to be - # updated. If raise BadRequest, some may be updated and - # others may be not. - continue - self._validate_quota_limit(value) - try: - db.quota_update(context, project_id, key, value) - except exception.ProjectQuotaNotFound: - db.quota_create(context, project_id, key, value) - except exception.AdminRequired: - raise webob.exc.HTTPForbidden() + if (key not in QUOTAS and + key != 'tenant_id' and + key != 'id'): + bad_keys.append(key) + + if len(bad_keys) > 0: + msg = _("Bad key(s) %s in quota_set") % ",".join(bad_keys) + raise webob.exc.HTTPBadRequest(explanation=msg) + + for key in body['quota_set'].keys(): + try: + value = int(body['quota_set'][key]) + except (ValueError, TypeError): + LOG.warn(_("Quota for %s should be integer.") % key) + # NOTE(hzzhoushaoyu): Do not prevent valid value to be + # updated. If raise BadRequest, some may be updated and + # others may be not. + continue + self._validate_quota_limit(value) + try: + db.quota_update(context, project_id, key, value) + except exception.ProjectQuotaNotFound: + db.quota_create(context, project_id, key, value) + except exception.AdminRequired: + raise webob.exc.HTTPForbidden() return {'quota_set': self._get_quotas(context, id)} @wsgi.serializers(xml=QuotaTemplate) diff --git a/nova/api/openstack/wsgi.py b/nova/api/openstack/wsgi.py index 5b9900f729f3..9d74306e7977 100644 --- a/nova/api/openstack/wsgi.py +++ b/nova/api/openstack/wsgi.py @@ -238,7 +238,8 @@ class XMLDeserializer(TextDeserializer): else: result = dict() for attr in node.attributes.keys(): - result[attr] = node.attributes[attr].nodeValue + if not attr.startswith("xmlns"): + result[attr] = node.attributes[attr].nodeValue for child in node.childNodes: if child.nodeType != node.TEXT_NODE: result[child.nodeName] = self._from_xml_node(child, diff --git a/nova/tests/api/openstack/compute/contrib/test_quotas.py b/nova/tests/api/openstack/compute/contrib/test_quotas.py index 0616c4628874..f9eab2b9471c 100644 --- a/nova/tests/api/openstack/compute/contrib/test_quotas.py +++ b/nova/tests/api/openstack/compute/contrib/test_quotas.py @@ -132,6 +132,17 @@ class QuotaSetsTest(test.TestCase): self.assertRaises(webob.exc.HTTPForbidden, self.controller.update, req, 'update_me', body) + def test_quotas_update_invalid_key(self): + body = {'quota_set': {'instances2': -2, 'cores': -2, + 'ram': -2, 'floating_ips': -2, + 'metadata_items': -2, 'injected_files': -2, + 'injected_file_content_bytes': -2}} + + req = fakes.HTTPRequest.blank('/v2/fake4/os-quota-sets/update_me', + use_admin_context=True) + self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update, + req, 'update_me', body) + def test_quotas_update_invalid_limit(self): body = {'quota_set': {'instances': -2, 'cores': -2, 'ram': -2, 'floating_ips': -2,