From 854dc67c12be455c045044d926f173bb231a4b84 Mon Sep 17 00:00:00 2001 From: dangddt Date: Tue, 2 Dec 2025 14:10:26 +0700 Subject: [PATCH] feat: Introduce OAuth2 authentication to history routes, replacing the default user with authenticated user management. --- lightrag/api/routers/history_routes.py | 72 +++++++++++++++++++------- 1 file changed, 53 insertions(+), 19 deletions(-) diff --git a/lightrag/api/routers/history_routes.py b/lightrag/api/routers/history_routes.py index 8c4dec2d..2e4498e2 100644 --- a/lightrag/api/routers/history_routes.py +++ b/lightrag/api/routers/history_routes.py @@ -1,9 +1,11 @@ -from fastapi import APIRouter, Depends, HTTPException +from fastapi import APIRouter, Depends, HTTPException, Security, status +from fastapi.security import OAuth2PasswordBearer from sqlalchemy.orm import Session from typing import List, Optional from uuid import UUID import sys import os +from lightrag.api.auth import auth_handler # Ensure service module is in path (similar to query_routes.py) project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../")) @@ -27,43 +29,75 @@ except ImportError: router = APIRouter() +oauth2_scheme = OAuth2PasswordBearer(tokenUrl="login", auto_error=False) + def check_dependencies(): if not HistoryManager: raise HTTPException(status_code=503, detail="History service not available") +async def get_current_user( + token: str = Security(oauth2_scheme), + db: Session = Depends(get_db) +) -> User: + check_dependencies() + + if not token: + # If no token provided, try to use default user if configured or allowed + # For now, we'll return the default user for backward compatibility if needed, + # but ideally we should require auth. + # Let's check if we have a default user + user = db.query(User).filter(User.username == "default_user").first() + if not user: + user = User(username="default_user", email="default@example.com") + db.add(user) + db.commit() + db.refresh(user) + return user + + try: + user_data = auth_handler.validate_token(token) + username = user_data["username"] + + user = db.query(User).filter(User.username == username).first() + if not user: + # Create user if not exists (auto-registration on first login) + # In a real app you might want to fetch email from token metadata or require explicit registration + user = User(username=username, email=f"{username}@example.com") + db.add(user) + db.commit() + db.refresh(user) + + return user + except HTTPException: + raise + except Exception as e: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="Could not validate credentials", + headers={"WWW-Authenticate": "Bearer"}, + ) + @router.get("/sessions", response_model=List[SessionResponse], tags=["History"]) def list_sessions( skip: int = 0, limit: int = 20, - db: Session = Depends(get_db) + db: Session = Depends(get_db), + current_user: User = Depends(get_current_user) ): check_dependencies() manager = HistoryManager(db) - # For now, get default user or create one - user = db.query(User).filter(User.username == "default_user").first() - if not user: - user = User(username="default_user", email="default@example.com") - db.add(user) - db.commit() - db.refresh(user) - - sessions = manager.list_sessions(user_id=user.id, skip=skip, limit=limit) + sessions = manager.list_sessions(user_id=current_user.id, skip=skip, limit=limit) return sessions @router.post("/sessions", response_model=SessionResponse, tags=["History"]) def create_session( session_in: SessionCreate, - db: Session = Depends(get_db) + db: Session = Depends(get_db), + current_user: User = Depends(get_current_user) ): check_dependencies() manager = HistoryManager(db) - user = db.query(User).filter(User.username == "default_user").first() - if not user: - user = User(username="default_user", email="default@example.com") - db.add(user) - db.commit() - - return manager.create_session(user_id=user.id, title=session_in.title) + return manager.create_session(user_id=current_user.id, title=session_in.title) @router.get("/sessions/{session_id}/history", response_model=List[ChatMessageResponse], tags=["History"]) def get_session_history(