from django.shortcuts import render, redirect, get_object_or_404 from django.contrib.auth.decorators import login_required from django.contrib import messages from user_roles.models import Role, UserRole from user_roles.services import RoleService from user_roles.decorators import owner_required # Импортируем CustomUser напрямую, т.к. AUTH_USER_MODEL = PlatformAdmin from accounts.models import CustomUser @login_required @owner_required def user_role_list(request): """Список пользователей с их ролями""" # Фильтр по активности show_inactive = request.GET.get('show_inactive', 'false') == 'true' # Базовый queryset - исключаем скрытые роли (platform_support) base_qs = UserRole.objects.select_related('user', 'role', 'created_by').exclude( role__code__in=Role.HIDDEN_ROLES ) if show_inactive: user_roles = base_qs.all() else: # По умолчанию показываем только активных user_roles = base_qs.filter( is_active=True, user__is_active=True ) # Показываем только видимые роли (без platform_support) roles = RoleService.get_visible_roles() context = { 'user_roles': user_roles, 'roles': roles, 'show_inactive': show_inactive, } return render(request, 'user_roles/user_role_list.html', context) @login_required @owner_required def user_role_create(request): """Создание нового пользователя с ролью""" if request.method == 'POST': email = request.POST.get('email') name = request.POST.get('name') role_code = request.POST.get('role') password = request.POST.get('password', '').strip() # Если пароль не указан, генерируем случайный if not password: password = CustomUser.objects.make_random_password(12) try: # Проверяем, не существует ли уже пользователь с таким email existing_user = CustomUser.objects.filter(email=email).first() if existing_user: # Пользователь существует - проверяем его статус if not existing_user.is_active: # Пользователь деактивирован - предлагаем реактивировать messages.warning( request, f'Пользователь {email} уже существует, но деактивирован. ' f'Используйте функцию "Реактивировать" в списке пользователей.' ) else: # Пользователь активен - возможно, уже имеет роль в другом тенанте messages.error( request, f'Пользователь с email {email} уже существует в системе.' ) # ВАЖНО: Возвращаемся к форме, чтобы пользователь мог исправить email roles = RoleService.get_visible_roles() context = {'roles': roles} return render(request, 'user_roles/user_role_create.html', context) else: # Создаем нового пользователя user = CustomUser.objects.create_user( email=email, name=name, password=password, is_email_confirmed=True, is_staff=False, # SECURITY: Пользователи ролей НЕ имеют доступа к админке is_superuser=False # SECURITY: Пользователи ролей НЕ суперпользователи ) # Назначаем роль RoleService.assign_role_to_user(user, role_code, created_by=request.user) # DEBUG: Проверяем, что пароль есть print(f"DEBUG: created_user_email={email}, generated_password={password}") # Показываем страницу с паролем context = { 'created_user_email': email, 'generated_password': password, 'user_role': role_code, } return render(request, 'user_roles/user_role_created.html', context) except Exception as e: messages.error(request, f'Ошибка при создании пользователя: {str(e)}') # Показываем только видимые роли (без platform_support) roles = RoleService.get_visible_roles() context = { 'roles': roles, } return render(request, 'user_roles/user_role_create.html', context) @login_required @owner_required def user_role_edit(request, pk): """Изменение роли пользователя""" user_role = get_object_or_404(UserRole, pk=pk) # Защита от редактирования скрытых ролей (platform_support) if user_role.role.code in Role.HIDDEN_ROLES: messages.error(request, 'Недостаточно прав для редактирования этого пользователя') return redirect('user_roles:list') # Защита от самоблокировки can_modify, error_message = RoleService.can_modify_user_role(request.user, user_role) if not can_modify: messages.error(request, error_message) return redirect('user_roles:list') if request.method == 'POST': action = request.POST.get('action', 'update') # Обработка пересоздания пароля if action == 'regenerate_password': try: new_password = CustomUser.objects.make_random_password(12) user_role.user.set_password(new_password) user_role.user.save() messages.success(request, f'Пароль для пользователя {user_role.user.email} успешно обновлен') # Показываем новый пароль в модальном окне roles = RoleService.get_visible_roles() context = { 'user_role': user_role, 'roles': roles, 'generated_password': new_password, } return render(request, 'user_roles/user_role_edit.html', context) except Exception as e: messages.error(request, f'Ошибка при обновлении пароля: {str(e)}') # Обычное обновление роли и имени else: role_code = request.POST.get('role') is_active = request.POST.get('is_active') == 'on' name = request.POST.get('name', '').strip() try: # Обновляем роль role = RoleService.get_role_by_code(role_code) if not role: raise ValueError(f"Роль '{role_code}' не найдена") user_role.role = role user_role.is_active = is_active user_role.save() # Обновляем имя пользователя if name and name != user_role.user.name: user_role.user.name = name user_role.user.save() messages.success(request, f'Данные пользователя {user_role.user.email} обновлены') return redirect('user_roles:list') except Exception as e: messages.error(request, f'Ошибка при обновлении данных: {str(e)}') roles = RoleService.get_visible_roles() context = { 'user_role': user_role, 'roles': roles, } return render(request, 'user_roles/user_role_edit.html', context) @login_required @owner_required def user_role_delete(request, pk): """Деактивация пользователя (soft delete)""" user_role = get_object_or_404(UserRole, pk=pk) # Защита от удаления скрытых ролей (platform_support) if user_role.role.code in Role.HIDDEN_ROLES: messages.error(request, 'Недостаточно прав для удаления этого пользователя') return redirect('user_roles:list') # Защита от самоблокировки can_modify, error_message = RoleService.can_modify_user_role(request.user, user_role) if not can_modify: messages.error(request, error_message) return redirect('user_roles:list') if request.method == 'POST': email = user_role.user.email # Soft delete: деактивируем пользователя и его роль user_role.is_active = False user_role.save() user_role.user.is_active = False user_role.user.save() messages.success(request, f'Пользователь {email} деактивирован') return redirect('user_roles:list') context = { 'user_role': user_role, } return render(request, 'user_roles/user_role_delete.html', context) @login_required @owner_required def user_role_reactivate(request, pk): """Реактивация пользователя""" user_role = get_object_or_404(UserRole, pk=pk) # Защита от реактивации скрытых ролей (platform_support) if user_role.role.code in Role.HIDDEN_ROLES: messages.error(request, 'Недостаточно прав для изменения этого пользователя') return redirect('user_roles:list') if request.method == 'POST': email = user_role.user.email # Реактивируем пользователя и его роль user_role.is_active = True user_role.save() user_role.user.is_active = True user_role.user.save() messages.success(request, f'Пользователь {email} успешно реактивирован') return redirect('user_roles:list') context = { 'user_role': user_role, } return render(request, 'user_roles/user_role_reactivate.html', context)