diff --git a/awx/api/views.py b/awx/api/views.py index 366ee29957..00a862dd23 100644 --- a/awx/api/views.py +++ b/awx/api/views.py @@ -2851,13 +2851,8 @@ class JobTemplateSurveySpec(GenericAPIView): if not feature_enabled('surveys'): raise LicenseForbids(_('Your license does not allow ' 'adding surveys.')) - survey_spec = obj.survey_spec - for pos, field in enumerate(survey_spec.get('spec', [])): - if field.get('type') == 'password': - if 'default' in field and field['default']: - field['default'] = '$encrypted$' - return Response(survey_spec) + return Response(obj.display_survey_spec()) def post(self, request, *args, **kwargs): obj = self.get_object() diff --git a/awx/main/models/mixins.py b/awx/main/models/mixins.py index 9bdf7194d7..1186797b09 100644 --- a/awx/main/models/mixins.py +++ b/awx/main/models/mixins.py @@ -240,6 +240,17 @@ class SurveyJobTemplateMixin(models.Model): errors += self._survey_element_validation(survey_element, data) return errors + def display_survey_spec(self): + ''' + Hide encrypted default passwords in survey specs + ''' + survey_spec = self.survey_spec.copy() if self.survey_spec else {} + for field in survey_spec.get('spec', []): + if field.get('type') == 'password': + if 'default' in field and field['default']: + field['default'] = '$encrypted$' + return survey_spec + class SurveyJobMixin(models.Model): class Meta: diff --git a/awx/main/tests/unit/api/test_views.py b/awx/main/tests/unit/api/test_views.py index a2532a75d7..68ba754d48 100644 --- a/awx/main/tests/unit/api/test_views.py +++ b/awx/main/tests/unit/api/test_views.py @@ -7,7 +7,6 @@ from collections import namedtuple from awx.api.views import ( ApiVersionRootView, JobTemplateLabelList, - JobTemplateSurveySpec, InventoryInventorySourcesUpdate, InventoryHostsList, HostInsights, @@ -80,19 +79,6 @@ class TestJobTemplateLabelList: assert mixin_unattach.called_with(mock_request, None, None) -class TestJobTemplateSurveySpec(object): - @mock.patch('awx.api.views.feature_enabled', lambda feature: True) - def test_get_password_type(self, mocker, mock_response_new): - JobTemplate = namedtuple('JobTemplate', 'survey_spec') - obj = JobTemplate(survey_spec={'spec':[{'type': 'password', 'default': 'my_default'}]}) - with mocker.patch.object(JobTemplateSurveySpec, 'get_object', return_value=obj): - view = JobTemplateSurveySpec() - response = view.get(mocker.MagicMock()) - assert response == mock_response_new - # which there was a better way to do this! - assert response.call_args[0][1]['spec'][0]['default'] == '$encrypted$' - - class TestInventoryInventorySourcesUpdate: @pytest.mark.parametrize("can_update, can_access, is_source, is_up_on_proj, expected", [ diff --git a/awx/main/tests/unit/models/test_survey_models.py b/awx/main/tests/unit/models/test_survey_models.py index d40d6f4800..d283c57081 100644 --- a/awx/main/tests/unit/models/test_survey_models.py +++ b/awx/main/tests/unit/models/test_survey_models.py @@ -94,6 +94,15 @@ def test_update_kwargs_survey_invalid_default(survey_spec_factory): assert json.loads(defaulted_extra_vars['extra_vars'])['var2'] == 2 +@pytest.mark.survey +def test_display_survey_spec_encrypts_default(survey_spec_factory): + spec = survey_spec_factory('var2') + spec['spec'][0]['type'] = 'password' + spec['spec'][0]['default'] = 'some-default' + jt = JobTemplate(name="test-jt", survey_spec=spec, survey_enabled=True) + assert jt.display_survey_spec()['spec'][0]['default'] == '$encrypted$' + + @pytest.mark.survey @pytest.mark.parametrize("question_type,default,min,max,expect_use,expect_value", [ ("text", "", 0, 0, True, ''), # default used