From 5e0e058b3ac8f1117fc10dc0a3d8b63a4ae540d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B3=D0=BE=D1=80=D1=8C=20=D0=9D=D0=B0=D0=B4=D0=B5?= =?UTF-8?q?=D0=B8=D0=BD?= Date: Mon, 29 Dec 2025 16:08:15 +0300 Subject: [PATCH] fix: add CanViewRequest permission for recipients and cc_users to view request details --- backend/api/v1/requests_app/permissions.py | 37 ++++++++++++++++++++++ backend/api/v1/requests_app/views.py | 10 +++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/backend/api/v1/requests_app/permissions.py b/backend/api/v1/requests_app/permissions.py index a53a6d55..4dd928a4 100644 --- a/backend/api/v1/requests_app/permissions.py +++ b/backend/api/v1/requests_app/permissions.py @@ -37,6 +37,43 @@ class IsRecipientOfRequest(BasePermission): return obj.recipients.filter(id=user.id).exists() +class CanViewRequest(BasePermission): + """Проверяет, может ли пользователь просматривать заявку. + + Доступ разрешается если пользователь: + - staff/superuser + - автор заявки (employee) + - получатель заявки (recipients) + - в копии заявки (cc_users) + """ + + message = "У вас нет доступа к этой заявке." + + def has_permission(self, request: Request, view: Any) -> bool: + return bool(getattr(request.user, "is_authenticated", False)) + + def has_object_permission(self, request: Request, view: Any, obj: Any) -> bool: + user = request.user + + # Staff/superuser могут просматривать любые заявки + if getattr(user, "is_staff", False) or getattr(user, "is_superuser", False): + return True + + # Автор заявки + if getattr(obj, "employee_id", None) == user.id: + return True + + # Получатель заявки (recipients) + if obj.recipients.filter(id=user.id).exists(): + return True + + # В копии заявки (cc_users) + if obj.cc_users.filter(id=user.id).exists(): + return True + + return False + + class CommentsPermission(BasePermission): """Комментарии: модельные права, staff, head. diff --git a/backend/api/v1/requests_app/views.py b/backend/api/v1/requests_app/views.py index 6d97fdc5..7458791f 100644 --- a/backend/api/v1/requests_app/views.py +++ b/backend/api/v1/requests_app/views.py @@ -27,6 +27,7 @@ from rest_framework.serializers import ( from ..permissions import AdminOrActionOrModelPerms, AdminOrDeptAllowed, IsSelfOrStaff from .permissions import ( + CanViewRequest, CommentsPermission, DeptCanProcess, DeptChangeRequest, @@ -96,7 +97,14 @@ class RequestViewSet(viewsets.ModelViewSet): if self.action == "cancel": return [IsSelfOrStaff()] if self.action == "retrieve": - return [(IsSelfOrStaff | DeptViewRequest | AdminOrActionOrModelPerms)()] + # Автор, получатель, в копии, по отделу, staff/admin + return [ + ( + CanViewRequest + | DeptViewRequest + | AdminOrActionOrModelPerms + )() + ] if self.action == "destroy": return [ (IsSelfOrStaff | AdminOrActionOrModelPerms | DeptChangeRequest)(),