mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-10-20 13:42:47 +03:00
apply runtime role changes to jsmpeg streams
The output process never subscribed to config/auth, so role edits from the Roles UI (requires_restart 0) did not reach it and jsmpeg kept streaming cameras that had been removed from a role until restart. The output process now replaces its auth config on config/auth updates, which the camera and birdseye broadcast threads read through the shared config.
This commit is contained in:
@@ -18,7 +18,7 @@ from ws4py.server.wsgirefserver import (
|
|||||||
from frigate.comms.config_updater import ConfigSubscriber
|
from frigate.comms.config_updater import ConfigSubscriber
|
||||||
from frigate.comms.detections_updater import DetectionSubscriber, DetectionTypeEnum
|
from frigate.comms.detections_updater import DetectionSubscriber, DetectionTypeEnum
|
||||||
from frigate.comms.ws import OriginCheckedWebSocketApplication, WebSocket
|
from frigate.comms.ws import OriginCheckedWebSocketApplication, WebSocket
|
||||||
from frigate.config import FrigateConfig
|
from frigate.config import AuthConfig, FrigateConfig
|
||||||
from frigate.config.camera.updater import (
|
from frigate.config.camera.updater import (
|
||||||
CameraConfigUpdateEnum,
|
CameraConfigUpdateEnum,
|
||||||
CameraConfigUpdateSubscriber,
|
CameraConfigUpdateSubscriber,
|
||||||
@@ -153,6 +153,7 @@ class OutputProcess(FrigateProcess):
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
birdseye_config_subscriber = ConfigSubscriber("config/birdseye", exact=True)
|
birdseye_config_subscriber = ConfigSubscriber("config/birdseye", exact=True)
|
||||||
|
auth_config_subscriber = ConfigSubscriber("config/auth", exact=True)
|
||||||
|
|
||||||
jsmpeg_cameras: dict[str, JsmpegCamera] = {}
|
jsmpeg_cameras: dict[str, JsmpegCamera] = {}
|
||||||
birdseye: Birdseye | None = None
|
birdseye: Birdseye | None = None
|
||||||
@@ -193,6 +194,13 @@ class OutputProcess(FrigateProcess):
|
|||||||
self.config.birdseye = birdseye_config
|
self.config.birdseye = birdseye_config
|
||||||
logger.debug("Applied dynamic birdseye config update")
|
logger.debug("Applied dynamic birdseye config update")
|
||||||
|
|
||||||
|
# user changes publish None on this topic, role edits an AuthConfig
|
||||||
|
_, auth_config = auth_config_subscriber.check_for_update()
|
||||||
|
|
||||||
|
if isinstance(auth_config, AuthConfig):
|
||||||
|
self.config.auth = auth_config
|
||||||
|
logger.debug("Applied dynamic auth config update")
|
||||||
|
|
||||||
# drain review updates every iteration, not just when birdseye is
|
# drain review updates every iteration, not just when birdseye is
|
||||||
# being consumed, so a dropped end never strands a camera
|
# being consumed, so a dropped end never strands a camera
|
||||||
if birdseye is not None:
|
if birdseye is not None:
|
||||||
@@ -329,6 +337,7 @@ class OutputProcess(FrigateProcess):
|
|||||||
|
|
||||||
config_subscriber.stop()
|
config_subscriber.stop()
|
||||||
birdseye_config_subscriber.stop()
|
birdseye_config_subscriber.stop()
|
||||||
|
auth_config_subscriber.stop()
|
||||||
websocket_server.manager.close_all()
|
websocket_server.manager.close_all()
|
||||||
websocket_server.manager.stop()
|
websocket_server.manager.stop()
|
||||||
websocket_server.manager.join()
|
websocket_server.manager.join()
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
import unittest
|
import unittest
|
||||||
from types import SimpleNamespace
|
from types import SimpleNamespace
|
||||||
|
|
||||||
from frigate.config import FrigateConfig
|
from frigate.config import AuthConfig, FrigateConfig
|
||||||
from frigate.output.ws_auth import ws_has_camera_access
|
from frigate.output.ws_auth import ws_has_camera_access
|
||||||
|
|
||||||
|
|
||||||
@@ -55,3 +55,11 @@ class TestWsHasCameraAccess(unittest.TestCase):
|
|||||||
self.assertFalse(
|
self.assertFalse(
|
||||||
ws_has_camera_access(self._make_ws("limited_user"), "birdseye", self.config)
|
ws_has_camera_access(self._make_ws("limited_user"), "birdseye", self.config)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_replaced_auth_config_revokes_camera(self):
|
||||||
|
ws = self._make_ws("limited_user")
|
||||||
|
self.assertTrue(ws_has_camera_access(ws, "front_door", self.config))
|
||||||
|
|
||||||
|
self.config.auth = AuthConfig(roles={"limited_user": ["back_door"]})
|
||||||
|
self.assertFalse(ws_has_camera_access(ws, "front_door", self.config))
|
||||||
|
self.assertTrue(ws_has_camera_access(ws, "back_door", self.config))
|
||||||
|
|||||||
Reference in New Issue
Block a user