diff --git a/awx/main/migrations/_old_access.py b/awx/main/migrations/_old_access.py index 67b38db93e..c662f0ddd0 100644 --- a/awx/main/migrations/_old_access.py +++ b/awx/main/migrations/_old_access.py @@ -694,9 +694,9 @@ class ProjectAccess(BaseAccess): if self.user.is_superuser: return qs team_ids = set(Team.objects.filter(deprecated_users__in=[self.user]).values_list('id', flat=True)) - qs = qs.filter(Q(created_by=self.user, organizations__isnull=True) | - Q(organizations__deprecated_admins__in=[self.user], organizations__active=True) | - Q(organizations__deprecated_users__in=[self.user], organizations__active=True) | + qs = qs.filter(Q(created_by=self.user, deprecated_organizations__isnull=True) | + Q(deprecated_organizations__deprecated_admins__in=[self.user], deprecated_organizations__active=True) | + Q(deprecated_organizations__deprecated_users__in=[self.user], deprecated_organizations__active=True) | Q(teams__in=team_ids)) allowed_deploy = [PERM_JOBTEMPLATE_CREATE, PERM_INVENTORY_DEPLOY] allowed_check = [PERM_JOBTEMPLATE_CREATE, PERM_INVENTORY_DEPLOY, PERM_INVENTORY_CHECK] @@ -726,9 +726,9 @@ class ProjectAccess(BaseAccess): def can_change(self, obj, data): if self.user.is_superuser: return True - if obj.created_by == self.user and not obj.organizations.filter(active=True).count(): + if obj.created_by == self.user and not obj.deprecated_organizations.filter(active=True).count(): return True - if obj.organizations.filter(active=True, deprecated_admins__in=[self.user]).exists(): + if obj.deprecated_organizations.filter(active=True, deprecated_admins__in=[self.user]).exists(): return True return False @@ -880,7 +880,7 @@ class JobTemplateAccess(BaseAccess): Q(cloud_credential_id__in=credential_ids) | Q(cloud_credential__isnull=True), ) org_admin_ids = base_qs.filter( - Q(project__organizations__deprecated_admins__in=[self.user]) | + Q(project__deprecated_organizations__deprecated_admins__in=[self.user]) | (Q(project__isnull=True) & Q(job_type=PERM_INVENTORY_SCAN) & Q(inventory__organization__deprecated_admins__in=[self.user])) ) @@ -1097,7 +1097,7 @@ class JobAccess(BaseAccess): credential_id__in=credential_ids, ) org_admin_ids = base_qs.filter( - Q(project__organizations__deprecated_admins__in=[self.user]) | + Q(project__deprecated_organizations__deprecated_admins__in=[self.user]) | (Q(project__isnull=True) & Q(job_type=PERM_INVENTORY_SCAN) & Q(inventory__organization__deprecated_admins__in=[self.user])) ) diff --git a/awx/main/models/jobs.py b/awx/main/models/jobs.py index ba0170bf69..410f3c0392 100644 --- a/awx/main/models/jobs.py +++ b/awx/main/models/jobs.py @@ -362,9 +362,9 @@ class JobTemplate(UnifiedJobTemplate, JobOptions, ResourceMixin): success_notifiers = list(base_notifiers.filter(unifiedjobtemplate_notifiers_for_success__in=[self, self.project])) any_notifiers = list(base_notifiers.filter(unifiedjobtemplate_notifiers_for_any__in=[self, self.project])) # Get Organization Notifiers - error_notifiers = set(error_notifiers + list(base_notifiers.filter(organization_notifiers_for_errors__in=self.project.organizations.all()))) - success_notifiers = set(success_notifiers + list(base_notifiers.filter(organization_notifiers_for_success__in=self.project.organizations.all()))) - any_notifiers = set(any_notifiers + list(base_notifiers.filter(organization_notifiers_for_any__in=self.project.organizations.all()))) + error_notifiers = set(error_notifiers + list(base_notifiers.filter(organization_notifiers_for_errors=self.project.organization))) + success_notifiers = set(success_notifiers + list(base_notifiers.filter(organization_notifiers_for_success=self.project.organization))) + any_notifiers = set(any_notifiers + list(base_notifiers.filter(organization_notifiers_for_any=self.project.organization))) return dict(error=list(error_notifiers), success=list(success_notifiers), any=list(any_notifiers)) class Job(UnifiedJob, JobOptions): diff --git a/awx/main/models/projects.py b/awx/main/models/projects.py index bcf54627d1..aa416bb95a 100644 --- a/awx/main/models/projects.py +++ b/awx/main/models/projects.py @@ -350,9 +350,9 @@ class Project(UnifiedJobTemplate, ProjectOptions, ResourceMixin): success_notifiers = list(base_notifiers.filter(unifiedjobtemplate_notifiers_for_success=self)) any_notifiers = list(base_notifiers.filter(unifiedjobtemplate_notifiers_for_any=self)) # Get Organization Notifiers - error_notifiers = set(error_notifiers + list(base_notifiers.filter(organization_notifiers_for_errors__in=self.organizations.all()))) - success_notifiers = set(success_notifiers + list(base_notifiers.filter(organization_notifiers_for_success__in=self.organizations.all()))) - any_notifiers = set(any_notifiers + list(base_notifiers.filter(organization_notifiers_for_any__in=self.organizations.all()))) + error_notifiers = set(error_notifiers + list(base_notifiers.filter(organization_notifiers_for_errors=self.organization))) + success_notifiers = set(success_notifiers + list(base_notifiers.filter(organization_notifiers_for_success=self.organization))) + any_notifiers = set(any_notifiers + list(base_notifiers.filter(organization_notifiers_for_any=self.organization))) return dict(error=list(error_notifiers), success=list(success_notifiers), any=list(any_notifiers)) def get_absolute_url(self): diff --git a/awx/main/tests/functional/test_rbac_core.py b/awx/main/tests/functional/test_rbac_core.py index 9b3e29f6e8..acf36f835e 100644 --- a/awx/main/tests/functional/test_rbac_core.py +++ b/awx/main/tests/functional/test_rbac_core.py @@ -4,6 +4,7 @@ from awx.main.models import ( Role, RolePermission, Organization, + Group, ) @@ -97,20 +98,24 @@ def test_team_symantics(organization, team, alice): assert organization.accessible_by(alice, {'read': True}) is False @pytest.mark.django_db -def test_auto_m2m_adjuments(organization, project, alice): +def test_auto_m2m_adjuments(organization, inventory, group, alice): 'Ensures the auto role reparenting is working correctly through m2m maps' - organization.admin_role.members.add(alice) - assert project.accessible_by(alice, {'read': True}) is True + g1 = group(name='g1') + g1.admin_role.members.add(alice) + assert g1.accessible_by(alice, {'read': True}) is True + g2 = group(name='g2') + assert g2.accessible_by(alice, {'read': True}) is False - project.organizations.remove(organization) - assert project.accessible_by(alice, {'read': True}) is False - project.organizations.add(organization) - assert project.accessible_by(alice, {'read': True}) is True + g2.parents.add(g1) + assert g2.accessible_by(alice, {'read': True}) is True + g2.parents.remove(g1) + assert g2.accessible_by(alice, {'read': True}) is False + + g1.children.add(g2) + assert g2.accessible_by(alice, {'read': True}) is True + g1.children.remove(g2) + assert g2.accessible_by(alice, {'read': True}) is False - organization.projects.remove(project) - assert project.accessible_by(alice, {'read': True}) is False - organization.projects.add(project) - assert project.accessible_by(alice, {'read': True}) is True @pytest.mark.django_db def test_auto_field_adjuments(organization, inventory, team, alice): diff --git a/awx/main/tests/functional/test_rbac_job_templates.py b/awx/main/tests/functional/test_rbac_job_templates.py index 788f595b9b..497301e184 100644 --- a/awx/main/tests/functional/test_rbac_job_templates.py +++ b/awx/main/tests/functional/test_rbac_job_templates.py @@ -16,7 +16,7 @@ def test_job_template_migration_check(deploy_jobtemplate, check_jobtemplate, use joe = user('joe') - check_jobtemplate.project.organizations.all()[0].deprecated_users.add(joe) + check_jobtemplate.project.organization.deprecated_users.add(joe) Permission(user=joe, inventory=check_jobtemplate.inventory, permission_type='read').save() Permission(user=joe, inventory=check_jobtemplate.inventory, @@ -45,7 +45,7 @@ def test_job_template_migration_deploy(deploy_jobtemplate, check_jobtemplate, us joe = user('joe') - deploy_jobtemplate.project.organizations.all()[0].deprecated_users.add(joe) + deploy_jobtemplate.project.organization.deprecated_users.add(joe) Permission(user=joe, inventory=deploy_jobtemplate.inventory, permission_type='read').save() Permission(user=joe, inventory=deploy_jobtemplate.inventory, @@ -77,7 +77,7 @@ def test_job_template_team_migration_check(deploy_jobtemplate, check_jobtemplate team.organization = organization team.save() - check_jobtemplate.project.organizations.all()[0].deprecated_users.add(joe) + check_jobtemplate.project.organization.deprecated_users.add(joe) Permission(team=team, inventory=check_jobtemplate.inventory, permission_type='read').save() Permission(team=team, inventory=check_jobtemplate.inventory, @@ -112,7 +112,7 @@ def test_job_template_team_deploy_migration(deploy_jobtemplate, check_jobtemplat team.organization = organization team.save() - deploy_jobtemplate.project.organizations.all()[0].deprecated_users.add(joe) + deploy_jobtemplate.project.organization.deprecated_users.add(joe) Permission(team=team, inventory=deploy_jobtemplate.inventory, permission_type='read').save() Permission(team=team, inventory=deploy_jobtemplate.inventory,