mirror of
https://github.com/ansible/awx.git
synced 2026-02-14 09:44:47 -03:30
Develop ability to list permissions for existing roles Create a model registry for RBAC-tracked models Write the data migration logic for creating the preloaded role definitions Write migration to migrate old Role into ObjectRole model This loops over the old Role model, knowing it is unique on object and role_field Most of the logic is concerned with identifying the needed permissions, and then corresponding role definition As needed, object roles are created and users then teams are assigned Write re-computation of cache logic for teams and then for object role permissions Migrate new RBAC internals to ansible_base Migrate tests to ansible_base Implement solution for visible_roles Expose URLs for DAB RBAC
235 lines
7.2 KiB
Python
235 lines
7.2 KiB
Python
# Copyright (c) 2018 Red Hat, Inc.
|
|
# All Rights Reserved.
|
|
|
|
# Python
|
|
import logging
|
|
|
|
# Django
|
|
from django.db.models import Count
|
|
from django.contrib.contenttypes.models import ContentType
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
# AWX
|
|
from awx.main.models import (
|
|
ActivityStream,
|
|
Inventory,
|
|
Host,
|
|
Project,
|
|
ExecutionEnvironment,
|
|
JobTemplate,
|
|
WorkflowJobTemplate,
|
|
Organization,
|
|
NotificationTemplate,
|
|
Role,
|
|
User,
|
|
Team,
|
|
InstanceGroup,
|
|
Credential,
|
|
)
|
|
from awx.api.generics import (
|
|
ListCreateAPIView,
|
|
RetrieveUpdateDestroyAPIView,
|
|
SubListAPIView,
|
|
SubListCreateAttachDetachAPIView,
|
|
SubListAttachDetachAPIView,
|
|
SubListCreateAPIView,
|
|
ResourceAccessList,
|
|
BaseUsersList,
|
|
)
|
|
|
|
from awx.api.serializers import (
|
|
OrganizationSerializer,
|
|
InventorySerializer,
|
|
UserSerializer,
|
|
TeamSerializer,
|
|
ActivityStreamSerializer,
|
|
RoleSerializer,
|
|
NotificationTemplateSerializer,
|
|
InstanceGroupSerializer,
|
|
ExecutionEnvironmentSerializer,
|
|
ProjectSerializer,
|
|
JobTemplateSerializer,
|
|
WorkflowJobTemplateSerializer,
|
|
CredentialSerializer,
|
|
)
|
|
from awx.api.views.mixin import RelatedJobsPreventDeleteMixin, OrganizationCountsMixin
|
|
|
|
logger = logging.getLogger('awx.api.views.organization')
|
|
|
|
|
|
class OrganizationList(OrganizationCountsMixin, ListCreateAPIView):
|
|
model = Organization
|
|
serializer_class = OrganizationSerializer
|
|
|
|
|
|
class OrganizationDetail(RelatedJobsPreventDeleteMixin, RetrieveUpdateDestroyAPIView):
|
|
model = Organization
|
|
serializer_class = OrganizationSerializer
|
|
|
|
def get_serializer_context(self, *args, **kwargs):
|
|
full_context = super(OrganizationDetail, self).get_serializer_context(*args, **kwargs)
|
|
|
|
if not hasattr(self, 'kwargs') or 'pk' not in self.kwargs:
|
|
return full_context
|
|
org_id = int(self.kwargs['pk'])
|
|
|
|
org_counts = {}
|
|
access_kwargs = {'accessor': self.request.user, 'role_field': 'read_role'}
|
|
direct_counts = (
|
|
Organization.objects.filter(id=org_id)
|
|
.annotate(users=Count('member_role__members', distinct=True), admins=Count('admin_role__members', distinct=True))
|
|
.values('users', 'admins')
|
|
)
|
|
|
|
if not direct_counts:
|
|
return full_context
|
|
|
|
org_counts = direct_counts[0]
|
|
org_counts['inventories'] = Inventory.accessible_objects(**access_kwargs).filter(organization__id=org_id).count()
|
|
org_counts['teams'] = Team.accessible_objects(**access_kwargs).filter(organization__id=org_id).count()
|
|
org_counts['projects'] = Project.accessible_objects(**access_kwargs).filter(organization__id=org_id).count()
|
|
org_counts['job_templates'] = JobTemplate.accessible_objects(**access_kwargs).filter(organization__id=org_id).count()
|
|
org_counts['hosts'] = Host.objects.org_active_count(org_id)
|
|
|
|
full_context['related_field_counts'] = {}
|
|
full_context['related_field_counts'][org_id] = org_counts
|
|
|
|
return full_context
|
|
|
|
|
|
class OrganizationInventoriesList(SubListAPIView):
|
|
model = Inventory
|
|
serializer_class = InventorySerializer
|
|
parent_model = Organization
|
|
relationship = 'inventories'
|
|
|
|
|
|
class OrganizationUsersList(BaseUsersList):
|
|
model = User
|
|
serializer_class = UserSerializer
|
|
parent_model = Organization
|
|
relationship = 'member_role.members'
|
|
ordering = ('username',)
|
|
|
|
|
|
class OrganizationAdminsList(BaseUsersList):
|
|
model = User
|
|
serializer_class = UserSerializer
|
|
parent_model = Organization
|
|
relationship = 'admin_role.members'
|
|
ordering = ('username',)
|
|
|
|
|
|
class OrganizationProjectsList(SubListCreateAPIView):
|
|
model = Project
|
|
serializer_class = ProjectSerializer
|
|
parent_model = Organization
|
|
parent_key = 'organization'
|
|
|
|
|
|
class OrganizationExecutionEnvironmentsList(SubListCreateAttachDetachAPIView):
|
|
model = ExecutionEnvironment
|
|
serializer_class = ExecutionEnvironmentSerializer
|
|
parent_model = Organization
|
|
relationship = 'executionenvironments'
|
|
parent_key = 'organization'
|
|
swagger_topic = "Execution Environments"
|
|
|
|
|
|
class OrganizationJobTemplatesList(SubListCreateAPIView):
|
|
model = JobTemplate
|
|
serializer_class = JobTemplateSerializer
|
|
parent_model = Organization
|
|
parent_key = 'organization'
|
|
|
|
|
|
class OrganizationWorkflowJobTemplatesList(SubListCreateAPIView):
|
|
model = WorkflowJobTemplate
|
|
serializer_class = WorkflowJobTemplateSerializer
|
|
parent_model = Organization
|
|
parent_key = 'organization'
|
|
|
|
|
|
class OrganizationTeamsList(SubListCreateAttachDetachAPIView):
|
|
model = Team
|
|
serializer_class = TeamSerializer
|
|
parent_model = Organization
|
|
relationship = 'teams'
|
|
parent_key = 'organization'
|
|
|
|
|
|
class OrganizationActivityStreamList(SubListAPIView):
|
|
model = ActivityStream
|
|
serializer_class = ActivityStreamSerializer
|
|
parent_model = Organization
|
|
relationship = 'activitystream_set'
|
|
search_fields = ('changes',)
|
|
|
|
|
|
class OrganizationNotificationTemplatesList(SubListCreateAttachDetachAPIView):
|
|
model = NotificationTemplate
|
|
serializer_class = NotificationTemplateSerializer
|
|
parent_model = Organization
|
|
relationship = 'notification_templates'
|
|
parent_key = 'organization'
|
|
|
|
|
|
class OrganizationNotificationTemplatesAnyList(SubListCreateAttachDetachAPIView):
|
|
model = NotificationTemplate
|
|
serializer_class = NotificationTemplateSerializer
|
|
parent_model = Organization
|
|
|
|
|
|
class OrganizationNotificationTemplatesStartedList(OrganizationNotificationTemplatesAnyList):
|
|
relationship = 'notification_templates_started'
|
|
|
|
|
|
class OrganizationNotificationTemplatesErrorList(OrganizationNotificationTemplatesAnyList):
|
|
relationship = 'notification_templates_error'
|
|
|
|
|
|
class OrganizationNotificationTemplatesSuccessList(OrganizationNotificationTemplatesAnyList):
|
|
relationship = 'notification_templates_success'
|
|
|
|
|
|
class OrganizationNotificationTemplatesApprovalList(OrganizationNotificationTemplatesAnyList):
|
|
relationship = 'notification_templates_approvals'
|
|
|
|
|
|
class OrganizationInstanceGroupsList(SubListAttachDetachAPIView):
|
|
model = InstanceGroup
|
|
serializer_class = InstanceGroupSerializer
|
|
parent_model = Organization
|
|
relationship = 'instance_groups'
|
|
filter_read_permission = False
|
|
|
|
|
|
class OrganizationGalaxyCredentialsList(SubListAttachDetachAPIView):
|
|
model = Credential
|
|
serializer_class = CredentialSerializer
|
|
parent_model = Organization
|
|
relationship = 'galaxy_credentials'
|
|
filter_read_permission = False
|
|
|
|
def is_valid_relation(self, parent, sub, created=False):
|
|
if sub.kind != 'galaxy_api_token':
|
|
return {'msg': _(f"Credential must be a Galaxy credential, not {sub.credential_type.name}.")}
|
|
|
|
|
|
class OrganizationAccessList(ResourceAccessList):
|
|
model = User # needs to be User for AccessLists's
|
|
parent_model = Organization
|
|
|
|
|
|
class OrganizationObjectRolesList(SubListAPIView):
|
|
model = Role
|
|
serializer_class = RoleSerializer
|
|
parent_model = Organization
|
|
search_fields = ('role_field', 'content_type__model')
|
|
deprecated = True
|
|
|
|
def get_queryset(self):
|
|
po = self.get_parent_object()
|
|
content_type = ContentType.objects.get_for_model(self.parent_model)
|
|
return Role.objects.filter(content_type=content_type, object_id=po.pk)
|