refactor: Refactor chat request and response
All checks were successful
DCO checker / DCO checker (pull_request) Successful in 7s
Rust CI / Rust CI (pull_request) Successful in 5m35s

Signed-off-by: Awiteb <a@4rs.nl>
This commit is contained in:
Awiteb 2024-07-28 12:03:57 +03:00
parent d1ca5c0a48
commit 476bffb37b
Signed by: awiteb
GPG key ID: 3F6B55640AA6682F
2 changed files with 81 additions and 31 deletions

View file

@ -25,11 +25,18 @@ use crate::errors::ServerResult;
/// Extension trait for the `incoming_chat` table. /// Extension trait for the `incoming_chat` table.
pub trait IncomingChatExt { pub trait IncomingChatExt {
/// Save the chat request in the recipient table /// Save the incoming chat request
async fn save_in_chat_request( async fn save_in_chat_request(
&self, &self,
requester: &PublicKey, chat_request_recipient: &UserModel,
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<()>; ) -> ServerResult<()>;
} }
@ -37,12 +44,12 @@ impl IncomingChatExt for DatabaseConnection {
#[logcall::logcall] #[logcall::logcall]
async fn save_in_chat_request( async fn save_in_chat_request(
&self, &self,
sender: &PublicKey, chat_request_recipient: &UserModel,
recipient: &UserModel, chat_request_sender: &PublicKey,
) -> ServerResult<()> { ) -> ServerResult<()> {
IncomingChatEntity::insert(IncomingChatActiveModel { IncomingChatEntity::insert(IncomingChatActiveModel {
recipient_id: Set(recipient.id), recipient_id: Set(chat_request_recipient.id),
sender: Set(*sender), sender: Set(*chat_request_sender),
received_timestamp: Set(Utc::now()), received_timestamp: Set(Utc::now()),
..Default::default() ..Default::default()
}) })
@ -59,4 +66,25 @@ impl IncomingChatExt for DatabaseConnection {
.await?; .await?;
Ok(()) 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::<bool>::None)),
)
.one(self)
.await?
.map(IntoActiveModel::into_active_model)
{
user.delete(self).await?;
}
Ok(())
}
} }

View file

@ -33,44 +33,58 @@ use crate::{
#[logcall::logcall] #[logcall::logcall]
pub async fn handle_chat_request( pub async fn handle_chat_request(
db: &DatabaseConnection, db: &DatabaseConnection,
from: Option<&UserModel>, chat_request_sender: Option<&UserModel>,
to_public_key: &PublicKey, chat_request_recipient: &PublicKey,
) -> Option<ServerEvent<Unsigned>> { ) -> Option<ServerEvent<Unsigned>> {
let Some(from_user) = from else { let Some(chat_request_sender) = chat_request_sender else {
return Some(WsError::RegistredUserEvent.into()); 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()); 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()); 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()); 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()); return Some(WsError::RecipientBlacklist.into());
} }
// To ignore the error if the requester added the recipient to the whitelist // To ignore the error if the requester added the recipient to the whitelist
// table before send a request to them // 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()); 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()); return Some(WsError::AlreadyInRecipientWhitelist.into());
} }
try_ws!(Some db.save_out_chat_request(from_user, 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(to_public_key).await {
if let Some(conn_id) = ONLINE_USERS
.is_online(&chat_request_recipient.public_key)
.await
{
ONLINE_USERS ONLINE_USERS
.send(&conn_id, ServerEvent::chat_request(&from_user.public_key)) .send(
&conn_id,
ServerEvent::chat_request(&chat_request_sender.public_key),
)
.await; .await;
} else { } 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 None
} }
@ -78,22 +92,25 @@ pub async fn handle_chat_request(
#[logcall::logcall] #[logcall::logcall]
pub async fn handle_chat_response( pub async fn handle_chat_response(
db: &DatabaseConnection, db: &DatabaseConnection,
recipient: Option<&UserModel>, response_sender: Option<&UserModel>,
sender_public_key: &PublicKey, response_recipient: &PublicKey,
accepted: bool, accepted: bool,
) -> Option<ServerEvent<Unsigned>> { ) -> Option<ServerEvent<Unsigned>> {
let Some(recipient_user) = recipient else { let Some(response_sender) = response_sender else {
return Some(WsError::RegistredUserEvent.into()); 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()); return Some(WsError::UserNotFound.into());
}; };
if recipient_user.id == sender_user.id {
if response_sender.id == response_recipient.id {
return Some(WsError::CannotRespondToOwnChatRequest.into()); return Some(WsError::CannotRespondToOwnChatRequest.into());
} }
if try_ws!(Some 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 .await
) )
.is_none() .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 // 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 // whitelisted already, just add it if it is not already there
let _ = if accepted { 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 { } 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 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 .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 ONLINE_USERS
.send( .send(
&conn_id, &conn_id,
ServerEvent::chat_request_response(recipient_user.public_key, accepted), ServerEvent::chat_request_response(response_sender.public_key, accepted),
) )
.await; .await;
} else { } else {