From 563191bd7bcf86a0ff553d3f0cacf22885517653 Mon Sep 17 00:00:00 2001 From: sslypushenko Date: Tue, 8 Dec 2015 19:07:44 +0200 Subject: [PATCH] Add validataion for uploaded files If user upload yaml of json file, client should validate that file has correct format. Change-Id: I5d9f5966da49cff1f034b17c1bbf8eafed758b31 Closes-bug: #1523130 --- fuelclient/cli/serializers.py | 5 +++-- .../tests/unit/common/test_serializers.py | 7 +++++++ fuelclient/utils.py | 21 +++++++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/fuelclient/cli/serializers.py b/fuelclient/cli/serializers.py index fe34451..9678b40 100644 --- a/fuelclient/cli/serializers.py +++ b/fuelclient/cli/serializers.py @@ -21,6 +21,7 @@ import yaml from fuelclient.cli import error from fuelclient import consts +from fuelclient import utils class Serializer(object): @@ -30,11 +31,11 @@ class Serializer(object): serializers = { "json": { "w": lambda d: json.dumps(d, indent=4), - "r": lambda d: json.loads(d) + "r": utils.safe_deserialize(json.loads) }, "yaml": { "w": lambda d: yaml.safe_dump(d, default_flow_style=False), - "r": lambda d: yaml.load(d) + "r": utils.safe_deserialize(yaml.load) } } diff --git a/fuelclient/tests/unit/common/test_serializers.py b/fuelclient/tests/unit/common/test_serializers.py index 2084276..13163ad 100644 --- a/fuelclient/tests/unit/common/test_serializers.py +++ b/fuelclient/tests/unit/common/test_serializers.py @@ -57,6 +57,13 @@ class TestSerializers(base.UnitTestCase): deserialized = Serializer(format).deserialize(serialized) self.assertEqual(self.DATA, deserialized) + def test_deserialize_fail(self): + + broken_data = '{foo: bar: buzz:}' + for format in ('json', 'yaml'): + self.assertRaises(error.BadDataException, + Serializer(format).deserialize, broken_data) + def test_write_to_path_invalid_file_exception(self): serializer = Serializer('json') mo = mock.mock_open() diff --git a/fuelclient/utils.py b/fuelclient/utils.py index a7dd88c..5dfcaa0 100644 --- a/fuelclient/utils.py +++ b/fuelclient/utils.py @@ -14,6 +14,7 @@ # License for the specific language governing permissions and limitations # under the License. +import functools import glob import io import json @@ -173,3 +174,23 @@ def find_exec(program): candidate = os.path.join(path, program) if os.path.isfile(candidate) and os.access(candidate, os.X_OK): return candidate + + +def safe_deserialize(loader): + """Wrapper for deserializers. + + Exceptions are raising during deserialization will be transformed + into BadDataException + + :param loader: deserializer function + :return: wrapped loader + """ + @functools.wraps(loader) + def wrapper(data): + try: + return loader(data) + except (ValueError, TypeError, yaml.error.YAMLError) as e: + raise error.BadDataException('{0}: {1}' + ''.format(e.__class__.__name__, + six.text_type(e))) + return wrapper