""" Базовые классы разрешений для API. Предоставляет переиспользуемые permission classes для контроля доступа. """ from rest_framework import permissions from rest_framework.request import Request from rest_framework.views import APIView class IsOwner(permissions.BasePermission): """ Разрешает доступ только владельцу объекта. Объект должен иметь атрибут `user` или `owner`, который сравнивается с текущим пользователем. Пример использования: class MyView(APIView): permission_classes = [IsAuthenticated, IsOwner] """ owner_field = "user" # Можно переопределить в подклассах def has_object_permission(self, request: Request, view: APIView, obj) -> bool: """Проверяет, является ли пользователь владельцем объекта.""" owner = getattr(obj, self.owner_field, None) if owner is None: owner = getattr(obj, "owner", None) return owner == request.user class IsOwnerOrReadOnly(permissions.BasePermission): """ Разрешает изменение только владельцу, остальным - только чтение. SAFE_METHODS (GET, HEAD, OPTIONS) доступны всем аутентифицированным. Изменяющие методы (POST, PUT, PATCH, DELETE) - только владельцу. """ owner_field = "user" def has_object_permission(self, request: Request, view: APIView, obj) -> bool: """Проверяет права на объект.""" # Чтение разрешено всем if request.method in permissions.SAFE_METHODS: return True # Изменение - только владельцу owner = getattr(obj, self.owner_field, None) if owner is None: owner = getattr(obj, "owner", None) return owner == request.user class IsAdminOrReadOnly(permissions.BasePermission): """ Разрешает изменение только админам, остальным - только чтение. SAFE_METHODS доступны всем (включая анонимных). Изменяющие методы - только staff/superuser. """ def has_permission(self, request: Request, view: APIView) -> bool: """Проверяет права на уровне view.""" if request.method in permissions.SAFE_METHODS: return True return request.user and request.user.is_staff class IsAdmin(permissions.BasePermission): """ Разрешает доступ только администраторам (is_staff=True). """ def has_permission(self, request: Request, view: APIView) -> bool: """Проверяет, является ли пользователь администратором.""" return request.user and request.user.is_staff class IsSuperuser(permissions.BasePermission): """ Разрешает доступ только суперпользователям (is_superuser=True). """ def has_permission(self, request: Request, view: APIView) -> bool: """Проверяет, является ли пользователь суперпользователем.""" return request.user and request.user.is_superuser class IsVerified(permissions.BasePermission): """ Разрешает доступ только пользователям с подтверждённым email. Требует наличие поля `is_verified` у модели пользователя. """ message = "Email не подтверждён" def has_permission(self, request: Request, view: APIView) -> bool: """Проверяет, подтверждён ли email пользователя.""" return ( request.user and request.user.is_authenticated and getattr(request.user, "is_verified", False) ) class IsOwnerOrAdmin(permissions.BasePermission): """ Разрешает доступ владельцу объекта или администратору. Полезно для случаев, когда админ должен иметь доступ к любым объектам, а пользователь - только к своим. """ owner_field = "user" def has_object_permission(self, request: Request, view: APIView, obj) -> bool: """Проверяет права на объект.""" if request.user and request.user.is_staff: return True owner = getattr(obj, self.owner_field, None) if owner is None: owner = getattr(obj, "owner", None) return owner == request.user