From 506e7c39bc313e04bb817e9218231ad4b6184054 Mon Sep 17 00:00:00 2001 From: rup-narayan-rajbanshi Date: Fri, 23 Aug 2024 16:09:10 +0545 Subject: [PATCH] Add DenyUserGuestPermission - Use separate DenyUserGuestPermission to restict all (get, post ,put, patch) operation. - User DenyGuestUserMutationPermission permission to restict only POST operation. --- api/drf_views.py | 12 +++--- api/test_views.py | 87 +++++++++++++++++++++++++++++--------- api/views.py | 4 +- databank/views.py | 4 +- deployments/drf_views.py | 6 +-- dref/views.py | 26 ++++++------ flash_update/views.py | 12 +++--- lang/views.py | 4 +- local_units/views.py | 11 +++-- main/permissions.py | 24 +++++++++-- notifications/drf_views.py | 4 +- per/drf_views.py | 28 ++++++------ 12 files changed, 144 insertions(+), 78 deletions(-) diff --git a/api/drf_views.py b/api/drf_views.py index c12304328..8cd9b0bae 100644 --- a/api/drf_views.py +++ b/api/drf_views.py @@ -59,7 +59,7 @@ from deployments.models import Personnel from main.enums import GlobalEnumSerializer, get_enum_values from main.filters import NullsLastOrderingFilter -from main.permissions import DenyGuestUserMutationPermission +from main.permissions import DenyGuestUserMutationPermission, DenyGuestUserPermission from main.utils import is_tableau from per.models import Overview from per.serializers import CountryLatestOverviewSerializer @@ -871,7 +871,7 @@ def get_serializer_class(self): class ProfileViewset(viewsets.ModelViewSet): serializer_class = ProfileSerializer authentication_classes = (TokenAuthentication,) - permission_classes = (IsAuthenticated, DenyGuestUserMutationPermission) + permission_classes = (IsAuthenticated, DenyGuestUserPermission) def get_queryset(self): return Profile.objects.filter(user=self.request.user) @@ -880,7 +880,7 @@ def get_queryset(self): class UserViewset(viewsets.ModelViewSet): serializer_class = UserSerializer authentication_classes = (TokenAuthentication,) - permission_classes = [IsAuthenticated, DenyGuestUserMutationPermission] + permission_classes = [IsAuthenticated, DenyGuestUserPermission] def get_queryset(self): return User.objects.filter(pk=self.request.user.pk) @@ -912,7 +912,7 @@ class FieldReportViewset(ReadOnlyVisibilityViewsetMixin, viewsets.ModelViewSet): ) # for /docs ordering_fields = ("summary", "event", "dtype", "created_at", "updated_at") filterset_class = FieldReportFilter - permission_classes = [IsAuthenticated, DenyGuestUserMutationPermission] + permission_classes = [DenyGuestUserMutationPermission] queryset = FieldReport.objects.select_related("dtype", "event").prefetch_related( "actions_taken", "actions_taken__actions", @@ -1315,7 +1315,7 @@ class UsersViewset(viewsets.ReadOnlyModelViewSet): """ serializer_class = UserSerializer - permission_classes = [IsAuthenticated, DenyGuestUserMutationPermission] + permission_classes = [IsAuthenticated, DenyGuestUserPermission] filterset_class = UserFilterSet def get_queryset(self): @@ -1353,7 +1353,7 @@ def get(self, _): class ExportViewSet(viewsets.ModelViewSet): serializer_class = ExportSerializer - permission_classes = [IsAuthenticated, DenyGuestUserMutationPermission] + permission_classes = [IsAuthenticated, DenyGuestUserPermission] def get_queryset(self): user = self.request.user diff --git a/api/test_views.py b/api/test_views.py index 0c74bd07b..fea5ce686 100644 --- a/api/test_views.py +++ b/api/test_views.py @@ -10,7 +10,8 @@ EventFeaturedDocumentFactory, EventLinkFactory, ) -from api.models import Profile +from api.factories.field_report import FieldReportFactory +from api.models import Profile, VisibilityChoices from deployments.factories.user import UserFactory from main.test_case import APITestCase, SnapshotTestCase @@ -24,21 +25,34 @@ def setUp(self): guest_profile.save() # Create go user - self.go_user = User.objects.create(username="go-user") + self.go_user = User.objects.create(username="go-user", is_superuser=True, is_staff=True) go_user_profile = Profile.objects.get(user=self.go_user) go_user_profile.limit_access_to_guest = False go_user_profile.save() + # Create public field reports + FieldReportFactory.create_batch(4, visibility=VisibilityChoices.PUBLIC) + # Create non-public field reports + FieldReportFactory.create_batch(5, visibility=VisibilityChoices.IFRC) + def test_guest_user_permission(self): body = {} + id = 1 # NOTE: id is used just to test api that requires id, it doesnot indicate real id. It can be any number. + guest_apis = [ "/api/v2/add_subscription/", "/api/v2/del_subscription/", "/api/v2/external-token/", + ] + guest_get_apis = [ "/api/v2/user/me/", + "/api/v2/field-report/", + f"/api/v2/field-report/{id}/", + "/api/v2/language/", + f"/api/v2/language/{id}/", ] - id = 1 # NOTE: id is used just to test api that requires id, it doesnot indicate real id. It can be any number. - go_apis = [ + + go_post_apis = [ "/api/v2/dref/", "/api/v2/dref-final-report/", f"/api/v2/dref-final-report/{id}/publish/", @@ -76,13 +90,9 @@ def test_guest_user_permission(self): f"/api/v2/dref-final-report/{id}/", "/api/v2/dref-op-update/", f"/api/v2/dref/{id}/", - "/api/v2/field-report/", - f"/api/v2/field-report/{id}/", "/api/v2/flash-update/", "/api/v2/flash-update-file/", f"/api/v2/flash-update/{id}/", - "/api/v2/language/", - f"/api/v2/language/{id}/", "/api/v2/local-units/", f"/api/v2/local-units/{id}/", "/api/v2/ops-learning/", @@ -106,6 +116,15 @@ def test_guest_user_permission(self): f"/api/v2/subscription/{id}/", "/api/v2/users/", f"/api/v2/users/{id}/", + "/api/v2/per-stats/", + "/api/v2/per-options/", + "/api/v2/per-process-status/", + "/api/v2/aggregated-per-process-status/", + "/api/v2/completed-dref/", + "/api/v2/active-dref/", + "/api/v2/dref-share-user/", + "/api/v2/personnel_deployment/", + f"/api/v2/delegation-office/{id}/", # Exports f"/api/v2/export-flash-update/{1}/", ] @@ -115,49 +134,70 @@ def test_guest_user_permission(self): f"/api/v2/export-per/{1}/", ] - go_apis_req_additional_perm = [ + go_post_apis_req_additional_perm = [ "/api/v2/ops-learning/", "/api/v2/per-overview/", f"/api/v2/user/{id}/accepted_license_terms/", - f"/api/v2/language/{id}/bulk-action/", ] - self.authenticate(user=self.guest_user) - def _success_check(response): # NOTE: Only handles json responses self.assertNotIn(response.status_code, [401, 403], response.content) self.assertNotIn(response.json().get("error_code"), [401, 403], response.content) - def _failure_check(response, is_json=True): + def _failure_check(response, check_json_error_code=True): self.assertIn(response.status_code, [401, 403], response.content) - if is_json: + if check_json_error_code: self.assertIn(response.json()["error_code"], [401, 403], response.content) + # check for unauthenticated user + # Unauthenticated user should be able to view public field reports + field_report_pub_response = self.client.get("/api/v2/field-report/") + _success_check(field_report_pub_response) + self.assertEqual(len(field_report_pub_response.json()["results"]), 4) + + # Unauthenticated user should be not be able to do post operations in field reports + field_report_pub_response = self.client.post("/api/v2/field-report/", json=body) + _failure_check(field_report_pub_response, check_json_error_code=False) + + # authenticate guest user + self.authenticate(user=self.guest_user) + for api_url in get_custom_negotiation_apis: headers = { "Accept": "text/html", } response = self.client.get(api_url, headers=headers, stream=True) - _failure_check(response, is_json=False) + _failure_check(response, check_json_error_code=False) - # Guest user should not be able to access get apis that requires IsAuthenticated permission + # # Guest user should not be able to access get apis that requires IsAuthenticated permission for api_url in get_apis: response = self.client.get(api_url) _failure_check(response) - # Guest user should not be able to hit post apis. - for api_url in go_apis + go_apis_req_additional_perm: + # # Guest user should not be able to hit post apis. + for api_url in go_post_apis + go_post_apis_req_additional_perm: response = self.client.post(api_url, json=body) _failure_check(response) - # Guest user should be able to access guest apis + # Guest user should be able to access guest post apis for api_url in guest_apis: response = self.client.post(api_url, json=body) _success_check(response) - # Go user should be able to access go_apis + # Guest user should be able to access guest get apis + for api_url in guest_get_apis: + response = self.client.get(api_url) + _success_check(response) + + # Guest user should be able to view only public field reports + field_report_pub_response = self.client.get("/api/v2/field-report/") + _success_check(field_report_pub_response) + self.assertEqual(len(field_report_pub_response.json()["results"]), 4) + + # authenticate ifrc go user + # Go user should be able to access go_post_apis self.authenticate(user=self.go_user) - for api_url in go_apis: + for api_url in go_post_apis: response = self.client.post(api_url, json=body) _success_check(response) @@ -165,6 +205,11 @@ def _failure_check(response, is_json=True): response = self.client.get(api_url) _success_check(response) + # Go user should be able to view both public + non-public field reports + field_report_response = self.client.get("/api/v2/field-report/") + _success_check(field_report_response) + self.assertEqual(len(field_report_response.json()["results"]), 9) + class AuthTokenTest(APITestCase): def setUp(self): diff --git a/api/views.py b/api/views.py index 5fb1d214d..55e0dfe5f 100644 --- a/api/views.py +++ b/api/views.py @@ -43,7 +43,7 @@ Statuses, ) from flash_update.models import FlashUpdate -from main.permissions import DenyGuestUserMutationPermission +from main.permissions import DenyGuestUserPermission from notifications.models import Subscription, SurgeAlert from notifications.notification import send_notification from registrations.models import Pending, Recovery @@ -977,7 +977,7 @@ def post(self, request): class AddCronJobLog(APIView): authentication_classes = (authentication.TokenAuthentication,) - permission_classes = [permissions.IsAuthenticated, DenyGuestUserMutationPermission] + permission_classes = [permissions.IsAuthenticated, DenyGuestUserPermission] def post(self, request): errors, created = CronJob.sync_cron(request.data) diff --git a/databank/views.py b/databank/views.py index 9fc9198d0..5071031d3 100644 --- a/databank/views.py +++ b/databank/views.py @@ -2,6 +2,8 @@ from rest_framework.authentication import BasicAuthentication, TokenAuthentication from rest_framework.permissions import IsAuthenticated +from main.permissions import DenyGuestUserPermission + from .filter_set import FDRSIncomeFilter from .models import CountryOverview, FDRSIncome from .serializers import CountryOverviewSerializer, FDRSIncomeSerializer @@ -11,7 +13,7 @@ class CountryOverviewViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet) queryset = CountryOverview.objects.all() # TODO: Use global authentication class authentication_classes = (BasicAuthentication, TokenAuthentication) - permission_classes = (IsAuthenticated,) + permission_classes = (IsAuthenticated, DenyGuestUserPermission) serializer_class = CountryOverviewSerializer lookup_field = "country__iso__iexact" diff --git a/deployments/drf_views.py b/deployments/drf_views.py index c4abd3563..fa7d419a4 100644 --- a/deployments/drf_views.py +++ b/deployments/drf_views.py @@ -23,7 +23,7 @@ from api.models import Country, Region from api.view_filters import ListFilter from api.visibility_class import ReadOnlyVisibilityViewsetMixin -from main.permissions import DenyGuestUserMutationPermission +from main.permissions import DenyGuestUserPermission from main.serializers import CsvListMixin from main.utils import is_tableau @@ -143,7 +143,7 @@ class Meta: class PersonnelDeploymentViewset(viewsets.ReadOnlyModelViewSet): authentication_classes = (TokenAuthentication,) - permission_classes = (IsAuthenticated,) + permission_classes = (IsAuthenticated, DenyGuestUserPermission) queryset = PersonnelDeployment.objects.all() serializer_class = PersonnelDeploymentSerializer filterset_class = PersonnelDeploymentFilter @@ -456,7 +456,7 @@ def get_permissions(self): if self.action in ["list", "retrieve"]: permission_classes = [] else: - permission_classes = [IsAuthenticated, DenyGuestUserMutationPermission] + permission_classes = [IsAuthenticated, DenyGuestUserPermission] return [permission() for permission in permission_classes] diff --git a/dref/views.py b/dref/views.py index cf04e7834..f63d33d13 100644 --- a/dref/views.py +++ b/dref/views.py @@ -35,7 +35,7 @@ DrefShareUserSerializer, MiniDrefSerializer, ) -from main.permissions import DenyGuestUserMutationPermission +from main.permissions import DenyGuestUserPermission def filter_dref_queryset_by_user_access(user, queryset): @@ -59,7 +59,7 @@ def filter_dref_queryset_by_user_access(user, queryset): class DrefViewSet(RevisionMixin, viewsets.ModelViewSet): serializer_class = DrefSerializer - permission_classes = [permissions.IsAuthenticated, DenyGuestUserMutationPermission] + permission_classes = [permissions.IsAuthenticated, DenyGuestUserPermission] filterset_class = DrefFilter def get_queryset(self): @@ -76,7 +76,7 @@ def get_queryset(self): url_path="publish", methods=["post"], serializer_class=DrefSerializer, - permission_classes=[permissions.IsAuthenticated, PublishDrefPermission, DenyGuestUserMutationPermission], + permission_classes=[permissions.IsAuthenticated, PublishDrefPermission, DenyGuestUserPermission], ) def get_published(self, request, pk=None, version=None): dref = self.get_object() @@ -89,7 +89,7 @@ def get_published(self, request, pk=None, version=None): class DrefOperationalUpdateViewSet(RevisionMixin, viewsets.ModelViewSet): serializer_class = DrefOperationalUpdateSerializer - permission_classes = [permissions.IsAuthenticated, DenyGuestUserMutationPermission] + permission_classes = [permissions.IsAuthenticated, DenyGuestUserPermission] filterset_class = DrefOperationalUpdateFilter def get_queryset(self): @@ -123,7 +123,7 @@ def get_queryset(self): url_path="publish", methods=["post"], serializer_class=DrefOperationalUpdateSerializer, - permission_classes=[permissions.IsAuthenticated, PublishDrefPermission, DenyGuestUserMutationPermission], + permission_classes=[permissions.IsAuthenticated, PublishDrefPermission, DenyGuestUserPermission], ) def get_published(self, request, pk=None, version=None): operational_update = self.get_object() @@ -136,7 +136,7 @@ def get_published(self, request, pk=None, version=None): class DrefFinalReportViewSet(RevisionMixin, viewsets.ModelViewSet): serializer_class = DrefFinalReportSerializer - permission_classes = [permissions.IsAuthenticated, DenyGuestUserMutationPermission] + permission_classes = [permissions.IsAuthenticated, DenyGuestUserPermission] def get_queryset(self): user = self.request.user @@ -155,7 +155,7 @@ def get_queryset(self): url_path="publish", methods=["post"], serializer_class=DrefFinalReportSerializer, - permission_classes=[permissions.IsAuthenticated, PublishDrefPermission, DenyGuestUserMutationPermission], + permission_classes=[permissions.IsAuthenticated, PublishDrefPermission, DenyGuestUserPermission], ) def get_published(self, request, pk=None, version=None): field_report = self.get_object() @@ -172,7 +172,7 @@ def get_published(self, request, pk=None, version=None): class DrefFileViewSet(mixins.ListModelMixin, mixins.CreateModelMixin, viewsets.GenericViewSet): - permission_classes = [permissions.IsAuthenticated, DenyGuestUserMutationPermission] + permission_classes = [permissions.IsAuthenticated, DenyGuestUserPermission] serializer_class = DrefFileSerializer def get_queryset(self): @@ -185,7 +185,7 @@ def get_queryset(self): detail=False, url_path="multiple", methods=["POST"], - permission_classes=[permissions.IsAuthenticated, DenyGuestUserMutationPermission], + permission_classes=[permissions.IsAuthenticated, DenyGuestUserPermission], ) def multiple_file(self, request, pk=None, version=None): # converts querydict to original dict @@ -202,6 +202,7 @@ class CompletedDrefOperationsViewSet(viewsets.ReadOnlyModelViewSet): serializer_class = CompletedDrefOperationsSerializer permission_classes = [ permissions.IsAuthenticated, + DenyGuestUserPermission, ] filterset_class = CompletedDrefOperationsFilterSet queryset = DrefFinalReport.objects.filter(is_published=True).order_by("-created_at").distinct() @@ -213,9 +214,7 @@ def get_queryset(self): class ActiveDrefOperationsViewSet(viewsets.ReadOnlyModelViewSet): serializer_class = MiniDrefSerializer - permission_classes = [ - permissions.IsAuthenticated, - ] + permission_classes = [permissions.IsAuthenticated, DenyGuestUserPermission] filterset_class = ActiveDrefFilterSet queryset = ( Dref.objects.prefetch_related("planned_interventions", "needs_identified", "national_society_actions", "users") @@ -230,7 +229,7 @@ def get_queryset(self): class DrefShareView(views.APIView): - permission_classes = [permissions.IsAuthenticated, DenyGuestUserMutationPermission] + permission_classes = [permissions.IsAuthenticated, DenyGuestUserPermission] @extend_schema(request=AddDrefUserSerializer, responses=None) def post(self, request): @@ -245,6 +244,7 @@ def post(self, request): class DrefShareUserViewSet(viewsets.ReadOnlyModelViewSet): permission_classes = [ permissions.IsAuthenticated, + DenyGuestUserPermission, ] serializer_class = DrefShareUserSerializer filterset_class = DrefShareUserFilterSet diff --git a/flash_update/views.py b/flash_update/views.py index fb89a5cd6..b6761f553 100644 --- a/flash_update/views.py +++ b/flash_update/views.py @@ -14,7 +14,7 @@ from rest_framework.response import Response from api.serializers import ActionSerializer -from main.permissions import DenyGuestUserMutationPermission +from main.permissions import DenyGuestUserPermission from .filter_set import FlashUpdateFilter from .models import ( @@ -39,7 +39,7 @@ class FlashUpdateViewSet(viewsets.ModelViewSet): serializer_class = FlashUpdateSerializer - permission_classes = [permissions.IsAuthenticated, DenyGuestUserMutationPermission] + permission_classes = [permissions.IsAuthenticated, DenyGuestUserPermission] filterset_class = FlashUpdateFilter def get_queryset(self): @@ -69,7 +69,7 @@ def get_queryset(self): class FlashUpdateFileViewSet(mixins.ListModelMixin, mixins.CreateModelMixin, viewsets.GenericViewSet): - permission_classes = [permissions.IsAuthenticated, DenyGuestUserMutationPermission] + permission_classes = [permissions.IsAuthenticated, DenyGuestUserPermission] serializer_class = FlashGraphicMapSerializer def get_queryset(self): @@ -80,7 +80,7 @@ def get_queryset(self): detail=False, url_path="multiple", methods=["POST"], - permission_classes=[permissions.IsAuthenticated, DenyGuestUserMutationPermission], + permission_classes=[permissions.IsAuthenticated, DenyGuestUserPermission], ) def multiple_file(self, request, pk=None, version=None): files = [files[0] for files in dict((request.data).lists()).values()] @@ -113,13 +113,13 @@ class DonorsViewSet(viewsets.ReadOnlyModelViewSet): class ShareFlashUpdateViewSet(mixins.CreateModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet): queryset = FlashUpdateShare.objects.all() serializer_class = ShareFlashUpdateSerializer - permission_classes = [permissions.IsAuthenticated, DenyGuestUserMutationPermission] + permission_classes = [permissions.IsAuthenticated, DenyGuestUserPermission] class ExportFlashUpdateView(views.APIView): permission_classes = [ permissions.IsAuthenticated, - DenyGuestUserMutationPermission, + DenyGuestUserPermission, ] @extend_schema(request=None, responses=ExportFlashUpdateViewSerializer) diff --git a/lang/views.py b/lang/views.py index e34e7c801..03e26f8fd 100644 --- a/lang/views.py +++ b/lang/views.py @@ -9,8 +9,6 @@ from rest_framework.authentication import TokenAuthentication from rest_framework.decorators import action as djaction -from main.permissions import DenyGuestUserMutationPermission - from .models import String from .permissions import LangStringPermission from .serializers import ( @@ -26,7 +24,7 @@ class LanguageViewSet(viewsets.ViewSet): # TODO: Cache retrive response to file authentication_classes = (TokenAuthentication,) - permission_classes = (LangStringPermission, DenyGuestUserMutationPermission) + permission_classes = (LangStringPermission,) lookup_url_kwarg = "pk" @extend_schema(request=None, responses=LanguageListSerializer) diff --git a/local_units/views.py b/local_units/views.py index 3a6dc0805..e1a0ecdc6 100644 --- a/local_units/views.py +++ b/local_units/views.py @@ -33,7 +33,7 @@ PrivateLocalUnitDetailSerializer, PrivateLocalUnitSerializer, ) -from main.permissions import DenyGuestUserMutationPermission +from main.permissions import DenyGuestUserPermission class PrivateLocalUnitViewSet(viewsets.ModelViewSet): @@ -48,7 +48,7 @@ class PrivateLocalUnitViewSet(viewsets.ModelViewSet): "local_branch_name", "english_branch_name", ) - permission_classes = [permissions.IsAuthenticated, IsAuthenticatedForLocalUnit, DenyGuestUserMutationPermission] + permission_classes = [permissions.IsAuthenticated, IsAuthenticatedForLocalUnit, DenyGuestUserPermission] def get_serializer_class(self): if self.action == "list": @@ -64,7 +64,7 @@ def destroy(self, request, *args, **kwargs): url_path="validate", methods=["post"], serializer_class=PrivateLocalUnitSerializer, - permission_classes=[permissions.IsAuthenticated, ValidateLocalUnitPermission, DenyGuestUserMutationPermission], + permission_classes=[permissions.IsAuthenticated, ValidateLocalUnitPermission, DenyGuestUserPermission], ) def get_validate(self, request, pk=None, version=None): local_unit = self.get_object() @@ -136,4 +136,7 @@ class DelegationOfficeListAPIView(ListAPIView): class DelegationOfficeDetailAPIView(RetrieveAPIView): queryset = DelegationOffice.objects.all() serializer_class = DelegationOfficeSerializer - permission_classes = [permissions.IsAuthenticated] + permission_classes = [ + permissions.IsAuthenticated, + DenyGuestUserPermission, + ] diff --git a/main/permissions.py b/main/permissions.py index d58662e96..be0f78cda 100644 --- a/main/permissions.py +++ b/main/permissions.py @@ -14,14 +14,17 @@ def has_object_permission(self, request, view, obj): class DenyGuestUserMutationPermission(permissions.BasePermission): """ - Custom permission to deny mutation and query actions for logged-in guest users. + Custom permission to deny mutation actions for logged-in guest users. - This permission class restricts all (read, write, update, delete) operations if the user is a guest. + This permission class restricts all (write, update, delete) operations if the user is a guest. """ def _has_permission(self, request, view): + # Allow all safe methods (GET, HEAD, OPTIONS) which are non-mutating. + if request.method in permissions.SAFE_METHODS: + return True + # For mutation methods (POST, PUT, DELETE, etc.): - # Check if the user is authenticated. if not bool(request.user and request.user.is_authenticated): # Deny access if the user is not authenticated. return False @@ -33,3 +36,18 @@ def has_permission(self, request, view): def has_object_permission(self, request, view, obj): return self._has_permission(request, view) + + +class DenyGuestUserPermission(DenyGuestUserMutationPermission): + """ + Custom permission to deny all actions(GET, POST, PUT, DELETE) for logged-in guest users. + + This permission class restricts all (read, write, update, delete) operations if the user is a guest. + """ + + def _has_permission(self, request, view): + if not bool(request.user and request.user.is_authenticated): + # Deny access if the user is not authenticated. + return False + + return not request.user.profile.limit_access_to_guest diff --git a/notifications/drf_views.py b/notifications/drf_views.py index 79fa957cd..1cc48e79c 100644 --- a/notifications/drf_views.py +++ b/notifications/drf_views.py @@ -8,7 +8,7 @@ from deployments.models import MolnixTag from main.filters import CharInFilter -from main.permissions import DenyGuestUserMutationPermission +from main.permissions import DenyGuestUserPermission from .models import Subscription, SurgeAlert from .serializers import ( # UnauthenticatedSurgeAlertSerializer, @@ -95,7 +95,7 @@ def get_queryset(self): class SubscriptionViewset(viewsets.ModelViewSet): serializer_class = SubscriptionSerializer authentication_classes = (TokenAuthentication,) - permission_classes = (IsAuthenticated, DenyGuestUserMutationPermission) + permission_classes = (IsAuthenticated, DenyGuestUserPermission) search_fields = ("user__username", "rtype") # for /docs def get_queryset(self): diff --git a/per/drf_views.py b/per/drf_views.py index 7743b9d79..fd1c64e65 100644 --- a/per/drf_views.py +++ b/per/drf_views.py @@ -19,7 +19,7 @@ from api.models import Country from deployments.models import SectorTag -from main.permissions import DenyGuestUserMutationPermission +from main.permissions import DenyGuestUserPermission from main.utils import SpreadSheetContentNegotiation from per.filter_set import ( PerDocumentFilter, @@ -227,7 +227,7 @@ def get_queryset(self): class CountryPerStatsViewset(mixins.ListModelMixin, viewsets.GenericViewSet): serializer_class = LatestCountryOverviewSerializer filterset_class = PerOverviewFilter - permission_classes = [IsAuthenticated] + permission_classes = [IsAuthenticated, DenyGuestUserPermission] def get_queryset(self): return Overview.objects.select_related("country", "type_of_assessment").order_by("-created_at") @@ -235,7 +235,7 @@ def get_queryset(self): class PerOverviewViewSet(viewsets.ModelViewSet): serializer_class = PerOverviewSerializer - permission_classes = [IsAuthenticated, PerPermission, DenyGuestUserMutationPermission] + permission_classes = [IsAuthenticated, PerPermission, DenyGuestUserPermission] filterset_class = PerOverviewFilter ordering_fields = "__all__" get_request_user_regions = RegionRestrictedAdmin.get_request_user_regions @@ -247,7 +247,7 @@ def get_queryset(self): class ExportPerView(views.APIView): - permission_classes = [permissions.IsAuthenticated, DenyGuestUserMutationPermission] + permission_classes = [permissions.IsAuthenticated, DenyGuestUserPermission] content_negotiation_class = SpreadSheetContentNegotiation @@ -507,7 +507,7 @@ def get(self, request, pk, format=None): class NewPerWorkPlanViewSet(viewsets.ModelViewSet): - permission_classes = (IsAuthenticated, PerGeneralPermission, DenyGuestUserMutationPermission) + permission_classes = (IsAuthenticated, PerGeneralPermission, DenyGuestUserPermission) queryset = PerWorkPlan.objects.all() serializer_class = PerWorkPlanSerializer filterset_class = PerWorkPlanFilter @@ -524,7 +524,7 @@ class FormPrioritizationViewSet(viewsets.ModelViewSet): serializer_class = FormPrioritizationSerializer queryset = FormPrioritization.objects.all() filterset_class = PerPrioritizationFilter - permission_classes = (IsAuthenticated, PerGeneralPermission, DenyGuestUserMutationPermission) + permission_classes = (IsAuthenticated, PerGeneralPermission, DenyGuestUserPermission) ordering_fields = "__all__" @@ -535,7 +535,7 @@ class PublicFormPrioritizationViewSet(viewsets.ReadOnlyModelViewSet): class PerOptionsView(views.APIView): - permission_classes = [permissions.IsAuthenticated] + permission_classes = [permissions.IsAuthenticated, DenyGuestUserPermission] ordering_fields = "__all__" @extend_schema(request=None, responses=PerOptionsSerializer) @@ -554,7 +554,7 @@ def get(self, request, version=None): class PerProcessStatusViewSet(viewsets.ReadOnlyModelViewSet): serializer_class = PerProcessSerializer filterset_class = PerOverviewFilter - permission_classes = [permissions.IsAuthenticated] + permission_classes = [permissions.IsAuthenticated, DenyGuestUserPermission] ordering_fields = "__all__" get_request_user_regions = RegionRestrictedAdmin.get_request_user_regions get_filtered_queryset = RegionRestrictedAdmin.get_filtered_queryset @@ -575,7 +575,7 @@ def get_queryset(self): class FormAssessmentViewSet(viewsets.ModelViewSet): serializer_class = PerAssessmentSerializer - permission_classes = [permissions.IsAuthenticated, PerGeneralPermission, DenyGuestUserMutationPermission] + permission_classes = [permissions.IsAuthenticated, PerGeneralPermission, DenyGuestUserPermission] ordering_fields = "__all__" def get_queryset(self): @@ -591,7 +591,7 @@ def get_queryset(self): class PerFileViewSet(mixins.ListModelMixin, mixins.CreateModelMixin, viewsets.GenericViewSet): - permission_classes = [permissions.IsAuthenticated, DenyGuestUserMutationPermission] + permission_classes = [permissions.IsAuthenticated, DenyGuestUserPermission] serializer_class = PerFileSerializer def get_queryset(self): @@ -604,7 +604,7 @@ def get_queryset(self): detail=False, url_path="multiple", methods=["POST"], - permission_classes=[permissions.IsAuthenticated, DenyGuestUserMutationPermission], + permission_classes=[permissions.IsAuthenticated, DenyGuestUserPermission], ) def multiple_file(self, request, pk=None, version=None): # converts querydict to original dict @@ -639,7 +639,7 @@ def get_queryset(self): class PerAggregatedViewSet(viewsets.ReadOnlyModelViewSet): serializer_class = PerProcessSerializer filterset_class = PerOverviewFilter - permission_classes = [permissions.IsAuthenticated] + permission_classes = [permissions.IsAuthenticated, DenyGuestUserPermission] ordering_fields = ["assessment_number", "phase", "date_of_assessment"] get_request_user_regions = RegionRestrictedAdmin.get_request_user_regions get_filtered_queryset = RegionRestrictedAdmin.get_filtered_queryset @@ -708,7 +708,7 @@ class OpsLearningViewset(viewsets.ModelViewSet): """ queryset = OpsLearning.objects.all() - permission_classes = [DenyGuestUserMutationPermission, OpsLearningPermission] + permission_classes = [DenyGuestUserPermission, OpsLearningPermission] filterset_class = OpsLearningFilter search_fields = ( "learning", @@ -812,7 +812,7 @@ class PerDocumentUploadViewSet(viewsets.ModelViewSet): queryset = PerDocumentUpload.objects.all() serializer_class = PerDocumentUploadSerializer filterset_class = PerDocumentFilter - permission_classes = [permissions.IsAuthenticated, PerDocumentUploadPermission, DenyGuestUserMutationPermission] + permission_classes = [permissions.IsAuthenticated, PerDocumentUploadPermission, DenyGuestUserPermission] def get_queryset(self): queryset = super().get_queryset()