From 59f61517d4de7ebec635d6c931e7a043a28b1870 Mon Sep 17 00:00:00 2001 From: Alan Rominger Date: Mon, 22 Jul 2024 14:51:32 -0400 Subject: [PATCH] Loosen up team EE restrictions (#15384) * Try to loosen up team EE restrictions * Fix missed permission case of nulling EE org --- awx/main/access.py | 12 +++++++++-- awx/main/models/execution_environments.py | 4 ---- .../test_rbac_execution_environment.py | 21 +++++++++++-------- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/awx/main/access.py b/awx/main/access.py index a1cd956fd1..24b8b746fd 100644 --- a/awx/main/access.py +++ b/awx/main/access.py @@ -1400,7 +1400,9 @@ class ExecutionEnvironmentAccess(BaseAccess): def filtered_queryset(self): return ExecutionEnvironment.objects.filter( - Q(organization__in=Organization.accessible_pk_qs(self.user, 'read_role')) | Q(organization__isnull=True) + Q(organization__in=Organization.accessible_pk_qs(self.user, 'read_role')) + | Q(organization__isnull=True) + | Q(id__in=ExecutionEnvironment.access_ids_qs(self.user, 'change')) ).distinct() @check_superuser @@ -1419,7 +1421,13 @@ class ExecutionEnvironmentAccess(BaseAccess): else: if self.user not in obj.organization.execution_environment_admin_role: raise PermissionDenied - return self.check_related('organization', Organization, data, obj=obj, role_field='execution_environment_admin_role') + if not self.check_related('organization', Organization, data, obj=obj, role_field='execution_environment_admin_role'): + return False + # Special case that check_related does not catch, org users can not remove the organization from the EE + if data and ('organization' in data or 'organization_id' in data): + if (not data.get('organization')) and (not data.get('organization_id')): + return False + return True def can_delete(self, obj): if obj.managed: diff --git a/awx/main/models/execution_environments.py b/awx/main/models/execution_environments.py index 8f24a9d5e2..321b38264b 100644 --- a/awx/main/models/execution_environments.py +++ b/awx/main/models/execution_environments.py @@ -66,7 +66,3 @@ class ExecutionEnvironment(CommonModel): if actor._meta.model_name == 'user' and (not actor.has_obj_perm(self.organization, 'view')): raise ValidationError({'user': _('User must have view permission to Execution Environment organization')}) - if actor._meta.model_name == 'team': - organization_cls = self._meta.get_field('organization').related_model - if self.organization not in organization_cls.access_qs(actor, 'view'): - raise ValidationError({'team': _('Team must have view permission to Execution Environment organization')}) diff --git a/awx/main/tests/functional/test_rbac_execution_environment.py b/awx/main/tests/functional/test_rbac_execution_environment.py index 42af780595..e5bc355371 100644 --- a/awx/main/tests/functional/test_rbac_execution_environment.py +++ b/awx/main/tests/functional/test_rbac_execution_environment.py @@ -63,6 +63,11 @@ def check_user_capabilities(get, setup_managed_roles): # ___ begin tests ___ +@pytest.mark.django_db +def test_any_user_can_view_global_ee(control_plane_execution_environment, rando): + assert ExecutionEnvironmentAccess(rando).can_read(control_plane_execution_environment) + + @pytest.mark.django_db def test_managed_ee_not_assignable(control_plane_execution_environment, ee_rd, rando, admin_user, post): url = django_reverse('roleuserassignment-list') @@ -78,23 +83,18 @@ def test_org_member_required_for_assignment(org_ee, ee_rd, rando, admin_user, po @pytest.mark.django_db -def test_team_view_permission_required(org_ee, ee_rd, rando, admin_user, post): +def test_team_can_have_permission(org_ee, ee_rd, rando, admin_user, post): org2 = Organization.objects.create(name='a different team') team = Team.objects.create(name='a team', organization=org2) team.member_role.members.add(rando) assert org_ee not in ExecutionEnvironmentAccess(rando).get_queryset() # user can not view the EE - url = django_reverse('roleteamassignment-list') - r = post(url, {'role_definition': ee_rd.pk, 'team': team.id, 'object_id': org_ee.pk}, user=admin_user, expect=400) - assert 'Team must have view permission to Execution Environment organization' in str(r.data) - org_view_rd = RoleDefinition.objects.create_from_permissions( - name='organization viewer role', permissions=['view_organization'], content_type=ContentType.objects.get_for_model(Organization) - ) - org_view_rd.give_permission(team, org_ee.organization) - assert org_ee in ExecutionEnvironmentAccess(rando).get_queryset() # user can view the EE now + url = django_reverse('roleteamassignment-list') + # can give object roles to the team now post(url, {'role_definition': ee_rd.pk, 'team': team.id, 'object_id': org_ee.pk}, user=admin_user, expect=201) assert rando.has_obj_perm(org_ee, 'change') + assert org_ee in ExecutionEnvironmentAccess(rando).get_queryset() # user can view the EE now @pytest.mark.django_db @@ -143,3 +143,6 @@ def test_give_org_permission_to_ee(org_ee, organization, org_member, check_user_ assert access.can_change(org_ee, {'name': 'new', 'organization': organization.id}) check_user_capabilities(org_member, org_ee, {'edit': True, 'delete': True, 'copy': True}) + + # Extra check, user can not remove the EE from the organization + assert not access.can_change(org_ee, {'name': 'new', 'organization': None})