Ready to implement sync client manager
This commit is contained in:
		
							
								
								
									
										17
									
								
								src/broadcast_messages.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/broadcast_messages.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | use crate::sync_client::SyncClientID; | ||||||
|  | use crate::user::{APIClientID, UserID}; | ||||||
|  |  | ||||||
|  | /// Broadcast messages | ||||||
|  | #[derive(Debug, Clone)] | ||||||
|  | pub enum BroadcastMessage { | ||||||
|  |     /// Request to close the session of a specific client | ||||||
|  |     CloseClientSession(APIClientID), | ||||||
|  |     /// Close all the sessions of a given user | ||||||
|  |     CloseAllUserSessions(UserID), | ||||||
|  |     /// Stop sync client for a given user | ||||||
|  |     StopSyncClientForUser(UserID), | ||||||
|  |     /// Start sync client for a given user (if not already running) | ||||||
|  |     StartSyncClientForUser(UserID), | ||||||
|  |     /// Stop a client with a given client ID | ||||||
|  |     StopSyncClient(SyncClientID), | ||||||
|  | } | ||||||
| @@ -4,3 +4,5 @@ pub mod extractors; | |||||||
| pub mod server; | pub mod server; | ||||||
| pub mod user; | pub mod user; | ||||||
| pub mod utils; | pub mod utils; | ||||||
|  | pub mod sync_client; | ||||||
|  | pub mod broadcast_messages; | ||||||
| @@ -4,7 +4,7 @@ use actix_session::{storage::RedisSessionStore, SessionMiddleware}; | |||||||
| use actix_web::cookie::Key; | use actix_web::cookie::Key; | ||||||
| use actix_web::{web, App, HttpServer}; | use actix_web::{web, App, HttpServer}; | ||||||
| use matrix_gateway::app_config::AppConfig; | use matrix_gateway::app_config::AppConfig; | ||||||
| use matrix_gateway::server::api::ws::WsMessage; | use matrix_gateway::broadcast_messages::BroadcastMessage; | ||||||
| use matrix_gateway::server::{api, web_ui}; | use matrix_gateway::server::{api, web_ui}; | ||||||
| use matrix_gateway::user::UserConfig; | use matrix_gateway::user::UserConfig; | ||||||
|  |  | ||||||
| @@ -22,7 +22,9 @@ async fn main() -> std::io::Result<()> { | |||||||
|         .await |         .await | ||||||
|         .expect("Failed to connect to Redis!"); |         .expect("Failed to connect to Redis!"); | ||||||
|  |  | ||||||
|     let (ws_tx, _) = tokio::sync::broadcast::channel::<WsMessage>(16); |     let (ws_tx, _) = tokio::sync::broadcast::channel::<BroadcastMessage>(16); | ||||||
|  |  | ||||||
|  |     // TODO : spawn a tokio task to launch sync client | ||||||
|  |  | ||||||
|     log::info!( |     log::info!( | ||||||
|         "Starting to listen on {} for {}", |         "Starting to listen on {} for {}", | ||||||
|   | |||||||
| @@ -1,7 +1,6 @@ | |||||||
| use crate::constants::{WS_CLIENT_TIMEOUT, WS_HEARTBEAT_INTERVAL}; | use crate::constants::{WS_CLIENT_TIMEOUT, WS_HEARTBEAT_INTERVAL}; | ||||||
| use crate::extractors::client_auth::APIClientAuth; | use crate::extractors::client_auth::APIClientAuth; | ||||||
| use crate::server::HttpResult; | use crate::server::HttpResult; | ||||||
| use crate::user::{APIClientID, UserID}; |  | ||||||
| use actix_web::dev::Payload; | use actix_web::dev::Payload; | ||||||
| use actix_web::{web, FromRequest, HttpRequest}; | use actix_web::{web, FromRequest, HttpRequest}; | ||||||
| use actix_ws::Message; | use actix_ws::Message; | ||||||
| @@ -11,21 +10,15 @@ use tokio::select; | |||||||
| use tokio::sync::broadcast; | use tokio::sync::broadcast; | ||||||
| use tokio::sync::broadcast::Receiver; | use tokio::sync::broadcast::Receiver; | ||||||
| use tokio::time::interval; | use tokio::time::interval; | ||||||
|  | use crate::broadcast_messages::BroadcastMessage; | ||||||
|  |  | ||||||
|  |  | ||||||
| /// WebSocket message |  | ||||||
| #[derive(Debug, Clone)] |  | ||||||
| pub enum WsMessage { |  | ||||||
|     /// Request to close the session of a specific client |  | ||||||
|     CloseClientSession(APIClientID), |  | ||||||
|     /// Close all the sessions of a given user |  | ||||||
|     CloseAllUserSessions(UserID), |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /// Main WS route | /// Main WS route | ||||||
| pub async fn ws( | pub async fn ws( | ||||||
|     req: HttpRequest, |     req: HttpRequest, | ||||||
|     stream: web::Payload, |     stream: web::Payload, | ||||||
|     tx: web::Data<broadcast::Sender<WsMessage>>, |     tx: web::Data<broadcast::Sender<BroadcastMessage>>, | ||||||
| ) -> HttpResult { | ) -> HttpResult { | ||||||
|     // Forcefully ignore request payload by manually extracting authentication information |     // Forcefully ignore request payload by manually extracting authentication information | ||||||
|     let auth = APIClientAuth::from_request(&req, &mut Payload::None).await?; |     let auth = APIClientAuth::from_request(&req, &mut Payload::None).await?; | ||||||
| @@ -44,7 +37,7 @@ pub async fn ws_handler( | |||||||
|     mut session: actix_ws::Session, |     mut session: actix_ws::Session, | ||||||
|     mut msg_stream: actix_ws::MessageStream, |     mut msg_stream: actix_ws::MessageStream, | ||||||
|     auth: APIClientAuth, |     auth: APIClientAuth, | ||||||
|     mut rx: Receiver<WsMessage>, |     mut rx: Receiver<BroadcastMessage>, | ||||||
| ) { | ) { | ||||||
|     log::info!("WS connected"); |     log::info!("WS connected"); | ||||||
|  |  | ||||||
| @@ -64,7 +57,7 @@ pub async fn ws_handler( | |||||||
|                 }; |                 }; | ||||||
|  |  | ||||||
|                 match msg { |                 match msg { | ||||||
|                     WsMessage::CloseClientSession(id)  => { |                     BroadcastMessage::CloseClientSession(id)  => { | ||||||
|                         if let Some(client) = &auth.client { |                         if let Some(client) = &auth.client { | ||||||
|                             if client.id == id { |                             if client.id == id { | ||||||
|                                 log::info!( |                                 log::info!( | ||||||
| @@ -74,7 +67,7 @@ pub async fn ws_handler( | |||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|                     }, |                     }, | ||||||
|                     WsMessage::CloseAllUserSessions(userid) => { |                     BroadcastMessage::CloseAllUserSessions(userid) => { | ||||||
|                         if userid == auth.user.user_id { |                         if userid == auth.user.user_id { | ||||||
|                             log::info!( |                             log::info!( | ||||||
|                                 "closing WS session of user {userid:?} as requested" |                                 "closing WS session of user {userid:?} as requested" | ||||||
| @@ -82,7 +75,7 @@ pub async fn ws_handler( | |||||||
|                             break None; |                             break None; | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                 }; |                 _ => {}}; | ||||||
|  |  | ||||||
|             } |             } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,5 @@ | |||||||
| use crate::app_config::AppConfig; | use crate::app_config::AppConfig; | ||||||
| use crate::constants::{STATE_KEY, USER_SESSION_KEY}; | use crate::constants::{STATE_KEY, USER_SESSION_KEY}; | ||||||
| use crate::server::api::ws::WsMessage; |  | ||||||
| use crate::server::{HttpFailure, HttpResult}; | use crate::server::{HttpFailure, HttpResult}; | ||||||
| use crate::user::{APIClient, APIClientID, User, UserConfig, UserID}; | use crate::user::{APIClient, APIClientID, User, UserConfig, UserID}; | ||||||
| use crate::utils; | use crate::utils; | ||||||
| @@ -11,6 +10,7 @@ use ipnet::IpNet; | |||||||
| use light_openid::primitives::OpenIDConfig; | use light_openid::primitives::OpenIDConfig; | ||||||
| use std::str::FromStr; | use std::str::FromStr; | ||||||
| use tokio::sync::broadcast; | use tokio::sync::broadcast; | ||||||
|  | use crate::broadcast_messages::BroadcastMessage; | ||||||
|  |  | ||||||
| /// Static assets | /// Static assets | ||||||
| #[derive(rust_embed::Embed)] | #[derive(rust_embed::Embed)] | ||||||
| @@ -65,7 +65,7 @@ pub struct FormRequest { | |||||||
| pub async fn home( | pub async fn home( | ||||||
|     session: Session, |     session: Session, | ||||||
|     form_req: Option<web::Form<FormRequest>>, |     form_req: Option<web::Form<FormRequest>>, | ||||||
|     tx: web::Data<broadcast::Sender<WsMessage>>, |     tx: web::Data<broadcast::Sender<BroadcastMessage>>, | ||||||
| ) -> HttpResult { | ) -> HttpResult { | ||||||
|     // Get user information, requesting authentication if information is missing |     // Get user information, requesting authentication if information is missing | ||||||
|     let Some(user): Option<User> = session.get(USER_SESSION_KEY)? else { |     let Some(user): Option<User> = session.get(USER_SESSION_KEY)? else { | ||||||
| @@ -103,8 +103,10 @@ pub async fn home( | |||||||
|                 config.save().await?; |                 config.save().await?; | ||||||
|                 success_message = Some("Matrix token was successfully updated!".to_string()); |                 success_message = Some("Matrix token was successfully updated!".to_string()); | ||||||
|  |  | ||||||
|  |                 // TODO : stop user sync thread | ||||||
|  |  | ||||||
|                 // Invalidate all Ws connections |                 // Invalidate all Ws connections | ||||||
|                 if let Err(e) = tx.send(WsMessage::CloseAllUserSessions(user.id.clone())) { |                 if let Err(e) = tx.send(BroadcastMessage::CloseAllUserSessions(user.id.clone())) { | ||||||
|                     log::error!("Failed to send CloseAllUserSessions: {}", e); |                     log::error!("Failed to send CloseAllUserSessions: {}", e); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| @@ -139,7 +141,7 @@ pub async fn home( | |||||||
|             config.save().await?; |             config.save().await?; | ||||||
|             success_message = Some("The client was successfully deleted!".to_string()); |             success_message = Some("The client was successfully deleted!".to_string()); | ||||||
|  |  | ||||||
|             if let Err(e) = tx.send(WsMessage::CloseClientSession(delete_client_id)) { |             if let Err(e) = tx.send(BroadcastMessage::CloseClientSession(delete_client_id)) { | ||||||
|                 log::error!("Failed to send CloseClientSession: {}", e); |                 log::error!("Failed to send CloseClientSession: {}", e); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								src/sync_client.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/sync_client.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | /// ID of sync client | ||||||
|  | #[derive(Debug, Clone)] | ||||||
|  | pub struct SyncClientID(uuid::Uuid); | ||||||
		Reference in New Issue
	
	Block a user