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.
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::<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]
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<ServerEvent<Unsigned>> {
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<ServerEvent<Unsigned>> {
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 {