Merge "Restrict sort_keys for stack lists"

This commit is contained in:
Jenkins 2013-12-03 23:36:21 +00:00 committed by Gerrit Code Review
commit e1c2b622fa
2 changed files with 35 additions and 9 deletions

View File

@ -271,6 +271,21 @@ def stack_get_all_by_owner_id(context, owner_id):
return results
def _filter_sort_keys(sort_keys, whitelist):
'''Returns an array containing only whitelisted keys
:param sort_keys: an array of strings
:param whitelist: an array of allowed strings
:returns: filtered list of sort keys
'''
if not sort_keys:
return []
elif not isinstance(sort_keys, list):
sort_keys = [sort_keys]
return [key for key in sort_keys if key in whitelist]
def _paginate_query(context, query, model, limit=None, sort_keys=None,
marker=None, sort_dir=None):
default_sort_keys = ['created_at']
@ -278,8 +293,6 @@ def _paginate_query(context, query, model, limit=None, sort_keys=None,
sort_keys = default_sort_keys
if not sort_dir:
sort_dir = 'desc'
elif not isinstance(sort_keys, list):
sort_keys = [sort_keys]
# This assures the order of the stacks will always be the same
# even for sort_key values that are not unique in the database
@ -311,9 +324,15 @@ def stack_get_all_by_tenant(context, limit=None, sort_keys=None, marker=None,
if filters is None:
filters = {}
allowed_sort_keys = [models.Stack.name.key,
models.Stack.status.key,
models.Stack.created_at.key,
models.Stack.updated_at.key]
filtered_keys = _filter_sort_keys(sort_keys, allowed_sort_keys)
query = _query_stack_get_all_by_tenant(context)
query = db_filters.exact_filter(query, models.Stack, filters)
return _paginate_query(context, query, models.Stack, limit, sort_keys,
return _paginate_query(context, query, models.Stack, limit, filtered_keys,
marker, sort_dir).all()

View File

@ -16,6 +16,7 @@ from datetime import timedelta
import fixtures
from json import loads
from json import dumps
import mock
import mox
@ -280,6 +281,18 @@ class SqlAlchemyTest(HeatTestCase):
self.assertEqual(stacks[1].id, st_db[1].id)
self.assertEqual(stacks[2].id, st_db[2].id)
@mock.patch.object(db_api.utils, 'paginate_query')
def test_stack_get_all_by_tenant_filters_sort_keys(self, mock_paginate):
sort_keys = ['name', 'status', 'created_at', 'updated_at', 'username']
st_db = db_api.stack_get_all_by_tenant(self.ctx,
sort_keys=sort_keys)
args, _ = mock_paginate.call_args
used_sort_keys = set(args[3])
expected_keys = set(['name', 'status', 'created_at',
'updated_at', 'id'])
self.assertEqual(expected_keys, used_sort_keys)
def test_stack_get_all_by_tenant_marker(self):
stacks = [self._setup_test_stack('stack', x)[1] for x in UUIDs]
@ -294,12 +307,6 @@ class SqlAlchemyTest(HeatTestCase):
st_db = db_api.stack_get_all_by_tenant(self.ctx, marker=uuid)
self.assertEqual(3, len(st_db))
def test_stack_get_all_by_tenant_handles_invalid_sort_key(self):
self.assertRaises(exception.Invalid,
db_api.stack_get_all_by_tenant,
self.ctx,
sort_keys=['foo'])
def test_stack_get_all_by_tenant_doesnt_mutate_sort_keys(self):
stacks = [self._setup_test_stack('stack', x)[1] for x in UUIDs]
sort_keys = ['id']