Обновления в accounts: модели, представления, миграции и новый бэкенд

This commit is contained in:
2026-01-08 22:09:38 +03:00
parent dbf00dab29
commit 796fd8fe18
4 changed files with 139 additions and 15 deletions

View File

@@ -0,0 +1,90 @@
# -*- coding: utf-8 -*-
"""
Authentication backend для CustomUser (пользователей тенантов).
Этот backend используется для аутентификации пользователей магазинов.
Работает ТОЛЬКО на tenant доменах, НЕ на public домене.
ВАЖНО: CustomUser теперь в TENANT_APPS - каждый тенант имеет свою таблицу!
Backend работает с таблицей accounts_customuser в текущей tenant schema.
"""
from django.contrib.auth.backends import ModelBackend
from django.db import connection
class TenantUserBackend(ModelBackend):
"""
Backend аутентификации для CustomUser (tenant-only).
Особенности:
- Работает ТОЛЬКО на tenant доменах (не на public)
- Ищет пользователя в таблице accounts_customuser текущей tenant schema
- Один email в разных тенантах = разные записи в разных таблицах БД
Пользователь из tenant A физически не существует в tenant B.
"""
def authenticate(self, request, username=None, password=None, **kwargs):
"""
Аутентификация CustomUser по email и паролю.
Args:
request: HTTP запрос
username: Email пользователя
password: Пароль
Returns:
CustomUser если аутентификация успешна, иначе None
"""
# Не работает на public домене
schema_name = getattr(connection, 'schema_name', 'public')
if schema_name == 'public':
return None
if username is None or password is None:
return None
# Импортируем напрямую, не через get_user_model()
# т.к. AUTH_USER_MODEL теперь PlatformAdmin
from accounts.models import CustomUser
try:
# django-tenants автоматически направляет запрос в текущую schema
user = CustomUser.objects.get(email=username)
except CustomUser.DoesNotExist:
# Run the default password hasher once to reduce the timing
# difference between an existing and a non-existing user
CustomUser().set_password(password)
return None
if not user.check_password(password):
return None
if not self.user_can_authenticate(user):
return None
return user
def get_user(self, user_id):
"""
Получение CustomUser по ID.
На public домене возвращает None.
"""
schema_name = getattr(connection, 'schema_name', 'public')
if schema_name == 'public':
return None
from accounts.models import CustomUser
try:
return CustomUser.objects.get(pk=user_id)
except CustomUser.DoesNotExist:
return None
def user_can_authenticate(self, user):
"""
Проверка что пользователь активен.
"""
is_active = getattr(user, 'is_active', None)
return is_active or is_active is None