fix: Исправлена вторая ошибка - отключен ModelBackend для CustomUser
Проблема: После первого исправления ошибка продолжалась, но теперь в другом месте. Django's ModelBackend пытался проверить permissions для CustomUser через Permission.objects.filter(group__user=user_obj), что вызывало ошибку "Cannot query 'chupa@chus.by': Must be 'PlatformAdmin' instance" Причина: RoleBasedPermissionBackend наследует ModelBackend, и для CustomUser все равно вызывался super().has_perm(), который обращался к Django Permission таблице в public schema, ожидая PlatformAdmin. Решение: Полностью отключен вызов super().has_perm() и super().has_module_perms() для CustomUser. Теперь для CustomUser используется только role-based permission checking, а для PlatformAdmin - стандартный ModelBackend. Изменения в user_roles/auth_backend.py: - has_perm(): добавлена ветка if is_tenant, которая полностью обрабатывает CustomUser без вызова super() - has_module_perms(): аналогичная логика - Для PlatformAdmin сохранена проверка через super() (ModelBackend) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -99,45 +99,46 @@ class RoleBasedPermissionBackend(ModelBackend):
|
||||
if not user_obj.is_authenticated:
|
||||
return False
|
||||
|
||||
# Для CustomUser (пользователи тенантов) пропускаем стандартную проверку Django permissions
|
||||
# т.к. AUTH_USER_MODEL = PlatformAdmin, и super().has_perm() будет пытаться
|
||||
# искать permissions для PlatformAdmin, а не для CustomUser
|
||||
# Определяем тип пользователя
|
||||
is_tenant = _is_tenant_user(user_obj)
|
||||
|
||||
if not is_tenant:
|
||||
# Для PlatformAdmin проверяем стандартные permissions через ModelBackend
|
||||
if super().has_perm(user_obj, perm, obj):
|
||||
# Для CustomUser (пользователи тенантов) НЕ вызываем super().has_perm()
|
||||
# т.к. AUTH_USER_MODEL = PlatformAdmin, и ModelBackend будет пытаться
|
||||
# искать permissions в Django Permission таблице для PlatformAdmin
|
||||
if is_tenant:
|
||||
# Суперпользователь имеет все права
|
||||
if user_obj.is_superuser:
|
||||
return True
|
||||
|
||||
# Суперпользователь имеет все права
|
||||
if user_obj.is_superuser:
|
||||
return True
|
||||
# ВАЖНО: В public схеме нет таблиц UserRole/Role!
|
||||
if _is_public_schema():
|
||||
return False
|
||||
|
||||
# ВАЖНО: В public схеме нет таблиц UserRole/Role!
|
||||
# Используем только стандартные Django permissions.
|
||||
if _is_public_schema():
|
||||
return False
|
||||
# Для CustomUser получаем роль пользователя в текущем тенанте
|
||||
user_role = RoleService.get_user_role(user_obj)
|
||||
if not user_role:
|
||||
return False
|
||||
|
||||
# Для CustomUser получаем роль пользователя в текущем тенанте
|
||||
# ВАЖНО: RoleService работает с текущей tenant schema!
|
||||
user_role = RoleService.get_user_role(user_obj)
|
||||
if not user_role:
|
||||
return False
|
||||
# Парсим разрешение: 'app_label.action_modelname'
|
||||
try:
|
||||
app_label, codename = perm.split('.')
|
||||
action = codename.split('_')[0]
|
||||
except (ValueError, IndexError):
|
||||
return False
|
||||
|
||||
# Парсим разрешение: 'app_label.action_modelname'
|
||||
# Например: 'products.add_product' -> app_label='products', action='add'
|
||||
try:
|
||||
app_label, codename = perm.split('.')
|
||||
# Извлекаем действие из codename (add_product -> add, change_order -> change)
|
||||
action = codename.split('_')[0]
|
||||
except (ValueError, IndexError):
|
||||
return False
|
||||
# Проверяем, есть ли у роли это разрешение
|
||||
role_perms = self.ROLE_PERMISSIONS.get(user_role.code, {})
|
||||
app_perms = role_perms.get(app_label, [])
|
||||
|
||||
# Проверяем, есть ли у роли это разрешение
|
||||
role_perms = self.ROLE_PERMISSIONS.get(user_role.code, {})
|
||||
app_perms = role_perms.get(app_label, [])
|
||||
return action in app_perms
|
||||
else:
|
||||
# Для PlatformAdmin проверяем стандартные permissions через ModelBackend
|
||||
# Суперпользователь имеет все права
|
||||
if user_obj.is_superuser:
|
||||
return True
|
||||
|
||||
return action in app_perms
|
||||
# Проверяем через родительский ModelBackend
|
||||
return super().has_perm(user_obj, perm, obj)
|
||||
|
||||
def has_module_perms(self, user_obj, app_label):
|
||||
"""
|
||||
@@ -156,28 +157,32 @@ class RoleBasedPermissionBackend(ModelBackend):
|
||||
if not user_obj.is_authenticated:
|
||||
return False
|
||||
|
||||
# Для CustomUser (пользователи тенантов) пропускаем стандартную проверку Django permissions
|
||||
# Определяем тип пользователя
|
||||
is_tenant = _is_tenant_user(user_obj)
|
||||
|
||||
if not is_tenant:
|
||||
# Для PlatformAdmin проверяем стандартные permissions через ModelBackend
|
||||
if super().has_module_perms(user_obj, app_label):
|
||||
# Для CustomUser (пользователи тенантов) НЕ вызываем super().has_module_perms()
|
||||
if is_tenant:
|
||||
# Суперпользователь имеет все права
|
||||
if user_obj.is_superuser:
|
||||
return True
|
||||
|
||||
# Суперпользователь имеет все права
|
||||
if user_obj.is_superuser:
|
||||
return True
|
||||
# ВАЖНО: В public схеме нет таблиц UserRole/Role!
|
||||
if _is_public_schema():
|
||||
return False
|
||||
|
||||
# ВАЖНО: В public схеме нет таблиц UserRole/Role!
|
||||
# Используем только стандартные Django permissions.
|
||||
if _is_public_schema():
|
||||
return False
|
||||
# Для CustomUser получаем роль пользователя в текущем тенанте
|
||||
user_role = RoleService.get_user_role(user_obj)
|
||||
if not user_role:
|
||||
return False
|
||||
|
||||
# Для CustomUser получаем роль пользователя в текущем тенанте
|
||||
user_role = RoleService.get_user_role(user_obj)
|
||||
if not user_role:
|
||||
return False
|
||||
# Проверяем, есть ли у роли какие-либо разрешения для этого приложения
|
||||
role_perms = self.ROLE_PERMISSIONS.get(user_role.code, {})
|
||||
return app_label in role_perms and len(role_perms[app_label]) > 0
|
||||
else:
|
||||
# Для PlatformAdmin проверяем стандартные permissions через ModelBackend
|
||||
# Суперпользователь имеет все права
|
||||
if user_obj.is_superuser:
|
||||
return True
|
||||
|
||||
# Проверяем, есть ли у роли какие-либо разрешения для этого приложения
|
||||
role_perms = self.ROLE_PERMISSIONS.get(user_role.code, {})
|
||||
return app_label in role_perms and len(role_perms[app_label]) > 0
|
||||
# Проверяем через родительский ModelBackend
|
||||
return super().has_module_perms(user_obj, app_label)
|
||||
|
||||
Reference in New Issue
Block a user