diff --git a/navi/api/websocket.py b/navi/api/websocket.py index c9cd3c6..7b24e7d 100644 --- a/navi/api/websocket.py +++ b/navi/api/websocket.py @@ -195,6 +195,7 @@ user: Annotated[User | None, Depends(get_current_user_ws)] = None, ) -> None: log.info("ws.handler_enter", session_id=session_id, user_id=user.id if user else None) + session_store = get_session_store() session = await session_store.get(session_id) @@ -211,17 +212,19 @@ log.info("ws.accepted", session_id=session_id) if user is None: - log.warning("ws.anonymous_denied", session_id=session_id) - await websocket.close(code=4003, reason="Authentication required") - return - - try: - check_session_access(session, user) - log.info("ws.access_granted", session_id=session_id, user_id=user.id) - except Exception: - log.warning("ws.access_denied", session_id=session_id, user_id=user.id) - await websocket.close(code=4003, reason="Access denied") - return + # Anonymous users may only connect to legacy sessions (no owner). + if session.user_id is not None: + log.warning("ws.anonymous_denied", session_id=session_id) + await websocket.close(code=4003, reason="Authentication required") + return + else: + try: + check_session_access(session, user) + log.info("ws.access_granted", session_id=session_id, user_id=user.id) + except Exception: + log.warning("ws.access_denied", session_id=session_id, user_id=user.id) + await websocket.close(code=4003, reason="Access denied") + return from navi.api.deps import get_memory_store, get_registries, get_workers tools, profiles, backends, cp_registry = get_registries() diff --git a/navi/auth/deps.py b/navi/auth/deps.py index f485008..477c4fd 100644 --- a/navi/auth/deps.py +++ b/navi/auth/deps.py @@ -140,7 +140,10 @@ async def get_current_user_ws(websocket) -> User | None: """Resolve the current user from the auth session cookie for WebSocket connections.""" - return await _resolve_user(websocket) + log.info("auth.ws_dep_enter") + result = await _resolve_user(websocket) + log.info("auth.ws_dep_exit", user_id=result.id if result else None) + return result # ── Helpers that talk to the session store ──────────────────────────────────