exclude precise metaquery in query field

We use metaquery as a parameter of db func, and valid keys include
db func parameters.

When we parse query filters, the metadata dict is stored as key named
metaquery in kwargs, and we store q.field=foo as key named foo in kwargs.
Then if q.field=metaquery, the kwargs will get the key metaquery but
its type is something, for i.e. string, but not dict. However the db
func expects metaquery to be a dict but gets a string, then 500 is returned

This patch returns a 400 error for such case, and removes 'metaquery'
from valid keys in error message to avoid misleading end user.

Change-Id: I430717e71a6586d63f267baee29bb71ef8c9eac1
Closes-Bug: #1426466
This commit is contained in:
ZhiQiang Fan 2015-02-28 12:24:16 +08:00
parent 348ecb0861
commit e056f6f312
4 changed files with 27 additions and 14 deletions

View File

@ -104,8 +104,6 @@ def validate_query(query, db_func, internal_keys=None,
:param allow_timestamps: defines whether the timestamp-based constraint is
applicable for this query or not
:returns: valid query keys the db_func supported
:raises InvalidInput: if an operator is not supported for a given field
:raises InvalidInput: if timestamp constraints are allowed, but
search_offset was included without timestamp constraint
@ -127,6 +125,7 @@ def validate_query(query, db_func, internal_keys=None,
internal_keys += internal_timestamp_keys
valid_keys += ['timestamp', 'search_offset']
internal_keys.append('self')
internal_keys.append('metaquery')
valid_keys = set(valid_keys) - set(internal_keys)
translation = {'user_id': 'user',
'project_id': 'project',
@ -168,7 +167,6 @@ def validate_query(query, db_func, internal_keys=None,
msg = ("unrecognized field in query: %s, "
"valid keys: %s") % (query, sorted(valid_keys))
raise wsme.exc.UnknownArgument(key, msg)
return valid_keys
def _validate_timestamp_fields(query, field_name, operator_list,
@ -214,8 +212,7 @@ def _validate_timestamp_fields(query, field_name, operator_list,
def query_to_kwargs(query, db_func, internal_keys=None,
allow_timestamps=True):
internal_keys = internal_keys or []
valid_keys = validate_query(query, db_func, internal_keys=internal_keys,
validate_query(query, db_func, internal_keys=internal_keys,
allow_timestamps=allow_timestamps)
query = sanitize_query(query, db_func)
translation = {'user_id': 'user',
@ -247,7 +244,7 @@ def query_to_kwargs(query, db_func, internal_keys=None,
key = translation.get(i.field, i.field)
kwargs[key] = i.value
if metaquery and 'metaquery' in valid_keys:
if metaquery and 'metaquery' in inspect.getargspec(db_func)[0]:
kwargs['metaquery'] = metaquery
if stamp:
kwargs.update(_get_query_timestamps(stamp))

View File

@ -374,6 +374,23 @@ class TestListMeters(v2.FunctionalTest,
}
}], data)
def test_list_with_field_metaquery(self):
def _helper(url):
resp = self.get_json(url,
q=[{'field':
'metaquery',
'op': 'eq',
'value': 'cow',
}],
expect_errors=True)
self.assertEqual(400, resp.status_code)
expected = ('Unknown argument: "metaquery": '
'unrecognized field in query')
self.assertIn(expected, resp.json['error_message']['faultstring'])
_helper('/samples')
_helper('/meters/meter.test')
def test_list_meters_metadata_query(self):
data = self.get_json('/meters/meter.test',
q=[{'field': 'metadata.tag',

View File

@ -367,9 +367,8 @@ class TestQueryToKwArgs(tests_base.BaseTestCase):
exc = self.assertRaises(
wsme.exc.UnknownArgument,
utils.query_to_kwargs, q, storage.SampleFilter.__init__)
valid_keys = ['message_id', 'metaquery', 'meter', 'project',
'resource', 'search_offset', 'source', 'timestamp',
'user']
valid_keys = ['message_id', 'meter', 'project', 'resource',
'search_offset', 'source', 'timestamp', 'user']
msg = ("unrecognized field in query: %s, "
"valid keys: %s") % (q, valid_keys)
expected_exc = wsme.exc.UnknownArgument('abc', msg)
@ -382,8 +381,7 @@ class TestQueryToKwArgs(tests_base.BaseTestCase):
exc = self.assertRaises(
wsme.exc.UnknownArgument,
utils.query_to_kwargs, q, storage_base.Connection.get_meters)
valid_keys = ['metaquery', 'pagination', 'project', 'resource',
'source', 'user']
valid_keys = ['pagination', 'project', 'resource', 'source', 'user']
msg = ("unrecognized field in query: %s, "
"valid keys: %s") % (q, valid_keys)
expected_exc = wsme.exc.UnknownArgument('abc', msg)
@ -396,7 +394,7 @@ class TestQueryToKwArgs(tests_base.BaseTestCase):
exc = self.assertRaises(
wsme.exc.UnknownArgument,
utils.query_to_kwargs, q, storage_base.Connection.get_resources)
valid_keys = ['metaquery', 'pagination', 'project', 'resource',
valid_keys = ['pagination', 'project', 'resource',
'search_offset', 'source', 'timestamp', 'user']
msg = ("unrecognized field in query: %s, "
"valid keys: %s") % (q, valid_keys)

View File

@ -74,7 +74,8 @@ tests:
url: /v2/samples?q.field=harpoon&q.value=cow&q.op=eq
status: 400
response_strings:
- metaquery
- timestamp
- project
- unrecognized field in query
- name: list samples with metaquery field