Add filter validation to glance API
Fixes lp: #919250 Change-Id: Ib47d9d107950f14404734b55486996dc0b095f0e
This commit is contained in:
parent
7c2e32511a
commit
3092156ae5
1
.mailmap
1
.mailmap
@ -12,3 +12,4 @@
|
||||
<soren.hansen@rackspace.com> <soren@openstack.org>
|
||||
<jeblair@hp.com> <corvus@gnu.org>
|
||||
<jeblair@hp.com> <james.blair@rackspace.com>
|
||||
<chris@pistoncloud.com> <chris@slicehost.com>
|
||||
|
2
Authors
2
Authors
@ -4,7 +4,7 @@ Andrey Brindeyev <abrindeyev@griddynamics.com>
|
||||
Brian Lamar <brian.lamar@rackspace.com>
|
||||
Brian Waldon <brian.waldon@rackspace.com>
|
||||
Chris Behrens <cbehrens@codestud.com>
|
||||
Christopher MacGown <chris@slicehost.com>
|
||||
Christopher MacGown <chris@pistoncloud.com>
|
||||
Cory Wright <corywright@gmail.com>
|
||||
Dan Prince <dan.prince@rackspace.com>
|
||||
Donal Lafferty <donal.lafferty@citrix.com>
|
||||
|
42
glance/api/v1/filters.py
Normal file
42
glance/api/v1/filters.py
Normal file
@ -0,0 +1,42 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2012, Piston Cloud Computing, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
def validate(filter, value):
|
||||
return FILTER_FUNCTIONS.get(filter, lambda v: True)(value)
|
||||
|
||||
|
||||
def validate_int_in_range(min=0, max=None):
|
||||
def _validator(v):
|
||||
try:
|
||||
if max is None:
|
||||
return min <= int(v)
|
||||
return min <= int(v) <= max
|
||||
except ValueError:
|
||||
return False
|
||||
return _validator
|
||||
|
||||
|
||||
def validate_boolean(v):
|
||||
return v.lower() in ('none', 'true', 'false', '1', '0')
|
||||
|
||||
|
||||
FILTER_FUNCTIONS = {'size_max': validate_int_in_range(), # build validator
|
||||
'size_min': validate_int_in_range(), # build validator
|
||||
'min_ram': validate_int_in_range(), # build validator
|
||||
'protected': validate_boolean,
|
||||
'is_public': validate_boolean, }
|
@ -35,6 +35,7 @@ from webob.exc import (HTTPError,
|
||||
from glance.api import policy
|
||||
import glance.api.v1
|
||||
from glance.api.v1 import controller
|
||||
from glance.api.v1 import filters
|
||||
from glance.common import cfg
|
||||
from glance.common import exception
|
||||
from glance.common import wsgi
|
||||
@ -182,6 +183,7 @@ class Controller(controller.BaseController):
|
||||
:retval dict of parameters that can be used by registry client
|
||||
"""
|
||||
params = {'filters': self._get_filters(req)}
|
||||
|
||||
for PARAM in SUPPORTED_PARAMS:
|
||||
if PARAM in req.str_params:
|
||||
params[PARAM] = req.str_params.get(PARAM)
|
||||
@ -194,12 +196,15 @@ class Controller(controller.BaseController):
|
||||
:param req: the Request object coming from the wsgi layer
|
||||
:retval a dict of key/value filters
|
||||
"""
|
||||
filters = {}
|
||||
query_filters = {}
|
||||
for param in req.str_params:
|
||||
if param in SUPPORTED_FILTERS or param.startswith('property-'):
|
||||
filters[param] = req.str_params.get(param)
|
||||
|
||||
return filters
|
||||
query_filters[param] = req.str_params.get(param)
|
||||
if not filters.validate(param, query_filters[param]):
|
||||
raise HTTPBadRequest('Bad value passed to filter %s '
|
||||
'got %s' % (param,
|
||||
query_filters[param]))
|
||||
return query_filters
|
||||
|
||||
def meta(self, req, id):
|
||||
"""
|
||||
|
@ -925,6 +925,51 @@ class TestApi(functional.FunctionalTest):
|
||||
data = json.loads(content)
|
||||
self.assertEqual(len(data['images']), 0)
|
||||
|
||||
# 18. GET /images with size_min filter
|
||||
# Verify correct images returned with size >= expected
|
||||
params = "size_min=-1"
|
||||
path = "http://%s:%d/v1/images?%s" % (
|
||||
"0.0.0.0", self.api_port, params)
|
||||
response, content = http.request(path, 'GET')
|
||||
self.assertEqual(response.status, 400)
|
||||
self.assertTrue("filter size_min got -1" in content)
|
||||
|
||||
# 19. GET /images with size_min filter
|
||||
# Verify correct images returned with size >= expected
|
||||
params = "size_max=-1"
|
||||
path = "http://%s:%d/v1/images?%s" % (
|
||||
"0.0.0.0", self.api_port, params)
|
||||
response, content = http.request(path, 'GET')
|
||||
self.assertEqual(response.status, 400)
|
||||
self.assertTrue("filter size_max got -1" in content)
|
||||
|
||||
# 20. GET /images with size_min filter
|
||||
# Verify correct images returned with size >= expected
|
||||
params = "min_ram=-1"
|
||||
path = "http://%s:%d/v1/images?%s" % (
|
||||
"0.0.0.0", self.api_port, params)
|
||||
response, content = http.request(path, 'GET')
|
||||
self.assertEqual(response.status, 400)
|
||||
self.assertTrue("Bad value passed to filter min_ram got -1" in content)
|
||||
|
||||
# 21. GET /images with size_min filter
|
||||
# Verify correct images returned with size >= expected
|
||||
params = "protected=imalittleteapot"
|
||||
path = "http://%s:%d/v1/images?%s" % (
|
||||
"0.0.0.0", self.api_port, params)
|
||||
response, content = http.request(path, 'GET')
|
||||
self.assertEqual(response.status, 400)
|
||||
self.assertTrue("protected got imalittleteapot" in content)
|
||||
|
||||
# 22. GET /images with size_min filter
|
||||
# Verify correct images returned with size >= expected
|
||||
params = "is_public=imalittleteapot"
|
||||
path = "http://%s:%d/v1/images?%s" % (
|
||||
"0.0.0.0", self.api_port, params)
|
||||
response, content = http.request(path, 'GET')
|
||||
self.assertEqual(response.status, 400)
|
||||
self.assertTrue("is_public got imalittleteapot" in content)
|
||||
|
||||
self.stop_servers()
|
||||
|
||||
@skip_if_disabled
|
||||
|
Loading…
x
Reference in New Issue
Block a user