279 lines
11 KiB
Python
279 lines
11 KiB
Python
"""
|
||
Тестирование логики доступа к заявлениям (requests)
|
||
|
||
Проверяет:
|
||
1. Обычные пользователи видят только свои + адресованные им
|
||
2. Руководители отделов видят заявки своих отделов
|
||
3. Пользователи с глобальными правами видят всё
|
||
4. Департаментные права работают корректно
|
||
5. sent_to_all_department работает
|
||
"""
|
||
|
||
import os
|
||
import sys
|
||
import django
|
||
|
||
# Настройка Django
|
||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'eusrr_backend.settings')
|
||
django.setup()
|
||
|
||
from django.contrib.auth import get_user_model
|
||
from django.db.models import Q
|
||
from employees.models import Department, EmployeeDepartment
|
||
from requests_app.models import Request
|
||
|
||
User = get_user_model()
|
||
|
||
|
||
def print_section(title):
|
||
"""Красивый вывод секции"""
|
||
print(f"\n{'=' * 80}")
|
||
print(f" {title}")
|
||
print('=' * 80)
|
||
|
||
|
||
def test_user_access(user, description=""):
|
||
"""Тестирует доступ пользователя к заявлениям"""
|
||
print(f"\n👤 Пользователь: {user.get_full_name() or user.username}")
|
||
if description:
|
||
print(f" {description}")
|
||
|
||
# Получаем отделы пользователя
|
||
my_depts = EmployeeDepartment.objects.filter(
|
||
employee=user,
|
||
is_active=True
|
||
).select_related('department')
|
||
|
||
print(f"\n📋 Отделы пользователя:")
|
||
if my_depts.exists():
|
||
for ed in my_depts:
|
||
role_name = ed.role.name if ed.role else "Без роли"
|
||
print(f" - {ed.department.name} ({role_name})")
|
||
if ed.role:
|
||
perms = ed.role.scoped_permissions.values_list('code', flat=True)
|
||
if perms:
|
||
print(f" Права: {', '.join(perms)}")
|
||
else:
|
||
print(" (нет отделов)")
|
||
|
||
# Проверяем глобальные права
|
||
print(f"\n🔑 Глобальные права:")
|
||
print(f" is_staff: {user.is_staff}")
|
||
print(f" can_view_all_requests: {user.has_perm('requests_app.can_view_all_requests')}")
|
||
print(f" view_request: {user.has_perm('requests_app.view_request')}")
|
||
print(f" can_process_requests: {user.has_perm('requests_app.can_process_requests')}")
|
||
|
||
# Проверяем руководство отделами
|
||
head_depts = Department.objects.filter(head=user)
|
||
if head_depts.exists():
|
||
print(f"\n👔 Руководитель отделов:")
|
||
for dept in head_depts:
|
||
print(f" - {dept.name}")
|
||
|
||
# Строим queryset как в реальном API
|
||
my_dept_ids = list(my_depts.values_list('department_id', flat=True))
|
||
|
||
# Проверяем: может ли видеть ВСЁ
|
||
can_view_all = (
|
||
user.is_staff
|
||
or user.has_perm("requests_app.can_view_all_requests")
|
||
or user.has_perm("requests_app.view_request")
|
||
)
|
||
|
||
if can_view_all:
|
||
print(f"\n✅ Может просматривать ВСЕ заявления (staff или глобальные права)")
|
||
qs = Request.objects.all()
|
||
else:
|
||
# Обычный пользователь - строим scope
|
||
scope = Q(employee_id=user.id) # Свои заявки
|
||
|
||
# Заявки, где я получатель
|
||
scope |= Q(recipients=user) | Q(cc_users=user)
|
||
|
||
# Заявки отделов с sent_to_all_department
|
||
if my_dept_ids:
|
||
scope |= Q(
|
||
sent_to_all_department=True,
|
||
departments__in=my_dept_ids
|
||
)
|
||
|
||
# Департаментные права
|
||
view_dept_ids = list(
|
||
EmployeeDepartment.objects.filter(
|
||
employee_id=user.id,
|
||
is_active=True,
|
||
role__scoped_permissions__code="view_request",
|
||
)
|
||
.values_list("department_id", flat=True)
|
||
.distinct()
|
||
)
|
||
proc_dept_ids = list(
|
||
EmployeeDepartment.objects.filter(
|
||
employee_id=user.id,
|
||
is_active=True,
|
||
role__scoped_permissions__code="can_process_requests",
|
||
)
|
||
.values_list("department_id", flat=True)
|
||
.distinct()
|
||
)
|
||
head_dept_ids = list(
|
||
Department.objects.filter(head_id=user.id).values_list("id", flat=True)
|
||
)
|
||
|
||
combined_ids = set(view_dept_ids) | set(proc_dept_ids) | set(head_dept_ids)
|
||
|
||
if combined_ids:
|
||
print(f"\n📊 Департаментные права для отделов (ID): {combined_ids}")
|
||
|
||
# Заявки этих отделов
|
||
scope |= Q(departments__in=combined_ids)
|
||
|
||
# Заявки сотрудников этих отделов
|
||
dept_emp_ids = list(
|
||
EmployeeDepartment.objects.filter(
|
||
department_id__in=list(combined_ids),
|
||
is_active=True,
|
||
)
|
||
.values_list("employee_id", flat=True)
|
||
.distinct()
|
||
)
|
||
if dept_emp_ids:
|
||
scope |= Q(employee_id__in=dept_emp_ids)
|
||
|
||
qs = Request.objects.filter(scope).distinct()
|
||
|
||
# Подсчитываем результаты
|
||
total = qs.count()
|
||
print(f"\n📈 Доступные заявления: {total}")
|
||
|
||
if total > 0:
|
||
# Разбивка по типам доступа
|
||
my_requests = qs.filter(employee=user).count()
|
||
addressed_to_me = qs.filter(Q(recipients=user) | Q(cc_users=user)).count()
|
||
|
||
print(f"\n Детализация:")
|
||
print(f" - Мои заявления: {my_requests}")
|
||
print(f" - Адресованные мне (To/CC): {addressed_to_me}")
|
||
|
||
if my_dept_ids:
|
||
all_dept = qs.filter(
|
||
sent_to_all_department=True,
|
||
departments__in=my_dept_ids
|
||
).distinct().count()
|
||
print(f" - 'Всем в отделе': {all_dept}")
|
||
|
||
# Последние 5 заявлений для примера
|
||
print(f"\n Примеры заявлений (последние 5):")
|
||
for req in qs.select_related('employee').order_by('-created_at')[:5]:
|
||
author = req.employee.get_full_name() or req.employee.username
|
||
|
||
# Определяем причину доступа
|
||
reasons = []
|
||
if req.employee == user:
|
||
reasons.append("автор")
|
||
if req.recipients.filter(id=user.id).exists():
|
||
reasons.append("получатель")
|
||
if req.cc_users.filter(id=user.id).exists():
|
||
reasons.append("CC")
|
||
if req.sent_to_all_department and any(
|
||
dept.id in my_dept_ids for dept in req.departments.all()
|
||
):
|
||
reasons.append("всем в отделе")
|
||
|
||
reason_str = ", ".join(reasons) if reasons else "департаментные права"
|
||
|
||
print(f" {req.id:4d}. {req.get_type_display():15s} | {author:20s} | {reason_str}")
|
||
|
||
return qs
|
||
|
||
|
||
def main():
|
||
print_section("ТЕСТИРОВАНИЕ ЛОГИКИ ДОСТУПА К ЗАЯВЛЕНИЯМ")
|
||
|
||
# Получаем тестовых пользователей
|
||
print("\n🔍 Поиск пользователей для тестирования...")
|
||
|
||
users_to_test = []
|
||
|
||
# 1. Обычный сотрудник (без особых прав)
|
||
regular_user = User.objects.filter(
|
||
is_staff=False,
|
||
is_superuser=False,
|
||
).exclude(
|
||
departments_links__role__scoped_permissions__code__in=[
|
||
'view_request', 'can_process_requests'
|
||
]
|
||
).first()
|
||
|
||
if regular_user:
|
||
users_to_test.append((regular_user, "Обычный сотрудник (без особых прав)"))
|
||
|
||
# 2. Руководитель отдела
|
||
head_user = Department.objects.exclude(head__isnull=True).first()
|
||
if head_user and head_user.head:
|
||
users_to_test.append((head_user.head, f"Руководитель отдела '{head_user.name}'"))
|
||
|
||
# 3. С департаментными правами
|
||
dept_rights_user = EmployeeDepartment.objects.filter(
|
||
is_active=True,
|
||
role__scoped_permissions__code__in=['view_request', 'can_process_requests']
|
||
).select_related('employee').first()
|
||
|
||
if dept_rights_user:
|
||
users_to_test.append((
|
||
dept_rights_user.employee,
|
||
f"С департаментными правами в отделе '{dept_rights_user.department.name}'"
|
||
))
|
||
|
||
# 4. Staff пользователь
|
||
staff_user = User.objects.filter(is_staff=True, is_superuser=False).first()
|
||
if staff_user:
|
||
users_to_test.append((staff_user, "Django staff (без superuser)"))
|
||
|
||
# 5. Superuser
|
||
superuser = User.objects.filter(is_superuser=True).first()
|
||
if superuser:
|
||
users_to_test.append((superuser, "Superuser"))
|
||
|
||
if not users_to_test:
|
||
print("\n❌ Не найдено пользователей для тестирования!")
|
||
print(" Создайте пользователей и отделы в админке")
|
||
return
|
||
|
||
# Информация о заявлениях в системе
|
||
total_requests = Request.objects.count()
|
||
print(f"\n📊 Всего заявлений в системе: {total_requests}")
|
||
|
||
if total_requests == 0:
|
||
print("\n⚠️ В системе нет заявлений! Создайте хотя бы одну заявку для тестирования.")
|
||
return
|
||
|
||
# Статистика по получателям
|
||
with_recipients = Request.objects.filter(recipients__isnull=False).distinct().count()
|
||
with_cc = Request.objects.filter(cc_users__isnull=False).distinct().count()
|
||
with_depts = Request.objects.filter(departments__isnull=False).distinct().count()
|
||
with_all_dept = Request.objects.filter(sent_to_all_department=True).count()
|
||
|
||
print(f"\n Заявлений с получателями (To): {with_recipients}")
|
||
print(f" Заявлений с копией (CC): {with_cc}")
|
||
print(f" Заявлений с отделами: {with_depts}")
|
||
print(f" Заявлений 'Всем в отделе': {with_all_dept}")
|
||
|
||
# Тестируем каждого пользователя
|
||
for user, description in users_to_test:
|
||
print_section(f"ТЕСТ: {description}")
|
||
test_user_access(user, description)
|
||
|
||
print_section("ТЕСТИРОВАНИЕ ЗАВЕРШЕНО")
|
||
print("\n✅ Все проверки выполнены!")
|
||
print("\nРекомендации:")
|
||
print("1. Проверьте, что обычные пользователи НЕ видят чужие заявки")
|
||
print("2. Руководители должны видеть заявки своих отделов")
|
||
print("3. Staff видят всё")
|
||
print("4. Получатели (To/CC) видят адресованные им заявки")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|