diff --git a/awx/api/serializers.py b/awx/api/serializers.py index ad05837d08..30ea61de50 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -3137,7 +3137,8 @@ class LaunchConfigurationBaseSerializer(BaseSerializer): raise serializers.ValidationError(errors) # Model `.save` needs the container dict, not the psuedo fields - attrs['char_prompts'] = mock_obj.char_prompts + if mock_obj.char_prompts: + attrs['char_prompts'] = mock_obj.char_prompts # Insert survey_passwords to track redacted variables if 'extra_data' in attrs: diff --git a/awx/main/models/jobs.py b/awx/main/models/jobs.py index beaceab0a8..4ddeda81a5 100644 --- a/awx/main/models/jobs.py +++ b/awx/main/models/jobs.py @@ -355,7 +355,8 @@ class JobTemplate(UnifiedJobTemplate, JobOptions, SurveyJobTemplateMixin, Resour rejected_data = {} accepted_vars, rejected_vars, errors_dict = self.accept_or_ignore_variables( kwargs.get('extra_vars', {}), - _exclude_errors=exclude_errors) + _exclude_errors=exclude_errors, + extra_passwords=kwargs.get('survey_passwords', {})) if accepted_vars: prompted_data['extra_vars'] = accepted_vars if rejected_vars: diff --git a/awx/main/models/mixins.py b/awx/main/models/mixins.py index 488ea3d609..5e30b29e05 100644 --- a/awx/main/models/mixins.py +++ b/awx/main/models/mixins.py @@ -253,7 +253,7 @@ class SurveyJobTemplateMixin(models.Model): choice_list)) return errors - def _accept_or_ignore_variables(self, data, errors=None, _exclude_errors=()): + def _accept_or_ignore_variables(self, data, errors=None, _exclude_errors=(), extra_passwords=None): survey_is_enabled = (self.survey_enabled and self.survey_spec) extra_vars = data.copy() if errors is None: @@ -265,8 +265,13 @@ class SurveyJobTemplateMixin(models.Model): # Check for data violation of survey rules survey_errors = [] for survey_element in self.survey_spec.get("spec", []): - element_errors = self._survey_element_validation(survey_element, data) key = survey_element.get('variable', None) + if extra_passwords and key in extra_passwords and data.get(key, None): + element_errors = self._survey_element_validation(survey_element, { + key: decrypt_value(get_encryption_key('value', pk=None), data[key]) + }) + else: + element_errors = self._survey_element_validation(survey_element, data) if element_errors: survey_errors += element_errors diff --git a/awx/main/models/unified_jobs.py b/awx/main/models/unified_jobs.py index f1c934b9a3..75e5e8dd05 100644 --- a/awx/main/models/unified_jobs.py +++ b/awx/main/models/unified_jobs.py @@ -441,7 +441,7 @@ class UnifiedJobTemplate(PolymorphicModel, CommonModelNameNotUnique, Notificatio errors[field_name] = [_("Field is not allowed on launch.")] return ({}, kwargs, errors) - def accept_or_ignore_variables(self, data, errors=None, _exclude_errors=()): + def accept_or_ignore_variables(self, data, errors=None, _exclude_errors=(), extra_passwords=None): ''' If subclasses accept any `variables` or `extra_vars`, they should define _accept_or_ignore_variables to place those variables in the accepted dict, @@ -459,7 +459,11 @@ class UnifiedJobTemplate(PolymorphicModel, CommonModelNameNotUnique, Notificatio # SurveyJobTemplateMixin cannot override any methods because of # resolution order, forced by how metaclass processes fields, # thus the need for hasattr check - return self._accept_or_ignore_variables(data, errors, _exclude_errors=_exclude_errors) + if extra_passwords: + return self._accept_or_ignore_variables( + data, errors, _exclude_errors=_exclude_errors, extra_passwords=extra_passwords) + else: + return self._accept_or_ignore_variables(data, errors, _exclude_errors=_exclude_errors) elif data: errors['extra_vars'] = [ _('Variables {list_of_keys} provided, but this template cannot accept variables.'.format(