diff --git a/routes/calendar_routes.py b/routes/calendar_routes.py index 3c767f2..da45068 100644 --- a/routes/calendar_routes.py +++ b/routes/calendar_routes.py @@ -12,7 +12,7 @@ from dateutil.rrule import rrulestr, rruleset from dateutil.rrule import DAILY, WEEKLY, MONTHLY, YEARLY from core.database import SessionLocal, CalendarCal, CalendarEvent -from src.auth_helpers import get_current_user +from src.auth_helpers import get_current_user, require_user logger = logging.getLogger(__name__) @@ -28,16 +28,17 @@ _SINGLE_USER_MODE = _os.environ.get("ODYSSEUS_SINGLE_USER", "1") != "0" def _require_user(request: Request) -> str: - """Return the authenticated user. In multi-user mode an unauthenticated - request raises 401; in single-user mode it falls through to - FALLBACK_OWNER. Prevents the silent cross-user data write that would - happen if a request slipped past auth middleware in a real deployment.""" - u = get_current_user(request) - if u: - return u - if _SINGLE_USER_MODE: - return FALLBACK_OWNER - raise HTTPException(401, "Authentication required") + """Return the authenticated user. Uses require_user so AUTH_ENABLED=false + and single-user mode both work: require_user returns "" when auth is + disabled or unconfigured, and only raises 401 when auth is configured but + the caller is unauthenticated. Falls back to FALLBACK_OWNER for calendar + writes so data isn't stored under an empty owner in single-user mode.""" + user = require_user(request) + if user: + return user + # require_user returned "" — auth is off or unconfigured (single-user). + # Use FALLBACK_OWNER so calendar rows have a stable owner for filtering. + return FALLBACK_OWNER def _get_or_404_calendar(db, cal_id: str, owner: str) -> CalendarCal: diff --git a/routes/memory_routes.py b/routes/memory_routes.py index d243b99..336f37e 100644 --- a/routes/memory_routes.py +++ b/routes/memory_routes.py @@ -27,7 +27,7 @@ from src.request_models import MemoryAddRequest from core.database import SessionLocal from src.llm_core import llm_call_async from services.memory.memory_extractor import audit_memories -from src.auth_helpers import get_current_user +from src.auth_helpers import get_current_user, require_user from src.endpoint_resolver import resolve_endpoint logger = logging.getLogger(__name__) @@ -191,8 +191,7 @@ def setup_memory_routes(memory_manager: MemoryManager, session_manager: SessionM @router.post("/extract") async def extract_memory(request: Request, session: str = Form(...)) -> Dict[str, List[str]]: """Analyze a session's chat history and return memory suggestions.""" - if not get_current_user(request): - raise HTTPException(401, "Not authenticated") + require_user(request) try: sess = session_manager.get_session(session) except KeyError: diff --git a/routes/note_routes.py b/routes/note_routes.py index 925b4fb..1524afc 100644 --- a/routes/note_routes.py +++ b/routes/note_routes.py @@ -683,9 +683,8 @@ def setup_note_routes(task_scheduler=None): Returns {synthesis, email_sent}. """ # Gate against anonymous callers — LLM synthesis can burn tokens. - from src.auth_helpers import get_current_user as _gcu - if not _gcu(request): - raise HTTPException(401, "Not authenticated") + from src.auth_helpers import require_user as _ru + _ru(request) body = await request.json() note_id = body.get("note_id") title = (body.get("title") or "").strip()