From 35a77a729eabf23832dbe98a670644be2ab34154 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Fri, 5 Feb 2021 14:24:00 +0100 Subject: [PATCH] Can toggle incognito mode --- src/controllers/mod.rs | 3 ++- src/controllers/user_ws_actions.rs | 15 +++++++++++ src/controllers/user_ws_controller.rs | 36 ++++++++++++++++++++++++--- src/controllers/user_ws_routes.rs | 11 +++++--- src/data/user_ws_request_handler.rs | 35 +++++++++++++++----------- 5 files changed, 77 insertions(+), 23 deletions(-) create mode 100644 src/controllers/user_ws_actions.rs diff --git a/src/controllers/mod.rs b/src/controllers/mod.rs index 02bde37..7f0c37f 100644 --- a/src/controllers/mod.rs +++ b/src/controllers/mod.rs @@ -19,4 +19,5 @@ pub mod movies_controller; pub mod virtual_directory_controller; pub mod web_app_controller; pub mod calls_controller; -pub mod user_ws_routes; \ No newline at end of file +pub mod user_ws_routes; +pub mod user_ws_actions; \ No newline at end of file diff --git a/src/controllers/user_ws_actions.rs b/src/controllers/user_ws_actions.rs new file mode 100644 index 0000000..3f72bd9 --- /dev/null +++ b/src/controllers/user_ws_actions.rs @@ -0,0 +1,15 @@ +//! # User WebSocket actions +//! +//! This module contains all the base action that can be executed by the WebSocket + +use crate::data::base_request_handler::BaseRequestHandler; +use crate::data::error::Res; +use crate::data::user_ws_request_handler::UserWsRequestHandler; + +/// Update incognito status of the connection +pub fn set_incognito(r: &mut UserWsRequestHandler) -> Res { + let new_state = r.post_bool("enable")?; + r.update_conn(|c| c.incognito = new_state)?; + + r.success("Updated.") +} \ No newline at end of file diff --git a/src/controllers/user_ws_controller.rs b/src/controllers/user_ws_controller.rs index 36c5508..ae224d7 100644 --- a/src/controllers/user_ws_controller.rs +++ b/src/controllers/user_ws_controller.rs @@ -23,7 +23,7 @@ use crate::data::error::{ExecError, Res, ResultBoxError}; use crate::data::http_request_handler::HttpRequestHandler; use crate::data::user::UserID; use crate::data::user_ws_message::UserWsMessage; -use crate::data::user_ws_request_handler::{WsRequestHandler, WsResponseType}; +use crate::data::user_ws_request_handler::{UserWsRequestHandler, UserWsResponseType}; use crate::utils::crypt_utils::rand_str; use crate::utils::date_utils::time; @@ -106,12 +106,37 @@ mod ws_connections_list { use crate::controllers::user_ws_controller::WsSession; use crate::data::user::UserID; + /// This structure contains information about an active connection #[derive(Clone, Debug)] pub struct WsConnection { pub user_id: UserID, pub client_id: u32, pub remote_ip: String, pub session: actix::Addr, + pub incognito: bool, + } + + impl WsConnection { + /// Change some of the properties of the connection + pub fn replace(mut self, do_update: H) -> Self where H: FnOnce(&mut Self) { + let list = get_ws_connections_list(); + let mut list = list.lock().unwrap(); + + for i in 0..list.len() { + if !list[i].session.eq(&self.session) { + continue; + } + + do_update(&mut self); + list[i] = self.clone(); + + break; + } + + drop(list); + + self + } } lazy_static! { @@ -176,6 +201,8 @@ pub fn get_token(r: &mut HttpRequestHandler) -> ResultBoxError { #[derive(Debug)] pub struct WsSession { + // NOTE : apart from hb, the values here won't change ! + user_id: UserID, // Client used for the connection @@ -231,7 +258,7 @@ impl WsSession { }); } - let mut handler = WsRequestHandler::new( + let mut handler = UserWsRequestHandler::new( &find_connection(ctx.address()).ok_or(ExecError::boxed_new("Connection not found!"))?, args, ); @@ -260,8 +287,8 @@ impl WsSession { Ok(UserWsMessage { id: incoming_msg.id, title: match response.r#type { - WsResponseType::SUCCESS => "success".to_string(), - WsResponseType::ERROR => "error".to_string(), + UserWsResponseType::SUCCESS => "success".to_string(), + UserWsResponseType::ERROR => "error".to_string(), }, data: response.content, }) @@ -281,6 +308,7 @@ impl Actor for WsSession { client_id: self.client_id, remote_ip: self.remote_ip.clone(), session: ctx.address(), + incognito: self.incognito, }) } diff --git a/src/controllers/user_ws_routes.rs b/src/controllers/user_ws_routes.rs index f2a0afe..f718e5e 100644 --- a/src/controllers/user_ws_routes.rs +++ b/src/controllers/user_ws_routes.rs @@ -2,11 +2,11 @@ //! //! @author Pierre Hubert -use crate::controllers::likes_controller; +use crate::controllers::{likes_controller, user_ws_actions}; use crate::data::error::Res; -use crate::data::user_ws_request_handler::WsRequestHandler; +use crate::data::user_ws_request_handler::UserWsRequestHandler; -pub type WsRequestProcess = Box Res>; +pub type WsRequestProcess = Box Res>; /// WebSocket route pub struct UserWsRoute { @@ -16,7 +16,7 @@ pub struct UserWsRoute { impl UserWsRoute { pub fn new(route: &str, handler: H) -> UserWsRoute - where H: 'static + Fn(&mut WsRequestHandler) -> Res { + where H: 'static + Fn(&mut UserWsRequestHandler) -> Res { UserWsRoute { route: route.to_string(), handler: Box::new(handler), @@ -27,6 +27,9 @@ impl UserWsRoute { /// Get the list of available WebSocket routes pub fn get_user_ws_routes() -> Vec { vec![ + // Main controller + UserWsRoute::new("$main/set_incognito", user_ws_actions::set_incognito), + // Likes controller UserWsRoute::new("likes/update", likes_controller::update) ] diff --git a/src/data/user_ws_request_handler.rs b/src/data/user_ws_request_handler.rs index 57b5b62..e3ca2e8 100644 --- a/src/data/user_ws_request_handler.rs +++ b/src/data/user_ws_request_handler.rs @@ -11,25 +11,25 @@ use crate::data::base_request_handler::{BaseRequestHandler, RequestValue}; use crate::data::error::ResultBoxError; use crate::data::user::UserID; -pub enum WsResponseType { +pub enum UserWsResponseType { SUCCESS, ERROR, } -pub struct WsResponse { - pub r#type: WsResponseType, +pub struct UserWsResponse { + pub r#type: UserWsResponseType, pub content: serde_json::Value, } -pub struct WsRequestHandler { +pub struct UserWsRequestHandler { connection: WsConnection, args: HashMap, - response: Option, + response: Option, } -impl WsRequestHandler { - pub fn new(connection: &WsConnection, args: HashMap) -> WsRequestHandler { - WsRequestHandler { +impl UserWsRequestHandler { + pub fn new(connection: &WsConnection, args: HashMap) -> UserWsRequestHandler { + UserWsRequestHandler { connection: connection.clone(), args: args.into_iter().map(|f| (f.0, RequestValue::String(f.1))).collect(), response: None, @@ -42,23 +42,30 @@ impl WsRequestHandler { } /// Get the response to the request - pub fn response(mut self) -> WsResponse { + pub fn response(mut self) -> UserWsResponse { if !self.has_response() { self.success("Request done.").unwrap(); } return self.response.unwrap(); } + + /// Update information about the WebSocket connection + pub fn update_conn(&mut self, do_updates: H) -> ResultBoxError where H: FnOnce(&mut WsConnection) { + self.connection = self.connection.clone().replace(do_updates); + + Ok(()) + } } -impl BaseRequestHandler for WsRequestHandler { +impl BaseRequestHandler for UserWsRequestHandler { fn post_parameter_opt(&self, name: &str) -> Option<&RequestValue> { self.args.get(name) } fn set_response(&mut self, response: T) -> RequestResult { - self.response = Some(WsResponse { - r#type: WsResponseType::SUCCESS, + self.response = Some(UserWsResponse { + r#type: UserWsResponseType::SUCCESS, content: serde_json::to_value(response)?, }); @@ -66,8 +73,8 @@ impl BaseRequestHandler for WsRequestHandler { } fn set_error(&mut self, error: HttpError) { - self.response = Some(WsResponse { - r#type: WsResponseType::ERROR, + self.response = Some(UserWsResponse { + r#type: UserWsResponseType::ERROR, content: serde_json::Value::String(error.error.message), }); }