diff --git a/myproject/accounts/models.py b/myproject/accounts/models.py index 1a290f9..d835b75 100644 --- a/myproject/accounts/models.py +++ b/myproject/accounts/models.py @@ -21,14 +21,12 @@ class CustomUserManager(BaseUserManager): return user def create_superuser(self, email, name, password=None, **extra_fields): - extra_fields.setdefault('is_staff', True) + extra_fields.setdefault('is_staff', False) # CustomUser не должен иметь доступ к Django Admin extra_fields.setdefault('is_superuser', True) extra_fields.setdefault('is_active', True) # Суперпользователь автоматически имеет подтвержденный email extra_fields.setdefault('is_email_confirmed', True) - if extra_fields.get('is_staff') is not True: - raise ValueError('Суперпользователь должен иметь is_staff=True.') if extra_fields.get('is_superuser') is not True: raise ValueError('Суперпользователь должен иметь is_superuser=True.') diff --git a/myproject/myproject/admin_access_middleware.py b/myproject/myproject/admin_access_middleware.py deleted file mode 100644 index 921569f..0000000 --- a/myproject/myproject/admin_access_middleware.py +++ /dev/null @@ -1,98 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Middleware для ограничения доступа к админке. - -SECURITY: Этот middleware обеспечивает изоляцию аутентификации между -PlatformAdmin (public schema) и CustomUser (tenant schemas). - -Правила доступа к /admin/: -- На PUBLIC домене: только PlatformAdmin может входить -- На TENANT доменах: только PlatformAdmin с is_superuser=True (для поддержки) - или CustomUser с is_superuser=True (системный пользователь тенанта) -""" -from django.shortcuts import render -from django.db import connection - - -class TenantAdminAccessMiddleware: - """ - Middleware для контроля доступа к административным разделам. - - Обеспечивает разделение между: - - PlatformAdmin (администраторы платформы) на public домене - - CustomUser (пользователи тенантов) на tenant доменах - """ - - def __init__(self, get_response): - self.get_response = get_response - - def _render_error(self, request, message): - """Рендерит страницу ошибки доступа.""" - return render(request, 'errors/access_denied.html', { - 'message': message - }, status=403) - - def __call__(self, request): - # Оптимизация: загружаем роль пользователя один раз для всего запроса - if hasattr(request, 'user') and request.user.is_authenticated: - schema_name = getattr(connection, 'schema_name', 'public') - # Только для tenant схем и CustomUser загружаем роль с select_related - if schema_name != 'public': - from accounts.models import CustomUser - if isinstance(request.user, CustomUser): - # Проверяем, не загружена ли уже роль - if not hasattr(request.user, '_role_prefetched'): - try: - # Загружаем пользователя с ролью через select_related - request.user = CustomUser.objects.select_related( - 'tenant_role__role' - ).get(pk=request.user.pk) - request.user._role_prefetched = True - except CustomUser.DoesNotExist: - pass - - # Проверяем, это admin URL? - if request.path.startswith('/admin/'): - # Импортируем здесь чтобы избежать circular imports - from platform_admin.models import PlatformAdmin - - # Получаем текущую schema - schema_name = getattr(connection, 'schema_name', 'public') - is_public = schema_name == 'public' - - # Проверяем наличие атрибута user (добавляется AuthenticationMiddleware) - if hasattr(request, 'user') and request.user.is_authenticated: - user = request.user - is_platform_admin = isinstance(user, PlatformAdmin) - - if is_public: - # PUBLIC DOMAIN: только PlatformAdmin - if not is_platform_admin: - return self._render_error( - request, - 'Административная панель платформы доступна только ' - 'для администраторов платформы. ' - 'Если вы владелец магазина, перейдите на домен вашего магазина.' - ) - else: - # TENANT DOMAIN: PlatformAdmin (superuser) или CustomUser (superuser) - if is_platform_admin: - # PlatformAdmin на tenant домене - только суперадмин - if not user.is_superuser: - return self._render_error( - request, - 'Только суперадминистраторы платформы ' - 'могут получить доступ к этому разделу.' - ) - else: - # CustomUser на tenant домене - if not user.is_superuser: - return self._render_error( - request, - 'Только системные администраторы тенанта ' - 'могут получить доступ к этому разделу. ' - 'Используйте панель управления магазином.' - ) - - response = self.get_response(request) - return response diff --git a/myproject/myproject/settings.py b/myproject/myproject/settings.py index bbf0a34..a44f70a 100644 --- a/myproject/myproject/settings.py +++ b/myproject/myproject/settings.py @@ -126,7 +126,6 @@ MIDDLEWARE = [ 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', # 4. Определение пользователя - 'myproject.admin_access_middleware.TenantAdminAccessMiddleware', # 5. ТЕПЕРЬ проверка работает (после auth) 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'simple_history.middleware.HistoryRequestMiddleware', diff --git a/myproject/tenants/services/onboarding.py b/myproject/tenants/services/onboarding.py index abd2f44..01bad19 100644 --- a/myproject/tenants/services/onboarding.py +++ b/myproject/tenants/services/onboarding.py @@ -231,7 +231,7 @@ class TenantOnboardingService: # 2. Техподдержка платформы # SECURITY: НЕ создаём отдельную учетку CustomUser для саппорта # PlatformAdmin с is_superuser=True уже имеет полный доступ к tenant - # через PlatformAdminBackend и TenantAdminAccessMiddleware + # через PlatformAdminBackend (может залогиниться и зайти в /admin/) logger.info("Техподдержка: используется PlatformAdmin (отдельный CustomUser НЕ создаётся)") @classmethod