From 7efacb69aa046b1e5be2b3dc5c8928c0afe91d23 Mon Sep 17 00:00:00 2001 From: Rebeccah Date: Mon, 30 Sep 2019 17:16:08 -0400 Subject: [PATCH] added in parsing for multiple choice and multiselect, which either takes a string, splits it up, and then eliminates any extra newlines, or just accepts alist. Extra newlines are sanitized out. Signed-off-by: Rebeccah --- awx/api/views/__init__.py | 32 ++++++++++++++++++++++++++++---- awx/main/models/mixins.py | 4 ++-- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/awx/api/views/__init__.py b/awx/api/views/__init__.py index 4c4ff93cac..383c7aeee9 100644 --- a/awx/api/views/__init__.py +++ b/awx/api/views/__init__.py @@ -2568,10 +2568,34 @@ class JobTemplateSurveySpec(GenericAPIView): return Response(dict(error=_( "The {min_or_max} limit in survey question {idx} expected to be integer." ).format(min_or_max=key, **context))) - if qtype in ['multiplechoice', 'multiselect'] and 'choices' not in survey_item: - return Response(dict(error=_( - "Survey question {idx} of type {survey_item[type]} must specify choices.".format(**context) - ))) + # if it's a multiselect or multiple choice, it must have coices listed + # choices and defualts must come in as strings seperated by /n characters. + if qtype == 'multiselect' or qtype == 'multiplechoice': + if 'choices' in survey_item: + if isinstance(survey_item['choices'], str): + survey_item['choices'] = '\n'.join(choice for choice in survey_item['choices'].splitlines() if choice.strip() != '') + else: + return Response(dict(error=_( + "Survey question {idx} of type {survey_item[type]} must specify choices.".format(**context) + ))) + # If there is a default string split it out removing extra /n characters. + # Note: There can still be extra newline characters added in the API, these are sanitized out using .strip() + if 'default' in survey_item: + if isinstance(survey_item['default'], str): + survey_item['default'] = '\n'.join(choice for choice in survey_item['default'].splitlines() if choice.strip() != '') + list_of_defaults = survey_item['default'].splitlines() + else: + list_of_defaults = survey_item['default'] + if qtype == 'multiplechoice': + # Multiplechoice types should only have 1 default. + if len(list_of_defaults) > 1: + return Response(dict(error=_( + "Multiple Choice (Single Select) can only have one default value.".format(**context) + ))) + if any(item not in survey_item['choices'] for item in list_of_defaults): + return Response(dict(error=_( + "Default choice must be answered from the choices listed.".format(**context) + ))) # Process encryption substitution if ("default" in survey_item and isinstance(survey_item['default'], str) and diff --git a/awx/main/models/mixins.py b/awx/main/models/mixins.py index 913750930c..e51807f47b 100644 --- a/awx/main/models/mixins.py +++ b/awx/main/models/mixins.py @@ -253,7 +253,7 @@ class SurveyJobTemplateMixin(models.Model): else: choice_list = copy(survey_element['choices']) if isinstance(choice_list, str): - choice_list = choice_list.split('\n') + choice_list = [choice for choice in choice_list.splitlines() if choice.strip() != ''] for val in data[survey_element['variable']]: if val not in choice_list: errors.append("Value %s for '%s' expected to be one of %s." % (val, survey_element['variable'], @@ -261,7 +261,7 @@ class SurveyJobTemplateMixin(models.Model): elif survey_element['type'] == 'multiplechoice': choice_list = copy(survey_element['choices']) if isinstance(choice_list, str): - choice_list = choice_list.split('\n') + choice_list = [choice for choice in choice_list.splitlines() if choice.strip() != ''] if survey_element['variable'] in data: if data[survey_element['variable']] not in choice_list: errors.append("Value %s for '%s' expected to be one of %s." % (data[survey_element['variable']],