From 9697999ddd3143dd2317c39fccfb4c80102dfe89 Mon Sep 17 00:00:00 2001 From: Jeff Bradberry Date: Wed, 1 Jul 2020 16:12:24 -0400 Subject: [PATCH] Create the RBAC access class for execution environments --- awx/main/access.py | 51 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/awx/main/access.py b/awx/main/access.py index 89a6c0607d..24e6bbc569 100644 --- a/awx/main/access.py +++ b/awx/main/access.py @@ -29,9 +29,9 @@ from awx.main.utils import ( ) from awx.main.models import ( ActivityStream, AdHocCommand, AdHocCommandEvent, Credential, CredentialType, - CredentialInputSource, CustomInventoryScript, Group, Host, Instance, InstanceGroup, - Inventory, InventorySource, InventoryUpdate, InventoryUpdateEvent, Job, JobEvent, - JobHostSummary, JobLaunchConfig, JobTemplate, Label, Notification, + CredentialInputSource, CustomInventoryScript, ExecutionEnvironment, Group, Host, Instance, + InstanceGroup, Inventory, InventorySource, InventoryUpdate, InventoryUpdateEvent, Job, + JobEvent, JobHostSummary, JobLaunchConfig, JobTemplate, Label, Notification, NotificationTemplate, Organization, Project, ProjectUpdate, ProjectUpdateEvent, Role, Schedule, SystemJob, SystemJobEvent, SystemJobTemplate, Team, UnifiedJob, UnifiedJobTemplate, WorkflowJob, @@ -1308,6 +1308,51 @@ class TeamAccess(BaseAccess): *args, **kwargs) +class ExecutionEnvironmentAccess(BaseAccess): + """ + I can see an execution environment when: + - I'm a superuser + - I'm a member of the organization + - it is a global ExecutionEnvironment + I can create/change an execution environment when: + - I'm a superuser + - I'm an admin for the organization(s) + """ + + model = ExecutionEnvironment + + def filtered_queryset(self): + return ExecutionEnvironment.objects.filter( + Q(organization__in=Organization.accessible_pk_qs(self.user, 'admin_role')) | + Q(organization__isnull=True) + ).distinct() + + @check_superuser + def can_add(self, data): + if not data: # So the browseable API will work + return Organization.accessible_objects(self.user, 'admin_role').exists() + return self.check_related('organization', Organization, data) + + @check_superuser + def can_change(self, obj, data): + if obj and obj.organization_id is None: + raise PermissionDenied + if self.user not in obj.organization.admin_role: + raise PermissionDenied + org_pk = get_pk_from_dict(data, 'organization') + if obj and obj.organization_id != org_pk: + # Prevent moving an EE to a different organization, unless a superuser or admin on both orgs. + if obj.organization_id is None or org_pk is None: + raise PermissionDenied + if self.user not in Organization.objects.get(id=org_pk).admin_role: + raise PermissionDenied + + return True + + def can_delete(self, obj): + return self.can_change(obj, None) + + class ProjectAccess(NotificationAttachMixin, BaseAccess): ''' I can see projects when: