Authenticate sockets by header or one-time ticket instead of ?token=
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013GAeg4Jo6xjZzjwy9QDWMQ
This commit is contained in:
@@ -579,3 +579,35 @@ def test_a_member_the_portal_vouches_for_is_adopted(
|
||||
"fluksio.cloud.enroll.httpx.get", side_effect=httpx.ConnectError("no route")
|
||||
):
|
||||
assert user_from_token(db, stranger) is None
|
||||
|
||||
|
||||
def test_the_tunnel_opens_the_live_socket_with_a_ticket(
|
||||
client: TestClient, superuser_token_headers: dict[str, str]
|
||||
) -> None:
|
||||
"""A browser under the portal brings a ticket, which the engine redeems."""
|
||||
import json
|
||||
|
||||
from fluksio.cloud.connector import CloudConnector
|
||||
|
||||
ticket = client.post(
|
||||
f"{settings.API_V1_STR}/flows/ws-ticket", headers=superuser_token_headers
|
||||
).json()["ticket"]
|
||||
connector = CloudConnector(client.app)
|
||||
frame = {"id": "s1", "path": "/api/v1/flows/ws", "query": f"ticket={ticket}"}
|
||||
|
||||
async def opened() -> list[str]:
|
||||
sent: list[str] = []
|
||||
|
||||
class Socket:
|
||||
async def send(self, text: str) -> None:
|
||||
sent.append(text)
|
||||
|
||||
task = asyncio.create_task(connector._stream(Socket(), frame))
|
||||
while len(sent) < 1:
|
||||
await asyncio.sleep(0.01)
|
||||
task.cancel()
|
||||
return [str(json.loads(text)["op"]) for text in sent]
|
||||
|
||||
assert asyncio.run(opened())[0] == "ws_open_ok"
|
||||
# Used once: the same ticket again is refused.
|
||||
assert asyncio.run(opened()) == ["ws_close"]
|
||||
|
||||
Reference in New Issue
Block a user