From 975586d3786a5bd32cd06bde435bb42aee723930 Mon Sep 17 00:00:00 2001 From: Mridul Seth Date: Mon, 22 Sep 2025 14:38:35 +0200 Subject: [PATCH] Add basic password auth to the reduction dashboard --- src/ess/livedata/core/service.py | 14 ++++++++++++-- src/ess/livedata/dashboard/dashboard.py | 9 ++++++++- src/ess/livedata/dashboard/reduction.py | 16 ++++++++++++++-- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/ess/livedata/core/service.py b/src/ess/livedata/core/service.py index 90e432f45..ca1b4f46d 100644 --- a/src/ess/livedata/core/service.py +++ b/src/ess/livedata/core/service.py @@ -176,7 +176,7 @@ def _stop_impl(self) -> None: @staticmethod def setup_arg_parser( - description: str, *, dev_flag: bool = True + description: str, *, dev_flag: bool = True, dashboard_auth: bool = False ) -> argparse.ArgumentParser: parser = argparse.ArgumentParser( description=description, @@ -201,6 +201,17 @@ def setup_arg_parser( default='INFO', help='Set the logging level', ) + if dashboard_auth: + parser.add_argument( + '--basic-auth-password', + default=None, + help='Basic authentication password for the dashboard', + ) + parser.add_argument( + '--basic-auth-cookie-secret', + default=None, + help='Basic authentication cookie secret for the dashboard', + ) return parser @@ -218,7 +229,6 @@ def get_env_defaults( # Convert --arg-name to LIVEDATA_ARG_NAME env_name = f"{prefix}_{action.dest.upper().replace('-', '_')}" env_val = os.getenv(env_name) - # Override with environment variable if present if env_val is not None: if isinstance(default_value, bool): diff --git a/src/ess/livedata/dashboard/dashboard.py b/src/ess/livedata/dashboard/dashboard.py index 7fb8fca74..7a81d98a8 100644 --- a/src/ess/livedata/dashboard/dashboard.py +++ b/src/ess/livedata/dashboard/dashboard.py @@ -54,13 +54,16 @@ def __init__( log_level: int = logging.INFO, dashboard_name: str, port: int = 5007, + basic_auth_password: str | None = None, + basic_auth_cookie_secret: str | None = None, ): name = f'{instrument}_{dashboard_name}' super().__init__(name=name, log_level=log_level) self._instrument = instrument self._port = port self._dev = dev - + self._basic_auth_password = basic_auth_password + self._basic_auth_cookie_secret = basic_auth_cookie_secret self._exit_stack = ExitStack() self._exit_stack.__enter__() @@ -258,6 +261,8 @@ def server(self): show=False, autoreload=False, dev=self._dev, + basic_auth=self._basic_auth_password, + cookie_secret=self._basic_auth_cookie_secret, ) def _start_impl(self) -> None: @@ -276,6 +281,8 @@ def run_forever(self) -> None: show=False, autoreload=True, dev=self._dev, + basic_auth=self._basic_auth_password, + cookie_secret=self._basic_auth_cookie_secret, ) except KeyboardInterrupt: self._logger.info("Keyboard interrupt received, shutting down...") diff --git a/src/ess/livedata/dashboard/reduction.py b/src/ess/livedata/dashboard/reduction.py index 6a36f9f7a..8fb10138c 100644 --- a/src/ess/livedata/dashboard/reduction.py +++ b/src/ess/livedata/dashboard/reduction.py @@ -16,13 +16,23 @@ class ReductionApp(DashboardBase): """Reduction dashboard application.""" - def __init__(self, *, instrument: str = 'dummy', dev: bool = False, log_level: int): + def __init__( + self, + *, + instrument: str = 'dummy', + dev: bool = False, + log_level: int, + basic_auth_password: str | None = None, + basic_auth_cookie_secret: str | None = None, + ): super().__init__( instrument=instrument, dev=dev, log_level=log_level, dashboard_name='reduction_dashboard', port=5009, # Default port for reduction dashboard + basic_auth_password=basic_auth_password, + basic_auth_cookie_secret=basic_auth_cookie_secret, ) self._logger.info("Reduction dashboard initialized") @@ -39,7 +49,9 @@ def create_main_content(self) -> pn.viewable.Viewable: def get_arg_parser() -> argparse.ArgumentParser: - return Service.setup_arg_parser(description='ESSlivedata Dashboard') + return Service.setup_arg_parser( + description='ESSlivedata Dashboard', dashboard_auth=True + ) def main() -> None: