- 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 приложения
122 lines
4.8 KiB
Python
122 lines
4.8 KiB
Python
# -*- 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
|