protect export endpoints

This commit is contained in:
Josh Hawkins 2025-09-09 17:44:01 -05:00
parent f857ccd366
commit 2a9d5f5e51

View File

@ -4,6 +4,7 @@ import logging
import random import random
import string import string
from pathlib import Path from pathlib import Path
from typing import List
import psutil import psutil
from fastapi import APIRouter, Depends, Request from fastapi import APIRouter, Depends, Request
@ -11,7 +12,11 @@ from fastapi.responses import JSONResponse
from peewee import DoesNotExist from peewee import DoesNotExist
from playhouse.shortcuts import model_to_dict from playhouse.shortcuts import model_to_dict
from frigate.api.auth import require_role from frigate.api.auth import (
get_allowed_cameras_for_filter,
require_camera_access,
require_role,
)
from frigate.api.defs.request.export_recordings_body import ExportRecordingsBody from frigate.api.defs.request.export_recordings_body import ExportRecordingsBody
from frigate.api.defs.request.export_rename_body import ExportRenameBody from frigate.api.defs.request.export_rename_body import ExportRenameBody
from frigate.api.defs.tags import Tags from frigate.api.defs.tags import Tags
@ -30,12 +35,23 @@ router = APIRouter(tags=[Tags.export])
@router.get("/exports") @router.get("/exports")
def get_exports(): def get_exports(
exports = Export.select().order_by(Export.date.desc()).dicts().iterator() allowed_cameras: List[str] = Depends(get_allowed_cameras_for_filter),
):
exports = (
Export.select()
.where(Export.camera << allowed_cameras)
.order_by(Export.date.desc())
.dicts()
.iterator()
)
return JSONResponse(content=[e for e in exports]) return JSONResponse(content=[e for e in exports])
@router.post("/export/{camera_name}/start/{start_time}/end/{end_time}") @router.post(
"/export/{camera_name}/start/{start_time}/end/{end_time}",
dependencies=[Depends(require_camera_access)],
)
def export_recording( def export_recording(
request: Request, request: Request,
camera_name: str, camera_name: str,
@ -137,6 +153,7 @@ def export_recording(
def export_rename(event_id: str, body: ExportRenameBody): def export_rename(event_id: str, body: ExportRenameBody):
try: try:
export: Export = Export.get(Export.id == event_id) export: Export = Export.get(Export.id == event_id)
require_camera_access(export.camera)
except DoesNotExist: except DoesNotExist:
return JSONResponse( return JSONResponse(
content=( content=(
@ -165,6 +182,7 @@ def export_rename(event_id: str, body: ExportRenameBody):
def export_delete(event_id: str): def export_delete(event_id: str):
try: try:
export: Export = Export.get(Export.id == event_id) export: Export = Export.get(Export.id == event_id)
require_camera_access(export.camera)
except DoesNotExist: except DoesNotExist:
return JSONResponse( return JSONResponse(
content=( content=(
@ -217,7 +235,9 @@ def export_delete(event_id: str):
@router.get("/exports/{export_id}") @router.get("/exports/{export_id}")
def get_export(export_id: str): def get_export(export_id: str):
try: try:
return JSONResponse(content=model_to_dict(Export.get(Export.id == export_id))) export = Export.get(Export.id == export_id)
require_camera_access(export.camera)
return JSONResponse(content=model_to_dict(export))
except DoesNotExist: except DoesNotExist:
return JSONResponse( return JSONResponse(
content={"success": False, "message": "Export not found"}, content={"success": False, "message": "Export not found"},