Files
octopus/myproject/platform_admin/backends.py
Andrey Smakotin b63162b1cb Рефакторинг: убрана зависимость от Django Groups/Permissions для CustomUser
- CustomUser теперь наследуется от AbstractBaseUser (вместо AbstractUser)
- Удалены поля groups и user_permissions из CustomUser
- Все authentication backends (TenantUserBackend, PlatformAdminBackend, RoleBasedPermissionBackend) больше НЕ наследуются от ModelBackend
- Добавлены методы has_perm() и has_module_perms() в CustomUser для делегирования проверки прав кастомным backends
- Полная изоляция: CustomUser использует только систему ролей (UserRole), PlatformAdmin использует только is_superuser
- Удалён весь старый код, связанный с Django permissions
- Нет обратной совместимости (не требуется)
- Чистая архитектура для multi-tenant приложения
2026-01-10 00:10:25 +03:00

122 lines
4.8 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.
# -*- coding: utf-8 -*-
"""
Authentication backend для PlatformAdmin.
Этот backend используется для аутентификации администраторов платформы.
Работает на public домене, а также на tenant доменах для суперадминов.
ВАЖНО: НЕ наследуется от ModelBackend! Полностью независимая реализация.
"""
from django.db import connection
class PlatformAdminBackend:
"""
Backend аутентификации для PlatformAdmin.
НЕ наследуется от ModelBackend! Полностью независимая реализация.
Особенности:
- На public домене: аутентифицирует любого PlatformAdmin
- На tenant домене: аутентифицирует только PlatformAdmin с is_superuser=True
(для поддержки и отладки клиентов)
Обычные PlatformAdmin (без is_superuser) не могут логиниться на tenant доменах.
"""
def authenticate(self, request, username=None, password=None, **kwargs):
"""
Аутентификация PlatformAdmin по email и паролю.
Args:
request: HTTP запрос
username: Email администратора
password: Пароль
Returns:
PlatformAdmin если аутентификация успешна, иначе None
"""
from platform_admin.models import PlatformAdmin
if username is None or password is None:
return None
try:
# Всегда читаем из default (public schema)
user = PlatformAdmin.objects.using('default').get(email=username)
except PlatformAdmin.DoesNotExist:
# Run the default password hasher once to reduce the timing
# difference between an existing and a non-existing user
PlatformAdmin().set_password(password)
return None
if not user.check_password(password):
return None
if not self.user_can_authenticate(user):
return None
# На tenant домене — только суперадмин может логиниться
schema_name = getattr(connection, 'schema_name', 'public')
if schema_name != 'public' and not user.is_superuser:
return None
return user
def get_user(self, user_id):
"""
Получение PlatformAdmin по ID.
Всегда читает из public schema.
"""
from platform_admin.models import PlatformAdmin
try:
return PlatformAdmin.objects.using('default').get(pk=user_id)
except PlatformAdmin.DoesNotExist:
return None
def user_can_authenticate(self, user):
"""
Проверка что пользователь активен.
"""
is_active = getattr(user, 'is_active', None)
return is_active or is_active is None
def has_perm(self, user_obj, perm, obj=None):
"""
Проверка permissions для PlatformAdmin.
ВАЖНО: Этот backend работает ТОЛЬКО с PlatformAdmin!
Для CustomUser возвращает None (пропускает проверку).
Для PlatformAdmin проверяем только is_superuser (без groups/permissions).
"""
from platform_admin.models import PlatformAdmin
# Проверяем только PlatformAdmin, CustomUser пропускаем
if not isinstance(user_obj, PlatformAdmin):
return None
# Только суперпользователь имеет права
# (не используем groups/permissions из Django, т.к. AUTH_USER_MODEL != реальная модель)
return user_obj.is_active and user_obj.is_superuser
def has_module_perms(self, user_obj, app_label):
"""
Проверка module permissions для PlatformAdmin.
ВАЖНО: Этот backend работает ТОЛЬКО с PlatformAdmin!
Для CustomUser возвращает None (пропускает проверку).
Для PlatformAdmin проверяем только is_superuser (без groups/permissions).
"""
from platform_admin.models import PlatformAdmin
# Проверяем только PlatformAdmin, CustomUser пропускаем
if not isinstance(user_obj, PlatformAdmin):
return None
# Только суперпользователь имеет права
return user_obj.is_active and user_obj.is_superuser