fix: add auth guards to prevent anonymous access to write endpoints in non-public mode (#907)

* fix: add auth guards to prevent anonymous access to write endpoints in non-public mode

* test: anon data accessible regardless of guards

* fix: celery test
This commit is contained in:
Juan Diego García
2026-03-11 10:48:49 -05:00
committed by GitHub
parent 183601a121
commit cf6e867cf1
15 changed files with 745 additions and 21 deletions

View File

@@ -16,6 +16,7 @@ from reflector.db.meetings import (
)
from reflector.db.rooms import rooms_controller
from reflector.logger import logger
from reflector.settings import settings
from reflector.utils.string import NonEmptyString
from reflector.video_platforms.factory import create_platform_client
@@ -89,15 +90,17 @@ class StartRecordingRequest(BaseModel):
@router.post("/meetings/{meeting_id}/recordings/start")
async def start_recording(
meeting_id: NonEmptyString, body: StartRecordingRequest
meeting_id: NonEmptyString,
body: StartRecordingRequest,
user: Annotated[Optional[auth.UserInfo], Depends(auth.current_user_optional)],
) -> dict[str, Any]:
"""Start cloud or raw-tracks recording via Daily.co REST API.
Both cloud and raw-tracks are started via REST API to bypass enable_recording limitation of allowing only 1 recording at a time.
Uses different instanceIds for cloud vs raw-tracks (same won't work)
Note: No authentication required - anonymous users supported. TODO this is a DOS vector
"""
if not user and not settings.PUBLIC_MODE:
raise HTTPException(status_code=401, detail="Not authenticated")
meeting = await meetings_controller.get_by_id(meeting_id)
if not meeting:
raise HTTPException(status_code=404, detail="Meeting not found")

View File

@@ -348,6 +348,9 @@ async def transcripts_create(
info: CreateTranscript,
user: Annotated[Optional[auth.UserInfo], Depends(auth.current_user_optional)],
):
if not user and not settings.PUBLIC_MODE:
raise HTTPException(status_code=401, detail="Not authenticated")
user_id = user["sub"] if user else None
transcript = await transcripts_controller.add(
info.name,

View File

@@ -15,6 +15,7 @@ from reflector.services.transcript_process import (
prepare_transcript_processing,
validate_transcript_for_processing,
)
from reflector.settings import settings
router = APIRouter()
@@ -28,6 +29,9 @@ async def transcript_process(
transcript_id: str,
user: Annotated[Optional[auth.UserInfo], Depends(auth.current_user_optional)],
) -> ProcessStatus:
if not user and not settings.PUBLIC_MODE:
raise HTTPException(status_code=401, detail="Not authenticated")
user_id = user["sub"] if user else None
transcript = await transcripts_controller.get_by_id_for_http(
transcript_id, user_id=user_id

View File

@@ -7,6 +7,7 @@ from pydantic import BaseModel
import reflector.auth as auth
from reflector.db.transcripts import SourceKind, transcripts_controller
from reflector.pipelines.main_file_pipeline import task_pipeline_file_process
from reflector.settings import settings
router = APIRouter()
@@ -23,6 +24,9 @@ async def transcript_record_upload(
chunk: UploadFile,
user: Annotated[Optional[auth.UserInfo], Depends(auth.current_user_optional)],
):
if not user and not settings.PUBLIC_MODE:
raise HTTPException(status_code=401, detail="Not authenticated")
user_id = user["sub"] if user else None
transcript = await transcripts_controller.get_by_id_for_http(
transcript_id, user_id=user_id

View File

@@ -4,6 +4,7 @@ from fastapi import APIRouter, Depends, HTTPException, Request
import reflector.auth as auth
from reflector.db.transcripts import transcripts_controller
from reflector.settings import settings
from .rtc_offer import RtcOffer, rtc_offer_base
@@ -17,6 +18,9 @@ async def transcript_record_webrtc(
request: Request,
user: Annotated[Optional[auth.UserInfo], Depends(auth.current_user_optional)],
):
if not user and not settings.PUBLIC_MODE:
raise HTTPException(status_code=401, detail="Not authenticated")
user_id = user["sub"] if user else None
transcript = await transcripts_controller.get_by_id_for_http(
transcript_id, user_id=user_id

View File

@@ -132,7 +132,7 @@ async def process_recording(bucket_name: str, object_key: str):
target_language="en",
user_id=room.user_id,
recording_id=recording.id,
share_mode="public",
share_mode="semi-private",
meeting_id=meeting.id,
room_id=room.id,
)
@@ -343,7 +343,7 @@ async def _process_multitrack_recording_inner(
target_language="en",
user_id=room.user_id,
recording_id=recording.id,
share_mode="public",
share_mode="semi-private",
meeting_id=meeting.id,
room_id=room.id,
)