Final notes
This commit is contained in:
parent
5cbe355660
commit
0756aab53f
|
|
@ -48,7 +48,6 @@ class Client:
|
||||||
self.console.print(f"[cyan]• {message}[/]")
|
self.console.print(f"[cyan]• {message}[/]")
|
||||||
|
|
||||||
def srp_authenticate(self) -> None:
|
def srp_authenticate(self) -> None:
|
||||||
"""SRP authentication flow"""
|
|
||||||
with self.console.status("[cyan]Starting SRP handshake...[/]", spinner="dots"):
|
with self.console.status("[cyan]Starting SRP handshake...[/]", spinner="dots"):
|
||||||
|
|
||||||
usr = srp.User(b"chat", self.password, hash_alg=srp.SHA256)
|
usr = srp.User(b"chat", self.password, hash_alg=srp.SHA256)
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,21 @@
|
||||||
from dataclasses import asdict
|
from dataclasses import asdict
|
||||||
from uuid import uuid4
|
|
||||||
import json
|
import json
|
||||||
import base64
|
import base64
|
||||||
|
|
||||||
from sanic import Sanic, Request, response, Websocket
|
from sanic import Sanic, Request, response, Websocket
|
||||||
from sanic.response import HTTPResponse, json as json_response
|
from sanic.response import HTTPResponse, json as json_response
|
||||||
from cryptography.fernet import Fernet
|
|
||||||
|
|
||||||
from .models import Message, UserSession
|
from .models import Message, UserSession
|
||||||
from .logger import logger
|
from .logger import logger
|
||||||
from .helpers import (
|
from .helpers import (
|
||||||
get_client_ip,
|
get_client_ip,
|
||||||
get_param,
|
|
||||||
send_state,
|
send_state,
|
||||||
utcnow,
|
utcnow,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def srp_init(request: Request, app: Sanic) -> HTTPResponse:
|
async def srp_init(request: Request, app: Sanic) -> HTTPResponse:
|
||||||
"""SRP Step 1: клиент отправляет username + A"""
|
|
||||||
try:
|
try:
|
||||||
data = request.json or {}
|
data = request.json or {}
|
||||||
username = data.get("username", "unknown")
|
username = data.get("username", "unknown")
|
||||||
|
|
@ -50,7 +47,6 @@ async def srp_init(request: Request, app: Sanic) -> HTTPResponse:
|
||||||
|
|
||||||
|
|
||||||
async def srp_verify(request: Request, app: Sanic) -> HTTPResponse:
|
async def srp_verify(request: Request, app: Sanic) -> HTTPResponse:
|
||||||
"""SRP Step 2: клиент отправляет proof M"""
|
|
||||||
try:
|
try:
|
||||||
data = request.json or {}
|
data = request.json or {}
|
||||||
user_id = data.get("user_id")
|
user_id = data.get("user_id")
|
||||||
|
|
@ -104,7 +100,7 @@ async def chat_ws(request: Request, ws: Websocket, app: Sanic) -> None:
|
||||||
return
|
return
|
||||||
|
|
||||||
manager = app.ctx.connection_manager
|
manager = app.ctx.connection_manager
|
||||||
await manager.connect(user_id, ws) # await добавлен
|
await manager.connect(user_id, ws)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await send_state(ws, app)
|
await send_state(ws, app)
|
||||||
|
|
@ -134,7 +130,7 @@ async def chat_ws(request: Request, ws: Websocket, app: Sanic) -> None:
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.exception(f"WebSocket error for {user_id}")
|
logger.exception(f"WebSocket error for {user_id}")
|
||||||
finally:
|
finally:
|
||||||
await manager.disconnect(user_id) # await добавлен
|
await manager.disconnect(user_id)
|
||||||
await manager.broadcast(
|
await manager.broadcast(
|
||||||
json.dumps(
|
json.dumps(
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,9 @@
|
||||||
# tests/test_health.py
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
|
|
||||||
class TestHealth:
|
class TestHealth:
|
||||||
"""Тесты health endpoint"""
|
|
||||||
|
|
||||||
def test_health_ok(self, test_client):
|
def test_health_ok(self, test_client):
|
||||||
"""GET /health возвращает статус"""
|
|
||||||
_, response = test_client.get("/health")
|
_, response = test_client.get("/health")
|
||||||
|
|
||||||
assert response.status == 200
|
assert response.status == 200
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,9 @@
|
||||||
# tests/test_srp.py
|
|
||||||
import base64
|
import base64
|
||||||
import pytest
|
|
||||||
import srp
|
import srp
|
||||||
|
|
||||||
|
|
||||||
class TestSRPFlow:
|
class TestSRPFlow:
|
||||||
"""Тесты SRP аутентификации"""
|
|
||||||
|
|
||||||
def test_srp_init_success(self, test_client):
|
def test_srp_init_success(self, test_client):
|
||||||
"""POST /srp/init возвращает user_id, B, salt"""
|
|
||||||
usr = srp.User(b"chat", b"testpassword")
|
usr = srp.User(b"chat", b"testpassword")
|
||||||
_, A = usr.start_authentication()
|
_, A = usr.start_authentication()
|
||||||
|
|
||||||
|
|
@ -27,7 +22,6 @@ class TestSRPFlow:
|
||||||
assert "salt" in data
|
assert "salt" in data
|
||||||
|
|
||||||
def test_srp_init_missing_a(self, test_client):
|
def test_srp_init_missing_a(self, test_client):
|
||||||
"""POST /srp/init без A возвращает 400"""
|
|
||||||
_, response = test_client.post(
|
_, response = test_client.post(
|
||||||
"/srp/init",
|
"/srp/init",
|
||||||
json={"username": "testuser"},
|
json={"username": "testuser"},
|
||||||
|
|
@ -36,7 +30,6 @@ class TestSRPFlow:
|
||||||
assert response.status == 400
|
assert response.status == 400
|
||||||
|
|
||||||
def test_srp_verify_invalid_session(self, test_client):
|
def test_srp_verify_invalid_session(self, test_client):
|
||||||
"""Verify с несуществующим user_id возвращает 401"""
|
|
||||||
_, response = test_client.post(
|
_, response = test_client.post(
|
||||||
"/srp/verify",
|
"/srp/verify",
|
||||||
json={
|
json={
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,12 @@
|
||||||
# tests/test_websocket.py
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
|
|
||||||
class TestWebSocket:
|
class TestWebSocket:
|
||||||
"""Тесты WebSocket подключения"""
|
|
||||||
|
|
||||||
def test_ws_connect_no_user_id(self, test_client):
|
def test_ws_connect_no_user_id(self, test_client):
|
||||||
"""WebSocket без user_id отклоняется"""
|
|
||||||
_, ws = test_client.websocket("/ws/chat")
|
_, ws = test_client.websocket("/ws/chat")
|
||||||
# Проверяем что соединение закрыто или вернулась ошибка
|
|
||||||
assert ws is not None
|
assert ws is not None
|
||||||
|
|
||||||
def test_ws_connect_invalid_session(self, test_client):
|
def test_ws_connect_invalid_session(self, test_client):
|
||||||
"""WebSocket с невалидным user_id отклоняется"""
|
|
||||||
_, ws = test_client.websocket("/ws/chat?user_id=invalid123")
|
_, ws = test_client.websocket("/ws/chat?user_id=invalid123")
|
||||||
assert ws is not None
|
assert ws is not None
|
||||||
Loading…
Reference in New Issue
Block a user