From 6a550f9318e7db8192565d7ead9ec8c01434a859 Mon Sep 17 00:00:00 2001 From: Kay0u Date: Wed, 25 Nov 2020 10:41:20 +0100 Subject: [PATCH 1/4] Add tests for optional args with empty input --- .../tests/test_apps_arguments_parsing.py | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/yunohost/tests/test_apps_arguments_parsing.py b/src/yunohost/tests/test_apps_arguments_parsing.py index 598eb9eec..5edd450d8 100644 --- a/src/yunohost/tests/test_apps_arguments_parsing.py +++ b/src/yunohost/tests/test_apps_arguments_parsing.py @@ -95,6 +95,15 @@ def test_parse_args_in_yunohost_format_string_optional_with_input(): assert _parse_args_in_yunohost_format(answers, questions) == expected_result +def test_parse_args_in_yunohost_format_string_optional_with_empty_input(): + questions = [{"name": "some_string", "ask": "some question", "optional": True, }] + answers = {} + expected_result = OrderedDict({"some_string": ("", "string")}) + + with patch.object(msignals, "prompt", return_value=""): + assert _parse_args_in_yunohost_format(answers, questions) == expected_result + + def test_parse_args_in_yunohost_format_string_optional_with_input_without_ask(): questions = [{"name": "some_string", "optional": True, }] answers = {} @@ -268,6 +277,22 @@ def test_parse_args_in_yunohost_format_password_optional_with_input(): assert _parse_args_in_yunohost_format(answers, questions) == expected_result +def test_parse_args_in_yunohost_format_password_optional_with_empty_input(): + questions = [ + { + "name": "some_password", + "ask": "some question", + "type": "password", + "optional": True, + } + ] + answers = {} + expected_result = OrderedDict({"some_password": ("", "password")}) + + with patch.object(msignals, "prompt", return_value=""): + assert _parse_args_in_yunohost_format(answers, questions) == expected_result + + def test_parse_args_in_yunohost_format_password_optional_with_input_without_ask(): questions = [{"name": "some_password", "type": "password", "optional": True, }] answers = {} @@ -444,6 +469,17 @@ def test_parse_args_in_yunohost_format_path_optional_with_input(): assert _parse_args_in_yunohost_format(answers, questions) == expected_result +def test_parse_args_in_yunohost_format_path_optional_with_empty_input(): + questions = [ + {"name": "some_path", "ask": "some question", "type": "path", "optional": True, } + ] + answers = {} + expected_result = OrderedDict({"some_path": ("", "path")}) + + with patch.object(msignals, "prompt", return_value=""): + assert _parse_args_in_yunohost_format(answers, questions) == expected_result + + def test_parse_args_in_yunohost_format_path_optional_with_input_without_ask(): questions = [{"name": "some_path", "type": "path", "optional": True, }] answers = {} @@ -663,6 +699,22 @@ def test_parse_args_in_yunohost_format_boolean_optional_with_input(): assert _parse_args_in_yunohost_format(answers, questions) == expected_result +def test_parse_args_in_yunohost_format_boolean_optional_with_empty_input(): + questions = [ + { + "name": "some_boolean", + "ask": "some question", + "type": "boolean", + "optional": True, + } + ] + answers = {} + expected_result = OrderedDict({"some_boolean": (0, "boolean")}) + + with patch.object(msignals, "prompt", return_value=""): + assert _parse_args_in_yunohost_format(answers, questions) == expected_result + + def test_parse_args_in_yunohost_format_boolean_optional_with_input_without_ask(): questions = [{"name": "some_boolean", "type": "boolean", "optional": True, }] answers = {} From 93fd101663b84e7f2310c9773c658f8b91724c8e Mon Sep 17 00:00:00 2001 From: Kay0u Date: Wed, 25 Nov 2020 11:14:15 +0100 Subject: [PATCH 2/4] check if password is strong enough only if it's not an optional argument --- src/yunohost/app.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index 076096eef..1d103f00c 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -2498,8 +2498,9 @@ class PasswordArgumentParser(YunoHostArgumentFormatParser): if any(char in question.value for char in self.forbidden_chars): raise YunohostError('pattern_password_app', forbidden_chars=self.forbidden_chars) - from yunohost.utils.password import assert_password_is_strong_enough - assert_password_is_strong_enough('user', question.value) + if not question.optional: + from yunohost.utils.password import assert_password_is_strong_enough + assert_password_is_strong_enough('user', question.value) return super(PasswordArgumentParser, self)._post_parse_value(question) From f0d3d36365e26df52a0f80cd3c2b531855413edb Mon Sep 17 00:00:00 2001 From: Kay0u Date: Wed, 25 Nov 2020 11:41:00 +0100 Subject: [PATCH 3/4] An optional password should be either empty or strong enough --- src/yunohost/app.py | 3 ++- .../tests/test_apps_arguments_parsing.py | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/yunohost/app.py b/src/yunohost/app.py index 1d103f00c..432cabe67 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -2498,7 +2498,8 @@ class PasswordArgumentParser(YunoHostArgumentFormatParser): if any(char in question.value for char in self.forbidden_chars): raise YunohostError('pattern_password_app', forbidden_chars=self.forbidden_chars) - if not question.optional: + # If it's an optional argument the value should be empty or strong enough + if not question.optional or question.value: from yunohost.utils.password import assert_password_is_strong_enough assert_password_is_strong_enough('user', question.value) diff --git a/src/yunohost/tests/test_apps_arguments_parsing.py b/src/yunohost/tests/test_apps_arguments_parsing.py index 5edd450d8..646f7da58 100644 --- a/src/yunohost/tests/test_apps_arguments_parsing.py +++ b/src/yunohost/tests/test_apps_arguments_parsing.py @@ -418,6 +418,24 @@ def test_parse_args_in_yunohost_format_password_strong_enough(): _parse_args_in_yunohost_format({"some_password": "password"}, questions) +def test_parse_args_in_yunohost_format_password_optional_strong_enough(): + questions = [ + { + "name": "some_password", + "ask": "some question", + "type": "password", + "optional": True, + } + ] + + with pytest.raises(YunohostError): + # too short + _parse_args_in_yunohost_format({"some_password": "a"}, questions) + + with pytest.raises(YunohostError): + _parse_args_in_yunohost_format({"some_password": "password"}, questions) + + def test_parse_args_in_yunohost_format_path(): questions = [{"name": "some_path", "type": "path", }] answers = {"some_path": "some_value"} From 698d543c5656b634dbd0fc6e97049de99cfc8aa0 Mon Sep 17 00:00:00 2001 From: Kay0u Date: Wed, 25 Nov 2020 11:47:57 +0100 Subject: [PATCH 4/4] Fix tests --- src/yunohost/tests/test_apps_arguments_parsing.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/yunohost/tests/test_apps_arguments_parsing.py b/src/yunohost/tests/test_apps_arguments_parsing.py index 646f7da58..c8203f2c5 100644 --- a/src/yunohost/tests/test_apps_arguments_parsing.py +++ b/src/yunohost/tests/test_apps_arguments_parsing.py @@ -256,9 +256,9 @@ def test_parse_args_in_yunohost_format_password_input_no_ask(): def test_parse_args_in_yunohost_format_password_no_input_optional(): questions = [{"name": "some_password", "type": "password", "optional": True, }] answers = {} + expected_result = OrderedDict({"some_password": ("", "password")}) - with pytest.raises(YunohostError): - _parse_args_in_yunohost_format(answers, questions) + assert _parse_args_in_yunohost_format(answers, questions) == expected_result def test_parse_args_in_yunohost_format_password_optional_with_input(): @@ -727,7 +727,7 @@ def test_parse_args_in_yunohost_format_boolean_optional_with_empty_input(): } ] answers = {} - expected_result = OrderedDict({"some_boolean": (0, "boolean")}) + expected_result = OrderedDict({"some_boolean": (0, "boolean")}) # default to false with patch.object(msignals, "prompt", return_value=""): assert _parse_args_in_yunohost_format(answers, questions) == expected_result