257 lines
11 KiB
Python
257 lines
11 KiB
Python
from django.shortcuts import render, redirect, get_object_or_404
|
||
from django.contrib.auth.decorators import login_required
|
||
from django.contrib import messages
|
||
from django.contrib.auth import get_user_model
|
||
from user_roles.models import Role, UserRole
|
||
from user_roles.services import RoleService
|
||
from user_roles.decorators import owner_required
|
||
|
||
User = get_user_model()
|
||
|
||
|
||
@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 = User.objects.make_random_password(12)
|
||
|
||
try:
|
||
# Проверяем, не существует ли уже пользователь с таким email
|
||
existing_user = User.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 = User.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 = User.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)
|