diff --git a/awx/main/tests/functional/test_rbac_credential.py b/awx/main/tests/functional/test_rbac_credential.py index b02b30755a..783fdd9e82 100644 --- a/awx/main/tests/functional/test_rbac_credential.py +++ b/awx/main/tests/functional/test_rbac_credential.py @@ -35,9 +35,31 @@ def test_credential_access_auditor(credential, organization_factory): @pytest.mark.django_db -def test_org_credential_access_member(alice, org_credential, credential): - org_credential.admin_role.members.add(alice) +def test_credential_access_member(alice, credential): credential.admin_role.members.add(alice) + access = CredentialAccess(alice) + assert access.can_change(credential, { + 'description': 'New description.', + 'organization': None}) + + +@pytest.mark.django_db +@pytest.mark.parametrize("role_name", ["admin_role", "credential_admin_role"]) +def test_org_credential_access_admin(role_name, alice, org_credential): + role = getattr(org_credential.organization, role_name) + role.members.add(alice) + + access = CredentialAccess(alice) + + # Alice should be able to PATCH if organization is not changed + assert access.can_change(org_credential, { + 'description': 'New description.', + 'organization': org_credential.organization.pk}) + + +@pytest.mark.django_db +def test_org_credential_access_member(alice, org_credential): + org_credential.admin_role.members.add(alice) access = CredentialAccess(alice) @@ -47,9 +69,6 @@ def test_org_credential_access_member(alice, org_credential, credential): 'organization': org_credential.organization.pk}) assert access.can_change(org_credential, { 'description': 'New description.'}) - assert access.can_change(credential, { - 'description': 'New description.', - 'organization': None}) @pytest.mark.django_db diff --git a/awx/main/tests/functional/test_rbac_inventory.py b/awx/main/tests/functional/test_rbac_inventory.py index 830e5a7b52..fd195b10b3 100644 --- a/awx/main/tests/functional/test_rbac_inventory.py +++ b/awx/main/tests/functional/test_rbac_inventory.py @@ -62,10 +62,13 @@ def test_org_member_inventory_script_permissions(org_member, organization): @pytest.mark.django_db -def test_access_admin(organization, inventory, user): +@pytest.mark.parametrize("role", ["admin_role", "inventory_admin_role"]) +def test_access_admin(role, organization, inventory, user): a = user('admin', False) inventory.organization = organization - organization.admin_role.members.add(a) + + role = getattr(organization, role) + role.members.add(a) access = InventoryAccess(a) assert access.can_read(inventory) diff --git a/awx/main/tests/functional/test_rbac_job_templates.py b/awx/main/tests/functional/test_rbac_job_templates.py index 91778a3c5d..34a6b06e97 100644 --- a/awx/main/tests/functional/test_rbac_job_templates.py +++ b/awx/main/tests/functional/test_rbac_job_templates.py @@ -80,10 +80,15 @@ def test_job_template_access_use_level(jt_linked, rando): @pytest.mark.django_db -def test_job_template_access_org_admin(jt_linked, rando): +@pytest.mark.parametrize("role_names", [("admin_role",), ("inventory_admin_role", "project_admin_role")]) +def test_job_template_access_admin(role_names, jt_linked, rando): access = JobTemplateAccess(rando) # Appoint this user as admin of the organization - jt_linked.inventory.organization.admin_role.members.add(rando) + #jt_linked.inventory.organization.admin_role.members.add(rando) + for role_name in role_names: + role = getattr(jt_linked.inventory.organization, role_name) + role.members.add(rando) + # Assign organization permission in the same way the create view does organization = jt_linked.inventory.organization jt_linked.get_deprecated_credential('ssh').admin_role.parents.add(organization.admin_role) diff --git a/awx/main/tests/functional/test_rbac_workflow.py b/awx/main/tests/functional/test_rbac_workflow.py index 578db417d0..5cd63027d2 100644 --- a/awx/main/tests/functional/test_rbac_workflow.py +++ b/awx/main/tests/functional/test_rbac_workflow.py @@ -49,6 +49,13 @@ class TestWorkflowJobTemplateAccess: assert org_admin in wfjt.execute_role assert org_admin in wfjt.read_role + def test_org_workflow_admin_role_inheritance(self, wfjt, org_member): + wfjt.organization.workflow_admin_role.members.add(org_member) + + assert org_member in wfjt.admin_role + assert org_member in wfjt.execute_role + assert org_member in wfjt.read_role + @pytest.mark.django_db class TestWorkflowJobTemplateNodeAccess: @@ -103,8 +110,12 @@ class TestWorkflowJobTemplateNodeAccess: @pytest.mark.django_db class TestWorkflowJobAccess: - def test_org_admin_can_delete_workflow_job(self, workflow_job, org_admin): - access = WorkflowJobAccess(org_admin) + @pytest.mark.parametrize("role_name", ["admin_role", "workflow_admin_role"]) + def test_org_admin_can_delete_workflow_job(self, role_name, workflow_job, org_member): + role = getattr(workflow_job.workflow_job_template.organization, role_name) + role.members.add(org_member) + + access = WorkflowJobAccess(org_member) assert access.can_delete(workflow_job) def test_wfjt_admin_can_delete_workflow_job(self, workflow_job, rando): @@ -132,9 +143,13 @@ class TestWFJTCopyAccess: admin_access = WorkflowJobTemplateAccess(org_admin) assert admin_access.can_copy(wfjt) + wfjt.organization.workflow_admin_role.members.add(org_member) + admin_access = WorkflowJobTemplateAccess(org_member) + assert admin_access.can_copy(wfjt) + def test_copy_permissions_user(self, wfjt, org_admin, org_member): ''' - Only org admins are able to add WFJTs, only org admins + Only org admins and org workflow admins are able to add WFJTs, only org admins are able to copy them ''' wfjt.admin_role.members.add(org_member) diff --git a/awx/main/tests/unit/test_access.py b/awx/main/tests/unit/test_access.py index 0692ba0490..44231daf59 100644 --- a/awx/main/tests/unit/test_access.py +++ b/awx/main/tests/unit/test_access.py @@ -244,8 +244,7 @@ class TestWorkflowAccessMethods: def test_workflow_can_add(self, workflow, user_unit): organization = Organization(name='test-org') workflow.organization = organization - organization.admin_role = Role() - + organization.workflow_admin_role = Role() def mock_get_object(Class, **kwargs): if Class == Organization: return organization