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.
|
# limitations under the License.
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
from mistral.utils import filter_utils
|
||||||
from oslo_utils import uuidutils
|
from oslo_utils import uuidutils
|
||||||
import six
|
import six
|
||||||
from wsme import types as wtypes
|
from wsme import types as wtypes
|
||||||
@ -77,12 +78,13 @@ class UuidType(wtypes.UserType):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def validate(value):
|
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(
|
raise exc.InputException(
|
||||||
"Expected a uuid but received %s." % value
|
"Expected a uuid but received %s." % data
|
||||||
)
|
)
|
||||||
|
|
||||||
return value
|
return data
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def frombasetype(value):
|
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 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
|
# 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
|
# not use this file except in compliance with the License. You may obtain
|
||||||
@ -14,6 +15,20 @@
|
|||||||
|
|
||||||
import six
|
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):
|
def create_filters_from_request_params(none_values=None, **params):
|
||||||
"""Create filters from REST request parameters.
|
"""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():
|
for column, data in params.items():
|
||||||
if (data is None and column in none_values) or data is not None:
|
if (data is None and column in none_values) or data is not None:
|
||||||
if isinstance(data, six.string_types):
|
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)
|
create_or_update_filter(column, value, f_type, filters)
|
||||||
else:
|
else:
|
||||||
@ -58,7 +73,7 @@ def create_or_update_filter(column, value, filter_type='eq', _filter=None):
|
|||||||
return _filter
|
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.
|
"""Extract filter type and its value from the data.
|
||||||
|
|
||||||
:param data: REST parameter value from which filter type and
|
:param data: REST parameter value from which filter type and
|
||||||
@ -66,35 +81,20 @@ def _extract_filter_type_and_value(data):
|
|||||||
'filter_type:value'.
|
'filter_type:value'.
|
||||||
:return: filter type and value.
|
:return: filter type and value.
|
||||||
"""
|
"""
|
||||||
if data.startswith("in:"):
|
if has_filters(data):
|
||||||
value = list(six.text_type(data[3:]).split(","))
|
filter_type, value = data.split(':', 1)
|
||||||
filter_type = 'in'
|
value = six.text_type(value)
|
||||||
elif data.startswith("nin:"):
|
if data.startswith((IN, NOT_IN)):
|
||||||
value = list(six.text_type(data[4:]).split(","))
|
value = list(value.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'
|
|
||||||
else:
|
else:
|
||||||
value = data
|
value = data
|
||||||
filter_type = 'eq'
|
filter_type = EQUALS
|
||||||
|
|
||||||
return filter_type, value
|
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