From dd8d8be79be4d7ad80641d07340c77a1c6f5fdec Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Fri, 8 May 2026 11:15:53 +0200 Subject: [PATCH] Refactor WebSocket server access control logic for worker schedules: Updated the handling of user permissions in `handle_connection` to utilize `tokio::task::spawn_blocking`, improving error handling and debugging information in the `WorkerScheduleAccessDebug` struct. This change enhances the robustness of access checks and provides clearer feedback when access is denied. --- src/websocket_server.rs | 56 +++++++++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/src/websocket_server.rs b/src/websocket_server.rs index d0173c2..33f21c8 100644 --- a/src/websocket_server.rs +++ b/src/websocket_server.rs @@ -480,10 +480,27 @@ async fn handle_connection( let guard = user_id_for_incoming.lock().await; guard.clone() }; - let access = uid_opt - .as_deref() - .map(|uid| user_can_read_worker_schedules(&pool_for_incoming, uid)) - .unwrap_or(WorkerScheduleAccessDebug { + let access = match uid_opt { + Some(uid) => { + let pool_for_check = pool_for_incoming.clone(); + match tokio::task::spawn_blocking(move || { + user_can_read_worker_schedules(&pool_for_check, &uid) + }) + .await + { + Ok(v) => v, + Err(e) => WorkerScheduleAccessDebug { + requested_user_id: "".to_string(), + resolved_community_user_id: None, + matched_by: "spawn_blocking_failed".to_string(), + allowed_direct: false, + allowed_falukant: false, + allowed: false, + error: Some(format!("spawn_blocking_failed: {e}")), + }, + } + } + None => WorkerScheduleAccessDebug { requested_user_id: "".to_string(), resolved_community_user_id: None, matched_by: "missing_setUserId".to_string(), @@ -491,7 +508,8 @@ async fn handle_connection( allowed_falukant: false, allowed: false, error: Some("missing_setUserId".to_string()), - }); + }, + }; if !access.allowed { let payload = serde_json::json!({ "event": "getWorkerSchedulesResponse", @@ -523,10 +541,27 @@ async fn handle_connection( let guard = user_id_for_incoming.lock().await; guard.clone() }; - let access = uid_opt - .as_deref() - .map(|uid| user_can_read_worker_schedules(&pool_for_incoming, uid)) - .unwrap_or(WorkerScheduleAccessDebug { + let access = match uid_opt { + Some(uid) => { + let pool_for_check = pool_for_incoming.clone(); + match tokio::task::spawn_blocking(move || { + user_can_read_worker_schedules(&pool_for_check, &uid) + }) + .await + { + Ok(v) => v, + Err(e) => WorkerScheduleAccessDebug { + requested_user_id: "".to_string(), + resolved_community_user_id: None, + matched_by: "spawn_blocking_failed".to_string(), + allowed_direct: false, + allowed_falukant: false, + allowed: false, + error: Some(format!("spawn_blocking_failed: {e}")), + }, + } + } + None => WorkerScheduleAccessDebug { requested_user_id: "".to_string(), resolved_community_user_id: None, matched_by: "missing_setUserId".to_string(), @@ -534,7 +569,8 @@ async fn handle_connection( allowed_falukant: false, allowed: false, error: Some("missing_setUserId".to_string()), - }); + }, + }; if !access.allowed { let payload = serde_json::json!({ "event": "getWorkerSchedulesDetailedResponse",