Allow the prefixes like "eq:" and "neq:" in the custom REST UUID type
* Fields of type UUID with a filter prefix are denied because they don't match the UUID string format. E.g. "eq:6c07a453-c5e1-4bbe-97ed-3cb77b4f55ff" will throw an InputException. This patch makes the change that allows to have: "eq:" "neq:" "gt:" "gte:" "lt:" "lte:" "has:" "in:" "nin:" prefixes in a value of such fields. Closes-Bug: #1792875 Change-Id: I26667a82ec768c858f0282124864e377d8cf39f4 Signed-off-by: ali <ali.abdelal@nokia.com>
This commit is contained in:
parent
bc46b29f01
commit
6948e50de8
@ -13,6 +13,7 @@
|
||||
# limitations under the License.
|
||||
import json
|
||||
|
||||
from mistral.utils import filter_utils
|
||||
from oslo_utils import uuidutils
|
||||
import six
|
||||
from wsme import types as wtypes
|
||||
@ -77,12 +78,13 @@ class UuidType(wtypes.UserType):
|
||||
|
||||
@staticmethod
|
||||
def validate(value):
|
||||
if not uuidutils.is_uuid_like(value):
|
||||
_, data = filter_utils.extract_filter_type_and_value(value)
|
||||
if not uuidutils.is_uuid_like(data):
|
||||
raise exc.InputException(
|
||||
"Expected a uuid but received %s." % value
|
||||
"Expected a uuid but received %s." % data
|
||||
)
|
||||
|
||||
return value
|
||||
return data
|
||||
|
||||
@staticmethod
|
||||
def frombasetype(value):
|
||||
|
46
mistral/tests/unit/actions/test_types.py
Normal file
46
mistral/tests/unit/actions/test_types.py
Normal file
@ -0,0 +1,46 @@
|
||||
# Copyright 2017 - Nokia Networks
|
||||
#
|
||||
# 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.
|
||||
|
||||
from mistral.api.controllers.v2 import types
|
||||
from mistral import exceptions as exc
|
||||
from mistral.tests.unit import base
|
||||
from mistral.utils import filter_utils
|
||||
|
||||
|
||||
class TestTypesController(base.BaseTest):
|
||||
|
||||
base_id = '88888888-4444-4444-4444-777777755555'
|
||||
uuid_type = types.uuid
|
||||
|
||||
def test_uuid_type(self):
|
||||
self.uuid_type.validate(self.base_id)
|
||||
|
||||
def test_uuid_type_wit_invalid_format(self):
|
||||
self.assertRaises(exc.InputException,
|
||||
self.uuid_type.validate, 'invalid_format')
|
||||
self.assertRaises(exc.InputException,
|
||||
self.uuid_type.validate, '44-231-454-542123')
|
||||
|
||||
def test_uuid_with_filters(self):
|
||||
for filter_type in filter_utils.ALL:
|
||||
value = '{}{}'.format(filter_type + ':', self.base_id)
|
||||
if filter_type.startswith((filter_utils.IN, filter_utils.NOT_IN)):
|
||||
self.assertRaises(exc.InputException,
|
||||
self.uuid_type.validate, value)
|
||||
else:
|
||||
self.uuid_type.validate(value)
|
||||
|
||||
def test_uuid_type_with_invalid_prefix(self):
|
||||
value = 'invalid:{}'.format(self.base_id)
|
||||
self.assertRaises(exc.InputException, self.uuid_type.validate, value)
|
@ -1,4 +1,5 @@
|
||||
# Copyright 2016 NEC Corporation. All rights reserved.
|
||||
# Copyright 2019 Nokia Software. 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
|
||||
@ -14,6 +15,20 @@
|
||||
|
||||
import six
|
||||
|
||||
EQUALS = 'eq'
|
||||
NOT_EQUAL = 'neq'
|
||||
LESS_THAN = 'lt'
|
||||
LESS_THAN_EQUALS = 'lte'
|
||||
GREATER_THAN = 'gt'
|
||||
GREATER_THAN_EQUALS = 'gte'
|
||||
IN = 'in'
|
||||
NOT_IN = 'nin'
|
||||
HAS = 'has'
|
||||
|
||||
ALL = (GREATER_THAN_EQUALS, GREATER_THAN,
|
||||
LESS_THAN_EQUALS, HAS, NOT_EQUAL,
|
||||
LESS_THAN, IN, EQUALS, NOT_IN)
|
||||
|
||||
|
||||
def create_filters_from_request_params(none_values=None, **params):
|
||||
"""Create filters from REST request parameters.
|
||||
@ -28,7 +43,7 @@ def create_filters_from_request_params(none_values=None, **params):
|
||||
for column, data in params.items():
|
||||
if (data is None and column in none_values) or data is not None:
|
||||
if isinstance(data, six.string_types):
|
||||
f_type, value = _extract_filter_type_and_value(data)
|
||||
f_type, value = extract_filter_type_and_value(data)
|
||||
|
||||
create_or_update_filter(column, value, f_type, filters)
|
||||
else:
|
||||
@ -58,7 +73,7 @@ def create_or_update_filter(column, value, filter_type='eq', _filter=None):
|
||||
return _filter
|
||||
|
||||
|
||||
def _extract_filter_type_and_value(data):
|
||||
def extract_filter_type_and_value(data):
|
||||
"""Extract filter type and its value from the data.
|
||||
|
||||
:param data: REST parameter value from which filter type and
|
||||
@ -66,35 +81,20 @@ def _extract_filter_type_and_value(data):
|
||||
'filter_type:value'.
|
||||
:return: filter type and value.
|
||||
"""
|
||||
if data.startswith("in:"):
|
||||
value = list(six.text_type(data[3:]).split(","))
|
||||
filter_type = 'in'
|
||||
elif data.startswith("nin:"):
|
||||
value = list(six.text_type(data[4:]).split(","))
|
||||
filter_type = 'nin'
|
||||
elif data.startswith("neq:"):
|
||||
value = six.text_type(data[4:])
|
||||
filter_type = 'neq'
|
||||
elif data.startswith("gt:"):
|
||||
value = six.text_type(data[3:])
|
||||
filter_type = 'gt'
|
||||
elif data.startswith("gte:"):
|
||||
value = six.text_type(data[4:])
|
||||
filter_type = 'gte'
|
||||
elif data.startswith("lt:"):
|
||||
value = six.text_type(data[3:])
|
||||
filter_type = 'lt'
|
||||
elif data.startswith("lte:"):
|
||||
value = six.text_type(data[4:])
|
||||
filter_type = 'lte'
|
||||
elif data.startswith("eq:"):
|
||||
value = six.text_type(data[3:])
|
||||
filter_type = 'eq'
|
||||
elif data.startswith("has:"):
|
||||
value = six.text_type(data[4:])
|
||||
filter_type = 'has'
|
||||
if has_filters(data):
|
||||
filter_type, value = data.split(':', 1)
|
||||
value = six.text_type(value)
|
||||
if data.startswith((IN, NOT_IN)):
|
||||
value = list(value.split(","))
|
||||
else:
|
||||
value = data
|
||||
filter_type = 'eq'
|
||||
filter_type = EQUALS
|
||||
|
||||
return filter_type, value
|
||||
|
||||
|
||||
def has_filters(value):
|
||||
for filter_type in ALL:
|
||||
if value.startswith(filter_type + ':'):
|
||||
return True
|
||||
return False
|
||||
|
Loading…
Reference in New Issue
Block a user