From ac474e21089c61d9de5128c124604fa5317e0cf7 Mon Sep 17 00:00:00 2001 From: AlanCoding Date: Thu, 2 Apr 2020 10:17:04 -0400 Subject: [PATCH] Fix RBAC loose items from reversed decision on JT org permissions --- awx/main/access.py | 7 +--- .../functional/test_rbac_job_templates.py | 36 ++++++++++++------- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/awx/main/access.py b/awx/main/access.py index c1afd5c803..f6e30bd99a 100644 --- a/awx/main/access.py +++ b/awx/main/access.py @@ -1434,7 +1434,7 @@ class JobTemplateAccess(NotificationAttachMixin, BaseAccess): Users who are able to create deploy jobs can also run normal and check (dry run) jobs. ''' if not data: # So the browseable API will work - return Organization.accessible_objects(self.user, 'job_template_admin_role').exists() + return Project.accessible_objects(self.user, 'use_role').exists() # if reference_obj is provided, determine if it can be copied reference_obj = data.get('reference_obj', None) @@ -1503,11 +1503,6 @@ class JobTemplateAccess(NotificationAttachMixin, BaseAccess): if data is None: return True - # standard type of check for organization - cannot change the value - # unless posessing the respective job_template_admin_role, otherwise non-blocking - if not self.check_related('organization', Organization, data, obj=obj, role_field='job_template_admin_role'): - return False - data = dict(data) if self.changes_are_non_sensitive(obj, data): diff --git a/awx/main/tests/functional/test_rbac_job_templates.py b/awx/main/tests/functional/test_rbac_job_templates.py index a4fbcbaf36..0cbd8bcbc6 100644 --- a/awx/main/tests/functional/test_rbac_job_templates.py +++ b/awx/main/tests/functional/test_rbac_job_templates.py @@ -65,14 +65,29 @@ def test_job_template_access_read_level(jt_linked, rando): assert not access.can_unattach(jt_linked, cred, 'credentials', {}) +@pytest.mark.django_db +def test_project_use_access(project, rando): + project.use_role.members.add(rando) + access = JobTemplateAccess(rando) + assert access.can_add(None) + assert access.can_add({'project': project.id, 'ask_inventory_on_launch': True}) + project2 = Project.objects.create( + name='second-project', scm_type=project.scm_type, playbook_files=project.playbook_files, + organization=project.organization, + ) + project2.use_role.members.add(rando) + jt = JobTemplate.objects.create(project=project, ask_inventory_on_launch=True) + jt.admin_role.members.add(rando) + assert access.can_change(jt, {'project': project2.pk}) + + @pytest.mark.django_db def test_job_template_access_use_level(jt_linked, rando): access = JobTemplateAccess(rando) jt_linked.project.use_role.members.add(rando) jt_linked.inventory.use_role.members.add(rando) - jt_linked.organization.job_template_admin_role.members.add(rando) + jt_linked.admin_role.members.add(rando) proj_pk = jt_linked.project.pk - org_pk = jt_linked.organization_id assert access.can_change(jt_linked, {'job_type': 'check', 'project': proj_pk}) assert access.can_change(jt_linked, {'job_type': 'check', 'inventory': None}) @@ -80,8 +95,8 @@ def test_job_template_access_use_level(jt_linked, rando): for cred in jt_linked.credentials.all(): assert access.can_unattach(jt_linked, cred, 'credentials', {}) - assert access.can_add(dict(inventory=jt_linked.inventory.pk, project=proj_pk, organization=org_pk)) - assert access.can_add(dict(project=proj_pk, organization=org_pk)) + assert access.can_add(dict(inventory=jt_linked.inventory.pk, project=proj_pk)) + assert access.can_add(dict(project=proj_pk)) @pytest.mark.django_db @@ -94,17 +109,16 @@ def test_job_template_access_admin(role_names, jt_linked, rando): assert not access.can_read(jt_linked) assert not access.can_delete(jt_linked) - # Appoint this user as admin of the organization - jt_linked.organization.admin_role.members.add(rando) - org_pk = jt_linked.organization.id + # Appoint this user to the org role + organization = jt_linked.organization + for role_name in role_names: + getattr(organization, role_name).members.add(rando) # Assign organization permission in the same way the create view does - organization = jt_linked.inventory.organization ssh_cred.admin_role.parents.add(organization.admin_role) proj_pk = jt_linked.project.pk - assert access.can_add(dict(inventory=jt_linked.inventory.pk, project=proj_pk, organization=org_pk)) - assert access.can_add(dict(credential=ssh_cred.pk, project=proj_pk, organization=org_pk)) + assert access.can_add(dict(inventory=jt_linked.inventory.pk, project=proj_pk)) for cred in jt_linked.credentials.all(): assert access.can_unattach(jt_linked, cred, 'credentials', {}) @@ -170,12 +184,10 @@ class TestOrphanJobTemplate: @pytest.mark.job_permissions def test_job_template_creator_access(project, organization, rando, post): project.use_role.members.add(rando) - organization.job_template_admin_role.members.add(rando) response = post(url=reverse('api:job_template_list'), data=dict( name='newly-created-jt', ask_inventory_on_launch=True, project=project.pk, - organization=organization.id, playbook='helloworld.yml' ), user=rando, expect=201)