mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-10-05 06:16:49 +03:00
return 403 for a snapshot or thumbnail on another camera
The broad `except Exception` handlers in `event_snapshot` and `event_thumbnail` caught the `HTTPException` from `require_camera_access`, so a restricted user asking for another camera's snapshot got a 404 instead of a 403, and for an object still being tracked the snapshot was rendered before the check ran. Both endpoints now look up the event and check access in their own block, the way the other endpoints do, so a denial propagates.
This commit is contained in:
+77
-55
@@ -955,64 +955,80 @@ async def event_snapshot(
|
|||||||
event_complete = False
|
event_complete = False
|
||||||
jpg_bytes = None
|
jpg_bytes = None
|
||||||
frame_time = 0
|
frame_time = 0
|
||||||
|
|
||||||
try:
|
try:
|
||||||
event = Event.get(Event.id == event_id, Event.end_time != None)
|
event = Event.get(Event.id == event_id, Event.end_time != None)
|
||||||
event_complete = True
|
|
||||||
await require_camera_access(event.camera, request=request)
|
await require_camera_access(event.camera, request=request)
|
||||||
|
except DoesNotExist:
|
||||||
|
event = None
|
||||||
|
|
||||||
|
if event is not None:
|
||||||
|
event_complete = True
|
||||||
|
|
||||||
if not event.has_snapshot:
|
if not event.has_snapshot:
|
||||||
return JSONResponse(
|
return JSONResponse(
|
||||||
content={"success": False, "message": "Snapshot not available"},
|
content={"success": False, "message": "Snapshot not available"},
|
||||||
status_code=404,
|
status_code=404,
|
||||||
)
|
)
|
||||||
snapshot_settings = _resolve_snapshot_settings(
|
|
||||||
request.app.frigate_config.cameras[event.camera].snapshots, params
|
|
||||||
)
|
|
||||||
jpg_bytes, frame_time = get_event_snapshot_bytes(
|
|
||||||
event,
|
|
||||||
ext="jpg",
|
|
||||||
timestamp=snapshot_settings["timestamp"],
|
|
||||||
bounding_box=snapshot_settings["bounding_box"],
|
|
||||||
crop=snapshot_settings["crop"],
|
|
||||||
height=snapshot_settings["height"],
|
|
||||||
quality=snapshot_settings["quality"],
|
|
||||||
timestamp_style=request.app.frigate_config.cameras[
|
|
||||||
event.camera
|
|
||||||
].timestamp_style,
|
|
||||||
colormap=request.app.frigate_config.model_for_camera(event.camera).colormap,
|
|
||||||
)
|
|
||||||
except DoesNotExist:
|
|
||||||
# see if the object is currently being tracked
|
|
||||||
try:
|
try:
|
||||||
camera_states: list[CameraState] = (
|
snapshot_settings = _resolve_snapshot_settings(
|
||||||
request.app.detected_frames_processor.get_camera_states()
|
request.app.frigate_config.cameras[event.camera].snapshots, params
|
||||||
|
)
|
||||||
|
jpg_bytes, frame_time = get_event_snapshot_bytes(
|
||||||
|
event,
|
||||||
|
ext="jpg",
|
||||||
|
timestamp=snapshot_settings["timestamp"],
|
||||||
|
bounding_box=snapshot_settings["bounding_box"],
|
||||||
|
crop=snapshot_settings["crop"],
|
||||||
|
height=snapshot_settings["height"],
|
||||||
|
quality=snapshot_settings["quality"],
|
||||||
|
timestamp_style=request.app.frigate_config.cameras[
|
||||||
|
event.camera
|
||||||
|
].timestamp_style,
|
||||||
|
colormap=request.app.frigate_config.model_for_camera(
|
||||||
|
event.camera
|
||||||
|
).colormap,
|
||||||
)
|
)
|
||||||
for camera_state in camera_states:
|
|
||||||
if event_id in camera_state.tracked_objects:
|
|
||||||
tracked_obj = camera_state.tracked_objects.get(event_id)
|
|
||||||
if tracked_obj is not None:
|
|
||||||
snapshot_settings = _resolve_snapshot_settings(
|
|
||||||
camera_state.camera_config.snapshots, params
|
|
||||||
)
|
|
||||||
jpg_bytes, frame_time = tracked_obj.get_img_bytes(
|
|
||||||
ext="jpg",
|
|
||||||
timestamp=snapshot_settings["timestamp"],
|
|
||||||
bounding_box=snapshot_settings["bounding_box"],
|
|
||||||
crop=snapshot_settings["crop"],
|
|
||||||
height=snapshot_settings["height"],
|
|
||||||
quality=snapshot_settings["quality"],
|
|
||||||
)
|
|
||||||
await require_camera_access(camera_state.name, request=request)
|
|
||||||
except Exception:
|
except Exception:
|
||||||
return JSONResponse(
|
return JSONResponse(
|
||||||
content={"success": False, "message": "Ongoing event not found"},
|
content={"success": False, "message": "Unknown error occurred"},
|
||||||
status_code=404,
|
status_code=404,
|
||||||
)
|
)
|
||||||
except Exception:
|
else:
|
||||||
return JSONResponse(
|
# see if the object is currently being tracked
|
||||||
content={"success": False, "message": "Unknown error occurred"},
|
camera_states: list[CameraState] = (
|
||||||
status_code=404,
|
request.app.detected_frames_processor.get_camera_states()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
for camera_state in camera_states:
|
||||||
|
tracked_obj = camera_state.tracked_objects.get(event_id)
|
||||||
|
|
||||||
|
if tracked_obj is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
await require_camera_access(camera_state.name, request=request)
|
||||||
|
|
||||||
|
try:
|
||||||
|
snapshot_settings = _resolve_snapshot_settings(
|
||||||
|
camera_state.camera_config.snapshots, params
|
||||||
|
)
|
||||||
|
jpg_bytes, frame_time = tracked_obj.get_img_bytes(
|
||||||
|
ext="jpg",
|
||||||
|
timestamp=snapshot_settings["timestamp"],
|
||||||
|
bounding_box=snapshot_settings["bounding_box"],
|
||||||
|
crop=snapshot_settings["crop"],
|
||||||
|
height=snapshot_settings["height"],
|
||||||
|
quality=snapshot_settings["quality"],
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
return JSONResponse(
|
||||||
|
content={"success": False, "message": "Ongoing event not found"},
|
||||||
|
status_code=404,
|
||||||
|
)
|
||||||
|
|
||||||
|
break
|
||||||
|
|
||||||
if jpg_bytes is None:
|
if jpg_bytes is None:
|
||||||
return JSONResponse(
|
return JSONResponse(
|
||||||
content={"success": False, "message": "Live frame not available"},
|
content={"success": False, "message": "Live frame not available"},
|
||||||
@@ -1061,19 +1077,25 @@ async def event_thumbnail(
|
|||||||
|
|
||||||
if not thumbnail_bytes:
|
if not thumbnail_bytes:
|
||||||
# see if the object is currently being tracked
|
# see if the object is currently being tracked
|
||||||
try:
|
camera_states = request.app.detected_frames_processor.get_camera_states()
|
||||||
camera_states = request.app.detected_frames_processor.get_camera_states()
|
|
||||||
for camera_state in camera_states:
|
for camera_state in camera_states:
|
||||||
if event_id in camera_state.tracked_objects:
|
tracked_obj = camera_state.tracked_objects.get(event_id)
|
||||||
tracked_obj = camera_state.tracked_objects.get(event_id)
|
|
||||||
if tracked_obj is not None:
|
if tracked_obj is None:
|
||||||
await require_camera_access(camera_state.name, request=request)
|
continue
|
||||||
thumbnail_bytes = tracked_obj.get_thumbnail(extension.value)
|
|
||||||
except Exception:
|
await require_camera_access(camera_state.name, request=request)
|
||||||
return JSONResponse(
|
|
||||||
content={"success": False, "message": "Event not found"},
|
try:
|
||||||
status_code=404,
|
thumbnail_bytes = tracked_obj.get_thumbnail(extension.value)
|
||||||
)
|
except Exception:
|
||||||
|
return JSONResponse(
|
||||||
|
content={"success": False, "message": "Event not found"},
|
||||||
|
status_code=404,
|
||||||
|
)
|
||||||
|
|
||||||
|
break
|
||||||
|
|
||||||
if not thumbnail_bytes:
|
if not thumbnail_bytes:
|
||||||
return JSONResponse(
|
return JSONResponse(
|
||||||
|
|||||||
Reference in New Issue
Block a user