From 76ca8c184bed7aa706ac6ef1010c3f4ebf08f7f0 Mon Sep 17 00:00:00 2001 From: Mark McLoughlin Date: Wed, 12 Sep 2012 12:51:01 +0100 Subject: Improve entity validation in volumes APIs Fixes bug #1048565 Use the new Controller.is_valid_body() helper to validate the entity body in various volumes related POST/PUT handlers and return 422 as appropriate. (Cherry picks commit dcecb586 from Cinder and adds similar fixes for the volumes bits in the compute API) Change-Id: I04127972981522c1ed81903893396c4f9665bcd3 --- nova/api/openstack/compute/contrib/volumes.py | 14 +++++++------- nova/api/openstack/compute/contrib/volumetypes.py | 9 +++------ .../openstack/volume/contrib/types_extra_specs.py | 21 +++++++++------------ nova/api/openstack/volume/contrib/types_manage.py | 7 ++----- nova/api/openstack/volume/snapshots.py | 6 +++--- nova/api/openstack/volume/volumes.py | 7 +++---- 6 files changed, 27 insertions(+), 37 deletions(-) (limited to 'nova/api') diff --git a/nova/api/openstack/compute/contrib/volumes.py b/nova/api/openstack/compute/contrib/volumes.py index 7194f64e3..9940e3050 100644 --- a/nova/api/openstack/compute/contrib/volumes.py +++ b/nova/api/openstack/compute/contrib/volumes.py @@ -160,7 +160,7 @@ class CreateDeserializer(CommonDeserializer): return {'body': {'volume': volume}} -class VolumeController(object): +class VolumeController(wsgi.Controller): """The Volumes API controller for the OpenStack API.""" def __init__(self): @@ -221,7 +221,7 @@ class VolumeController(object): context = req.environ['nova.context'] authorize(context) - if not body: + if not self.is_valid_body(body, 'volume'): raise exc.HTTPUnprocessableEntity() vol = body['volume'] @@ -323,7 +323,7 @@ class VolumeAttachmentsTemplate(xmlutil.TemplateBuilder): return xmlutil.MasterTemplate(root, 1) -class VolumeAttachmentController(object): +class VolumeAttachmentController(wsgi.Controller): """The volume attachment API controller for the OpenStack API. A child resource of the server. Note that we use the volume id @@ -381,7 +381,7 @@ class VolumeAttachmentController(object): context = req.environ['nova.context'] authorize(context) - if not body: + if not self.is_valid_body(body, 'volumeAttachment'): raise exc.HTTPUnprocessableEntity() volume_id = body['volumeAttachment']['volumeId'] @@ -525,7 +525,7 @@ class SnapshotsTemplate(xmlutil.TemplateBuilder): return xmlutil.MasterTemplate(root, 1) -class SnapshotController(object): +class SnapshotController(wsgi.Controller): """The Volumes API controller for the OpenStack API.""" def __init__(self): @@ -585,8 +585,8 @@ class SnapshotController(object): context = req.environ['nova.context'] authorize(context) - if not body: - return exc.HTTPUnprocessableEntity() + if not self.is_valid_body(body, 'snapshot'): + raise exc.HTTPUnprocessableEntity() snapshot = body['snapshot'] volume_id = snapshot['volume_id'] diff --git a/nova/api/openstack/compute/contrib/volumetypes.py b/nova/api/openstack/compute/contrib/volumetypes.py index 2711c45d7..036e3ff42 100644 --- a/nova/api/openstack/compute/contrib/volumetypes.py +++ b/nova/api/openstack/compute/contrib/volumetypes.py @@ -53,7 +53,7 @@ class VolumeTypesTemplate(xmlutil.TemplateBuilder): return xmlutil.MasterTemplate(root, 1) -class VolumeTypesController(object): +class VolumeTypesController(wsgi.Controller): """ The volume types API controller for the OpenStack API """ @wsgi.serializers(xml=VolumeTypesTemplate) @@ -69,13 +69,10 @@ class VolumeTypesController(object): context = req.environ['nova.context'] authorize(context) - if not body or body == "": - raise exc.HTTPUnprocessableEntity() - - vol_type = body.get('volume_type', None) - if vol_type is None or vol_type == "": + if not self.is_valid_body(body, 'volume_type'): raise exc.HTTPUnprocessableEntity() + vol_type = body['volume_type'] name = vol_type.get('name', None) specs = vol_type.get('extra_specs', {}) diff --git a/nova/api/openstack/volume/contrib/types_extra_specs.py b/nova/api/openstack/volume/contrib/types_extra_specs.py index d70e24538..2e993ad8a 100644 --- a/nova/api/openstack/volume/contrib/types_extra_specs.py +++ b/nova/api/openstack/volume/contrib/types_extra_specs.py @@ -50,7 +50,7 @@ class VolumeTypeExtraSpecTemplate(xmlutil.TemplateBuilder): return xmlutil.MasterTemplate(root, 1) -class VolumeTypeExtraSpecsController(object): +class VolumeTypeExtraSpecsController(wsgi.Controller): """ The volume type extra specs API controller for the OpenStack API """ def _get_extra_specs(self, context, type_id): @@ -60,11 +60,6 @@ class VolumeTypeExtraSpecsController(object): specs_dict[key] = value return dict(extra_specs=specs_dict) - def _check_body(self, body): - if not body: - expl = _('No Request Body') - raise webob.exc.HTTPBadRequest(explanation=expl) - def _check_type(self, context, type_id): try: volume_types.get_volume_type(context, type_id) @@ -83,12 +78,13 @@ class VolumeTypeExtraSpecsController(object): def create(self, req, type_id, body=None): context = req.environ['nova.context'] authorize(context) + + if not self.is_valid_body(body, 'extra_specs'): + raise webob.exc.HTTPUnprocessableEntity() + self._check_type(context, type_id) - self._check_body(body) - specs = body.get('extra_specs') - if not isinstance(specs, dict): - expl = _('Malformed extra specs') - raise webob.exc.HTTPBadRequest(explanation=expl) + + specs = body['extra_specs'] db.volume_type_extra_specs_update_or_create(context, type_id, specs) @@ -98,8 +94,9 @@ class VolumeTypeExtraSpecsController(object): def update(self, req, type_id, id, body=None): context = req.environ['nova.context'] authorize(context) + if not body: + raise webob.exc.HTTPUnprocessableEntity() self._check_type(context, type_id) - self._check_body(body) if not id in body: expl = _('Request body and URI mismatch') raise webob.exc.HTTPBadRequest(explanation=expl) diff --git a/nova/api/openstack/volume/contrib/types_manage.py b/nova/api/openstack/volume/contrib/types_manage.py index ff21174c3..e68093ce8 100644 --- a/nova/api/openstack/volume/contrib/types_manage.py +++ b/nova/api/openstack/volume/contrib/types_manage.py @@ -42,13 +42,10 @@ class VolumeTypesManageController(wsgi.Controller): context = req.environ['nova.context'] authorize(context) - if not body or body == "": - raise webob.exc.HTTPUnprocessableEntity() - - vol_type = body.get('volume_type', None) - if vol_type is None or vol_type == "": + if not self.is_valid_body(body, 'volume_type'): raise webob.exc.HTTPUnprocessableEntity() + vol_type = body['volume_type'] name = vol_type.get('name', None) specs = vol_type.get('extra_specs', {}) diff --git a/nova/api/openstack/volume/snapshots.py b/nova/api/openstack/volume/snapshots.py index 755398369..fa070e2e3 100644 --- a/nova/api/openstack/volume/snapshots.py +++ b/nova/api/openstack/volume/snapshots.py @@ -85,7 +85,7 @@ class SnapshotsTemplate(xmlutil.TemplateBuilder): return xmlutil.MasterTemplate(root, 1) -class SnapshotsController(object): +class SnapshotsController(wsgi.Controller): """The Volumes API controller for the OpenStack API.""" def __init__(self): @@ -145,8 +145,8 @@ class SnapshotsController(object): """Creates a new snapshot.""" context = req.environ['nova.context'] - if not body: - return exc.HTTPUnprocessableEntity() + if not self.is_valid_body(body, 'snapshot'): + raise exc.HTTPUnprocessableEntity() snapshot = body['snapshot'] volume_id = snapshot['volume_id'] diff --git a/nova/api/openstack/volume/volumes.py b/nova/api/openstack/volume/volumes.py index e83030945..f69ef0a21 100644 --- a/nova/api/openstack/volume/volumes.py +++ b/nova/api/openstack/volume/volumes.py @@ -192,7 +192,7 @@ class CreateDeserializer(CommonDeserializer): return {'body': {'volume': volume}} -class VolumeController(object): +class VolumeController(wsgi.Controller): """The Volumes API controller for the OpenStack API.""" def __init__(self): @@ -253,11 +253,10 @@ class VolumeController(object): @wsgi.deserializers(xml=CreateDeserializer) def create(self, req, body): """Creates a new volume.""" - context = req.environ['nova.context'] - - if not body: + if not self.is_valid_body(body, 'volume'): raise exc.HTTPUnprocessableEntity() + context = req.environ['nova.context'] volume = body['volume'] kwargs = {} -- cgit