mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-07-14 16:01:13 +03:00
restrict viewer access to logs, labels, and go2rtc stream list
This commit is contained in:
parent
19ec6fa245
commit
fc4910f817
@ -835,7 +835,7 @@ def nvinfo():
|
|||||||
@router.get(
|
@router.get(
|
||||||
"/logs/{service}",
|
"/logs/{service}",
|
||||||
tags=[Tags.logs],
|
tags=[Tags.logs],
|
||||||
dependencies=[Depends(allow_any_authenticated())],
|
dependencies=[Depends(require_role(["admin"]))],
|
||||||
)
|
)
|
||||||
async def logs(
|
async def logs(
|
||||||
service: str = Path(enum=["frigate", "nginx", "go2rtc"]),
|
service: str = Path(enum=["frigate", "nginx", "go2rtc"]),
|
||||||
@ -1040,12 +1040,27 @@ def get_media_sync_status(job_id: str):
|
|||||||
|
|
||||||
|
|
||||||
@router.get("/labels", dependencies=[Depends(allow_any_authenticated())])
|
@router.get("/labels", dependencies=[Depends(allow_any_authenticated())])
|
||||||
def get_labels(camera: str = ""):
|
def get_labels(
|
||||||
|
camera: str = "",
|
||||||
|
allowed_cameras: List[str] = Depends(get_allowed_cameras_for_filter),
|
||||||
|
):
|
||||||
try:
|
try:
|
||||||
if camera:
|
if camera:
|
||||||
|
if camera not in allowed_cameras:
|
||||||
|
return JSONResponse(
|
||||||
|
content={
|
||||||
|
"success": False,
|
||||||
|
"message": f"Access denied to camera '{camera}'",
|
||||||
|
},
|
||||||
|
status_code=403,
|
||||||
|
)
|
||||||
events = Event.select(Event.label).where(Event.camera == camera).distinct()
|
events = Event.select(Event.label).where(Event.camera == camera).distinct()
|
||||||
else:
|
else:
|
||||||
events = Event.select(Event.label).distinct()
|
events = (
|
||||||
|
Event.select(Event.label)
|
||||||
|
.where(Event.camera << allowed_cameras)
|
||||||
|
.distinct()
|
||||||
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(e)
|
logger.error(e)
|
||||||
return JSONResponse(
|
return JSONResponse(
|
||||||
@ -1058,9 +1073,16 @@ def get_labels(camera: str = ""):
|
|||||||
|
|
||||||
|
|
||||||
@router.get("/sub_labels", dependencies=[Depends(allow_any_authenticated())])
|
@router.get("/sub_labels", dependencies=[Depends(allow_any_authenticated())])
|
||||||
def get_sub_labels(split_joined: Optional[int] = None):
|
def get_sub_labels(
|
||||||
|
split_joined: Optional[int] = None,
|
||||||
|
allowed_cameras: List[str] = Depends(get_allowed_cameras_for_filter),
|
||||||
|
):
|
||||||
try:
|
try:
|
||||||
events = Event.select(Event.sub_label).distinct()
|
events = (
|
||||||
|
Event.select(Event.sub_label)
|
||||||
|
.where(Event.camera << allowed_cameras)
|
||||||
|
.distinct()
|
||||||
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
return JSONResponse(
|
return JSONResponse(
|
||||||
content=({"success": False, "message": "Failed to get sub_labels"}),
|
content=({"success": False, "message": "Failed to get sub_labels"}),
|
||||||
|
|||||||
@ -19,7 +19,9 @@ from zeep.exceptions import Fault, TransportError
|
|||||||
from zeep.transports import AsyncTransport
|
from zeep.transports import AsyncTransport
|
||||||
|
|
||||||
from frigate.api.auth import (
|
from frigate.api.auth import (
|
||||||
|
_get_stream_owner_cameras,
|
||||||
allow_any_authenticated,
|
allow_any_authenticated,
|
||||||
|
get_current_user,
|
||||||
require_go2rtc_stream_access,
|
require_go2rtc_stream_access,
|
||||||
require_role,
|
require_role,
|
||||||
)
|
)
|
||||||
@ -31,6 +33,7 @@ from frigate.config.camera.updater import (
|
|||||||
CameraConfigUpdateTopic,
|
CameraConfigUpdateTopic,
|
||||||
)
|
)
|
||||||
from frigate.config.env import substitute_frigate_vars
|
from frigate.config.env import substitute_frigate_vars
|
||||||
|
from frigate.models import User
|
||||||
from frigate.util.builtin import clean_camera_user_pass
|
from frigate.util.builtin import clean_camera_user_pass
|
||||||
from frigate.util.camera_cleanup import cleanup_camera_db, cleanup_camera_files
|
from frigate.util.camera_cleanup import cleanup_camera_db, cleanup_camera_files
|
||||||
from frigate.util.config import find_config_file
|
from frigate.util.config import find_config_file
|
||||||
@ -66,7 +69,7 @@ def _is_valid_host(host: str) -> bool:
|
|||||||
|
|
||||||
|
|
||||||
@router.get("/go2rtc/streams", dependencies=[Depends(allow_any_authenticated())])
|
@router.get("/go2rtc/streams", dependencies=[Depends(allow_any_authenticated())])
|
||||||
def go2rtc_streams():
|
async def go2rtc_streams(request: Request):
|
||||||
r = requests.get("http://127.0.0.1:1984/api/streams")
|
r = requests.get("http://127.0.0.1:1984/api/streams")
|
||||||
if not r.ok:
|
if not r.ok:
|
||||||
logger.error("Failed to fetch streams from go2rtc")
|
logger.error("Failed to fetch streams from go2rtc")
|
||||||
@ -75,6 +78,24 @@ def go2rtc_streams():
|
|||||||
status_code=500,
|
status_code=500,
|
||||||
)
|
)
|
||||||
stream_data = r.json()
|
stream_data = r.json()
|
||||||
|
|
||||||
|
# Roles with an explicit camera list see only streams owned by an allowed
|
||||||
|
# camera. Admin and full-access roles (no list / empty list) see all streams.
|
||||||
|
current_user = await get_current_user(request)
|
||||||
|
if not isinstance(current_user, JSONResponse):
|
||||||
|
role = current_user["role"]
|
||||||
|
roles_dict = request.app.frigate_config.auth.roles
|
||||||
|
if role != "admin" and roles_dict.get(role):
|
||||||
|
all_camera_names = set(request.app.frigate_config.cameras.keys())
|
||||||
|
allowed_cameras = set(
|
||||||
|
User.get_allowed_cameras(role, roles_dict, all_camera_names)
|
||||||
|
)
|
||||||
|
stream_data = {
|
||||||
|
name: data
|
||||||
|
for name, data in stream_data.items()
|
||||||
|
if _get_stream_owner_cameras(request, name) & allowed_cameras
|
||||||
|
}
|
||||||
|
|
||||||
for data in stream_data.values():
|
for data in stream_data.values():
|
||||||
for producer in data.get("producers") or []:
|
for producer in data.get("producers") or []:
|
||||||
producer["url"] = clean_camera_user_pass(producer.get("url", ""))
|
producer["url"] = clean_camera_user_pass(producer.get("url", ""))
|
||||||
@ -966,7 +987,6 @@ async def onvif_probe(
|
|||||||
probe = ffprobe_stream(
|
probe = ffprobe_stream(
|
||||||
request.app.frigate_config.ffmpeg, test_uri, detailed=False
|
request.app.frigate_config.ffmpeg, test_uri, detailed=False
|
||||||
)
|
)
|
||||||
print(probe)
|
|
||||||
ok = probe is not None and getattr(probe, "returncode", 1) == 0
|
ok = probe is not None and getattr(probe, "returncode", 1) == 0
|
||||||
tested_candidates.append(
|
tested_candidates.append(
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user