fix: enforce authentication on unauthenticated endpoints and harden auth_must (#1294)

Co-authored-by: bytecii <994513625@qq.com>
This commit is contained in:
Muhammet Eren Karakuş 2026-02-22 03:23:26 +03:00 committed by GitHub
parent 1831d2a686
commit 8d26e1a122
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 172 additions and 6 deletions

View file

@ -21,6 +21,7 @@ from itsdangerous import BadTimeSignature, SignatureExpired
from sqlmodel import Session, asc, select
from starlette.responses import StreamingResponse
from app.component.auth import Auth, auth_must
from app.component.database import session
from app.model.chat.chat_history import ChatHistory
from app.model.chat.chat_share import (
@ -116,12 +117,20 @@ async def share_playback(token: str, session: Session = Depends(session), delay_
@router.post("/share", name="Generate sharable link for a task(1 day expiration)")
def create_share_link(data: ChatShareIn):
def create_share_link(data: ChatShareIn, auth: Auth = Depends(auth_must)):
"""Generate sharing token with 1-day expiration for task."""
user_id = auth.user.id
try:
share_token = ChatShare.generate_token(data.task_id)
logger.info("Share link created", extra={"task_id": data.task_id, "token_prefix": share_token[:10]})
logger.info(
"Share link created",
extra={"user_id": user_id, "task_id": data.task_id, "token_prefix": share_token[:10]},
)
return {"share_token": share_token}
except Exception as e:
logger.error("Share link creation failed", extra={"task_id": data.task_id, "error": str(e)}, exc_info=True)
logger.error(
"Share link creation failed",
extra={"user_id": user_id, "task_id": data.task_id, "error": str(e)},
exc_info=True,
)
raise HTTPException(status_code=500, detail="Internal server error")

View file

@ -33,9 +33,11 @@ async def list_chat_snapshots(
camel_task_id: str | None = None,
browser_url: str | None = None,
session: Session = Depends(session),
auth: Auth = Depends(auth_must),
):
"""List chat snapshots with optional filtering."""
query = select(ChatSnapshot)
user_id = auth.user.id
query = select(ChatSnapshot).where(ChatSnapshot.user_id == user_id)
if api_task_id is not None:
query = query.where(ChatSnapshot.api_task_id == api_task_id)
if camel_task_id is not None:
@ -45,7 +47,8 @@ async def list_chat_snapshots(
snapshots = session.exec(query).all()
logger.debug(
"Snapshots listed", extra={"api_task_id": api_task_id, "camel_task_id": camel_task_id, "count": len(snapshots)}
"Snapshots listed",
extra={"user_id": user_id, "api_task_id": api_task_id, "camel_task_id": camel_task_id, "count": len(snapshots)},
)
return snapshots
@ -60,6 +63,13 @@ async def get_chat_snapshot(snapshot_id: int, session: Session = Depends(session
logger.warning("Snapshot not found", extra={"user_id": user_id, "snapshot_id": snapshot_id})
raise HTTPException(status_code=404, detail=_("Chat snapshot not found"))
if snapshot.user_id != user_id:
logger.warning(
"Unauthorized snapshot access",
extra={"user_id": user_id, "snapshot_id": snapshot_id, "owner_id": snapshot.user_id},
)
raise HTTPException(status_code=403, detail=_("You are not allowed to view this snapshot"))
logger.debug(
"Snapshot retrieved",
extra={"user_id": user_id, "snapshot_id": snapshot_id, "api_task_id": snapshot.api_task_id},