Files
chat/tests/test_security_check.py
Andrey K. Choi 3050e084fa
All checks were successful
continuous-integration/drone/push Build is passing
main functions commit
2025-10-19 19:50:00 +09:00

400 lines
20 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
Полный тест безопасности и функциональности Emergency Service
- Проверка блокировки временных токенов
- Проверка работы JWT аутентификации
- Полное тестирование всех Emergency API endpoints
- Создание и проверка записей экстренных вызовов
"""
import asyncio
import json
import httpx
import websockets
from typing import Optional
class SecurityTest:
def __init__(self):
self.base_url = "http://localhost:8000" # API Gateway
self.emergency_url = "http://localhost:8002" # Emergency Service напрямую
self.ws_url = "ws://localhost:8002" # Emergency Service
async def test_temp_token_rejection(self) -> bool:
"""Тестируем, что временные токены отклоняются"""
print("🔒 ТЕСТ БЕЗОПАСНОСТИ: Блокировка временных токенов")
print("="*60)
temp_tokens = [
"temp_token_for_shadow85@list.ru",
"test_token_123",
"temp_token_12345",
"test_token_admin"
]
all_rejected = True
for token in temp_tokens:
try:
ws_url = f"{self.ws_url}/api/v1/emergency/ws/current_user_id?token={token}"
print(f"🔍 Тестируем токен: {token[:30]}...")
# Пытаемся подключиться (должно быть отклонено)
async with websockets.connect(ws_url) as websocket:
print(f"❌ ПРОБЛЕМА БЕЗОПАСНОСТИ: Токен {token[:30]}... был принят!")
all_rejected = False
except websockets.exceptions.ConnectionClosed as e:
if e.code in [1008, 403]: # Policy violation или Forbidden
print(f"✅ Токен {token[:30]}... корректно отклонен (код: {e.code})")
else:
print(f"⚠️ Токен {token[:30]}... отклонен с неожиданным кодом: {e.code}")
except Exception as e:
print(f"✅ Токен {token[:30]}... корректно отклонен: {type(e).__name__}")
return all_rejected
async def test_jwt_token_acceptance(self) -> bool:
"""Тестируем, что настоящие JWT токены принимаются"""
print("\n🔓 ТЕСТ: Прием настоящих JWT токенов")
print("="*50)
try:
# Получаем настоящий JWT токен
async with httpx.AsyncClient() as client:
login_data = {
"email": "shadow85@list.ru",
"password": "R0sebud1985"
}
print("🔐 Получаем JWT токен...")
response = await client.post(
f"{self.base_url}/api/v1/auth/login",
json=login_data,
headers={"Content-Type": "application/json"}
)
if response.status_code != 200:
print(f"Не удалось получить JWT токен: {response.status_code}")
return False
auth_data = response.json()
jwt_token = auth_data.get("access_token")
if not jwt_token:
print("❌ JWT токен не найден в ответе")
return False
print(f"✅ JWT токен получен: {jwt_token[:50]}...")
# Тестируем WebSocket с JWT токеном
ws_url = f"{self.ws_url}/api/v1/emergency/ws/current_user_id?token={jwt_token}"
print("🔌 Тестируем WebSocket с JWT токеном...")
async with websockets.connect(ws_url) as websocket:
print("✅ JWT токен принят, WebSocket подключен!")
# Отправляем ping
await websocket.send(json.dumps({"type": "ping"}))
try:
response = await asyncio.wait_for(websocket.recv(), timeout=3.0)
print(f"📥 Ответ сервера: {response}")
except asyncio.TimeoutError:
print("⏰ Таймаут, но подключение работает")
return True
except Exception as e:
print(f"❌ Ошибка тестирования JWT токена: {e}")
return False
async def test_emergency_endpoints(self) -> bool:
"""Полное тестирование всех endpoint'ов экстренных вызовов"""
print("\n🚨 ТЕСТ: Полная проверка Emergency API")
print("="*60)
try:
# Получаем JWT токен
async with httpx.AsyncClient() as client:
login_data = {
"email": "shadow85@list.ru",
"password": "R0sebud1985"
}
print("🔐 Авторизация для тестирования API...")
response = await client.post(
f"{self.base_url}/api/v1/auth/login",
json=login_data,
headers={"Content-Type": "application/json"}
)
if response.status_code != 200:
print(f"❌ Ошибка авторизации: {response.status_code}")
return False
auth_data = response.json()
jwt_token = auth_data.get("access_token")
headers = {
"Authorization": f"Bearer {jwt_token}",
"Content-Type": "application/json"
}
test_results = {}
# 1. Создание экстренного вызова (правильный endpoint)
print("\n📞 1. Тест создания экстренного вызова...")
alert_data = {
"alert_type": "medical",
"latitude": 55.7558,
"longitude": 37.6176,
"address": "Красная площадь, Москва",
"description": "Тестовый экстренный вызов для проверки API"
}
response = await client.post(
f"{self.emergency_url}/api/v1/alert", # Используем правильный endpoint
json=alert_data,
headers=headers
)
if response.status_code in [200, 201]:
created_alert = response.json()
alert_id = created_alert.get("id")
print(f"✅ Экстренный вызов создан: ID={alert_id}")
test_results["create_alert"] = True
else:
print(f"❌ Ошибка создания вызова: {response.status_code} - {response.text}")
test_results["create_alert"] = False
alert_id = None
# 2. Получение моих вызовов
print("\n📋 2. Тест получения моих вызовов...")
response = await client.get(
f"{self.emergency_url}/api/v1/alerts/my",
headers=headers
)
if response.status_code == 200:
alerts = response.json()
print(f"✅ Получен список моих вызовов: {len(alerts)} записей")
test_results["get_my_alerts"] = True
else:
print(f"❌ Ошибка получения моих вызовов: {response.status_code}")
test_results["get_my_alerts"] = False
# 3. Получение активных вызовов
print("\n<EFBFBD> 3. Тест получения активных вызовов...")
response = await client.get(
f"{self.emergency_url}/api/v1/alerts/active",
headers=headers
)
if response.status_code == 200:
active_alerts = response.json()
print(f"✅ Получен список активных вызовов: {len(active_alerts)} записей")
test_results["get_active_alerts"] = True
else:
print(f"❌ Ошибка получения активных вызовов: {response.status_code}")
test_results["get_active_alerts"] = False
# 4. Создание отчета об экстренной ситуации
print("\n📝 4. Тест создания отчета...")
report_data = {
"incident_type": "suspicious_activity",
"latitude": 55.7500,
"longitude": 37.6200,
"address": "Тверская улица, Москва",
"description": "Тестовый отчет о подозрительной активности",
"severity": "medium"
}
response = await client.post(
f"{self.emergency_url}/api/v1/report",
json=report_data,
headers=headers
)
if response.status_code in [200, 201]:
created_report = response.json()
report_id = created_report.get("id")
print(f"✅ Отчет создан: ID={report_id}")
test_results["create_report"] = True
else:
print(f"❌ Ошибка создания отчета: {response.status_code} - {response.text}")
test_results["create_report"] = False
report_id = None
# 5. Получение списка отчетов
print("\n📊 5. Тест получения списка отчетов...")
response = await client.get(
f"{self.emergency_url}/api/v1/reports",
headers=headers
)
if response.status_code == 200:
reports = response.json()
print(f"✅ Получен список отчетов: {len(reports)} записей")
test_results["get_reports"] = True
else:
print(f"❌ Ошибка получения отчетов: {response.status_code}")
test_results["get_reports"] = False
# 6. Поиск ближайших вызовов
print("\n🗺️ 6. Тест поиска ближайших вызовов...")
response = await client.get(
f"{self.emergency_url}/api/v1/alerts/nearby?latitude=55.7558&longitude=37.6176&radius=5",
headers=headers
)
if response.status_code == 200:
nearby_alerts = response.json()
print(f"✅ Найдены ближайшие вызовы: {len(nearby_alerts)} в радиусе 5км")
test_results["nearby_alerts"] = True
else:
print(f"❌ Ошибка поиска ближайших: {response.status_code}")
test_results["nearby_alerts"] = False
# 7. Создание проверки безопасности
print("\n🛡️ 7. Тест создания проверки безопасности...")
safety_data = {
"latitude": 55.7600,
"longitude": 37.6100,
"status": "safe",
"message": "Тестовая проверка безопасности - всё в порядке"
}
response = await client.post(
f"{self.emergency_url}/api/v1/safety-check",
json=safety_data,
headers=headers
)
if response.status_code in [200, 201]:
safety_check = response.json()
print(f"✅ Проверка безопасности создана: статус={safety_check.get('status')}")
test_results["create_safety_check"] = True
else:
print(f"❌ Ошибка создания проверки: {response.status_code} - {response.text}")
test_results["create_safety_check"] = False
# 8. Получение списка проверок безопасности
print("\n<EFBFBD> 8. Тест получения проверок безопасности...")
response = await client.get(
f"{self.emergency_url}/api/v1/safety-checks",
headers=headers
)
if response.status_code == 200:
safety_checks = response.json()
print(f"✅ Получен список проверок: {len(safety_checks)} записей")
test_results["get_safety_checks"] = True
else:
print(f"❌ Ошибка получения проверок: {response.status_code}")
test_results["get_safety_checks"] = False
# 9. Получение статистики
print("\n📈 9. Тест получения статистики...")
response = await client.get(
f"{self.emergency_url}/api/v1/stats",
headers=headers
)
if response.status_code == 200:
stats = response.json()
print(f"✅ Статистика получена: {stats}")
test_results["get_statistics"] = True
else:
print(f"❌ Ошибка получения статистики: {response.status_code}")
test_results["get_statistics"] = False
# 10. Ответ на экстренный вызов (если создан)
if alert_id:
print(f"\n🆘 10. Тест ответа на вызов ID={alert_id}...")
response_data = {
"response_type": "help_on_way",
"message": "Помощь в пути, держитесь!"
}
response = await client.post(
f"{self.emergency_url}/api/v1/alert/{alert_id}/respond",
json=response_data,
headers=headers
)
if response.status_code in [200, 201]:
alert_response = response.json()
print(f"✅ Ответ на вызов создан: {alert_response.get('response_type')}")
test_results["respond_to_alert"] = True
else:
print(f"❌ Ошибка ответа на вызов: {response.status_code}")
test_results["respond_to_alert"] = False
# Результат тестирования API
total_tests = len(test_results)
passed_tests = sum(test_results.values())
print(f"\n📊 РЕЗУЛЬТАТ ТЕСТИРОВАНИЯ API:")
print(f"✅ Пройдено: {passed_tests}/{total_tests} тестов")
for test_name, result in test_results.items():
status = "" if result else ""
print(f" {status} {test_name}")
return passed_tests == total_tests
except Exception as e:
print(f"❌ Ошибка тестирования Emergency API: {e}")
return False
async def run_security_test(self):
"""Запуск полного теста безопасности"""
print("🛡️ ЗАПУСК ПОЛНОГО ТЕСТА БЕЗОПАСНОСТИ И ФУНКЦИОНАЛЬНОСТИ")
print("="*80)
# Тест 1: Блокировка временных токенов
temp_tokens_blocked = await self.test_temp_token_rejection()
# Тест 2: Прием JWT токенов
jwt_tokens_accepted = await self.test_jwt_token_acceptance()
# Тест 3: Полная проверка Emergency API
emergency_api_working = await self.test_emergency_endpoints()
# Результат
print("\n" + "="*80)
print("📊 ПОЛНЫЙ РЕЗУЛЬТАТ ТЕСТИРОВАНИЯ")
print("="*80)
all_tests_passed = temp_tokens_blocked and jwt_tokens_accepted and emergency_api_working
if all_tests_passed:
print("ВСЕ ТЕСТЫ ПРОЙДЕНЫ УСПЕШНО!")
print("✅ Безопасность: Временные токены корректно блокируются")
print("✅ Аутентификация: JWT токены корректно принимаются")
print("✅ Функциональность: Все Emergency API работают")
print("🔒 Система полностью готова к продакшену")
else:
print("❌ ОБНАРУЖЕНЫ ПРОБЛЕМЫ!")
if not temp_tokens_blocked:
print("❌ Проблема безопасности: Временные токены не блокируются")
if not jwt_tokens_accepted:
print("❌ Проблема аутентификации: JWT токены не принимаются")
if not emergency_api_working:
print("❌ Проблема функциональности: Emergency API работают неполностью")
print("⚠️ Система НЕ готова к продакшену")
print(f"\n📈 Статистика тестирования:")
print(f" 🔒 Безопасность: {'✅ ПРОЙДЕНО' if temp_tokens_blocked else '❌ ПРОВАЛЕНО'}")
print(f" 🔐 Аутентификация: {'✅ ПРОЙДЕНО' if jwt_tokens_accepted else '❌ ПРОВАЛЕНО'}")
print(f" 🚨 Emergency API: {'✅ ПРОЙДЕНО' if emergency_api_working else '❌ ПРОВАЛЕНО'}")
return all_tests_passed
async def main():
"""Главная функция"""
tester = SecurityTest()
await tester.run_security_test()
if __name__ == "__main__":
asyncio.run(main())