1
0
mirror of https://gitlab.com/comunic/comunicapiv3 synced 2024-11-25 23:09:22 +00:00

Turned a lot of function to async mode

This commit is contained in:
Pierre HUBERT 2022-03-12 07:47:22 +01:00
parent cfaaef68b7
commit 09ce13c554
24 changed files with 368 additions and 357 deletions

12
Cargo.lock generated
View File

@ -370,6 +370,17 @@ version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341" checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341"
[[package]]
name = "async-recursion"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cda8f4bcc10624c4e85bc66b3f452cca98cfa5ca002dc83a16aad2367641bea"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "attohttpc" name = "attohttpc"
version = "0.15.0" version = "0.15.0"
@ -700,6 +711,7 @@ dependencies = [
"actix-multipart", "actix-multipart",
"actix-web", "actix-web",
"actix-web-actors", "actix-web-actors",
"async-recursion",
"bcrypt", "bcrypt",
"bytes", "bytes",
"chrono", "chrono",

View File

@ -41,4 +41,5 @@ zip = "0.5.10"
webpage = "1.2.0" webpage = "1.2.0"
gouth = "0.2.0" gouth = "0.2.0"
webauthn-rs = "0.3.2" webauthn-rs = "0.3.2"
url = "2.2.2" url = "2.2.2"
async-recursion = "1.0.0"

View File

@ -16,7 +16,8 @@ pub fn start() -> Res {
/// Clean up thread handler /// Clean up thread handler
fn clean_up_thread_handler() { fn clean_up_thread_handler() {
// Let the server start before doing cleanup // TODO : uncomment
/*// Let the server start before doing cleanup
std::thread::sleep(INITIAL_REFRESH_LOAD_INTERVAL); std::thread::sleep(INITIAL_REFRESH_LOAD_INTERVAL);
loop { loop {
@ -32,14 +33,14 @@ fn clean_up_thread_handler() {
} }
std::thread::sleep(CLEAN_UP_INTERVAL); std::thread::sleep(CLEAN_UP_INTERVAL);
} }*/
} }
/// Do the cleanup /// Do the cleanup
fn do_clean() -> Res { async fn do_clean() -> Res {
// Clean old login tokens // Clean old login tokens
account_helper::clean_up_old_access_tokens()?; account_helper::clean_up_old_access_tokens().await?;
// Automatic account cleanup // Automatic account cleanup
for user in user_helper::get_all_users()? { for user in user_helper::get_all_users()? {
@ -51,16 +52,16 @@ fn do_clean() -> Res {
notifications_helper::clean_old_user_notifications(&user)?; notifications_helper::clean_old_user_notifications(&user)?;
// Clean old comments // Clean old comments
comments_helper::clean_old_comments(&user)?; comments_helper::clean_old_comments(&user).await?;
// Clean old posts // Clean old posts
posts_helper::clean_old_posts(&user)?; posts_helper::clean_old_posts(&user).await?;
// Clean old conversation messages // Clean old conversation messages
conversations_helper::clean_old_messages(&user)?; conversations_helper::clean_old_messages(&user).await?;
// Remove the account, if it have been inactive for a long time // Remove the account, if it have been inactive for a long time
account_helper::remove_if_inactive_for_too_long_time(&user)?; account_helper::remove_if_inactive_for_too_long_time(&user).await?;
} }
// Clean up old admin actions // Clean up old admin actions

View File

@ -94,7 +94,7 @@ pub async fn login_user(request: &mut HttpRequestHandler) -> RequestResult {
/// Sign out user /// Sign out user
pub async fn logout_user(request: &mut HttpRequestHandler) -> RequestResult { pub async fn logout_user(request: &mut HttpRequestHandler) -> RequestResult {
if let Some(token) = request.user_access_token() { if let Some(token) = request.user_access_token() {
account_helper::destroy_login_tokens(token)?; account_helper::destroy_login_tokens(token).await?;
} }
request.success("User disconnected.") request.success("User disconnected.")
@ -102,7 +102,7 @@ pub async fn logout_user(request: &mut HttpRequestHandler) -> RequestResult {
/// Disconnect a user from all his devices /// Disconnect a user from all his devices
pub async fn disconnect_all_devices(r: &mut HttpRequestHandler) -> RequestResult { pub async fn disconnect_all_devices(r: &mut HttpRequestHandler) -> RequestResult {
account_helper::destroy_all_user_tokens(r.user_id_ref()?)?; account_helper::destroy_all_user_tokens(r.user_id_ref()?).await?;
r.success("Successfully disconnected!") r.success("Successfully disconnected!")
} }
@ -208,7 +208,7 @@ pub async fn delete_account(r: &mut HttpRequestHandler) -> RequestResult {
r.forbidden("You shall not delete MY account (whoever you are, please note that hacking is bad !!!)".to_string())?; r.forbidden("You shall not delete MY account (whoever you are, please note that hacking is bad !!!)".to_string())?;
} }
account_helper::delete(r.user_id_ref()?)?; account_helper::delete(r.user_id_ref()?).await?;
r.success("Account deleted.") r.success("Account deleted.")
} }

View File

@ -88,7 +88,7 @@ impl UserWsRequestHandler {
} }
/// Get calls configuration /// Get calls configuration
pub fn get_config(r: &mut UserWsRequestHandler) -> RequestResult { pub async fn get_config(r: &mut UserWsRequestHandler) -> RequestResult {
// Check whether the user is the member of a call or not // Check whether the user is the member of a call or not
if let None = r.get_conn().active_call { if let None = r.get_conn().active_call {
r.forbidden("You do not belong to any call yet!".to_string())?; r.forbidden("You do not belong to any call yet!".to_string())?;
@ -124,7 +124,7 @@ pub fn is_conversation_having_call(conv_id: &ConvID) -> bool {
} }
/// Join a call /// Join a call
pub fn join_call(r: &mut UserWsRequestHandler) -> RequestResult { pub async fn join_call(r: &mut UserWsRequestHandler) -> RequestResult {
let conv_id = r.post_conv("convID")?.conv_id; let conv_id = r.post_conv("convID")?.conv_id;
// Check if the conversation can have a call // Check if the conversation can have a call
@ -135,23 +135,21 @@ pub fn join_call(r: &mut UserWsRequestHandler) -> RequestResult {
// Remove any other active call with current WebSocket // Remove any other active call with current WebSocket
if let Some(call) = &r.get_conn().active_call { if let Some(call) = &r.get_conn().active_call {
make_user_leave_call(&call.conv_id, r.get_conn())?; make_user_leave_call(&call.conv_id, r.get_conn()).await?;
} }
// Remove any other active connection to current call of current user // Remove any other active connection to current call of current user
user_ws_controller::foreach_connection(|conn| { for conn in user_ws_controller::get_all_connections()? {
if conn.user_id() != r.user_id_ref()? || conn.session.eq(&r.get_conn().session) { if conn.user_id() != r.user_id_ref()? || conn.session.eq(&r.get_conn().session) {
return Ok(()); return Ok(());
} }
if let Some(call) = &conn.active_call { if let Some(call) = &conn.active_call {
if call.conv_id == conv_id { if call.conv_id == conv_id {
make_user_leave_call(&call.conv_id, conn)?; make_user_leave_call(&call.conv_id, &conn).await?;
} }
} }
};
Ok(())
})?;
r.update_conn(|r| r.active_call = Some(ActiveCall { r.update_conn(|r| r.active_call = Some(ActiveCall {
conv_id, conv_id,
@ -159,13 +157,13 @@ pub fn join_call(r: &mut UserWsRequestHandler) -> RequestResult {
}))?; }))?;
// Propagate event // Propagate event
events_helper::propagate_event(&Event::UserJoinedCall(&conv_id, r.user_id_ref()?))?; events_helper::propagate_event(Event::UserJoinedCall(conv_id, r.user_id()?)).await?;
Ok(()) Ok(())
} }
/// Leave a call /// Leave a call
pub fn leave_call(r: &mut UserWsRequestHandler) -> RequestResult { pub async fn leave_call(r: &mut UserWsRequestHandler) -> RequestResult {
// Warning ! For some technical reasons, we do not check if the user // Warning ! For some technical reasons, we do not check if the user
// really belongs to the conversation, so be careful when manipulating // really belongs to the conversation, so be careful when manipulating
// conversation ID here // conversation ID here
@ -177,13 +175,13 @@ pub fn leave_call(r: &mut UserWsRequestHandler) -> RequestResult {
} }
// Make the user leave the call // Make the user leave the call
make_user_leave_call(&conv_id, r.get_conn())?; make_user_leave_call(&conv_id, r.get_conn()).await?;
r.success("Left call!") r.success("Left call!")
} }
/// Get the list of members of a call /// Get the list of members of a call
pub fn get_members_list(r: &mut UserWsRequestHandler) -> RequestResult { pub async fn get_members_list(r: &mut UserWsRequestHandler) -> RequestResult {
let conv_id = r.post_call_id("callID")?; let conv_id = r.post_call_id("callID")?;
let mut list = vec![]; let mut list = vec![];
@ -204,7 +202,7 @@ pub fn gen_call_hash(call_id: &ConvID, peer_id: &UserID) -> String {
} }
/// Handles client signal /// Handles client signal
pub fn on_client_signal(r: &mut UserWsRequestHandler) -> RequestResult { pub async fn on_client_signal(r: &mut UserWsRequestHandler) -> RequestResult {
let call_id = r.post_call_id("callID")?; let call_id = r.post_call_id("callID")?;
let peer_id = r.post_call_peer_id(&call_id, "peerID")?; let peer_id = r.post_call_peer_id(&call_id, "peerID")?;
let sig_type = r.post_string("type")?; let sig_type = r.post_string("type")?;
@ -271,18 +269,18 @@ pub fn on_client_signal(r: &mut UserWsRequestHandler) -> RequestResult {
} }
}; };
events_helper::propagate_event(&Event::NewUserCallSignal(&NewUserCallSignal { events_helper::propagate_event(Event::NewUserCallSignal(NewUserCallSignal {
call_hash: gen_call_hash(&call_id, &peer_id), call_hash: gen_call_hash(&call_id, &peer_id),
user_id: if r.user_id_ref()? == &peer_id { None } else { Some(r.user_id()?) }, user_id: if r.user_id_ref()? == &peer_id { None } else { Some(r.user_id()?) },
signal, signal,
raw_data: r.post_string("data")?, raw_data: r.post_string("data")?,
}))?; })).await?;
r.success("Signal sent") r.success("Signal sent")
} }
/// Mark user ready for streaming /// Mark user ready for streaming
pub fn mark_user_ready(r: &mut UserWsRequestHandler) -> Res { pub async fn mark_user_ready(r: &mut UserWsRequestHandler) -> Res {
let call_id = r.post_call_id("callID")?; let call_id = r.post_call_id("callID")?;
let user_id = r.user_id()?; let user_id = r.user_id()?;
@ -291,14 +289,13 @@ pub fn mark_user_ready(r: &mut UserWsRequestHandler) -> Res {
user_ws_controller::send_message_to_specific_connections( user_ws_controller::send_message_to_specific_connections(
|c| c.user_id() != &user_id && c.is_having_call_with_conversation(&call_id), |c| c.user_id() != &user_id && c.is_having_call_with_conversation(&call_id),
|_| UserWsMessage::no_id_message("call_peer_ready", CallPeerReadyAPI::new(&call_id, r.user_id_ref()?)), |_| UserWsMessage::no_id_message("call_peer_ready", CallPeerReadyAPI::new(&call_id, r.user_id_ref()?)),
None::<fn(&_) -> _>,
)?; )?;
r.success("Information propagated.") r.success("Information propagated.")
} }
/// Request an offer from the server /// Request an offer from the server
pub fn request_offer(r: &mut UserWsRequestHandler) -> Res { pub async fn request_offer(r: &mut UserWsRequestHandler) -> Res {
let call_id = r.post_call_id("callID")?; let call_id = r.post_call_id("callID")?;
// The ID of the user we stream the audio / video from // The ID of the user we stream the audio / video from
@ -308,16 +305,16 @@ pub fn request_offer(r: &mut UserWsRequestHandler) -> Res {
r.forbidden("You can not request an offer for yourself!".to_string())?; r.forbidden("You can not request an offer for yourself!".to_string())?;
} }
events_helper::propagate_event(&Event::UserRequestedCallOffer(&UserCallOfferRequest { events_helper::propagate_event(Event::UserRequestedCallOffer(UserCallOfferRequest {
call_hash: gen_call_hash(&call_id, &peer_id), call_hash: gen_call_hash(&call_id, &peer_id),
user_id: r.user_id()?, user_id: r.user_id()?,
}))?; })).await?;
r.success("Request sent") r.success("Request sent")
} }
/// Notify the user stopped to stream /// Notify the user stopped to stream
pub fn stop_streaming(r: &mut UserWsRequestHandler) -> Res { pub async fn stop_streaming(r: &mut UserWsRequestHandler) -> Res {
let call_id = r.post_call_id("callID")?; let call_id = r.post_call_id("callID")?;
let user_id = r.user_id()?; let user_id = r.user_id()?;
@ -329,22 +326,21 @@ pub fn stop_streaming(r: &mut UserWsRequestHandler) -> Res {
user_ws_controller::send_message_to_specific_connections( user_ws_controller::send_message_to_specific_connections(
|c| c.is_having_call_with_conversation(&call_id) && c.user_id() != &user_id, |c| c.is_having_call_with_conversation(&call_id) && c.user_id() != &user_id,
|_| UserWsMessage::no_id_message("call_peer_interrupted_streaming", CallPeerInterruptedStreamingAPI::new(&call_id, &user_id)), |_| UserWsMessage::no_id_message("call_peer_interrupted_streaming", CallPeerInterruptedStreamingAPI::new(&call_id, &user_id)),
None::<fn(&_) -> _>,
)?; )?;
} }
// Notify proxy // Notify proxy
events_helper::propagate_event(&Event::CloseCallStream(&CloseCallStream { events_helper::propagate_event(Event::CloseCallStream(CloseCallStream {
call_hash: gen_call_hash(&call_id, &user_id), call_hash: gen_call_hash(&call_id, &user_id),
peer_id: None, peer_id: None,
}))?; })).await?;
r.success("ok") r.success("ok")
} }
/// Make the user leave the call /// Make the user leave the call
pub fn make_user_leave_call(conv_id: &ConvID, connection: &UserWsConnection) -> Res { pub async fn make_user_leave_call(conv_id: &ConvID, connection: &UserWsConnection) -> Res {
connection.clone().replace(|c| c.active_call = None); connection.clone().replace(|c| c.active_call = None);
// Notify user (if possible) // Notify user (if possible)
@ -353,39 +349,37 @@ pub fn make_user_leave_call(conv_id: &ConvID, connection: &UserWsConnection) ->
} }
// Close main stream (sender) // Close main stream (sender)
events_helper::propagate_event(&Event::CloseCallStream(&CloseCallStream { events_helper::propagate_event(Event::CloseCallStream(CloseCallStream {
call_hash: gen_call_hash(&conv_id, connection.user_id()), call_hash: gen_call_hash(&conv_id, connection.user_id()),
peer_id: None, peer_id: None,
}))?; })).await?;
// Close receiver streams (other users streams) // Close receiver streams (other users streams)
user_ws_controller::foreach_connection( for peer_conn in user_ws_controller::get_all_connections()? {
|peer_conn| { if peer_conn.is_having_call_with_conversation(conv_id) && peer_conn.user_id() != connection.user_id() {
if peer_conn.is_having_call_with_conversation(conv_id) && peer_conn.user_id() != connection.user_id() { events_helper::propagate_event(Event::CloseCallStream(CloseCallStream {
events_helper::propagate_event(&Event::CloseCallStream(&CloseCallStream { call_hash: gen_call_hash(&conv_id, peer_conn.user_id()),
call_hash: gen_call_hash(&conv_id, peer_conn.user_id()), peer_id: Some(connection.user_id().clone()),
peer_id: Some(connection.user_id().clone()), })).await?;
}))?; }
} };
Ok(())
},
)?;
// Create a notification // Create a notification
events_helper::propagate_event(&Event::UserLeftCall(conv_id, connection.user_id()))?; events_helper::propagate_event(Event::UserLeftCall(
conv_id.clone(),
connection.user_id().clone(),
)).await?;
Ok(()) Ok(())
} }
/// Events handler /// Events handler
pub fn handle_event(e: &events_helper::Event) -> Res { pub async fn handle_event(e: &events_helper::Event) -> Res {
match e { match e {
Event::UserJoinedCall(conv_id, user_id) => { Event::UserJoinedCall(conv_id, user_id) => {
user_ws_controller::send_message_to_specific_connections( user_ws_controller::send_message_to_specific_connections(
|c| c.is_having_call_with_conversation(conv_id) && c.user_id() != user_id, |c| c.is_having_call_with_conversation(conv_id) && c.user_id() != user_id,
|_| UserWsMessage::no_id_message("user_joined_call", JoinedCallMessage::new(conv_id, user_id)), |_| UserWsMessage::no_id_message("user_joined_call", JoinedCallMessage::new(conv_id, user_id)),
None::<fn(&_) -> _>,
)?; )?;
} }
@ -393,13 +387,12 @@ pub fn handle_event(e: &events_helper::Event) -> Res {
user_ws_controller::send_message_to_specific_connections( user_ws_controller::send_message_to_specific_connections(
|c| c.is_having_call_with_conversation(conv_id), |c| c.is_having_call_with_conversation(conv_id),
|_| UserWsMessage::no_id_message("user_left_call", LeftCallMessage::new(conv_id, user_id)), |_| UserWsMessage::no_id_message("user_left_call", LeftCallMessage::new(conv_id, user_id)),
None::<fn(&_) -> _>,
)?; )?;
} }
Event::UserWsClosed(c) => { Event::UserWsClosed(c) => {
if let Some(call) = c.active_call.clone() { if let Some(call) = c.active_call.clone() {
make_user_leave_call(&call.conv_id, c)?; make_user_leave_call(&call.conv_id, c).await?;
} }
} }
@ -423,20 +416,17 @@ pub fn handle_event(e: &events_helper::Event) -> Res {
user_ws_controller::send_message_to_specific_connections( user_ws_controller::send_message_to_specific_connections(
|c| c.user_id() == target_user && c.is_having_call_with_conversation(&call_id), |c| c.user_id() == target_user && c.is_having_call_with_conversation(&call_id),
|_| UserWsMessage::no_id_message("new_call_signal", NewCallSignalAPI::new(&call_id, &peer_id, &msg.data)?), |_| UserWsMessage::no_id_message("new_call_signal", NewCallSignalAPI::new(&call_id, &peer_id, &msg.data)?),
None::<fn(&_) -> _>,
)?; )?;
} }
// Handle proxy disconnect => close all active calls // Handle proxy disconnect => close all active calls
Event::ClosedRTCRelayWebSocket => { Event::ClosedRTCRelayWebSocket => {
user_ws_controller::foreach_connection(|f| { for f in user_ws_controller::get_all_connections()? {
// Close all active connections // Close all active connections
if let Some(call) = &f.active_call { if let Some(call) = &f.active_call {
make_user_leave_call(&call.conv_id, f)?; make_user_leave_call(&call.conv_id, &f).await?;
} }
};
Ok(())
})?;
} }
// Call active call of user (if any) // Call active call of user (if any)
@ -450,7 +440,7 @@ pub fn handle_event(e: &events_helper::Event) -> Res {
})?; })?;
if let Some(c) = conn { if let Some(c) = conn {
make_user_leave_call(conv_id, &c)?; make_user_leave_call(conv_id, &c).await?;
} }
} }
@ -465,7 +455,7 @@ pub fn handle_event(e: &events_helper::Event) -> Res {
})?; })?;
for con in connections { for con in connections {
make_user_leave_call(conv_id, &con)?; make_user_leave_call(conv_id, &con).await?;
} }
} }

View File

@ -49,13 +49,13 @@ pub async fn create(r: &mut HttpRequestHandler) -> RequestResult {
image_path: image, image_path: image,
}; };
let comment_id = comments_helper::create(&comment)?; let comment_id = comments_helper::create(&comment).await?;
// Create notifications // Create notifications
notifications_helper::create_post_notification(&r.user_id()?, post.id, NotifEventType::COMMENT_CREATED)?; notifications_helper::create_post_notification(&r.user_id()?, post.id, NotifEventType::COMMENT_CREATED).await?;
// Remove notifications targeting current user about the post // Remove notifications targeting current user about the post
notifications_helper::delete_all_post_notifications_targeting_user(r.user_id_ref()?, post.id)?; notifications_helper::delete_all_post_notifications_targeting_user(r.user_id_ref()?, post.id).await?;
r.set_response(ResCreateComment::new(comment_id)) r.set_response(ResCreateComment::new(comment_id))
} }
@ -72,7 +72,7 @@ pub async fn edit(r: &mut HttpRequestHandler) -> RequestResult {
let comment = r.post_comment_with_full_access("commentID")?; let comment = r.post_comment_with_full_access("commentID")?;
let new_content = r.post_content("content", 2, true)?; let new_content = r.post_content("content", 2, true)?;
comments_helper::edit(comment.id, &new_content)?; comments_helper::edit(comment.id, &new_content).await?;
r.success("Content updated.") r.success("Content updated.")
} }
@ -81,13 +81,13 @@ pub async fn edit(r: &mut HttpRequestHandler) -> RequestResult {
pub async fn delete(r: &mut HttpRequestHandler) -> RequestResult { pub async fn delete(r: &mut HttpRequestHandler) -> RequestResult {
let comment = r.post_comment_with_full_access("commentID")?; let comment = r.post_comment_with_full_access("commentID")?;
comments_helper::delete(&comment)?; comments_helper::delete(&comment).await?;
r.success("Comment deleted.") r.success("Comment deleted.")
} }
/// Events handler /// Events handler
pub fn handle_event(e: &events_helper::Event) -> Res { pub async fn handle_event(e: &events_helper::Event) -> Res {
match e { match e {
Event::NewComment(comment) => { Event::NewComment(comment) => {
user_ws_controller::send_message_to_specific_connections( user_ws_controller::send_message_to_specific_connections(
@ -95,8 +95,7 @@ pub fn handle_event(e: &events_helper::Event) -> Res {
|c| UserWsMessage::no_id_message( |c| UserWsMessage::no_id_message(
"new_comment", "new_comment",
CommentAPI::new(comment, &Some(c.user_id().clone()))?, CommentAPI::new(comment, &Some(c.user_id().clone()))?,
), )
None::<fn(&_) -> _>,
)?; )?;
} }
@ -106,8 +105,7 @@ pub fn handle_event(e: &events_helper::Event) -> Res {
|c| UserWsMessage::no_id_message( |c| UserWsMessage::no_id_message(
"comment_updated", "comment_updated",
CommentAPI::new(comment, &Some(c.user_id().clone()))?, CommentAPI::new(comment, &Some(c.user_id().clone()))?,
), )
None::<fn(&_) -> _>,
)?; )?;
} }
@ -118,7 +116,6 @@ pub fn handle_event(e: &events_helper::Event) -> Res {
"comment_deleted", "comment_deleted",
comment.id.clone(), comment.id.clone(),
), ),
None::<fn(&_) -> _>,
)?; )?;
} }

View File

@ -21,7 +21,6 @@ use crate::data::error::Res;
use crate::data::http_request_handler::HttpRequestHandler; use crate::data::http_request_handler::HttpRequestHandler;
use crate::data::new_conversation::NewConversation; use crate::data::new_conversation::NewConversation;
use crate::data::new_conversation_message::NewConversationMessage; use crate::data::new_conversation_message::NewConversationMessage;
use crate::data::user_ws_connection::UserWsConnection;
use crate::data::user_ws_message::UserWsMessage; use crate::data::user_ws_message::UserWsMessage;
use crate::data::user_ws_request_handler::UserWsRequestHandler; use crate::data::user_ws_request_handler::UserWsRequestHandler;
use crate::helpers::{conversations_helper, events_helper}; use crate::helpers::{conversations_helper, events_helper};
@ -50,7 +49,7 @@ pub async fn create(r: &mut HttpRequestHandler) -> RequestResult {
}; };
// Create the conversation // Create the conversation
let conv_id = conversations_helper::create(&conv)?; let conv_id = conversations_helper::create(&conv).await?;
r.set_response(ResCreateConversation::new(conv_id)) r.set_response(ResCreateConversation::new(conv_id))
} }
@ -147,7 +146,7 @@ pub async fn add_member(r: &mut HttpRequestHandler) -> RequestResult {
r.bad_request("This user is already a member of this conversation!".to_string())?; r.bad_request("This user is already a member of this conversation!".to_string())?;
} }
conversations_helper::add_member(conv.id, &user_to_add, true, false, Some(r.user_id_ref()?))?; conversations_helper::add_member(conv.id, &user_to_add, true, false, Some(r.user_id_ref()?)).await?;
r.success("The user was added to the conversation!") r.success("The user was added to the conversation!")
} }
@ -195,7 +194,7 @@ pub async fn remove_member(r: &mut HttpRequestHandler) -> RequestResult {
r.bad_request("This user is not a member of this conversation!".to_string())?; r.bad_request("This user is not a member of this conversation!".to_string())?;
} }
conversations_helper::remove_member(&user_to_remove, conv.id, Some(r.user_id_ref()?))?; conversations_helper::remove_member(&user_to_remove, conv.id, Some(r.user_id_ref()?)).await?;
r.ok() r.ok()
} }
@ -228,7 +227,7 @@ pub async fn find_private(r: &mut HttpRequestHandler) -> RequestResult {
group_id: None, group_id: None,
group_min_membership_level: None, group_min_membership_level: None,
}; };
let conv_id = conversations_helper::create(&new_conv)?; let conv_id = conversations_helper::create(&new_conv).await?;
list.push(conv_id); list.push(conv_id);
} }
@ -255,7 +254,7 @@ pub async fn refresh_single(r: &mut HttpRequestHandler) -> RequestResult {
conv.conv_id, conv.conv_id,
r.user_id_ref()?, r.user_id_ref()?,
&messages.last().unwrap(), &messages.last().unwrap(),
)?; ).await?;
} }
r.set_response(ConversationMessageAPI::for_list(&messages)) r.set_response(ConversationMessageAPI::for_list(&messages))
@ -395,7 +394,7 @@ pub async fn send_message(r: &mut HttpRequestHandler) -> RequestResult {
message, message,
file, file,
server_message: None, server_message: None,
})?; }).await?;
r.success("Conversation message was successfully sent!") r.success("Conversation message was successfully sent!")
} }
@ -423,7 +422,7 @@ pub async fn delete_conversation(r: &mut HttpRequestHandler) -> RequestResult {
r.bad_request("This conversation is managed, it can not be deleted by this way!".to_string())?; r.bad_request("This conversation is managed, it can not be deleted by this way!".to_string())?;
} }
conversations_helper::remove_user_from_conversation(&r.user_id()?, &conv, r.user_id_ref()?)?; conversations_helper::remove_user_from_conversation(&r.user_id()?, &conv, r.user_id_ref()?).await?;
r.success("The conversation has been deleted") r.success("The conversation has been deleted")
} }
@ -447,7 +446,7 @@ pub async fn update_message(r: &mut HttpRequestHandler) -> RequestResult {
r.bad_request("New message is too long!".to_string())?; r.bad_request("New message is too long!".to_string())?;
} }
conversations_helper::update_message_content(msg_id, &new_content)?; conversations_helper::update_message_content(msg_id, &new_content).await?;
r.success("Conversation message content successfully updated") r.success("Conversation message content successfully updated")
} }
@ -460,25 +459,25 @@ pub async fn delete_message(r: &mut HttpRequestHandler) -> RequestResult {
r.forbidden("You are not the owner of this message!".to_string())?; r.forbidden("You are not the owner of this message!".to_string())?;
} }
conversations_helper::delete_message_by_id(msg_id)?; conversations_helper::delete_message_by_id(msg_id).await?;
r.success("The message has been successfully deleted!") r.success("The message has been successfully deleted!")
} }
/// A user is writing a message in a conversation /// A user is writing a message in a conversation
pub fn member_is_writing(r: &mut UserWsRequestHandler) -> RequestResult { pub async fn member_is_writing(r: &mut UserWsRequestHandler) -> RequestResult {
let conv_id = r.post_registered_conv_id("convID")?; let conv_id = r.post_registered_conv_id("convID")?;
// Propagate event // Propagate event
events_helper::propagate_event( events_helper::propagate_event(
&Event::UserIsWritingMessageInConversation(r.user_id_ref()?, conv_id) Event::UserIsWritingMessageInConversation(r.user_id()?, conv_id)
)?; ).await?;
r.ok() r.ok()
} }
/// Events handler /// Events handler
pub fn handle_event(e: &events_helper::Event) -> Res { pub async fn handle_event(e: &events_helper::Event) -> Res {
match e { match e {
Event::UpdatedNumberUnreadConversations(users) => { Event::UpdatedNumberUnreadConversations(users) => {
for user in users.iter() { for user in users.iter() {
@ -498,23 +497,22 @@ pub fn handle_event(e: &events_helper::Event) -> Res {
user_ws_controller::send_message_to_specific_connections( user_ws_controller::send_message_to_specific_connections(
|s| s.conversations.contains(conv_id) && s.user_id() != user_id, |s| s.conversations.contains(conv_id) && s.user_id() != user_id,
|_| UserWsMessage::no_id_message("writing_message_in_conv", UserIsWritingMessageInConversation::new(user_id, *conv_id)), |_| UserWsMessage::no_id_message("writing_message_in_conv", UserIsWritingMessageInConversation::new(user_id, *conv_id)),
None::<fn(&_) -> _>,
)?; )?;
} }
Event::NewConversationMessage(msg) => { Event::NewConversationMessage(msg) => {
user_ws_controller::send_message_to_specific_connections( for conn in user_ws_controller::send_message_to_specific_connections(
|f| f.conversations.contains(&msg.conv_id), |f| f.conversations.contains(&msg.conv_id),
|_| UserWsMessage::no_id_message("new_conv_message", ConversationMessageAPI::new(msg)), |_| UserWsMessage::no_id_message("new_conv_message", ConversationMessageAPI::new(msg)),
Some(|conn: &UserWsConnection| conversations_helper::mark_user_seen(msg.conv_id, conn.user_id(), msg)), )? {
)?; conversations_helper::mark_user_seen(msg.conv_id, conn.user_id(), msg).await?;
}
} }
Event::UpdatedConversationMessage(msg) => { Event::UpdatedConversationMessage(msg) => {
user_ws_controller::send_message_to_specific_connections( user_ws_controller::send_message_to_specific_connections(
|f| f.conversations.contains(&msg.conv_id), |f| f.conversations.contains(&msg.conv_id),
|_| UserWsMessage::no_id_message("updated_conv_message", ConversationMessageAPI::new(msg)), |_| UserWsMessage::no_id_message("updated_conv_message", ConversationMessageAPI::new(msg)),
None::<fn(&_) -> _>,
)?; )?;
} }
@ -522,7 +520,6 @@ pub fn handle_event(e: &events_helper::Event) -> Res {
user_ws_controller::send_message_to_specific_connections( user_ws_controller::send_message_to_specific_connections(
|f| f.conversations.contains(&msg.conv_id), |f| f.conversations.contains(&msg.conv_id),
|_| UserWsMessage::no_id_message("deleted_conv_message", ConversationMessageAPI::new(msg)), |_| UserWsMessage::no_id_message("deleted_conv_message", ConversationMessageAPI::new(msg)),
None::<fn(&_) -> _>,
)?; )?;
} }
@ -531,7 +528,6 @@ pub fn handle_event(e: &events_helper::Event) -> Res {
user_ws_controller::send_message_to_specific_connections( user_ws_controller::send_message_to_specific_connections(
|f| f.conversations.contains(conv_id), |f| f.conversations.contains(conv_id),
|_| UserWsMessage::no_id_message("removed_user_from_conv", RemovedUserFromConversationMessage::new(user_id, *conv_id)), |_| UserWsMessage::no_id_message("removed_user_from_conv", RemovedUserFromConversationMessage::new(user_id, *conv_id)),
None::<fn(&_) -> _>,
)?; )?;
// Disconnect user from conversation // Disconnect user from conversation
@ -551,7 +547,6 @@ pub fn handle_event(e: &events_helper::Event) -> Res {
user_ws_controller::send_message_to_specific_connections( user_ws_controller::send_message_to_specific_connections(
|f| f.conversations.contains(conv_id), |f| f.conversations.contains(conv_id),
|_| UserWsMessage::no_id_message("deleted_conversation", conv_id.id()), |_| UserWsMessage::no_id_message("deleted_conversation", conv_id.id()),
None::<fn(&_) -> _>,
)?; )?;
// Disconnect user from conversation // Disconnect user from conversation

View File

@ -85,7 +85,7 @@ pub async fn send_request(r: &mut HttpRequestHandler) -> RequestResult {
notifications_helper::create_friends_notification( notifications_helper::create_friends_notification(
r.user_id_ref()?, r.user_id_ref()?,
&friend_id, &friend_id,
NotifEventType::SENT_FRIEND_REQUEST)?; NotifEventType::SENT_FRIEND_REQUEST).await?;
r.success("The friendship request was successfully sent!") r.success("The friendship request was successfully sent!")
} }
@ -101,7 +101,7 @@ pub async fn cancel_request(r: &mut HttpRequestHandler) -> RequestResult {
friends_helper::remove_request(&r.user_id()?, &friend_id)?; friends_helper::remove_request(&r.user_id()?, &friend_id)?;
// Delete related notifications // Delete related notifications
notifications_helper::delete_all_related_with_friendship_request(r.user_id_ref()?, &friend_id)?; notifications_helper::delete_all_related_with_friendship_request(r.user_id_ref()?, &friend_id).await?;
r.success("Friendship request removed!") r.success("Friendship request removed!")
} }
@ -125,7 +125,7 @@ pub async fn respond_request(r: &mut HttpRequestHandler) -> RequestResult {
true => NotifEventType::ACCEPTED_FRIEND_REQUEST, true => NotifEventType::ACCEPTED_FRIEND_REQUEST,
false => NotifEventType::REJECTED_FRIEND_REQUEST false => NotifEventType::REJECTED_FRIEND_REQUEST
}, },
)?; ).await?;
r.set_response("Response to the friendship request successfully saved!") r.set_response("Response to the friendship request successfully saved!")
} }
@ -137,7 +137,7 @@ pub async fn remove_friend(r: &mut HttpRequestHandler) -> RequestResult {
friends_helper::remove_friendship(r.user_id_ref()?, &friend_id)?; friends_helper::remove_friendship(r.user_id_ref()?, &friend_id)?;
// Delete any related notification // Delete any related notification
notifications_helper::delete_all_related_with_friendship_request(r.user_id_ref()?, &friend_id)?; notifications_helper::delete_all_related_with_friendship_request(r.user_id_ref()?, &friend_id).await?;
r.success("The friend was removed from the list!") r.success("The friend was removed from the list!")
} }

View File

@ -57,7 +57,7 @@ pub async fn create(r: &mut HttpRequestHandler) -> RequestResult {
owner_id: r.user_id()?, owner_id: r.user_id()?,
}; };
let group_id = groups_helper::create(&new_group)?; let group_id = groups_helper::create(&new_group).await?;
r.set_response(GroupCreationResult::new(&group_id)) r.set_response(GroupCreationResult::new(&group_id))
} }
@ -187,7 +187,7 @@ pub async fn create_conversation(r: &mut HttpRequestHandler) -> RequestResult {
let min_membership_level = r.post_group_membership_level_for_conversation("min_membership_level")?; let min_membership_level = r.post_group_membership_level_for_conversation("min_membership_level")?;
let name = r.post_string("name")?; let name = r.post_string("name")?;
let conv_id = conversations_helper::create_conversation_for_group(group, min_membership_level, &name)?; let conv_id = conversations_helper::create_conversation_for_group(group, min_membership_level, &name).await?;
r.set_response(ResCreateConversationForGroup::new(conv_id)) r.set_response(ResCreateConversationForGroup::new(conv_id))
} }
@ -197,7 +197,7 @@ pub async fn set_conversation_visibility(r: &mut HttpRequestHandler) -> RequestR
let conv = r.post_group_conv_admin("conv_id")?; let conv = r.post_group_conv_admin("conv_id")?;
let min_level = r.post_group_membership_level_for_conversation("min_membership_level")?; let min_level = r.post_group_membership_level_for_conversation("min_membership_level")?;
conversations_helper::set_min_group_conversation_membership_level(conv.id, min_level)?; conversations_helper::set_min_group_conversation_membership_level(conv.id, min_level).await?;
r.ok() r.ok()
} }
@ -206,7 +206,7 @@ pub async fn set_conversation_visibility(r: &mut HttpRequestHandler) -> RequestR
pub async fn delete_conversation(r: &mut HttpRequestHandler) -> RequestResult { pub async fn delete_conversation(r: &mut HttpRequestHandler) -> RequestResult {
let conv = r.post_group_conv_admin("conv_id")?; let conv = r.post_group_conv_admin("conv_id")?;
conversations_helper::delete_conversation(&conv)?; conversations_helper::delete_conversation(&conv).await?;
r.ok() r.ok()
} }
@ -236,10 +236,10 @@ pub async fn cancel_invitation(r: &mut HttpRequestHandler) -> RequestResult {
r.forbidden("This user has not been invited to join this group!".to_string())?; r.forbidden("This user has not been invited to join this group!".to_string())?;
} }
groups_helper::delete_member(&group_id, &user_id)?; groups_helper::delete_member(&group_id, &user_id).await?;
// Delete related notifications // Delete related notifications
notifications_helper::delete_all_related_to_group_membership_notifications(&user_id, &group_id)?; notifications_helper::delete_all_related_to_group_membership_notifications(&user_id, &group_id).await?;
r.success("Membership invitation has been cancelled!") r.success("Membership invitation has been cancelled!")
} }
@ -253,11 +253,11 @@ pub async fn invite_user(r: &mut HttpRequestHandler) -> RequestResult {
r.bad_request("The user is not a visitor of the group!".to_string())?; r.bad_request("The user is not a visitor of the group!".to_string())?;
} }
groups_helper::send_invitation(&group_id, &user_id)?; groups_helper::send_invitation(&group_id, &user_id).await?;
// Send a notification // Send a notification
notifications_helper::create_group_membership_notification( notifications_helper::create_group_membership_notification(
&user_id, Some(r.user_id_ref()?), &group_id, NotifEventType::SENT_GROUP_MEMBERSHIP_INVITATION)?; &user_id, Some(r.user_id_ref()?), &group_id, NotifEventType::SENT_GROUP_MEMBERSHIP_INVITATION).await?;
r.success("The user has been successfully invited to join the group!") r.success("The user has been successfully invited to join the group!")
} }
@ -271,7 +271,7 @@ pub async fn respond_invitation(r: &mut HttpRequestHandler) -> RequestResult {
r.not_found("Invitation not found!".to_string())? r.not_found("Invitation not found!".to_string())?
} }
groups_helper::respond_invitation(&group_id, &r.user_id()?, accept)?; groups_helper::respond_invitation(&group_id, &r.user_id()?, accept).await?;
if accept { if accept {
groups_helper::set_following(&group_id, &r.user_id()?, true)?; groups_helper::set_following(&group_id, &r.user_id()?, true)?;
@ -281,7 +281,7 @@ pub async fn respond_invitation(r: &mut HttpRequestHandler) -> RequestResult {
notifications_helper::create_group_membership_notification(r.user_id_ref()?, None, &group_id, match accept { notifications_helper::create_group_membership_notification(r.user_id_ref()?, None, &group_id, match accept {
true => NotifEventType::ACCEPTED_GROUP_MEMBERSHIP_INVITATION, true => NotifEventType::ACCEPTED_GROUP_MEMBERSHIP_INVITATION,
false => NotifEventType::REJECTED_GROUP_MEMBERSHIP_INVITATION false => NotifEventType::REJECTED_GROUP_MEMBERSHIP_INVITATION
})?; }).await?;
r.success("Response to the invitation was successfully saved!") r.success("Response to the invitation was successfully saved!")
} }
@ -312,12 +312,12 @@ pub async fn send_request(r: &mut HttpRequestHandler) -> RequestResult {
time_create: time(), time_create: time(),
level, level,
following: true, following: true,
})?; }).await?;
// Send a notification, if required // Send a notification, if required
if matches!(group.registration_level, GroupRegistrationLevel::MODERATED_REGISTRATION) { if matches!(group.registration_level, GroupRegistrationLevel::MODERATED_REGISTRATION) {
notifications_helper::create_group_membership_notification(r.user_id_ref()?, None, notifications_helper::create_group_membership_notification(r.user_id_ref()?, None,
&group_id, NotifEventType::SENT_GROUP_MEMBERSHIP_REQUEST)?; &group_id, NotifEventType::SENT_GROUP_MEMBERSHIP_REQUEST).await?;
} }
@ -332,10 +332,10 @@ pub async fn cancel_request(r: &mut HttpRequestHandler) -> RequestResult {
r.forbidden("You did not send a membership request to this group!".to_string())?; r.forbidden("You did not send a membership request to this group!".to_string())?;
} }
groups_helper::delete_member(&group_id, &r.user_id()?)?; groups_helper::delete_member(&group_id, &r.user_id()?).await?;
// Delete any related notification // Delete any related notification
notifications_helper::delete_all_related_to_group_membership_notifications(r.user_id_ref()?, &group_id)?; notifications_helper::delete_all_related_to_group_membership_notifications(r.user_id_ref()?, &group_id).await?;
r.success("The request has been successfully cancelled!") r.success("The request has been successfully cancelled!")
} }
@ -360,10 +360,10 @@ pub async fn delete_member(r: &mut HttpRequestHandler) -> RequestResult {
r.forbidden("Only administrators can delete this membership!".to_string())?; r.forbidden("Only administrators can delete this membership!".to_string())?;
} }
groups_helper::delete_member(&group_id, &user_id)?; groups_helper::delete_member(&group_id, &user_id).await?;
// Delete related notifications // Delete related notifications
notifications_helper::delete_all_related_to_group_membership_notifications(&user_id, &group_id)?; notifications_helper::delete_all_related_to_group_membership_notifications(&user_id, &group_id).await?;
r.success("Membership of the user has been successfully deleted!") r.success("Membership of the user has been successfully deleted!")
} }
@ -389,7 +389,7 @@ pub async fn update_membership(r: &mut HttpRequestHandler) -> RequestResult {
r.forbidden("You can not assign this visibility level!".to_string())?; r.forbidden("You can not assign this visibility level!".to_string())?;
} }
groups_helper::update_membership_level(&group_id, &user_id, new_level)?; groups_helper::update_membership_level(&group_id, &user_id, new_level).await?;
r.success("User membership has been successfully updated!") r.success("User membership has been successfully updated!")
} }
@ -404,13 +404,13 @@ pub async fn respond_request(r: &mut HttpRequestHandler) -> RequestResult {
r.forbidden("This user has not requested a membership for this group!".to_string())?; r.forbidden("This user has not requested a membership for this group!".to_string())?;
} }
groups_helper::respond_request(&group_id, &user_id, accept)?; groups_helper::respond_request(&group_id, &user_id, accept).await?;
// Create a notification // Create a notification
notifications_helper::create_group_membership_notification(&user_id, Some(r.user_id_ref()?), &group_id, match accept { notifications_helper::create_group_membership_notification(&user_id, Some(r.user_id_ref()?), &group_id, match accept {
true => NotifEventType::ACCEPTED_GROUP_MEMBERSHIP_REQUEST, true => NotifEventType::ACCEPTED_GROUP_MEMBERSHIP_REQUEST,
false => NotifEventType::REJECTED_GROUP_MEMBERSHIP_REQUEST false => NotifEventType::REJECTED_GROUP_MEMBERSHIP_REQUEST
})?; }).await?;
r.success("The response to the request has been successfully saved!") r.success("The response to the request has been successfully saved!")
} }
@ -433,10 +433,10 @@ pub async fn remove_membership(r: &mut HttpRequestHandler) -> RequestResult {
r.forbidden("You are the last administrator of this group!".to_string())?; r.forbidden("You are the last administrator of this group!".to_string())?;
} }
groups_helper::delete_member(&group_id, &r.user_id()?)?; groups_helper::delete_member(&group_id, &r.user_id()?).await?;
// Delete group membership notifications // Delete group membership notifications
notifications_helper::delete_all_related_to_group_membership_notifications(r.user_id_ref()?, &group_id)?; notifications_helper::delete_all_related_to_group_membership_notifications(r.user_id_ref()?, &group_id).await?;
r.success("Your membership has been successfully deleted!") r.success("Your membership has been successfully deleted!")
} }
@ -456,7 +456,7 @@ pub async fn delete_group(r: &mut HttpRequestHandler) -> RequestResult {
let group_id = r.post_group_id_with_access("groupID", GroupAccessLevel::ADMIN_ACCESS)?; let group_id = r.post_group_id_with_access("groupID", GroupAccessLevel::ADMIN_ACCESS)?;
r.need_user_password("password")?; r.need_user_password("password")?;
groups_helper::delete(&group_id)?; groups_helper::delete(&group_id).await?;
r.success("Group deleted.") r.success("Group deleted.")
} }

View File

@ -2,23 +2,18 @@
//! //!
//! @author Pierre Hubert //! @author Pierre Hubert
use crate::routes::RequestResult;
use crate::data::base_request_handler::BaseRequestHandler; use crate::data::base_request_handler::BaseRequestHandler;
use crate::data::error::ExecError; use crate::data::error::ExecError;
use crate::data::group::GroupAccessLevel; use crate::data::group::GroupAccessLevel;
use crate::data::post::PostAccessLevel; use crate::data::post::PostAccessLevel;
use crate::helpers::{likes_helper, notifications_helper, user_helper}; use crate::helpers::{likes_helper, notifications_helper, user_helper};
use crate::helpers::likes_helper::LikeType; use crate::helpers::likes_helper::LikeType;
use crate::routes::RequestResult;
struct LikeTarget(u64, LikeType); struct LikeTarget(u64, LikeType);
/// Update like status (async version)
pub async fn update_async<H: BaseRequestHandler>(r: &mut H) -> RequestResult {
update(r)
}
/// Update like status /// Update like status
pub fn update<H: BaseRequestHandler>(r: &mut H) -> RequestResult { pub async fn update<H: BaseRequestHandler>(r: &mut H) -> RequestResult {
let req_type = r.post_string("type")?; let req_type = r.post_string("type")?;
let is_liking = r.post_bool("like")?; let is_liking = r.post_bool("like")?;
@ -41,7 +36,7 @@ pub fn update<H: BaseRequestHandler>(r: &mut H) -> RequestResult {
let post = r.post_post_with_access("id", PostAccessLevel::BASIC_ACCESS)?; let post = r.post_post_with_access("id", PostAccessLevel::BASIC_ACCESS)?;
// Delete any notification targeting this user about the post // Delete any notification targeting this user about the post
notifications_helper::delete_all_post_notifications_targeting_user(r.user_id_ref()?, post.id)?; notifications_helper::delete_all_post_notifications_targeting_user(r.user_id_ref()?, post.id).await?;
LikeTarget(post.id, LikeType::POST) LikeTarget(post.id, LikeType::POST)
} }
@ -51,7 +46,7 @@ pub fn update<H: BaseRequestHandler>(r: &mut H) -> RequestResult {
let comment = r.post_comment_with_access("id")?; let comment = r.post_comment_with_access("id")?;
// Delete any notification targeting this user about the post // Delete any notification targeting this user about the post
notifications_helper::delete_all_post_notifications_targeting_user(r.user_id_ref()?, comment.post_id)?; notifications_helper::delete_all_post_notifications_targeting_user(r.user_id_ref()?, comment.post_id).await?;
LikeTarget(comment.id, LikeType::COMMENT) LikeTarget(comment.id, LikeType::COMMENT)
} }

View File

@ -73,14 +73,14 @@ pub async fn mark_seen(r: &mut HttpRequestHandler) -> RequestResult {
notif.from_user_id = None; notif.from_user_id = None;
} }
notifications_helper::delete(&notif)?; notifications_helper::delete(&notif).await?;
r.success("Notification deleted") r.success("Notification deleted")
} }
/// Delete all the notifications of the current user /// Delete all the notifications of the current user
pub async fn delete_all(r: &mut HttpRequestHandler) -> RequestResult { pub async fn delete_all(r: &mut HttpRequestHandler) -> RequestResult {
notifications_helper::delete_all_user(r.user_id_ref()?)?; notifications_helper::delete_all_user(r.user_id_ref()?).await?;
r.success("Notifications deleted.") r.success("Notifications deleted.")
} }

View File

@ -235,7 +235,7 @@ pub async fn create_post(r: &mut HttpRequestHandler) -> RequestResult {
} }
// Create a notification // Create a notification
notifications_helper::create_post_notification(r.user_id_ref()?, post_id, NotifEventType::ELEM_CREATED)?; notifications_helper::create_post_notification(r.user_id_ref()?, post_id, NotifEventType::ELEM_CREATED).await?;
r.set_response(ResCreatePost::new(post_id)) r.set_response(ResCreatePost::new(post_id))
} }
@ -249,7 +249,7 @@ pub async fn set_visibility_level(r: &mut HttpRequestHandler) -> RequestResult {
// Depending on new level, delete (or not) notifications about the post // Depending on new level, delete (or not) notifications about the post
if matches!(new_visibility, PostVisibilityLevel::VISIBILITY_USER) { if matches!(new_visibility, PostVisibilityLevel::VISIBILITY_USER) {
notifications_helper::delete_all_related_with_post(post.id)?; notifications_helper::delete_all_related_with_post(post.id).await?;
} }
r.success("Visibility level updated") r.success("Visibility level updated")
@ -263,7 +263,7 @@ pub async fn update_content(r: &mut HttpRequestHandler) -> RequestResult {
posts_helper::set_content(post.id, &new_content)?; posts_helper::set_content(post.id, &new_content)?;
// Delete the notifications targeting the current user about this post // Delete the notifications targeting the current user about this post
notifications_helper::delete_all_post_notifications_targeting_user(r.user_id_ref()?, post.id)?; notifications_helper::delete_all_post_notifications_targeting_user(r.user_id_ref()?, post.id).await?;
r.success("Content updated") r.success("Content updated")
} }
@ -272,7 +272,7 @@ pub async fn update_content(r: &mut HttpRequestHandler) -> RequestResult {
pub async fn delete(r: &mut HttpRequestHandler) -> RequestResult { pub async fn delete(r: &mut HttpRequestHandler) -> RequestResult {
let post = r.post_post_with_access("postID", PostAccessLevel::FULL_ACCESS)?; let post = r.post_post_with_access("postID", PostAccessLevel::FULL_ACCESS)?;
posts_helper::delete(&post)?; posts_helper::delete(&post).await?;
r.success("Post deleted.") r.success("Post deleted.")
} }

View File

@ -99,27 +99,36 @@ impl actix::Actor for RtcRelayActor {
}).unwrap()) }).unwrap())
} }
fn stopped(&mut self, _ctx: &mut Self::Context) { fn stopped(&mut self, ctx: &mut Self::Context) {
println!("Closed connection to RTC relay."); println!("Closed connection to RTC relay.");
let future = async move {
// Propagate information
if let Err(e) = events_helper::propagate_event(Event::ClosedRTCRelayWebSocket).await {
eprintln!("Failed to propagate rtc closed event! {:#?}", e);
}
// Propagate information eprintln!("Successfully propagated RTC relay stopped envent!");
if let Err(e) = events_helper::propagate_event(&Event::ClosedRTCRelayWebSocket) { };
eprintln!("Failed to propagate rtc closed event! {:#?}", e);
} future.into_actor(self).wait(ctx);
} }
} }
impl RtcRelayActor { impl RtcRelayActor {
fn handle_message(&self, txt: &str) { fn handle_message(&self, txt: &str, ctx: &mut <RtcRelayActor as actix::Actor>::Context) {
match serde_json::from_str::<RTCSocketMessage>(&txt) { match serde_json::from_str::<RTCSocketMessage>(&txt) {
Err(e) => { Err(e) => {
eprintln!("Failed to parse a message from RTC proxy! {:#?}", e); eprintln!("Failed to parse a message from RTC proxy! {:#?}", e);
} }
Ok(msg) => { Ok(msg) => {
if let Err(e) = process_message_from_relay(&msg) { let future = async move {
eprintln!("Failed to process signal from RTC Relay! {:#?}", e); if let Err(e) = process_message_from_relay(&msg).await {
} eprintln!("Failed to process signal from RTC Relay! {:#?}", e);
}
};
future.into_actor(self).spawn(ctx);
} }
} }
} }
@ -142,7 +151,7 @@ impl StreamHandler<Result<actix_web_actors::ws::Message, actix_web_actors::ws::P
// Handle messages // Handle messages
match msg { match msg {
Message::Text(txt) => { Message::Text(txt) => {
self.handle_message(&txt); self.handle_message(&txt, ctx);
} }
Message::Binary(_) => { Message::Binary(_) => {
eprintln!("RTC WS Message::Binary"); eprintln!("RTC WS Message::Binary");
@ -164,7 +173,7 @@ impl StreamHandler<Result<actix_web_actors::ws::Message, actix_web_actors::ws::P
} }
Item::Last(c) => { Item::Last(c) => {
self.recv_buff.extend_from_slice(c.as_ref()); self.recv_buff.extend_from_slice(c.as_ref());
self.handle_message(&String::from_utf8_lossy(&self.recv_buff)) self.handle_message(&String::from_utf8_lossy(&self.recv_buff), ctx)
} }
} }
} }
@ -182,15 +191,15 @@ impl StreamHandler<Result<actix_web_actors::ws::Message, actix_web_actors::ws::P
} }
/// Process a message from the server /// Process a message from the server
fn process_message_from_relay(msg: &RTCSocketMessage) -> Res { async fn process_message_from_relay(msg: &RTCSocketMessage) -> Res {
match msg.title.as_str() { match msg.title.as_str() {
"signal" => { "signal" => {
events_helper::propagate_event(&Event::NewRTCRelayMessage(&NewRtcRelayMessage { events_helper::propagate_event(Event::NewRTCRelayMessage(NewRtcRelayMessage {
call_hash: msg.callHash.clone().unwrap_or(String::new()), call_hash: msg.callHash.clone().unwrap_or(String::new()),
peer_id: msg.peerId.clone().unwrap_or("0".to_string()), peer_id: msg.peerId.clone().unwrap_or("0".to_string()),
data: serde_json::to_string(msg.data.as_ref().unwrap_or(&Value::Null)) data: serde_json::to_string(msg.data.as_ref().unwrap_or(&Value::Null))
.unwrap_or("failed to serialize signal data".to_string()), .unwrap_or("failed to serialize signal data".to_string()),
}))?; })).await?;
} }
title => { title => {

View File

@ -317,9 +317,16 @@ impl Actor for WsSession {
fn stopping(&mut self, ctx: &mut Self::Context) -> Running { fn stopping(&mut self, ctx: &mut Self::Context) -> Running {
// Send an event (user_ws_closed) // Send an event (user_ws_closed)
if let Some(conn) = find_connection(ctx.address()) { if let Some(conn) = find_connection(ctx.address()) {
if let Err(e) = events_helper::propagate_event(&Event::UserWsClosed(&conn)) { let future = async move {
eprintln!("Failed to propagate web socket closed event ! {:#?}", e); if let Err(e) = events_helper::propagate_event(Event::UserWsClosed(conn)).await {
} eprintln!("Failed to propagate web socket closed event ! {:#?}", e);
}
// TODO : remove
eprintln!("Successfully propagated user ws stopping event!");
};
future.into_actor(self).wait(ctx);
} }
remove_connection(ctx.address()); remove_connection(ctx.address());
@ -495,10 +502,9 @@ pub fn send_to_client(conn: &UserWsConnection, msg: &UserWsMessage) -> Res {
} }
/// Send a message to specific users /// Send a message to specific users
pub fn send_message_to_specific_connections<F, M, A>(filter: F, msg_generator: M, after_send: Option<A>) -> Res pub fn send_message_to_specific_connections<F, M>(filter: F, msg_generator: M) -> Res<Vec<UserWsConnection>>
where F: Fn(&UserWsConnection) -> bool, where F: Fn(&UserWsConnection) -> bool,
M: Fn(&UserWsConnection) -> Res<UserWsMessage>, M: Fn(&UserWsConnection) -> Res<UserWsMessage>
A: Fn(&UserWsConnection) -> Res
{ {
let connections = get_ws_connections_list() let connections = get_ws_connections_list()
.lock() .lock()
@ -508,15 +514,11 @@ pub fn send_message_to_specific_connections<F, M, A>(filter: F, msg_generator: M
.map(|f| f.clone()) .map(|f| f.clone())
.collect::<Vec<UserWsConnection>>(); .collect::<Vec<UserWsConnection>>();
for con in connections { for con in &connections {
send_message(con.session.clone(), &msg_generator(&con)?)?; send_message(con.session.clone(), &msg_generator(&con)?)?;
if let Some(cb) = &after_send {
cb(&con)?;
}
} }
Ok(()) Ok(connections)
} }
/// Check out whether user is connected or not /// Check out whether user is connected or not
@ -576,6 +578,11 @@ pub fn foreach_connection<F>(mut f: F) -> Res
Ok(()) Ok(())
} }
/// Get a copy of the entire list of connections
pub fn get_all_connections() -> Res<Vec<UserWsConnection>> {
Ok(get_ws_connections_list().lock().unwrap().clone())
}
/// Events handler /// Events handler
pub fn handle_event(e: &events_helper::Event) -> Res { pub fn handle_event(e: &events_helper::Event) -> Res {
match e { match e {

View File

@ -4,6 +4,7 @@
use crate::data::user::UserID; use crate::data::user::UserID;
#[derive(Debug, Clone)]
pub struct Comment { pub struct Comment {
pub id: u64, pub id: u64,
pub time_sent: u64, pub time_sent: u64,

View File

@ -100,7 +100,7 @@ pub fn refresh_access_token(token: &UserAccessToken) -> Res {
} }
/// Destroy a given user login tokens /// Destroy a given user login tokens
pub fn destroy_login_tokens(access_tokens: &UserAccessToken) -> Res { pub async fn destroy_login_tokens(access_tokens: &UserAccessToken) -> Res {
// Un-register from independent push notifications service // Un-register from independent push notifications service
// (continue to destroy token even in case of failure) // (continue to destroy token even in case of failure)
push_notifications_helper::un_register_from_previous_service(access_tokens)?; push_notifications_helper::un_register_from_previous_service(access_tokens)?;
@ -110,20 +110,20 @@ pub fn destroy_login_tokens(access_tokens: &UserAccessToken) -> Res {
.exec()?; .exec()?;
// Send an event (destroyed_login_tokens) // Send an event (destroyed_login_tokens)
events_helper::propagate_event(&Event::DestroyedLoginToken(access_tokens))?; events_helper::propagate_event(Event::DestroyedLoginToken(access_tokens.clone())).await?;
Ok(()) Ok(())
} }
/// Clean up old access tokens /// Clean up old access tokens
pub fn clean_up_old_access_tokens() -> Res { pub async fn clean_up_old_access_tokens() -> Res {
let to_delete = QueryInfo::new(USER_ACCESS_TOKENS_TABLE) let to_delete = QueryInfo::new(USER_ACCESS_TOKENS_TABLE)
.set_custom_where("last_refresh + timeout < ?") .set_custom_where("last_refresh + timeout < ?")
.add_custom_where_argument_u64(time()) .add_custom_where_argument_u64(time())
.exec(db_to_user_access_token)?; .exec(db_to_user_access_token)?;
for token in to_delete { for token in to_delete {
destroy_login_tokens(&token)?; destroy_login_tokens(&token).await?;
} }
Ok(()) Ok(())
@ -137,11 +137,11 @@ pub fn get_all_login_tokens(id: &UserID) -> Res<Vec<UserAccessToken>> {
} }
/// Destroy all login tokens of a user /// Destroy all login tokens of a user
pub fn destroy_all_user_tokens(id: &UserID) -> ResultBoxError { pub async fn destroy_all_user_tokens(id: &UserID) -> ResultBoxError {
user_ws_controller::disconnect_user_from_all_sockets(id)?; user_ws_controller::disconnect_user_from_all_sockets(id)?;
for token in get_all_login_tokens(id)? { for token in get_all_login_tokens(id)? {
destroy_login_tokens(&token)?; destroy_login_tokens(&token).await?;
} }
Ok(()) Ok(())
@ -365,18 +365,18 @@ pub fn export(user_id: &UserID) -> ResultBoxError<AccountExport> {
} }
/// Delete a user's account /// Delete a user's account
pub fn delete(user_id: &UserID) -> ResultBoxError { pub async fn delete(user_id: &UserID) -> ResultBoxError {
// Close all WebSockets of user // Close all WebSockets of user
destroy_all_user_tokens(user_id)?; destroy_all_user_tokens(user_id).await?;
// Delete all group membership // Delete all group membership
groups_helper::delete_all_user_groups(user_id)?; groups_helper::delete_all_user_groups(user_id).await?;
// Delete all user comments // Delete all user comments
comments_helper::delete_all_user(user_id)?; comments_helper::delete_all_user(user_id).await?;
// Delete all user posts // Delete all user posts
posts_helper::delete_all_user(user_id)?; posts_helper::delete_all_user(user_id).await?;
// Delete all responses of user to surveys // Delete all responses of user to surveys
survey_helper::delete_all_user_responses(user_id)?; survey_helper::delete_all_user_responses(user_id)?;
@ -385,13 +385,13 @@ pub fn delete(user_id: &UserID) -> ResultBoxError {
likes_helper::delete_all_user(user_id)?; likes_helper::delete_all_user(user_id)?;
// Delete all conversation messages // Delete all conversation messages
conversations_helper::delete_all_user_messages(user_id)?; conversations_helper::delete_all_user_messages(user_id).await?;
// Remove the user from all its conversations // Remove the user from all its conversations
conversations_helper::delete_all_user_conversations(user_id)?; conversations_helper::delete_all_user_conversations(user_id).await?;
// Delete all the notifications related with the user // Delete all the notifications related with the user
notifications_helper::delete_all_related_with_user(user_id)?; notifications_helper::delete_all_related_with_user(user_id).await?;
// Delete all user friends, including friendship requests // Delete all user friends, including friendship requests
friends_helper::delete_all_user(user_id)?; friends_helper::delete_all_user(user_id)?;
@ -409,7 +409,7 @@ pub fn delete(user_id: &UserID) -> ResultBoxError {
forez_presence_helper::delete_all_user(user_id)?; forez_presence_helper::delete_all_user(user_id)?;
// Delete connections to all services // Delete connections to all services
destroy_all_user_tokens(user_id)?; destroy_all_user_tokens(user_id).await?;
// Remove the user from the database // Remove the user from the database
database::DeleteQuery::new(USERS_TABLE) database::DeleteQuery::new(USERS_TABLE)
@ -420,7 +420,7 @@ pub fn delete(user_id: &UserID) -> ResultBoxError {
} }
/// Automatically delete the account, if it have been inactive for a too long time /// Automatically delete the account, if it have been inactive for a too long time
pub fn remove_if_inactive_for_too_long_time(user: &User) -> Res { pub async fn remove_if_inactive_for_too_long_time(user: &User) -> Res {
let timeout = user.delete_account_after.unwrap_or(0); let timeout = user.delete_account_after.unwrap_or(0);
if timeout < 1 { if timeout < 1 {
@ -428,7 +428,7 @@ pub fn remove_if_inactive_for_too_long_time(user: &User) -> Res {
} }
if user.last_activity < time() - timeout { if user.last_activity < time() - timeout {
delete(&user.id)?; delete(&user.id).await?;
} }
Ok(()) Ok(())

View File

@ -13,7 +13,7 @@ use crate::utils::date_utils::{mysql_date, time};
use crate::utils::user_data_utils::user_data_path; use crate::utils::user_data_utils::user_data_path;
/// Create a new comment. In case of success, this function returns the ID of the created comment /// Create a new comment. In case of success, this function returns the ID of the created comment
pub fn create(c: &Comment) -> ResultBoxError<u64> { pub async fn create(c: &Comment) -> ResultBoxError<u64> {
let comment_id = database::InsertQuery::new(COMMENTS_TABLE) let comment_id = database::InsertQuery::new(COMMENTS_TABLE)
.add_u64("ID_texte", c.post_id) .add_u64("ID_texte", c.post_id)
.add_user_id("ID_personne", &c.user_id) .add_user_id("ID_personne", &c.user_id)
@ -25,7 +25,7 @@ pub fn create(c: &Comment) -> ResultBoxError<u64> {
.ok_or(ExecError::new("No ID returned after comment creation!"))?; .ok_or(ExecError::new("No ID returned after comment creation!"))?;
// Emit an event // Emit an event
events_helper::propagate_event(&Event::NewComment(&get_single(comment_id)?))?; events_helper::propagate_event(Event::NewComment(get_single(comment_id)?)).await?;
Ok(comment_id) Ok(comment_id)
} }
@ -67,20 +67,20 @@ fn db_to_comment(row: &database::RowResult) -> ResultBoxError<Comment> {
} }
/// Update comment content /// Update comment content
pub fn edit(comment_id: u64, new_content: &str) -> ResultBoxError { pub async fn edit(comment_id: u64, new_content: &str) -> ResultBoxError {
database::UpdateInfo::new(COMMENTS_TABLE) database::UpdateInfo::new(COMMENTS_TABLE)
.cond_u64("ID", comment_id) .cond_u64("ID", comment_id)
.set_str("commentaire", new_content) .set_str("commentaire", new_content)
.exec()?; .exec()?;
// Emit an event // Emit an event
events_helper::propagate_event(&Event::UpdatedComment(&get_single(comment_id)?))?; events_helper::propagate_event(Event::UpdatedComment(get_single(comment_id)?)).await?;
Ok(()) Ok(())
} }
/// Delete a single comment /// Delete a single comment
pub fn delete(c: &Comment) -> ResultBoxError { pub async fn delete(c: &Comment) -> ResultBoxError {
// Delete associated image (if any) // Delete associated image (if any)
if let Some(image) = &c.image_path { if let Some(image) = &c.image_path {
let path = user_data_path(image.as_ref()); let path = user_data_path(image.as_ref());
@ -98,31 +98,32 @@ pub fn delete(c: &Comment) -> ResultBoxError {
.exec()?; .exec()?;
// Emit an event // Emit an event
events_helper::propagate_event(&Event::DeletedComment(c))?; let c = (*c).clone();
events_helper::propagate_event(Event::DeletedComment(c)).await?;
Ok(()) Ok(())
} }
/// Delete all the comments associated to a post /// Delete all the comments associated to a post
pub fn delete_all(post_id: u64) -> ResultBoxError { pub async fn delete_all(post_id: u64) -> ResultBoxError {
for c in &get(post_id)? { for c in &get(post_id)? {
delete(c)?; delete(c).await?;
} }
Ok(()) Ok(())
} }
/// Delete all the comments created by a user /// Delete all the comments created by a user
pub fn delete_all_user(user_id: &UserID) -> ResultBoxError { pub async fn delete_all_user(user_id: &UserID) -> ResultBoxError {
for comment in &export_all_user(user_id)? { for comment in &export_all_user(user_id)? {
delete(comment)?; delete(comment).await?;
} }
Ok(()) Ok(())
} }
/// Clean old user comments /// Clean old user comments
pub fn clean_old_comments(user: &User) -> Res { pub async fn clean_old_comments(user: &User) -> Res {
let lifetime = user.delete_comments_after.unwrap_or(0); let lifetime = user.delete_comments_after.unwrap_or(0);
if lifetime < 1 { if lifetime < 1 {
return Ok(()); return Ok(());
@ -135,7 +136,7 @@ pub fn clean_old_comments(user: &User) -> Res {
.exec(db_to_comment)?; .exec(db_to_comment)?;
for comment in comments { for comment in comments {
delete(&comment)?; delete(&comment).await?;
} }
Ok(()) Ok(())

View File

@ -18,7 +18,7 @@ use crate::utils::date_utils::time;
use crate::utils::user_data_utils::delete_user_data_file_if_exists; use crate::utils::user_data_utils::delete_user_data_file_if_exists;
/// Create a new conversation. This method returns the ID of the created conversation /// Create a new conversation. This method returns the ID of the created conversation
pub fn create(conv: &NewConversation) -> Res<ConvID> { pub async fn create(conv: &NewConversation) -> Res<ConvID> {
// Create the conversation in the main table // Create the conversation in the main table
let conv_id = InsertQuery::new(CONV_LIST_TABLE) let conv_id = InsertQuery::new(CONV_LIST_TABLE)
.add_str("name", conv.name.clone().unwrap_or(String::new()).as_str()) .add_str("name", conv.name.clone().unwrap_or(String::new()).as_str())
@ -36,15 +36,16 @@ pub fn create(conv: &NewConversation) -> Res<ConvID> {
// Initialize the list of members of the group // Initialize the list of members of the group
if conv.group_id.is_some() { if conv.group_id.is_some() {
update_members_list_for_group_conversation(conv_id)?; update_members_list_for_group_conversation(conv_id).await?;
} else { } else {
// Add the creator of the conversation // Add the creator of the conversation
add_member(conv_id, &conv.owner_id, conv.owner_following, true, Some(&conv.owner_id))?; add_member(conv_id, &conv.owner_id, conv.owner_following, true, Some(&conv.owner_id)).await?;
// Add other members to the conversation // Add other members to the conversation
for member in &conv.members { for member in &conv.members {
if !member.eq(&conv.owner_id) { if !member.eq(&conv.owner_id) {
add_member(conv_id, member, true, false, Some(&conv.owner_id))?; add_member(conv_id, member, true, false,
Some(&conv.owner_id)).await?;
} }
} }
} }
@ -53,7 +54,7 @@ pub fn create(conv: &NewConversation) -> Res<ConvID> {
} }
/// Create a conversation for a group /// Create a conversation for a group
pub fn create_conversation_for_group(group_id: GroupID, min_membership_level: GroupMembershipLevel, name: &String) -> Res<ConvID> { pub async fn create_conversation_for_group(group_id: GroupID, min_membership_level: GroupMembershipLevel, name: &String) -> Res<ConvID> {
create(&NewConversation { create(&NewConversation {
owner_id: UserID::invalid(), owner_id: UserID::invalid(),
name: Some(name.to_string()), name: Some(name.to_string()),
@ -64,11 +65,11 @@ pub fn create_conversation_for_group(group_id: GroupID, min_membership_level: Gr
owner_following: false, owner_following: false,
members: Default::default(), members: Default::default(),
can_everyone_add_members: false, can_everyone_add_members: false,
}) }).await
} }
/// Add a member to a conversation /// Add a member to a conversation
pub fn add_member(conv_id: ConvID, user_id: &UserID, following: bool, admin: bool, adder: Option<&UserID>) -> Res { pub async fn add_member(conv_id: ConvID, user_id: &UserID, following: bool, admin: bool, adder: Option<&UserID>) -> Res {
InsertQuery::new(CONV_MEMBERS_TABLE) InsertQuery::new(CONV_MEMBERS_TABLE)
.add_conv_id("conv_id", conv_id) .add_conv_id("conv_id", conv_id)
.add_user_id("user_id", user_id) .add_user_id("user_id", user_id)
@ -91,11 +92,11 @@ pub fn add_member(conv_id: ConvID, user_id: &UserID, following: bool, admin: boo
user_added: user_id.clone(), user_added: user_id.clone(),
}), }),
) )
)?; ).await?;
} else { } else {
send_message(&NewConversationMessage::new_server_message( send_message(&NewConversationMessage::new_server_message(
conv_id, ConversationServerMessageType::UserCreatedConversation(user_id.clone()), conv_id, ConversationServerMessageType::UserCreatedConversation(user_id.clone()),
))?; )).await?;
} }
} }
@ -191,13 +192,13 @@ pub fn set_settings(settings: NewConversationSettings) -> Res {
} }
/// Change minimal membership level to join a group conversation /// Change minimal membership level to join a group conversation
pub fn set_min_group_conversation_membership_level(conv_id: ConvID, level: GroupMembershipLevel) -> Res { pub async fn set_min_group_conversation_membership_level(conv_id: ConvID, level: GroupMembershipLevel) -> Res {
database::UpdateInfo::new(CONV_LIST_TABLE) database::UpdateInfo::new(CONV_LIST_TABLE)
.cond_conv_id("id", conv_id) .cond_conv_id("id", conv_id)
.set_u32("min_group_membership_level", level.to_db()) .set_u32("min_group_membership_level", level.to_db())
.exec()?; .exec()?;
update_members_list_for_group_conversation(conv_id) update_members_list_for_group_conversation(conv_id).await
} }
/// Search for private conversation between two users /// Search for private conversation between two users
@ -274,7 +275,7 @@ pub fn export_all_user_messages(user_id: &UserID) -> ResultBoxError<Vec<Conversa
} }
/// Clean old user conversation messages /// Clean old user conversation messages
pub fn clean_old_messages(user: &User) -> Res { pub async fn clean_old_messages(user: &User) -> Res {
let lifetime = user.delete_conversation_messages_after.unwrap_or(0); let lifetime = user.delete_conversation_messages_after.unwrap_or(0);
if lifetime < 1 { if lifetime < 1 {
return Ok(()); return Ok(());
@ -287,16 +288,16 @@ pub fn clean_old_messages(user: &User) -> Res {
.exec(db_to_conversation_message)?; .exec(db_to_conversation_message)?;
for message in messages { for message in messages {
delete_message(&message)?; delete_message(&message).await?;
} }
Ok(()) Ok(())
} }
/// Delete all the messages of a given user /// Delete all the messages of a given user
pub fn delete_all_user_messages(user_id: &UserID) -> ResultBoxError { pub async fn delete_all_user_messages(user_id: &UserID) -> ResultBoxError {
for msg in &export_all_user_messages(user_id)? { for msg in &export_all_user_messages(user_id)? {
delete_message(msg)?; delete_message(msg).await?;
} }
// Remove all server messages related with the user // Remove all server messages related with the user
@ -312,9 +313,9 @@ pub fn delete_all_user_messages(user_id: &UserID) -> ResultBoxError {
} }
/// Remove the user from all the conversations he belongs to /// Remove the user from all the conversations he belongs to
pub fn delete_all_user_conversations(user_id: &UserID) -> ResultBoxError { pub async fn delete_all_user_conversations(user_id: &UserID) -> ResultBoxError {
for conversation in &get_list_user(user_id)? { for conversation in &get_list_user(user_id)? {
remove_user_from_conversation(user_id, conversation, user_id)?; remove_user_from_conversation(user_id, conversation, user_id).await?;
} }
Ok(()) Ok(())
@ -335,7 +336,7 @@ pub fn get_single_message(msg_id: u64) -> ResultBoxError<ConversationMessage> {
} }
/// Send a new conversation message /// Send a new conversation message
pub fn send_message(msg: &NewConversationMessage) -> ResultBoxError<()> { pub async fn send_message(msg: &NewConversationMessage) -> ResultBoxError<()> {
let t = time(); let t = time();
// Insert the message in the database // Insert the message in the database
@ -378,33 +379,33 @@ pub fn send_message(msg: &NewConversationMessage) -> ResultBoxError<()> {
// Mark the user has seen his message // Mark the user has seen his message
if let Some(user_id) = &msg.user_id { if let Some(user_id) = &msg.user_id {
mark_user_seen(msg.conv_id, user_id, &new_message)?; mark_user_seen(msg.conv_id, user_id, &new_message).await?;
} }
// Send an event (updated_number_unread_conversations) // Send an event (updated_number_unread_conversations)
events_helper::propagate_event(&Event::UpdatedNumberUnreadConversations(&list_to_notify))?; events_helper::propagate_event(Event::UpdatedNumberUnreadConversations(list_to_notify)).await?;
// Send an event (sent_conversation_message) // Send an event (sent_conversation_message)
events_helper::propagate_event(&Event::NewConversationMessage(&new_message))?; events_helper::propagate_event(Event::NewConversationMessage(new_message)).await?;
Ok(()) Ok(())
} }
/// Update message content /// Update message content
pub fn update_message_content(msg_id: u64, new_content: &str) -> ResultBoxError<()> { pub async fn update_message_content(msg_id: u64, new_content: &str) -> ResultBoxError<()> {
database::UpdateInfo::new(CONV_MESSAGES_TABLE) database::UpdateInfo::new(CONV_MESSAGES_TABLE)
.cond_u64("id", msg_id) .cond_u64("id", msg_id)
.set_str("message", new_content) .set_str("message", new_content)
.exec()?; .exec()?;
// Send an event (conv_message_updated) // Send an event (conv_message_updated)
events_helper::propagate_event(&Event::UpdatedConversationMessage(&get_single_message(msg_id)?))?; events_helper::propagate_event(Event::UpdatedConversationMessage(get_single_message(msg_id)?)).await?;
Ok(()) Ok(())
} }
/// Remove a message from a conversation /// Remove a message from a conversation
pub fn delete_message(msg: &ConversationMessage) -> ResultBoxError<()> { pub async fn delete_message(msg: &ConversationMessage) -> ResultBoxError<()> {
// Delete associated files // Delete associated files
if let Some(file) = &msg.file { if let Some(file) = &msg.file {
@ -420,14 +421,14 @@ pub fn delete_message(msg: &ConversationMessage) -> ResultBoxError<()> {
.exec()?; .exec()?;
// Send en event (conv_message_deleted) // Send en event (conv_message_deleted)
events_helper::propagate_event(&Event::DeleteConversationMessage(msg))?; events_helper::propagate_event(Event::DeleteConversationMessage(msg.clone())).await?;
Ok(()) Ok(())
} }
/// Delete a message with a specific ID /// Delete a message with a specific ID
pub fn delete_message_by_id(id: u64) -> ResultBoxError<()> { pub async fn delete_message_by_id(id: u64) -> ResultBoxError<()> {
delete_message(&get_single_message(id)?) delete_message(&get_single_message(id)?).await
} }
/// Count the number of unread conversation for a specified user /// Count the number of unread conversation for a specified user
@ -453,7 +454,7 @@ pub fn get_list_unread(user_id: &UserID) -> ResultBoxError<Vec<ConvID>> {
} }
/// Indicate that a user has seen the last messages of a conversation /// Indicate that a user has seen the last messages of a conversation
pub fn mark_user_seen(conv_id: ConvID, user_id: &UserID, last_msg: &ConversationMessage) -> ResultBoxError<()> { pub async fn mark_user_seen(conv_id: ConvID, user_id: &UserID, last_msg: &ConversationMessage) -> Res {
database::UpdateInfo::new(CONV_MEMBERS_TABLE) database::UpdateInfo::new(CONV_MEMBERS_TABLE)
.cond_conv_id("conv_id", conv_id) .cond_conv_id("conv_id", conv_id)
.cond_user_id("user_id", user_id) .cond_user_id("user_id", user_id)
@ -462,34 +463,34 @@ pub fn mark_user_seen(conv_id: ConvID, user_id: &UserID, last_msg: &Conversation
.exec()?; .exec()?;
// Push an event // Push an event
events_helper::propagate_event(&Event::SeenLastConversationMessage(user_id, conv_id))?; events_helper::propagate_event(Event::SeenLastConversationMessage(user_id.clone(), conv_id)).await?;
// Push an event (updated_number_unread_conversations) // Push an event (updated_number_unread_conversations)
events_helper::propagate_event(&Event::UpdatedNumberUnreadConversations(&vec![user_id.clone()]))?; events_helper::propagate_event(Event::UpdatedNumberUnreadConversations(vec![user_id.clone()])).await?;
Ok(()) Ok(())
} }
/// Remove a user from a conversation /// Remove a user from a conversation
pub fn remove_user_from_conversation(user_id: &UserID, conv: &Conversation, remover: &UserID) -> ResultBoxError<()> { pub async fn remove_user_from_conversation(user_id: &UserID, conv: &Conversation, remover: &UserID) -> ResultBoxError<()> {
if conv.is_last_admin(user_id) { if conv.is_last_admin(user_id) {
delete_conversation(conv) delete_conversation(conv).await
} else { } else {
remove_member(user_id, conv.id, Some(remover)) remove_member(user_id, conv.id, Some(remover)).await
} }
} }
/// Update members list for all the conversations of a given group /// Update members list for all the conversations of a given group
pub fn update_members_list_for_group_conversations(group_id: &GroupID) -> Res { pub async fn update_members_list_for_group_conversations(group_id: &GroupID) -> Res {
for conv in get_list_group(group_id)? { for conv in get_list_group(group_id)? {
update_members_list_for_group_conversation(conv.id)?; update_members_list_for_group_conversation(conv.id).await?;
} }
Ok(()) Ok(())
} }
/// Update the list of members for a group conversation /// Update the list of members for a group conversation
pub fn update_members_list_for_group_conversation(conv_id: ConvID) -> Res { pub async fn update_members_list_for_group_conversation(conv_id: ConvID) -> Res {
let conv = get_single(conv_id)?; let conv = get_single(conv_id)?;
if !conv.is_linked_to_group() { if !conv.is_linked_to_group() {
@ -511,7 +512,7 @@ pub fn update_members_list_for_group_conversation(conv_id: ConvID) -> Res {
// Create the member // Create the member
else if conv.min_group_membership_level.as_ref().unwrap() >= &member.level { else if conv.min_group_membership_level.as_ref().unwrap() >= &member.level {
add_member(conv_id, &member.user_id, true, member.is_admin(), None)?; add_member(conv_id, &member.user_id, true, member.is_admin(), None).await?;
} }
} }
@ -521,7 +522,7 @@ pub fn update_members_list_for_group_conversation(conv_id: ConvID) -> Res {
// Remove the member, if required // Remove the member, if required
if member.is_none() || conv.min_group_membership_level.as_ref().unwrap() < &member.unwrap().level { if member.is_none() || conv.min_group_membership_level.as_ref().unwrap() < &member.unwrap().level {
remove_member(&conv_member.user_id, conv_id, None)?; remove_member(&conv_member.user_id, conv_id, None).await?;
} }
} }
@ -529,10 +530,10 @@ pub fn update_members_list_for_group_conversation(conv_id: ConvID) -> Res {
} }
/// Remove permanently a conversation /// Remove permanently a conversation
pub fn delete_conversation(conv: &Conversation) -> ResultBoxError<()> { pub async fn delete_conversation(conv: &Conversation) -> ResultBoxError<()> {
// Delete all the messages of the conversations // Delete all the messages of the conversations
for message in get_all_messages(conv.id)? { for message in get_all_messages(conv.id)? {
delete_message(&message)?; delete_message(&message).await?;
} }
// Delete all the members of the conversation // Delete all the members of the conversation
@ -551,24 +552,24 @@ pub fn delete_conversation(conv: &Conversation) -> ResultBoxError<()> {
.exec()?; .exec()?;
// Propagate information // Propagate information
events_helper::propagate_event(&Event::DeletedConversation(conv.id))?; events_helper::propagate_event(Event::DeletedConversation(conv.id)).await?;
Ok(()) Ok(())
} }
/// Delete all the conversations of a group /// Delete all the conversations of a group
pub fn delete_all_group_conversations(group_id: &GroupID) -> Res { pub async fn delete_all_group_conversations(group_id: &GroupID) -> Res {
for conv in get_list_group(group_id)? { for conv in get_list_group(group_id)? {
delete_conversation(&conv)?; delete_conversation(&conv).await?;
} }
Ok(()) Ok(())
} }
/// Delete a conversation membership /// Delete a conversation membership
pub fn remove_member(user_id: &UserID, conv_id: ConvID, remover: Option<&UserID>) -> ResultBoxError<()> { pub async fn remove_member(user_id: &UserID, conv_id: ConvID, remover: Option<&UserID>) -> ResultBoxError<()> {
for msg in get_user_messages_for_conversations(conv_id, user_id)? { for msg in get_user_messages_for_conversations(conv_id, user_id)? {
delete_message(&msg)?; delete_message(&msg).await?;
} }
// Delete membership // Delete membership
@ -583,7 +584,7 @@ pub fn remove_member(user_id: &UserID, conv_id: ConvID, remover: Option<&UserID>
send_message(&NewConversationMessage::new_server_message( send_message(&NewConversationMessage::new_server_message(
conv_id, conv_id,
ConversationServerMessageType::UserLeftConversation(user_id.clone()), ConversationServerMessageType::UserLeftConversation(user_id.clone()),
))?; )).await?;
} else { } else {
send_message(&NewConversationMessage::new_server_message( send_message(&NewConversationMessage::new_server_message(
conv_id, conv_id,
@ -591,12 +592,12 @@ pub fn remove_member(user_id: &UserID, conv_id: ConvID, remover: Option<&UserID>
user_who_removed: remover.clone(), user_who_removed: remover.clone(),
user_removed: user_id.clone(), user_removed: user_id.clone(),
}), }),
))?; )).await?;
} }
} }
// Propagate event // Propagate event
events_helper::propagate_event(&Event::RemovedUserFromConversation(user_id, conv_id))?; events_helper::propagate_event(Event::RemovedUserFromConversation(user_id.clone(), conv_id)).await?;
Ok(()) Ok(())
} }

View File

@ -2,7 +2,7 @@
//! //!
//! @author Pierre Hubert //! @author Pierre Hubert
use async_recursion::async_recursion;
use crate::controllers::{calls_controller, comments_controller, conversations_controller, notifications_controller, rtc_relay_controller, user_ws_controller}; use crate::controllers::{calls_controller, comments_controller, conversations_controller, notifications_controller, rtc_relay_controller, user_ws_controller};
use crate::data::call_signal::{CloseCallStream, NewRtcRelayMessage, NewUserCallSignal, UserCallOfferRequest}; use crate::data::call_signal::{CloseCallStream, NewRtcRelayMessage, NewUserCallSignal, UserCallOfferRequest};
@ -15,84 +15,85 @@ use crate::data::user_token::UserAccessToken;
use crate::data::user_ws_connection::UserWsConnection; use crate::data::user_ws_connection::UserWsConnection;
use crate::helpers::push_notifications_helper; use crate::helpers::push_notifications_helper;
pub enum Event<'a> { pub enum Event {
/// Websocket of a user was closed /// Websocket of a user was closed
/// ///
/// This event is propagated BEFORE the removal of the connection from the list /// This event is propagated BEFORE the removal of the connection from the list
UserWsClosed(&'a UserWsConnection), UserWsClosed(UserWsConnection),
/// Destroyed a login token /// Destroyed a login token
DestroyedLoginToken(&'a UserAccessToken), DestroyedLoginToken(UserAccessToken),
/// Updated the number of notifications of one of multiple users user /// Updated the number of notifications of one of multiple users user
UpdatedNotificationsNumber(&'a Vec<UserID>), UpdatedNotificationsNumber(Vec<UserID>),
/// Indicate that a user has seen the last message of a conversation /// Indicate that a user has seen the last message of a conversation
SeenLastConversationMessage(&'a UserID, ConvID), SeenLastConversationMessage(UserID, ConvID),
/// Updated the number of unread conversations /// Updated the number of unread conversations
UpdatedNumberUnreadConversations(&'a Vec<UserID>), UpdatedNumberUnreadConversations(Vec<UserID>),
/// Created a new conversation message /// Created a new conversation message
NewConversationMessage(&'a ConversationMessage), NewConversationMessage(ConversationMessage),
/// Updated conversation message /// Updated conversation message
UpdatedConversationMessage(&'a ConversationMessage), UpdatedConversationMessage(ConversationMessage),
/// Deleted a conversation message /// Deleted a conversation message
DeleteConversationMessage(&'a ConversationMessage), DeleteConversationMessage(ConversationMessage),
/// User is writing a message in a conversation /// User is writing a message in a conversation
UserIsWritingMessageInConversation(&'a UserID, ConvID), UserIsWritingMessageInConversation(UserID, ConvID),
/// Removed a user from a conversation /// Removed a user from a conversation
RemovedUserFromConversation(&'a UserID, ConvID), RemovedUserFromConversation(UserID, ConvID),
/// Delete a conversation /// Delete a conversation
DeletedConversation(ConvID), DeletedConversation(ConvID),
/// Created a new comment /// Created a new comment
NewComment(&'a Comment), NewComment(Comment),
/// Updated a comment /// Updated a comment
UpdatedComment(&'a Comment), UpdatedComment(Comment),
/// Deleted a comment /// Deleted a comment
DeletedComment(&'a Comment), DeletedComment(Comment),
/// Connection to RTC relay was closed /// Connection to RTC relay was closed
ClosedRTCRelayWebSocket, ClosedRTCRelayWebSocket,
/// User joined call /// User joined call
UserJoinedCall(&'a ConvID, &'a UserID), UserJoinedCall(ConvID, UserID),
/// User left call /// User left call
UserLeftCall(&'a ConvID, &'a UserID), UserLeftCall(ConvID, UserID),
/// Got a new user call signal /// Got a new user call signal
NewUserCallSignal(&'a NewUserCallSignal), NewUserCallSignal(NewUserCallSignal),
/// Got a new RTC relay message /// Got a new RTC relay message
NewRTCRelayMessage(&'a NewRtcRelayMessage), NewRTCRelayMessage(NewRtcRelayMessage),
/// User requested an offer for a call /// User requested an offer for a call
UserRequestedCallOffer(&'a UserCallOfferRequest), UserRequestedCallOffer(UserCallOfferRequest),
/// Close call stream /// Close call stream
CloseCallStream(&'a CloseCallStream), CloseCallStream(CloseCallStream),
/// No event /// No event
None, None,
} }
/// Propagate an event through the different components of the application /// Propagate an event through the different components of the application
pub fn propagate_event(e: &Event) -> Res { #[async_recursion(?Send)]
conversations_controller::handle_event(e)?; pub async fn propagate_event(e: Event) -> Res {
comments_controller::handle_event(e)?; conversations_controller::handle_event(&e).await?;
notifications_controller::handle_event(e)?; comments_controller::handle_event(&e).await?;
user_ws_controller::handle_event(e)?; notifications_controller::handle_event(&e)?;
calls_controller::handle_event(e)?; user_ws_controller::handle_event(&e)?;
rtc_relay_controller::handle_event(e)?; calls_controller::handle_event(&e).await?;
push_notifications_helper::handle_event(e)?; rtc_relay_controller::handle_event(&e)?;
push_notifications_helper::handle_event(&e)?;
Ok(()) Ok(())
} }

View File

@ -94,7 +94,7 @@ impl GroupPostsCreationLevel {
} }
/// Create a new group. Returns the ID of the new group /// Create a new group. Returns the ID of the new group
pub fn create(group: &NewGroup) -> ResultBoxError<GroupID> { pub async fn create(group: &NewGroup) -> ResultBoxError<GroupID> {
// First, create the group // First, create the group
let group_id = database::InsertQuery::new(GROUPS_LIST_TABLE) let group_id = database::InsertQuery::new(GROUPS_LIST_TABLE)
.add_u64("time_create", time()) .add_u64("time_create", time())
@ -111,13 +111,13 @@ pub fn create(group: &NewGroup) -> ResultBoxError<GroupID> {
time_create: time(), time_create: time(),
level: GroupMembershipLevel::ADMINISTRATOR, level: GroupMembershipLevel::ADMINISTRATOR,
following: true, following: true,
})?; }).await?;
Ok(group_id) Ok(group_id)
} }
/// Insert a new group into the database /// Insert a new group into the database
pub fn insert_member(m: &GroupMember) -> ResultBoxError<()> { pub async fn insert_member(m: &GroupMember) -> ResultBoxError<()> {
database::InsertQuery::new(GROUPS_MEMBERS_TABLE) database::InsertQuery::new(GROUPS_MEMBERS_TABLE)
.add_group_id("groups_id", &m.group_id) .add_group_id("groups_id", &m.group_id)
.add_user_id("user_id", &m.user_id) .add_user_id("user_id", &m.user_id)
@ -126,27 +126,27 @@ pub fn insert_member(m: &GroupMember) -> ResultBoxError<()> {
.insert_drop_result()?; .insert_drop_result()?;
if m.level.is_at_least_member() { if m.level.is_at_least_member() {
conversations_helper::update_members_list_for_group_conversations(&m.group_id)?; conversations_helper::update_members_list_for_group_conversations(&m.group_id).await?;
} }
Ok(()) Ok(())
} }
/// Remove a user's membership /// Remove a user's membership
pub fn delete_member(group_id: &GroupID, user_id: &UserID) -> ResultBoxError { pub async fn delete_member(group_id: &GroupID, user_id: &UserID) -> ResultBoxError {
database::DeleteQuery::new(GROUPS_MEMBERS_TABLE) database::DeleteQuery::new(GROUPS_MEMBERS_TABLE)
.cond_group_id("groups_id", group_id) .cond_group_id("groups_id", group_id)
.cond_user_id("user_id", user_id) .cond_user_id("user_id", user_id)
.exec()?; .exec()?;
// Update access to group's conversations // Update access to group's conversations
conversations_helper::update_members_list_for_group_conversations(&group_id)?; conversations_helper::update_members_list_for_group_conversations(&group_id).await?;
Ok(()) Ok(())
} }
/// Update a user's membership level /// Update a user's membership level
pub fn update_membership_level(group_id: &GroupID, user_id: &UserID, new_level: GroupMembershipLevel) -> ResultBoxError { pub async fn update_membership_level(group_id: &GroupID, user_id: &UserID, new_level: GroupMembershipLevel) -> ResultBoxError {
database::UpdateInfo::new(GROUPS_MEMBERS_TABLE) database::UpdateInfo::new(GROUPS_MEMBERS_TABLE)
.cond_user_id("user_id", user_id) .cond_user_id("user_id", user_id)
.cond_group_id("groups_id", group_id) .cond_group_id("groups_id", group_id)
@ -154,7 +154,7 @@ pub fn update_membership_level(group_id: &GroupID, user_id: &UserID, new_level:
.exec()?; .exec()?;
// Update access to group's conversations // Update access to group's conversations
conversations_helper::update_members_list_for_group_conversations(&group_id)?; conversations_helper::update_members_list_for_group_conversations(&group_id).await?;
Ok(()) Ok(())
} }
@ -440,7 +440,7 @@ pub fn get_list_members(g: &GroupID) -> ResultBoxError<Vec<GroupMember>> {
} }
/// Send an invitation to a user /// Send an invitation to a user
pub fn send_invitation(group_id: &GroupID, user_id: &UserID) -> ResultBoxError { pub async fn send_invitation(group_id: &GroupID, user_id: &UserID) -> ResultBoxError {
insert_member(&GroupMember { insert_member(&GroupMember {
id: 0, id: 0,
user_id: user_id.clone(), user_id: user_id.clone(),
@ -448,7 +448,7 @@ pub fn send_invitation(group_id: &GroupID, user_id: &UserID) -> ResultBoxError {
time_create: time(), time_create: time(),
level: GroupMembershipLevel::INVITED, level: GroupMembershipLevel::INVITED,
following: true, following: true,
}) }).await
} }
/// Check out whether a user received an invitation to join a group or not /// Check out whether a user received an invitation to join a group or not
@ -462,18 +462,18 @@ pub fn received_invitation(group_id: &GroupID, user_id: &UserID) -> ResultBoxErr
} }
/// Respond to a group membership invitation /// Respond to a group membership invitation
pub fn respond_invitation(g: &GroupID, u: &UserID, accept: bool) -> ResultBoxError { pub async fn respond_invitation(g: &GroupID, u: &UserID, accept: bool) -> ResultBoxError {
match accept { match accept {
true => update_membership_level(g, u, GroupMembershipLevel::MEMBER), true => update_membership_level(g, u, GroupMembershipLevel::MEMBER).await,
false => delete_member(g, u), false => delete_member(g, u).await,
} }
} }
/// Respond to a group membership request /// Respond to a group membership request
pub fn respond_request(group_id: &GroupID, user_id: &UserID, accept: bool) -> ResultBoxError { pub async fn respond_request(group_id: &GroupID, user_id: &UserID, accept: bool) -> ResultBoxError {
match accept { match accept {
true => update_membership_level(&group_id, &user_id, GroupMembershipLevel::MEMBER), true => update_membership_level(&group_id, &user_id, GroupMembershipLevel::MEMBER).await,
false => delete_member(&group_id, &user_id), false => delete_member(&group_id, &user_id).await,
} }
} }
@ -489,7 +489,7 @@ pub fn can_user_create_posts(group_id: &GroupID, user_id: &UserID) -> ResultBoxE
} }
/// Delete a group /// Delete a group
pub fn delete(group_id: &GroupID) -> ResultBoxError { pub async fn delete(group_id: &GroupID) -> ResultBoxError {
// Delete all likes of the group // Delete all likes of the group
likes_helper::delete_all(group_id.id(), LikeType::GROUP)?; likes_helper::delete_all(group_id.id(), LikeType::GROUP)?;
@ -497,13 +497,13 @@ pub fn delete(group_id: &GroupID) -> ResultBoxError {
delete_logo(group_id)?; delete_logo(group_id)?;
// Delete all group posts // Delete all group posts
posts_helper::delete_all_group(group_id)?; posts_helper::delete_all_group(group_id).await?;
// Delete all group related notifications // Delete all group related notifications
notifications_helper::delete_all_related_with_group(group_id)?; notifications_helper::delete_all_related_with_group(group_id).await?;
// Delete all conversations related with the group // Delete all conversations related with the group
conversations_helper::delete_all_group_conversations(group_id)?; conversations_helper::delete_all_group_conversations(group_id).await?;
// Delete all Forez presences related with the group // Delete all Forez presences related with the group
forez_presence_helper::delete_all_group(group_id)?; forez_presence_helper::delete_all_group(group_id)?;
@ -520,12 +520,12 @@ pub fn delete(group_id: &GroupID) -> ResultBoxError {
} }
/// Delete all the groups a user belongs to /// Delete all the groups a user belongs to
pub fn delete_all_user_groups(user_id: &UserID) -> ResultBoxError { pub async fn delete_all_user_groups(user_id: &UserID) -> ResultBoxError {
for group_id in &get_list_user(user_id, false)? { for group_id in &get_list_user(user_id, false)? {
if is_last_admin(group_id, user_id)? { if is_last_admin(group_id, user_id)? {
delete(group_id)?; delete(group_id).await?;
} else { } else {
delete_member(group_id, user_id)?; delete_member(group_id, user_id).await?;
} }
} }

View File

@ -17,18 +17,18 @@ use crate::utils::date_utils;
use crate::utils::date_utils::time; use crate::utils::date_utils::time;
/// Create post notification /// Create post notification
pub fn create_post_notification(from_user: &UserID, post_id: u64, action: NotifEventType) -> ResultBoxError { pub async fn create_post_notification(from_user: &UserID, post_id: u64, action: NotifEventType) -> ResultBoxError {
let mut n = PartialNotification::new() let mut n = PartialNotification::new()
.set_from_user_id(from_user) .set_from_user_id(from_user)
.set_on_elem_id(post_id) .set_on_elem_id(post_id)
.set_on_elem_type(NotifElemType::POST) .set_on_elem_type(NotifElemType::POST)
.set_type(action); .set_type(action);
push(&mut n) push(&mut n).await
} }
/// Create & push friend notification /// Create & push friend notification
pub fn create_friends_notification(from_user: &UserID, dest_user: &UserID, action: NotifEventType) -> ResultBoxError { pub async fn create_friends_notification(from_user: &UserID, dest_user: &UserID, action: NotifEventType) -> ResultBoxError {
let mut n = PartialNotification::new() let mut n = PartialNotification::new()
.set_from_user_id(from_user) .set_from_user_id(from_user)
.set_dest_user_id(dest_user) .set_dest_user_id(dest_user)
@ -36,13 +36,13 @@ pub fn create_friends_notification(from_user: &UserID, dest_user: &UserID, actio
.set_on_elem_type(NotifElemType::FRIENDSHIP_REQUEST) .set_on_elem_type(NotifElemType::FRIENDSHIP_REQUEST)
.set_type(action); .set_type(action);
push(&mut n) push(&mut n).await
} }
/// Create & push a group membership notification /// Create & push a group membership notification
pub fn create_group_membership_notification(user_id: &UserID, moderator_id: Option<&UserID>, group_id: &GroupID, kind: NotifEventType) -> ResultBoxError { pub async fn create_group_membership_notification(user_id: &UserID, moderator_id: Option<&UserID>, group_id: &GroupID, kind: NotifEventType) -> Res {
// Delete related group membership notifications // Delete related group membership notifications
delete_all_related_to_group_membership_notifications(user_id, group_id)?; delete_all_related_to_group_membership_notifications(user_id, group_id).await?;
let mut n = PartialNotification::new() let mut n = PartialNotification::new()
.set_on_elem_id(group_id.id()) .set_on_elem_id(group_id.id())
@ -64,11 +64,11 @@ pub fn create_group_membership_notification(user_id: &UserID, moderator_id: Opti
} }
} }
push(&mut n) push(&mut n).await
} }
/// Push a new notification /// Push a new notification
fn push(n: &mut PartialNotification) -> ResultBoxError async fn push(n: &mut PartialNotification) -> ResultBoxError
{ {
if n.time_create.is_none() if n.time_create.is_none()
{ {
@ -110,7 +110,7 @@ fn push(n: &mut PartialNotification) -> ResultBoxError
n.dest_user_id = Some(post.user_id); n.dest_user_id = Some(post.user_id);
} }
return push_private(n); return push_private(n).await;
} }
// Posts on user page // Posts on user page
@ -129,12 +129,12 @@ fn push(n: &mut PartialNotification) -> ResultBoxError
.map(|f| f.friend_id) .map(|f| f.friend_id)
.collect(); .collect();
return push_public(n, friends); return push_public(n, friends).await;
} }
// Posts on group pages // Posts on group pages
else if post.is_on_group_page() { else if post.is_on_group_page() {
return push_group_members(n, post.group_id().unwrap()); return push_group_members(n, post.group_id().unwrap()).await;
} }
// Unsupported scenario // Unsupported scenario
@ -148,7 +148,7 @@ fn push(n: &mut PartialNotification) -> ResultBoxError
n.container_id = None; n.container_id = None;
n.container_type = None; n.container_type = None;
return push_private(n); return push_private(n).await;
} }
@ -165,9 +165,9 @@ fn push(n: &mut PartialNotification) -> ResultBoxError
{ {
// Push the notification in private way (if it has a destination, // Push the notification in private way (if it has a destination,
// generally the target user of the membership request) // generally the target user of the membership request)
push_private(n) push_private(n).await
} else { } else {
push_group_moderators(n, &GroupID::new(n.on_elem_id.unwrap())) push_group_moderators(n, &GroupID::new(n.on_elem_id.unwrap())).await
}; };
} else { } else {
unimplemented!(); unimplemented!();
@ -175,32 +175,32 @@ fn push(n: &mut PartialNotification) -> ResultBoxError
} }
/// Push a notification to group members /// Push a notification to group members
fn push_group_members(n: &mut PartialNotification, group_id: &GroupID) -> ResultBoxError { async fn push_group_members(n: &mut PartialNotification, group_id: &GroupID) -> ResultBoxError {
let mut list = groups_helper::get_list_followers(group_id)?; let mut list = groups_helper::get_list_followers(group_id)?;
list = list.into_iter().filter(|f| f != n.from_user_id.as_ref().unwrap()).collect(); list = list.into_iter().filter(|f| f != n.from_user_id.as_ref().unwrap()).collect();
push_public(n, list) push_public(n, list).await
} }
/// Push a notification to all the moderators & administrators of a group /// Push a notification to all the moderators & administrators of a group
fn push_group_moderators(n: &mut PartialNotification, group_id: &GroupID) -> ResultBoxError { async fn push_group_moderators(n: &mut PartialNotification, group_id: &GroupID) -> ResultBoxError {
let list = groups_helper::get_list_members(group_id)?; let list = groups_helper::get_list_members(group_id)?;
let list: Vec<UserID> = list let list: Vec<UserID> = list
.into_iter() .into_iter()
.filter(|e| e.is_moderator()) .filter(|e| e.is_moderator())
.map(|f| f.user_id) .map(|f| f.user_id)
.collect(); .collect();
push_public(n, list) push_public(n, list).await
} }
/// Push a public notification /// Push a public notification
fn push_public(n: &mut PartialNotification, users: Vec<UserID>) -> ResultBoxError { async fn push_public(n: &mut PartialNotification, users: Vec<UserID>) -> Res {
n.visibility = Some(NotifEventVisibility::EVENT_PUBLIC); n.visibility = Some(NotifEventVisibility::EVENT_PUBLIC);
for user_id in users { for user_id in users {
n.dest_user_id = Some(user_id); n.dest_user_id = Some(user_id);
if !similar_exists(n)? { if !similar_exists(n)? {
create(n)?; create(n).await?;
} }
} }
@ -208,18 +208,18 @@ fn push_public(n: &mut PartialNotification, users: Vec<UserID>) -> ResultBoxErro
} }
/// Push a private notification (to 1 user) /// Push a private notification (to 1 user)
fn push_private(n: &mut PartialNotification) -> ResultBoxError { async fn push_private(n: &mut PartialNotification) -> Res {
n.visibility = Some(NotifEventVisibility::EVENT_PRIVATE); n.visibility = Some(NotifEventVisibility::EVENT_PRIVATE);
if !similar_exists(n)? { if !similar_exists(n)? {
create(n)?; create(n).await?;
} }
Ok(()) Ok(())
} }
/// Create a new notification /// Create a new notification
fn create(n: &PartialNotification) -> ResultBoxError { async fn create(n: &PartialNotification) -> ResultBoxError {
if n.dest_user_id.is_none() || n.from_user_id.is_none() if n.dest_user_id.is_none() || n.from_user_id.is_none()
{ {
return Err(ExecError::boxed_new("Trying to send a notification without a source or a destination!")); return Err(ExecError::boxed_new("Trying to send a notification without a source or a destination!"));
@ -230,14 +230,14 @@ fn create(n: &PartialNotification) -> ResultBoxError {
.insert_drop_result()?; .insert_drop_result()?;
// Send a notification (updated_number_conversations) // Send a notification (updated_number_conversations)
events_helper::propagate_event(&Event::UpdatedNotificationsNumber(&vec![n.dest_user_id.clone().unwrap()]))?; events_helper::propagate_event(Event::UpdatedNotificationsNumber(vec![n.dest_user_id.clone().unwrap()])).await?;
Ok(()) Ok(())
} }
/// Delete notifications /// Delete notifications
pub fn delete(notification: &PartialNotification) -> ResultBoxError { pub async fn delete(notification: &PartialNotification) -> ResultBoxError {
let conditions = notif_to_db(notification, false); let conditions = notif_to_db(notification, false);
// Get the list of affected users // Get the list of affected users
@ -252,23 +252,23 @@ pub fn delete(notification: &PartialNotification) -> ResultBoxError {
.exec()?; .exec()?;
// Send a notification (updated_number_conversations) // Send a notification (updated_number_conversations)
events_helper::propagate_event(&Event::UpdatedNotificationsNumber(&users))?; events_helper::propagate_event(Event::UpdatedNotificationsNumber(users)).await?;
Ok(()) Ok(())
} }
/// Delete all the notifications of a given user /// Delete all the notifications of a given user
pub fn delete_all_user(user_id: &UserID) -> ResultBoxError { pub async fn delete_all_user(user_id: &UserID) -> ResultBoxError {
delete(&PartialNotification::new().set_dest_user_id(user_id)) delete(&PartialNotification::new().set_dest_user_id(user_id)).await
} }
/// Delete all the notifications related with a user /// Delete all the notifications related with a user
pub fn delete_all_related_with_user(user_id: &UserID) -> ResultBoxError { pub async fn delete_all_related_with_user(user_id: &UserID) -> ResultBoxError {
// Delete all the notifications targeting the user // Delete all the notifications targeting the user
delete_all_user(user_id)?; delete_all_user(user_id).await?;
// Delete all the notifications created by the user // Delete all the notifications created by the user
delete(&PartialNotification::new().set_from_user_id(user_id))?; delete(&PartialNotification::new().set_from_user_id(user_id)).await?;
Ok(()) Ok(())
} }
@ -288,66 +288,66 @@ pub fn clean_old_user_notifications(user: &User) -> Res {
} }
/// Delete all the notifications related with a group /// Delete all the notifications related with a group
pub fn delete_all_related_with_group(group_id: &GroupID) -> ResultBoxError { pub async fn delete_all_related_with_group(group_id: &GroupID) -> ResultBoxError {
delete(&PartialNotification::new() delete(&PartialNotification::new()
.set_on_elem_type(NotifElemType::GROUP_MEMBERSHIP) .set_on_elem_type(NotifElemType::GROUP_MEMBERSHIP)
.set_on_elem_id(group_id.id()) .set_on_elem_id(group_id.id())
)?; ).await?;
delete(&PartialNotification::new() delete(&PartialNotification::new()
.set_on_elem_type(NotifElemType::GROUP_PAGE) .set_on_elem_type(NotifElemType::GROUP_PAGE)
.set_on_elem_id(group_id.id()) .set_on_elem_id(group_id.id())
) ).await
} }
/// Delete all the notifications related to a group membership /// Delete all the notifications related to a group membership
pub fn delete_all_related_to_group_membership_notifications(user_id: &UserID, group_id: &GroupID) -> ResultBoxError { pub async fn delete_all_related_to_group_membership_notifications(user_id: &UserID, group_id: &GroupID) -> ResultBoxError {
let mut n = PartialNotification::new() let mut n = PartialNotification::new()
.set_on_elem_type(NotifElemType::GROUP_MEMBERSHIP) .set_on_elem_type(NotifElemType::GROUP_MEMBERSHIP)
.set_on_elem_id(group_id.id()); .set_on_elem_id(group_id.id());
n.dest_user_id = Some(user_id.clone()); n.dest_user_id = Some(user_id.clone());
n.from_user_id = None; n.from_user_id = None;
delete(&n)?; delete(&n).await?;
n.dest_user_id = None; n.dest_user_id = None;
n.from_user_id = Some(user_id.clone()); n.from_user_id = Some(user_id.clone());
delete(&n)?; delete(&n).await?;
Ok(()) Ok(())
} }
/// Delete all the notifications about a post targeting a specified user /// Delete all the notifications about a post targeting a specified user
pub fn delete_all_post_notifications_targeting_user(user_id: &UserID, post_id: PostID) -> ResultBoxError { pub async fn delete_all_post_notifications_targeting_user(user_id: &UserID, post_id: PostID) -> ResultBoxError {
let n = PartialNotification::new() let n = PartialNotification::new()
.set_dest_user_id(user_id) .set_dest_user_id(user_id)
.set_on_elem_type(NotifElemType::POST) .set_on_elem_type(NotifElemType::POST)
.set_on_elem_id(post_id); .set_on_elem_id(post_id);
delete(&n) delete(&n).await
} }
/// Delete all the notifications related with a post /// Delete all the notifications related with a post
pub fn delete_all_related_with_post(post_id: PostID) -> ResultBoxError { pub async fn delete_all_related_with_post(post_id: PostID) -> ResultBoxError {
let n = PartialNotification::new() let n = PartialNotification::new()
.set_on_elem_type(NotifElemType::POST) .set_on_elem_type(NotifElemType::POST)
.set_on_elem_id(post_id); .set_on_elem_id(post_id);
delete(&n) delete(&n).await
} }
/// Delete all the notifications related with a friendship request /// Delete all the notifications related with a friendship request
pub fn delete_all_related_with_friendship_request(user_one: &UserID, user_two: &UserID) -> ResultBoxError { pub async fn delete_all_related_with_friendship_request(user_one: &UserID, user_two: &UserID) -> ResultBoxError {
let mut n = PartialNotification::new() let mut n = PartialNotification::new()
.set_on_elem_type(NotifElemType::FRIENDSHIP_REQUEST); .set_on_elem_type(NotifElemType::FRIENDSHIP_REQUEST);
n.from_user_id = Some(user_one.clone()); n.from_user_id = Some(user_one.clone());
n.dest_user_id = Some(user_two.clone()); n.dest_user_id = Some(user_two.clone());
delete(&n)?; delete(&n).await?;
n.from_user_id = Some(user_two.clone()); n.from_user_id = Some(user_two.clone());
n.dest_user_id = Some(user_one.clone()); n.dest_user_id = Some(user_one.clone());
delete(&n) delete(&n).await
} }
/// Check out whether a similar notification exists for given specifications /// Check out whether a similar notification exists for given specifications

View File

@ -412,15 +412,15 @@ pub fn set_content(post_id: u64, new_content: &str) -> ResultBoxError {
} }
/// Delete a post /// Delete a post
pub fn delete(p: &Post) -> ResultBoxError { pub async fn delete(p: &Post) -> ResultBoxError {
// Delete all the notifications related with the post // Delete all the notifications related with the post
notifications_helper::delete_all_related_with_post(p.id)?; notifications_helper::delete_all_related_with_post(p.id).await?;
// Delete all the likes associated with the post // Delete all the likes associated with the post
likes_helper::delete_all(p.id, LikeType::POST)?; likes_helper::delete_all(p.id, LikeType::POST)?;
// Delete all the comments associated to the post // Delete all the comments associated to the post
comments_helper::delete_all(p.id)?; comments_helper::delete_all(p.id).await?;
// Delete associated file / resource (if any) // Delete associated file / resource (if any)
match &p.kind { match &p.kind {
@ -452,25 +452,25 @@ pub fn delete(p: &Post) -> ResultBoxError {
} }
/// Delete all the posts related with a group /// Delete all the posts related with a group
pub fn delete_all_group(group_id: &GroupID) -> ResultBoxError { pub async fn delete_all_group(group_id: &GroupID) -> ResultBoxError {
for post in export_all_posts_group(group_id)? { for post in export_all_posts_group(group_id)? {
delete(&post)?; delete(&post).await?;
} }
Ok(()) Ok(())
} }
/// Delete all the posts of a given user /// Delete all the posts of a given user
pub fn delete_all_user(user_id: &UserID) -> ResultBoxError { pub async fn delete_all_user(user_id: &UserID) -> ResultBoxError {
for post in &export_all_posts_user(user_id)? { for post in &export_all_posts_user(user_id)? {
delete(&post)?; delete(&post).await?;
} }
Ok(()) Ok(())
} }
/// Clean the old posts of a user /// Clean the old posts of a user
pub fn clean_old_posts(user: &User) -> Res { pub async fn clean_old_posts(user: &User) -> Res {
let lifetime = user.delete_posts_after.unwrap_or(0); let lifetime = user.delete_posts_after.unwrap_or(0);
if lifetime < 1 { if lifetime < 1 {
return Ok(()); return Ok(());
@ -484,7 +484,7 @@ pub fn clean_old_posts(user: &User) -> Res {
.exec(db_to_post)?; .exec(db_to_post)?;
for post in posts { for post in posts {
delete(&post)?; delete(&post).await?;
} }
Ok(()) Ok(())

View File

@ -413,7 +413,7 @@ pub async fn find_route(req_uri: &str, call: Option<&mut HttpRequestHandler>) ->
// Likes controller // Likes controller
route!(req_uri, call, POST_LOGIN, "/likes/update", likes_controller::update_async); route!(req_uri, call, POST_LOGIN, "/likes/update", likes_controller::update);
// Surveys controller // Surveys controller

View File

@ -21,20 +21,20 @@ pub async fn exec_user_ws_route(uri: &str, handler: &mut UserWsRequestHandler) -
"$main/unregister_post" => Some(user_ws_actions::unregister_post(handler)), "$main/unregister_post" => Some(user_ws_actions::unregister_post(handler)),
// Likes controller // Likes controller
"likes/update" => Some(likes_controller::update(handler)), "likes/update" => Some(likes_controller::update(handler).await),
// Conversations controller // Conversations controller
"conversations/is_writing" => Some(conversations_controller::member_is_writing(handler)), "conversations/is_writing" => Some(conversations_controller::member_is_writing(handler).await),
// Calls controller // Calls controller
"calls/config" => Some(calls_controller::get_config(handler)), "calls/config" => Some(calls_controller::get_config(handler).await),
"calls/join" => Some(calls_controller::join_call(handler)), "calls/join" => Some(calls_controller::join_call(handler).await),
"calls/leave" => Some(calls_controller::leave_call(handler)), "calls/leave" => Some(calls_controller::leave_call(handler).await),
"calls/members" => Some(calls_controller::get_members_list(handler)), "calls/members" => Some(calls_controller::get_members_list(handler).await),
"calls/signal" => Some(calls_controller::on_client_signal(handler)), "calls/signal" => Some(calls_controller::on_client_signal(handler).await),
"calls/mark_ready" => Some(calls_controller::mark_user_ready(handler)), "calls/mark_ready" => Some(calls_controller::mark_user_ready(handler).await),
"calls/request_offer" => Some(calls_controller::request_offer(handler)), "calls/request_offer" => Some(calls_controller::request_offer(handler).await),
"calls/stop_streaming" => Some(calls_controller::stop_streaming(handler)), "calls/stop_streaming" => Some(calls_controller::stop_streaming(handler).await),
// Presence controller // Presence controller
"forez_presence/list" => Some(forez_controller::get_list(handler)), "forez_presence/list" => Some(forez_controller::get_list(handler)),