From 09cc1db665af30c32d043644806f65e56f80c510 Mon Sep 17 00:00:00 2001 From: Jon Date: Sat, 1 Jun 2024 22:07:13 +0930 Subject: [PATCH] fix(api): permissions for teams !16 --- app/api/serializers/access.py | 22 +++++++-- app/api/views/access.py | 84 ++++++++++++++++++++++++++++++----- 2 files changed, 90 insertions(+), 16 deletions(-) diff --git a/app/api/serializers/access.py b/app/api/serializers/access.py index 0ccbdcb4..45262537 100644 --- a/app/api/serializers/access.py +++ b/app/api/serializers/access.py @@ -42,6 +42,16 @@ class TeamSerializer(TeamSerializerBase): return request.build_absolute_uri(reverse('API:_api_team_permission', args=[team.organization_id,team.id])) + def validate(self, data): + """ + Check that start is before finish. + """ + + data['organization_id'] = self._context['view'].kwargs['organization_id'] + + return data + + url = serializers.SerializerMethodField('team_url') def team_url(self, obj): @@ -62,7 +72,8 @@ class TeamSerializer(TeamSerializerBase): 'url', ) read_only_fields = [ - 'permissions' + 'permissions', + 'url' ] @@ -90,15 +101,17 @@ class OrganizationSerializer(serializers.ModelSerializer): view_name="API:_api_organization", format="html" ) - teams = serializers.SerializerMethodField('get_url') + team_url = serializers.SerializerMethodField('get_url') def get_url(self, obj): request = self.context.get('request') - team = Team.objects.get(pk=obj.id) + team = Team.objects.filter(pk=obj.id) - return request.build_absolute_uri(reverse('API:_api_organization_teams', args=[team.organization_id])) + return request.build_absolute_uri(reverse('API:_api_organization_teams', args=[obj.id])) + + teams = TeamSerializerBase(source='team_set', many=True, read_only=False) view_name="API:_api_organization" @@ -110,4 +123,5 @@ class OrganizationSerializer(serializers.ModelSerializer): "name", 'teams', 'url', + 'team_url', ) diff --git a/app/api/views/access.py b/app/api/views/access.py index 7dc41c32..b98f5b83 100644 --- a/app/api/views/access.py +++ b/app/api/views/access.py @@ -15,18 +15,24 @@ class OrganizationPermissionAPI(DjangoObjectPermissions, OrganizationMixin): def has_permission(self, request, view): - self.request = request - - return True + return self.permission_check(request, view) def has_object_permission(self, request, view, obj): + return self.permission_check(request, view, obj) + + + def permission_check(self, request, view, obj=None) -> bool: + self.request = request - self.obj = obj + if hasattr(view, 'queryset'): + if view.queryset.model._meta: + self.obj = view.queryset.model - self.view = view + if obj and not self.obj: + self.obj = obj method = self.request.method.lower() @@ -49,26 +55,61 @@ class OrganizationPermissionAPI(DjangoObjectPermissions, OrganizationMixin): elif method == 'delete': action = 'delete' - + else: action = 'view' + object_organization = None + permission = self.obj._meta.app_label + '.' + action + '_' + self.obj._meta.model_name self.permission_required = [ permission ] - if not self.has_organization_permission() and not request.user.is_superuser: + + if view: + if 'organization_id' in view.kwargs: + + if view.kwargs['organization_id']: + + object_organization = view.kwargs['organization_id'] + + if 'pk' in view.kwargs: + + if not object_organization and view.queryset.model._meta.model_name == 'organization' and view.kwargs['pk']: + + object_organization = view.kwargs['pk'] + + if obj: + + if hasattr(self, 'obj') and not id: + + if isinstance(self.obj, type): + + boo = self.obj.organization.get_object() + + if self.obj.get_organization(): + + object_organization = self.obj.get_organization().id + + if self.obj.is_global: + + object_organization = 0 + + + + if not self.has_organization_permission(object_organization) and not request.user.is_superuser: return False return True - class OrganizationList(generics.ListCreateAPIView): - permission_classes = [OrganizationPermissionAPI] + permission_classes = [ + OrganizationPermissionAPI + ] queryset = Organization.objects.all() lookup_field = 'pk' @@ -82,9 +123,11 @@ class OrganizationList(generics.ListCreateAPIView): class OrganizationDetail(generics.RetrieveUpdateDestroyAPIView): - permission_classes = [OrganizationPermissionAPI] + permission_classes = [ + OrganizationPermissionAPI + ] - queryset = Organization.objects.filter() + queryset = Organization.objects.all() lookup_field = 'pk' serializer_class = OrganizationSerializer @@ -95,9 +138,15 @@ class OrganizationDetail(generics.RetrieveUpdateDestroyAPIView): class TeamList(generics.ListCreateAPIView): - queryset = Team.objects.filter() + + permission_classes = [ + OrganizationPermissionAPI + ] + + queryset = Team.objects.all() serializer_class = TeamSerializer + def get_queryset(self): self.queryset = Team.objects.filter(organization=self.kwargs['organization_id']) @@ -111,14 +160,25 @@ class TeamList(generics.ListCreateAPIView): class TeamDetail(generics.RetrieveUpdateDestroyAPIView): + + permission_classes = [ + OrganizationPermissionAPI + ] + queryset = Team.objects.all() serializer_class = TeamSerializer lookup_field = 'group_ptr_id' + class TeamPermissionDetail(routers.APIRootView): + # temp disabled until permission checker updated + # permission_classes = [ + # OrganizationPermissionAPI + # ] + def get(self, request, *args, **kwargs):