From 0d4c1a42453c0c8c2ac3f1fa2b96125b5126dcc4 Mon Sep 17 00:00:00 2001 From: Chris Church Date: Sun, 26 Apr 2015 12:28:39 -0400 Subject: [PATCH] Add tests for job template launch with invalid/inactive credential, fix bug that allowed an inactive credential to be passed if the job template already had an active credential. --- awx/api/serializers.py | 19 +++++++++---------- awx/main/tests/jobs/jobs_monolithic.py | 25 ++++++++++++++++++------- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/awx/api/serializers.py b/awx/api/serializers.py index 617bc48517..5bf92ab2b3 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -1706,21 +1706,22 @@ class JobLaunchSerializer(BaseSerializer): read_only_fields = ('ask_variables_on_launch',) write_only_fields = ('credential','extra_vars',) - def cred_valid(self, obj): - if obj.credential is not None: - return obj.credential.active - return False - def get_credential_needed_to_start(self, obj): - if obj: - return not self.cred_valid(obj) - return True + return not (obj and obj.credential and obj.credential.active) def get_survey_enabled(self, obj): if obj: return obj.survey_enabled and 'spec' in obj.survey_spec return False + def validate_credential(self, attrs, source): + obj = self.context.get('obj') + credential = attrs.get(source, None) or (obj and obj.credential) + if not credential or not credential.active: + raise serializers.ValidationError('Credential not provided') + attrs[source] = credential + return attrs + def validate_extra_vars(self, attrs, source): extra_vars = attrs.get(source, {}) if not extra_vars: @@ -1746,8 +1747,6 @@ class JobLaunchSerializer(BaseSerializer): def validate(self, attrs): obj = self.context.get('obj') - if not self.cred_valid(obj) and (attrs.get('credential', None) is None and attrs.get('credential_id', None) is None): - raise serializers.ValidationError(dict(errors=["Credential not provided"])) if obj.job_type != PERM_INVENTORY_SCAN and (obj.project is None or not obj.project.active): raise serializers.ValidationError(dict(errors=["Job Template Project is missing or undefined"])) if obj.inventory is None or not obj.inventory.active: diff --git a/awx/main/tests/jobs/jobs_monolithic.py b/awx/main/tests/jobs/jobs_monolithic.py index 34c3511e99..65d0e7aa66 100644 --- a/awx/main/tests/jobs/jobs_monolithic.py +++ b/awx/main/tests/jobs/jobs_monolithic.py @@ -492,9 +492,14 @@ class JobTemplateTest(BaseJobTestMixin, django.test.TestCase): j = Job.objects.get(pk=response['job']) self.assertTrue(j.status == 'new') - # Can't launch a job template without a credential defined + # Can't launch a job template without a credential defined (or if we + # pass an invalid/inactive credential value). with self.current_user(self.user_sue): response = self.post(no_launch_url, {}, expect=400) + response = self.post(no_launch_url, {'credential': 0}, expect=400) + response = self.post(no_launch_url, {'credential': 'one'}, expect=400) + self.cred_doug.mark_inactive() + response = self.post(no_launch_url, {'credential': self.cred_doug.pk}, expect=400) # Job Templates without projects can not be launched with self.current_user(self.user_sue): @@ -503,9 +508,9 @@ class JobTemplateTest(BaseJobTestMixin, django.test.TestCase): jt = JobTemplate.objects.get(pk=response['id']) jt.project = None jt.save() - launch_url = reverse('api:job_template_launch', - args=(response['id'],)) - self.post(launch_url, {}, expect=400) + launch_url2 = reverse('api:job_template_launch', + args=(response['id'],)) + self.post(launch_url2, {}, expect=400) # Job Templates without inventory can not be launched with self.current_user(self.user_sue): @@ -514,9 +519,15 @@ class JobTemplateTest(BaseJobTestMixin, django.test.TestCase): jt = JobTemplate.objects.get(pk=response['id']) jt.inventory = None jt.save() - launch_url = reverse('api:job_template_launch', - args=(response['id'],)) - self.post(launch_url, {}, expect=400) + launch_url3 = reverse('api:job_template_launch', + args=(response['id'],)) + self.post(launch_url3, {}, expect=400) + + # Job Templates with deleted credentials cannot be launched. + self.cred_sue.mark_inactive() + with self.current_user(self.user_sue): + response = self.post(launch_url, {}, expect=400) + class JobTest(BaseJobTestMixin, django.test.TestCase):