#!/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� 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�️ 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())