Files
mostovik-backend/src/apps/core/permissions.py
Aleksandr Meshchriakov f121445313 feat(core): add core module with mixins, services, and background jobs
- Add Model Mixins: TimestampMixin, SoftDeleteMixin, AuditMixin, etc.
- Add Base Services: BaseService, BulkOperationsMixin, QueryOptimizerMixin
- Add Base ViewSets with bulk operations
- Add BackgroundJob model for Celery task tracking
- Add BaseAppCommand for management commands
- Add permissions, pagination, filters, cache, logging
- Migrate tests to factory_boy + faker
- Add CHANGELOG.md
- 297 tests passing
2026-01-21 11:47:26 +01:00

129 lines
4.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Базовые классы разрешений для 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