From 476bffb37b8ed2256512b017f6a5eba2740f5d81 Mon Sep 17 00:00:00 2001 From: Awiteb Date: Sun, 28 Jul 2024 12:03:57 +0300 Subject: [PATCH] refactor: Refactor chat request and response Signed-off-by: Awiteb --- .../oxidetalis/src/database/incoming_chat.rs | 42 +++++++++-- .../src/websocket/handlers/chat_request.rs | 70 ++++++++++++------- 2 files changed, 81 insertions(+), 31 deletions(-) diff --git a/crates/oxidetalis/src/database/incoming_chat.rs b/crates/oxidetalis/src/database/incoming_chat.rs index 17f7a88..60a3308 100644 --- a/crates/oxidetalis/src/database/incoming_chat.rs +++ b/crates/oxidetalis/src/database/incoming_chat.rs @@ -25,11 +25,18 @@ use crate::errors::ServerResult; /// Extension trait for the `incoming_chat` table. pub trait IncomingChatExt { - /// Save the chat request in the recipient table + /// Save the incoming chat request async fn save_in_chat_request( &self, - requester: &PublicKey, - recipient: &UserModel, + chat_request_recipient: &UserModel, + chat_request_sender: &PublicKey, + ) -> ServerResult<()>; + + /// Remove incoming chat request + async fn remove_in_chat_request( + &self, + chat_request_recipient: &UserModel, + chat_request_sender: &PublicKey, ) -> ServerResult<()>; } @@ -37,12 +44,12 @@ impl IncomingChatExt for DatabaseConnection { #[logcall::logcall] async fn save_in_chat_request( &self, - sender: &PublicKey, - recipient: &UserModel, + chat_request_recipient: &UserModel, + chat_request_sender: &PublicKey, ) -> ServerResult<()> { IncomingChatEntity::insert(IncomingChatActiveModel { - recipient_id: Set(recipient.id), - sender: Set(*sender), + recipient_id: Set(chat_request_recipient.id), + sender: Set(*chat_request_sender), received_timestamp: Set(Utc::now()), ..Default::default() }) @@ -59,4 +66,25 @@ impl IncomingChatExt for DatabaseConnection { .await?; Ok(()) } + + async fn remove_in_chat_request( + &self, + chat_request_recipient: &UserModel, + chat_request_sender: &PublicKey, + ) -> ServerResult<()> { + if let Some(user) = chat_request_recipient + .find_related(IncomingChatEntity) + .filter( + IncomingChatColumn::Sender + .eq(chat_request_sender) + .and(IncomingChatColumn::AcceptedResponse.eq(Option::::None)), + ) + .one(self) + .await? + .map(IntoActiveModel::into_active_model) + { + user.delete(self).await?; + } + Ok(()) + } } diff --git a/crates/oxidetalis/src/websocket/handlers/chat_request.rs b/crates/oxidetalis/src/websocket/handlers/chat_request.rs index 77d6ade..448f481 100644 --- a/crates/oxidetalis/src/websocket/handlers/chat_request.rs +++ b/crates/oxidetalis/src/websocket/handlers/chat_request.rs @@ -33,44 +33,58 @@ use crate::{ #[logcall::logcall] pub async fn handle_chat_request( db: &DatabaseConnection, - from: Option<&UserModel>, - to_public_key: &PublicKey, + chat_request_sender: Option<&UserModel>, + chat_request_recipient: &PublicKey, ) -> Option> { - let Some(from_user) = from else { + let Some(chat_request_sender) = chat_request_sender else { return Some(WsError::RegistredUserEvent.into()); }; - let Some(to_user) = try_ws!(Some db.get_user_by_pubk(to_public_key).await) else { + let Some(chat_request_recipient) = + try_ws!(Some db.get_user_by_pubk(chat_request_recipient).await) + else { return Some(WsError::UserNotFound.into()); }; - if from_user.id == to_user.id { + if chat_request_sender.id == chat_request_recipient.id { return Some(WsError::CannotSendChatRequestToSelf.into()); } - if try_ws!(Some db.get_chat_request_to(from_user, to_public_key).await).is_some() { + if try_ws!(Some db.get_chat_request_to(chat_request_sender, &chat_request_recipient.public_key).await).is_some() { return Some(WsError::AlreadySendChatRequest.into()); } - if try_ws!(Some db.is_blacklisted(&to_user, &from_user.public_key).await) { + if try_ws!(Some db.is_blacklisted(&chat_request_recipient, &chat_request_sender.public_key).await) + { return Some(WsError::RecipientBlacklist.into()); } // To ignore the error if the requester added the recipient to the whitelist // table before send a request to them - if let Err(ServerError::Internal(_)) = db.add_to_whitelist(from_user, to_public_key).await { + if let Err(ServerError::Internal(_)) = db + .add_to_whitelist(chat_request_sender, &chat_request_recipient.public_key) + .await + { return Some(WsError::InternalServerError.into()); } - if try_ws!(Some db.is_whitelisted(&to_user, &from_user.public_key).await) { + if try_ws!(Some db.is_whitelisted(&chat_request_recipient, &chat_request_sender.public_key).await) + { return Some(WsError::AlreadyInRecipientWhitelist.into()); } - try_ws!(Some db.save_out_chat_request(from_user, to_public_key).await); - if let Some(conn_id) = ONLINE_USERS.is_online(to_public_key).await { + try_ws!(Some db.save_out_chat_request(chat_request_sender, &chat_request_recipient.public_key).await); + + if let Some(conn_id) = ONLINE_USERS + .is_online(&chat_request_recipient.public_key) + .await + { ONLINE_USERS - .send(&conn_id, ServerEvent::chat_request(&from_user.public_key)) + .send( + &conn_id, + ServerEvent::chat_request(&chat_request_sender.public_key), + ) .await; } else { - try_ws!(Some db.save_in_chat_request(&from_user.public_key, &to_user).await); + try_ws!(Some db.save_in_chat_request(&chat_request_recipient, &chat_request_sender.public_key).await); } None } @@ -78,22 +92,25 @@ pub async fn handle_chat_request( #[logcall::logcall] pub async fn handle_chat_response( db: &DatabaseConnection, - recipient: Option<&UserModel>, - sender_public_key: &PublicKey, + response_sender: Option<&UserModel>, + response_recipient: &PublicKey, accepted: bool, ) -> Option> { - let Some(recipient_user) = recipient else { + let Some(response_sender) = response_sender else { return Some(WsError::RegistredUserEvent.into()); }; - let Some(sender_user) = try_ws!(Some db.get_user_by_pubk(sender_public_key).await) else { + + let Some(response_recipient) = try_ws!(Some db.get_user_by_pubk(response_recipient).await) + else { return Some(WsError::UserNotFound.into()); }; - if recipient_user.id == sender_user.id { + + if response_sender.id == response_recipient.id { return Some(WsError::CannotRespondToOwnChatRequest.into()); } if try_ws!(Some - db.get_chat_request_to(&sender_user, &recipient_user.public_key) + db.get_chat_request_to(&response_recipient, &response_sender.public_key) .await ) .is_none() @@ -104,21 +121,26 @@ pub async fn handle_chat_response( // We don't need to handle the case where the sender is blacklisted or // whitelisted already, just add it if it is not already there let _ = if accepted { - db.add_to_whitelist(recipient_user, sender_public_key).await + db.add_to_whitelist(response_sender, &response_recipient.public_key) + .await } else { - db.add_to_blacklist(recipient_user, sender_public_key).await + db.add_to_blacklist(response_sender, &response_recipient.public_key) + .await }; try_ws!(Some - db.remove_out_chat_request(&sender_user, &recipient_user.public_key) + db.remove_out_chat_request(&response_recipient, &response_sender.public_key) .await ); + try_ws!(Some + db.remove_in_chat_request(response_sender, &response_recipient.public_key).await + ); - if let Some(conn_id) = ONLINE_USERS.is_online(sender_public_key).await { + if let Some(conn_id) = ONLINE_USERS.is_online(&response_recipient.public_key).await { ONLINE_USERS .send( &conn_id, - ServerEvent::chat_request_response(recipient_user.public_key, accepted), + ServerEvent::chat_request_response(response_sender.public_key, accepted), ) .await; } else {