From 02b31674c27937f77f9da487e42a05d4d58b8a94 Mon Sep 17 00:00:00 2001 From: Matthew Jones Date: Tue, 27 Jan 2015 15:11:54 -0500 Subject: [PATCH] Fix up some serious issues posting new surveys and deleting them by non-super users. Also fix up some issues checking can_change for job templates for operations like PATCH where not all of the data points will be submitted --- awx/api/views.py | 3 +++ awx/main/access.py | 9 ++++++++- awx/main/tests/jobs.py | 30 ++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/awx/api/views.py b/awx/api/views.py index 7f7f072d31..feb9184678 100644 --- a/awx/api/views.py +++ b/awx/api/views.py @@ -1493,6 +1493,7 @@ class JobTemplateSchedulesList(SubListCreateAPIView): class JobTemplateSurveySpec(GenericAPIView): model = JobTemplate + parent_model = JobTemplate # FIXME: Add serializer class to define fields in OPTIONS request! def get(self, request, *args, **kwargs): @@ -1537,6 +1538,8 @@ class JobTemplateSurveySpec(GenericAPIView): def delete(self, request, *args, **kwargs): obj = self.get_object() + if not request.user.can_access(self.model, 'delete', obj): + raise PermissionDenied() obj.survey_spec = {} obj.save() return Response() diff --git a/awx/main/access.py b/awx/main/access.py index 1363498a4f..b43c18dc1a 100644 --- a/awx/main/access.py +++ b/awx/main/access.py @@ -1005,7 +1005,14 @@ class JobTemplateAccess(BaseAccess): return dep_access and has_perm def can_change(self, obj, data): - return self.can_read(obj) and self.can_add(data) + data_for_change = data + if data is not None: + data_for_change = dict(data) + for required_field in ('credential', 'cloud_credential', 'inventory', 'project'): + required_obj = getattr(obj, required_field, None) + if required_field not in data_for_change and required_obj is not None: + data_for_change[required_field] = required_obj.pk + return self.can_read(obj) and self.can_add(data_for_change) def can_delete(self, obj): add_obj = dict(credential=obj.credential.id if obj.credential is not None else None, diff --git a/awx/main/tests/jobs.py b/awx/main/tests/jobs.py index a532d7f27c..c4ed43ac71 100644 --- a/awx/main/tests/jobs.py +++ b/awx/main/tests/jobs.py @@ -1021,6 +1021,36 @@ class JobTemplateTest(BaseJobTestMixin, django.test.TestCase): # Nested json self.post(launch_url, dict(extra_vars=dict(json_answer=dict(test="val", num=1), reqd_answer="foo")), expect=202) + # Bob can access and update the survey because he's an org-admin + with self.current_user(self.user_bob): + self.post(url, json.loads(TEST_SURVEY_REQUIREMENTS), expect=200) + + # Chuck is the lead engineer and has the right permissions to edit it also + with self.current_user(self.user_chuck): + self.post(url, json.loads(TEST_SURVEY_REQUIREMENTS), expect=200) + + # Doug shouldn't be able to access this playbook + with self.current_user(self.user_doug): + self.post(url, json.loads(TEST_SURVEY_REQUIREMENTS), expect=403) + + # Neither can juan because he doesn't have the job template create permission + with self.current_user(self.user_juan): + self.post(url, json.loads(TEST_SURVEY_REQUIREMENTS), expect=403) + + # Bob and chuck can read the template + with self.current_user(self.user_bob): + self.get(url, expect=200) + + with self.current_user(self.user_chuck): + self.get(url, expect=200) + + # Doug and Juan can't + with self.current_user(self.user_doug): + self.get(url, expect=403) + + with self.current_user(self.user_juan): + self.get(url, expect=403) + def test_launch_job_template(self): url = reverse('api:job_template_list') data = dict(