From b20609089c887f69b0b8e293c19bc83d972df3d4 Mon Sep 17 00:00:00 2001 From: Filip Leonarski Date: Tue, 30 Sep 2025 09:21:49 +0200 Subject: [PATCH] DAQ: Authentication for staff operations checks if session is active for the user --- daq/src/aaredaq/auth.py | 11 ++++++++++- daq/src/aaredaq/server.py | 26 +++++++++++++------------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/daq/src/aaredaq/auth.py b/daq/src/aaredaq/auth.py index 92ba11f5..d0603df1 100644 --- a/daq/src/aaredaq/auth.py +++ b/daq/src/aaredaq/auth.py @@ -84,7 +84,7 @@ def check_jwt_rw(cfg: BeamlineConfig, data: TokenData) -> None: ) -def check_jwt_staff(data: TokenData) -> None: +def check_jwt_staff(cfg: BeamlineConfig, data: TokenData) -> None: if not data.staff: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, @@ -92,6 +92,15 @@ def check_jwt_staff(data: TokenData) -> None: headers={"WWW-Authenticate": "Bearer"}, ) + try: + cfg.try_set_active_session(data.session, SESSION_EXPIRE_SECONDS) + except Exception as e: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="Another session is active.", + headers={"WWW-Authenticate": "Bearer"}, + ) + def force_current_sesion(cfg: BeamlineConfig, data: TokenData) -> None: cfg.force_set_active_session(data.session, SESSION_EXPIRE_SECONDS) diff --git a/daq/src/aaredaq/server.py b/daq/src/aaredaq/server.py index 40bc9ef3..2de5e676 100644 --- a/daq/src/aaredaq/server.py +++ b/daq/src/aaredaq/server.py @@ -97,14 +97,14 @@ async def smargon(val: SmargonCoordinate, token: str = Depends(oauth2_scheme)): @app.post("/beamline/tweak_abr_meas_pos") async def tweak_abr_meas_pos(val: Coordinate, token: str = Depends(oauth2_scheme)): - auth.check_jwt_staff(auth.parse_token(token)) + auth.check_jwt_staff(cfg, auth.parse_token(token)) daq.tweak_abr_meas_pos(val) return "OK" @app.post("/beamline/save_abr_meas_pos") async def save_abr_meas_pos(token: str = Depends(oauth2_scheme)): - auth.check_jwt_staff(auth.parse_token(token)) + auth.check_jwt_staff(cfg, auth.parse_token(token)) daq.save_abr_meas_pos() return "OK" @@ -122,26 +122,26 @@ async def goto_abr_meas_pos(token: str = Depends(oauth2_scheme)): @app.post("/beam_mark/add") async def mark_beam(x: float, y: float, token: str = Depends(oauth2_scheme)): - auth.check_jwt_staff(auth.parse_token(token)) + auth.check_jwt_staff(cfg, auth.parse_token(token)) daq.mark_beam(x, y) return "OK" @app.post("/beam_mark/clear") async def clear_beam_mark(token: str = Depends(oauth2_scheme)): - auth.check_jwt_staff(auth.parse_token(token)) + auth.check_jwt_staff(cfg, auth.parse_token(token)) daq.clear_mark_beam() return "OK" @app.post("/beamline/beam_center") async def beam_center(x: float, y: float, token: str = Depends(oauth2_scheme)): - auth.check_jwt_staff(auth.parse_token(token)) + auth.check_jwt_staff(cfg, auth.parse_token(token)) daq.beam_center = (x, y) return "OK" @app.post("/beamline/beam_size_mm") async def beam_size_mm(x: float, y: float, token: str = Depends(oauth2_scheme)): - auth.check_jwt_staff(auth.parse_token(token)) + auth.check_jwt_staff(cfg, auth.parse_token(token)) daq.beam_size_mm = Coordinate(x=x, y=y) return "OK" @@ -293,7 +293,7 @@ async def sample_alignment(token: str = Depends(oauth2_scheme)): @app.post("/state/beam_location") async def beam_location(token: str = Depends(oauth2_scheme)): - auth.check_jwt_staff(auth.parse_token(token)) + auth.check_jwt_staff(cfg, auth.parse_token(token)) daq.state = BeamlineStateEnum.BeamLocation # Scans @@ -348,14 +348,14 @@ async def pgroup(token: str = Depends(oauth2_scheme)) -> str: @app.put("/access/pgroup") async def set_pgroup(val: str, token: str = Depends(oauth2_scheme)) -> str: - auth.check_jwt_staff(auth.parse_token(token)) + auth.check_jwt_staff(cfg, auth.parse_token(token)) cfg.pgroup = val return "OK" @app.delete("/access/pgroup") async def del_pgroup(token: str = Depends(oauth2_scheme)) -> str: - auth.check_jwt_staff(auth.parse_token(token)) + auth.check_jwt_staff(cfg, auth.parse_token(token)) cfg.pgroup = None return "OK" @@ -381,23 +381,23 @@ async def force_current_session(token: str = Depends(oauth2_scheme)) -> str: @app.get("/beamline/settings") async def get_settings(token: str = Depends(oauth2_scheme)) -> BeamlineSettingsModel: - auth.check_jwt_staff(auth.parse_token(token)) + auth.check_jwt_staff(cfg, auth.parse_token(token)) return cfg.settings @app.put("/beamline/settings") async def put_settings(s: BeamlineSettingsModel, token: str = Depends(oauth2_scheme)): - auth.check_jwt_staff(auth.parse_token(token)) + auth.check_jwt_staff(cfg, auth.parse_token(token)) cfg.settings = s @app.get("/beamline/cryo_settings") async def get_cryo_settings(token: str = Depends(oauth2_scheme)) -> CryojetSettingsModel: - auth.check_jwt_staff(auth.parse_token(token)) + auth.check_jwt_staff(cfg, auth.parse_token(token)) return cfg.cryojet_settings @app.put("/beamline/cryo_settings") async def put_cryo_settings(s: CryojetSettingsModel, token: str = Depends(oauth2_scheme)): - auth.check_jwt_staff(auth.parse_token(token)) + auth.check_jwt_staff(cfg, auth.parse_token(token)) cfg.cryojet_settings = s LOGGING_CONFIG = {