diff --git a/awx/api/views/__init__.py b/awx/api/views/__init__.py index fe116afb984f..20515a69c8a0 100644 --- a/awx/api/views/__init__.py +++ b/awx/api/views/__init__.py @@ -2392,6 +2392,14 @@ class JobTemplateList(ListCreateAPIView): serializer_class = serializers.JobTemplateSerializer always_allow_superuser = False + def check_permissions(self, request): + if request.method == 'POST': + can_access, messages = request.user.can_access_with_errors(self.model, 'add', request.data) + if not can_access: + self.permission_denied(request, message=messages) + + super(JobTemplateList, self).check_permissions(request) + class JobTemplateDetail(RelatedJobsPreventDeleteMixin, RetrieveUpdateDestroyAPIView): model = models.JobTemplate diff --git a/awx/main/access.py b/awx/main/access.py index ae39bba1b135..9748ddd8d3df 100644 --- a/awx/main/access.py +++ b/awx/main/access.py @@ -1595,6 +1595,8 @@ def get_value(Class, field): inventory = get_value(Inventory, 'inventory') if inventory: if self.user not in inventory.use_role: + if self.save_messages: + self.messages['inventory'] = [_('You do not have use permission on Inventory')] return False if not self.check_related('execution_environment', ExecutionEnvironment, data, role_field='read_role'): @@ -1603,11 +1605,16 @@ def get_value(Class, field): project = get_value(Project, 'project') # If the user has admin access to the project (as an org admin), should # be able to proceed without additional checks. - if project: - return self.user in project.use_role - else: + if not project: + return False + + if self.user not in project.use_role: + if self.save_messages: + self.messages['project'] = [_('You do not have use permission on Project')] return False + return True + @check_superuser def can_copy_related(self, obj): """ diff --git a/awx/main/tests/functional/test_rbac_job_templates.py b/awx/main/tests/functional/test_rbac_job_templates.py index 0b73dc34cb76..34f82d9a74b9 100644 --- a/awx/main/tests/functional/test_rbac_job_templates.py +++ b/awx/main/tests/functional/test_rbac_job_templates.py @@ -182,8 +182,14 @@ def test_job_template_creator_access(project, organization, rando, post, setup_m @pytest.mark.django_db @pytest.mark.job_permissions -@pytest.mark.parametrize('lacking', ['project', 'inventory']) -def test_job_template_insufficient_creator_permissions(lacking, project, inventory, organization, rando, post): +@pytest.mark.parametrize( + 'lacking,reason', + [ + ('project', 'You do not have use permission on Project'), + ('inventory', 'You do not have use permission on Inventory'), + ], +) +def test_job_template_insufficient_creator_permissions(lacking, reason, project, inventory, organization, rando, post): if lacking != 'project': project.use_role.members.add(rando) else: @@ -192,12 +198,13 @@ def test_job_template_insufficient_creator_permissions(lacking, project, invento inventory.use_role.members.add(rando) else: inventory.read_role.members.add(rando) - post( + response = post( url=reverse('api:job_template_list'), data=dict(name='newly-created-jt', inventory=inventory.id, project=project.pk, playbook='helloworld.yml'), user=rando, expect=403, ) + assert reason in response.data[lacking] @pytest.mark.django_db