From 0b617d7538eb5ff95823cff26aba51e6bc9edb4f Mon Sep 17 00:00:00 2001 From: AlanCoding Date: Tue, 1 Aug 2017 19:42:00 -0400 Subject: [PATCH] treat vault_credential same as credential for JT launch --- awx/api/views.py | 26 +++++++++---------- awx/main/models/jobs.py | 1 + .../functional/test_rbac_job_templates.py | 19 ++++++++++++++ 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/awx/api/views.py b/awx/api/views.py index e4085cdf19..65a8f3fdb9 100644 --- a/awx/api/views.py +++ b/awx/api/views.py @@ -2776,10 +2776,10 @@ class JobTemplateLaunch(RetrieveAPIView, GenericAPIView): obj = self.get_object() ignored_fields = {} - if 'credential' not in request.data and 'credential_id' in request.data: - request.data['credential'] = request.data['credential_id'] - if 'inventory' not in request.data and 'inventory_id' in request.data: - request.data['inventory'] = request.data['inventory_id'] + for fd in ('credential', 'vault_credential', 'inventory'): + id_fd = '{}_id'.format(fd) + if fd not in request.data and id_fd in request.data: + request.data[fd] = request.data[id_fd] if get_request_version(self.request) == 1: # TODO: remove in 3.3 extra_creds = request.data.pop('extra_credentials', None) @@ -2795,15 +2795,15 @@ class JobTemplateLaunch(RetrieveAPIView, GenericAPIView): prompted_fields = _accepted_or_ignored[0] ignored_fields.update(_accepted_or_ignored[1]) - if 'credential' in prompted_fields and prompted_fields['credential'] != getattrd(obj, 'credential.pk', None): - new_credential = get_object_or_400(Credential, pk=get_pk_from_dict(prompted_fields, 'credential')) - if request.user not in new_credential.use_role: - raise PermissionDenied() - - if 'inventory' in prompted_fields and prompted_fields['inventory'] != getattrd(obj, 'inventory.pk', None): - new_inventory = get_object_or_400(Inventory, pk=get_pk_from_dict(prompted_fields, 'inventory')) - if request.user not in new_inventory.use_role: - raise PermissionDenied() + for fd, model in ( + ('credential', Credential), + ('vault_credential', Credential), + ('inventory', Inventory)): + if fd in prompted_fields and prompted_fields[fd] != getattrd(obj, '{}.pk'.format(fd), None): + new_res = get_object_or_400(model, pk=get_pk_from_dict(prompted_fields, fd)) + use_role = getattr(new_res, 'use_role') + if request.user not in use_role: + raise PermissionDenied() for cred in prompted_fields.get('extra_credentials', []): new_credential = get_object_or_400(Credential, pk=cred) diff --git a/awx/main/models/jobs.py b/awx/main/models/jobs.py index e01e08b21b..ed326f5d4f 100644 --- a/awx/main/models/jobs.py +++ b/awx/main/models/jobs.py @@ -377,6 +377,7 @@ class JobTemplate(UnifiedJobTemplate, JobOptions, SurveyJobTemplateMixin, Resour verbosity=self.ask_verbosity_on_launch, inventory=self.ask_inventory_on_launch, credential=self.ask_credential_on_launch, + vault_credential=self.ask_credential_on_launch, extra_credentials=self.ask_credential_on_launch, ) diff --git a/awx/main/tests/functional/test_rbac_job_templates.py b/awx/main/tests/functional/test_rbac_job_templates.py index 312c1fa8b2..cad2ad816b 100644 --- a/awx/main/tests/functional/test_rbac_job_templates.py +++ b/awx/main/tests/functional/test_rbac_job_templates.py @@ -96,6 +96,25 @@ def test_job_template_access_org_admin(jt_linked, rando): assert access.can_delete(jt_linked) +@pytest.mark.django_db +def test_job_template_extra_credentials_prompts_access( + rando, post, inventory, project, machine_credential, vault_credential): + jt = JobTemplate.objects.create( + name = 'test-jt', + project = project, + playbook = 'helloworld.yml', + inventory = inventory, + credential = machine_credential, + ask_credential_on_launch = True + ) + jt.execute_role.members.add(rando) + r = post( + reverse('api:job_template_launch', kwargs={'version': 'v2', 'pk': jt.id}), + {'vault_credential': vault_credential.pk}, rando + ) + assert r.status_code == 403 + + @pytest.mark.django_db class TestJobTemplateCredentials: