1
0
mirror of https://gitlab.com/comunic/comunicapiv3 synced 2024-11-22 05:19:21 +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"
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]]
name = "attohttpc"
version = "0.15.0"
@ -700,6 +711,7 @@ dependencies = [
"actix-multipart",
"actix-web",
"actix-web-actors",
"async-recursion",
"bcrypt",
"bytes",
"chrono",

View File

@ -41,4 +41,5 @@ zip = "0.5.10"
webpage = "1.2.0"
gouth = "0.2.0"
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
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);
loop {
@ -32,14 +33,14 @@ fn clean_up_thread_handler() {
}
std::thread::sleep(CLEAN_UP_INTERVAL);
}
}*/
}
/// Do the cleanup
fn do_clean() -> Res {
async fn do_clean() -> Res {
// Clean old login tokens
account_helper::clean_up_old_access_tokens()?;
account_helper::clean_up_old_access_tokens().await?;
// Automatic account cleanup
for user in user_helper::get_all_users()? {
@ -51,16 +52,16 @@ fn do_clean() -> Res {
notifications_helper::clean_old_user_notifications(&user)?;
// Clean old comments
comments_helper::clean_old_comments(&user)?;
comments_helper::clean_old_comments(&user).await?;
// Clean old posts
posts_helper::clean_old_posts(&user)?;
posts_helper::clean_old_posts(&user).await?;
// 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
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

View File

@ -94,7 +94,7 @@ pub async fn login_user(request: &mut HttpRequestHandler) -> RequestResult {
/// Sign out user
pub async fn logout_user(request: &mut HttpRequestHandler) -> RequestResult {
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.")
@ -102,7 +102,7 @@ pub async fn logout_user(request: &mut HttpRequestHandler) -> RequestResult {
/// Disconnect a user from all his devices
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!")
}
@ -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())?;
}
account_helper::delete(r.user_id_ref()?)?;
account_helper::delete(r.user_id_ref()?).await?;
r.success("Account deleted.")
}

View File

@ -88,7 +88,7 @@ impl UserWsRequestHandler {
}
/// 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
if let None = r.get_conn().active_call {
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
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;
// 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
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
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) {
return Ok(());
}
if let Some(call) = &conn.active_call {
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 {
conv_id,
@ -159,13 +157,13 @@ pub fn join_call(r: &mut UserWsRequestHandler) -> RequestResult {
}))?;
// 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(())
}
/// 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
// really belongs to the conversation, so be careful when manipulating
// conversation ID here
@ -177,13 +175,13 @@ pub fn leave_call(r: &mut UserWsRequestHandler) -> RequestResult {
}
// 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!")
}
/// 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 mut list = vec![];
@ -204,7 +202,7 @@ pub fn gen_call_hash(call_id: &ConvID, peer_id: &UserID) -> String {
}
/// 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 peer_id = r.post_call_peer_id(&call_id, "peerID")?;
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),
user_id: if r.user_id_ref()? == &peer_id { None } else { Some(r.user_id()?) },
signal,
raw_data: r.post_string("data")?,
}))?;
})).await?;
r.success("Signal sent")
}
/// 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 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(
|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()?)),
None::<fn(&_) -> _>,
)?;
r.success("Information propagated.")
}
/// 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")?;
// 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())?;
}
events_helper::propagate_event(&Event::UserRequestedCallOffer(&UserCallOfferRequest {
events_helper::propagate_event(Event::UserRequestedCallOffer(UserCallOfferRequest {
call_hash: gen_call_hash(&call_id, &peer_id),
user_id: r.user_id()?,
}))?;
})).await?;
r.success("Request sent")
}
/// 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 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(
|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)),
None::<fn(&_) -> _>,
)?;
}
// 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),
peer_id: None,
}))?;
})).await?;
r.success("ok")
}
/// 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);
// Notify user (if possible)
@ -353,39 +349,37 @@ pub fn make_user_leave_call(conv_id: &ConvID, connection: &UserWsConnection) ->
}
// 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()),
peer_id: None,
}))?;
})).await?;
// Close receiver streams (other users streams)
user_ws_controller::foreach_connection(
|peer_conn| {
if peer_conn.is_having_call_with_conversation(conv_id) && peer_conn.user_id() != connection.user_id() {
events_helper::propagate_event(&Event::CloseCallStream(&CloseCallStream {
call_hash: gen_call_hash(&conv_id, peer_conn.user_id()),
peer_id: Some(connection.user_id().clone()),
}))?;
}
Ok(())
},
)?;
for peer_conn in user_ws_controller::get_all_connections()? {
if peer_conn.is_having_call_with_conversation(conv_id) && peer_conn.user_id() != connection.user_id() {
events_helper::propagate_event(Event::CloseCallStream(CloseCallStream {
call_hash: gen_call_hash(&conv_id, peer_conn.user_id()),
peer_id: Some(connection.user_id().clone()),
})).await?;
}
};
// 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(())
}
/// Events handler
pub fn handle_event(e: &events_helper::Event) -> Res {
pub async fn handle_event(e: &events_helper::Event) -> Res {
match e {
Event::UserJoinedCall(conv_id, user_id) => {
user_ws_controller::send_message_to_specific_connections(
|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)),
None::<fn(&_) -> _>,
)?;
}
@ -393,13 +387,12 @@ pub fn handle_event(e: &events_helper::Event) -> Res {
user_ws_controller::send_message_to_specific_connections(
|c| c.is_having_call_with_conversation(conv_id),
|_| UserWsMessage::no_id_message("user_left_call", LeftCallMessage::new(conv_id, user_id)),
None::<fn(&_) -> _>,
)?;
}
Event::UserWsClosed(c) => {
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(
|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)?),
None::<fn(&_) -> _>,
)?;
}
// Handle proxy disconnect => close all active calls
Event::ClosedRTCRelayWebSocket => {
user_ws_controller::foreach_connection(|f| {
for f in user_ws_controller::get_all_connections()? {
// Close all active connections
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)
@ -450,7 +440,7 @@ pub fn handle_event(e: &events_helper::Event) -> Res {
})?;
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 {
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,
};
let comment_id = comments_helper::create(&comment)?;
let comment_id = comments_helper::create(&comment).await?;
// 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
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))
}
@ -72,7 +72,7 @@ pub async fn edit(r: &mut HttpRequestHandler) -> RequestResult {
let comment = r.post_comment_with_full_access("commentID")?;
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.")
}
@ -81,13 +81,13 @@ pub async fn edit(r: &mut HttpRequestHandler) -> RequestResult {
pub async fn delete(r: &mut HttpRequestHandler) -> RequestResult {
let comment = r.post_comment_with_full_access("commentID")?;
comments_helper::delete(&comment)?;
comments_helper::delete(&comment).await?;
r.success("Comment deleted.")
}
/// Events handler
pub fn handle_event(e: &events_helper::Event) -> Res {
pub async fn handle_event(e: &events_helper::Event) -> Res {
match e {
Event::NewComment(comment) => {
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(
"new_comment",
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(
"comment_updated",
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.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::new_conversation::NewConversation;
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_request_handler::UserWsRequestHandler;
use crate::helpers::{conversations_helper, events_helper};
@ -50,7 +49,7 @@ pub async fn create(r: &mut HttpRequestHandler) -> RequestResult {
};
// 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))
}
@ -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())?;
}
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!")
}
@ -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())?;
}
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()
}
@ -228,7 +227,7 @@ pub async fn find_private(r: &mut HttpRequestHandler) -> RequestResult {
group_id: 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);
}
@ -255,7 +254,7 @@ pub async fn refresh_single(r: &mut HttpRequestHandler) -> RequestResult {
conv.conv_id,
r.user_id_ref()?,
&messages.last().unwrap(),
)?;
).await?;
}
r.set_response(ConversationMessageAPI::for_list(&messages))
@ -395,7 +394,7 @@ pub async fn send_message(r: &mut HttpRequestHandler) -> RequestResult {
message,
file,
server_message: None,
})?;
}).await?;
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())?;
}
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")
}
@ -447,7 +446,7 @@ pub async fn update_message(r: &mut HttpRequestHandler) -> RequestResult {
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")
}
@ -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())?;
}
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!")
}
/// 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")?;
// Propagate event
events_helper::propagate_event(
&Event::UserIsWritingMessageInConversation(r.user_id_ref()?, conv_id)
)?;
Event::UserIsWritingMessageInConversation(r.user_id()?, conv_id)
).await?;
r.ok()
}
/// Events handler
pub fn handle_event(e: &events_helper::Event) -> Res {
pub async fn handle_event(e: &events_helper::Event) -> Res {
match e {
Event::UpdatedNumberUnreadConversations(users) => {
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(
|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)),
None::<fn(&_) -> _>,
)?;
}
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),
|_| 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) => {
user_ws_controller::send_message_to_specific_connections(
|f| f.conversations.contains(&msg.conv_id),
|_| 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(
|f| f.conversations.contains(&msg.conv_id),
|_| 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(
|f| f.conversations.contains(conv_id),
|_| UserWsMessage::no_id_message("removed_user_from_conv", RemovedUserFromConversationMessage::new(user_id, *conv_id)),
None::<fn(&_) -> _>,
)?;
// 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(
|f| f.conversations.contains(conv_id),
|_| UserWsMessage::no_id_message("deleted_conversation", conv_id.id()),
None::<fn(&_) -> _>,
)?;
// Disconnect user from conversation

View File

@ -85,7 +85,7 @@ pub async fn send_request(r: &mut HttpRequestHandler) -> RequestResult {
notifications_helper::create_friends_notification(
r.user_id_ref()?,
&friend_id,
NotifEventType::SENT_FRIEND_REQUEST)?;
NotifEventType::SENT_FRIEND_REQUEST).await?;
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)?;
// 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!")
}
@ -125,7 +125,7 @@ pub async fn respond_request(r: &mut HttpRequestHandler) -> RequestResult {
true => NotifEventType::ACCEPTED_FRIEND_REQUEST,
false => NotifEventType::REJECTED_FRIEND_REQUEST
},
)?;
).await?;
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)?;
// 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!")
}

View File

@ -57,7 +57,7 @@ pub async fn create(r: &mut HttpRequestHandler) -> RequestResult {
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))
}
@ -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 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))
}
@ -197,7 +197,7 @@ pub async fn set_conversation_visibility(r: &mut HttpRequestHandler) -> RequestR
let conv = r.post_group_conv_admin("conv_id")?;
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()
}
@ -206,7 +206,7 @@ pub async fn set_conversation_visibility(r: &mut HttpRequestHandler) -> RequestR
pub async fn delete_conversation(r: &mut HttpRequestHandler) -> RequestResult {
let conv = r.post_group_conv_admin("conv_id")?;
conversations_helper::delete_conversation(&conv)?;
conversations_helper::delete_conversation(&conv).await?;
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())?;
}
groups_helper::delete_member(&group_id, &user_id)?;
groups_helper::delete_member(&group_id, &user_id).await?;
// 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!")
}
@ -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())?;
}
groups_helper::send_invitation(&group_id, &user_id)?;
groups_helper::send_invitation(&group_id, &user_id).await?;
// Send a 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!")
}
@ -271,7 +271,7 @@ pub async fn respond_invitation(r: &mut HttpRequestHandler) -> RequestResult {
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 {
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 {
true => NotifEventType::ACCEPTED_GROUP_MEMBERSHIP_INVITATION,
false => NotifEventType::REJECTED_GROUP_MEMBERSHIP_INVITATION
})?;
}).await?;
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(),
level,
following: true,
})?;
}).await?;
// Send a notification, if required
if matches!(group.registration_level, GroupRegistrationLevel::MODERATED_REGISTRATION) {
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())?;
}
groups_helper::delete_member(&group_id, &r.user_id()?)?;
groups_helper::delete_member(&group_id, &r.user_id()?).await?;
// 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!")
}
@ -360,10 +360,10 @@ pub async fn delete_member(r: &mut HttpRequestHandler) -> RequestResult {
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
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!")
}
@ -389,7 +389,7 @@ pub async fn update_membership(r: &mut HttpRequestHandler) -> RequestResult {
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!")
}
@ -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())?;
}
groups_helper::respond_request(&group_id, &user_id, accept)?;
groups_helper::respond_request(&group_id, &user_id, accept).await?;
// Create a notification
notifications_helper::create_group_membership_notification(&user_id, Some(r.user_id_ref()?), &group_id, match accept {
true => NotifEventType::ACCEPTED_GROUP_MEMBERSHIP_REQUEST,
false => NotifEventType::REJECTED_GROUP_MEMBERSHIP_REQUEST
})?;
}).await?;
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())?;
}
groups_helper::delete_member(&group_id, &r.user_id()?)?;
groups_helper::delete_member(&group_id, &r.user_id()?).await?;
// 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!")
}
@ -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)?;
r.need_user_password("password")?;
groups_helper::delete(&group_id)?;
groups_helper::delete(&group_id).await?;
r.success("Group deleted.")
}

View File

@ -2,23 +2,18 @@
//!
//! @author Pierre Hubert
use crate::routes::RequestResult;
use crate::data::base_request_handler::BaseRequestHandler;
use crate::data::error::ExecError;
use crate::data::group::GroupAccessLevel;
use crate::data::post::PostAccessLevel;
use crate::helpers::{likes_helper, notifications_helper, user_helper};
use crate::helpers::likes_helper::LikeType;
use crate::routes::RequestResult;
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
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 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)?;
// 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)
}
@ -51,7 +46,7 @@ pub fn update<H: BaseRequestHandler>(r: &mut H) -> RequestResult {
let comment = r.post_comment_with_access("id")?;
// 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)
}

View File

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

View File

@ -235,7 +235,7 @@ pub async fn create_post(r: &mut HttpRequestHandler) -> RequestResult {
}
// 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))
}
@ -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
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")
@ -263,7 +263,7 @@ pub async fn update_content(r: &mut HttpRequestHandler) -> RequestResult {
posts_helper::set_content(post.id, &new_content)?;
// 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")
}
@ -272,7 +272,7 @@ pub async fn update_content(r: &mut HttpRequestHandler) -> RequestResult {
pub async fn delete(r: &mut HttpRequestHandler) -> RequestResult {
let post = r.post_post_with_access("postID", PostAccessLevel::FULL_ACCESS)?;
posts_helper::delete(&post)?;
posts_helper::delete(&post).await?;
r.success("Post deleted.")
}

View File

@ -99,27 +99,36 @@ impl actix::Actor for RtcRelayActor {
}).unwrap())
}
fn stopped(&mut self, _ctx: &mut Self::Context) {
fn stopped(&mut self, ctx: &mut Self::Context) {
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
if let Err(e) = events_helper::propagate_event(&Event::ClosedRTCRelayWebSocket) {
eprintln!("Failed to propagate rtc closed event! {:#?}", e);
}
eprintln!("Successfully propagated RTC relay stopped envent!");
};
future.into_actor(self).wait(ctx);
}
}
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) {
Err(e) => {
eprintln!("Failed to parse a message from RTC proxy! {:#?}", e);
}
Ok(msg) => {
if let Err(e) = process_message_from_relay(&msg) {
eprintln!("Failed to process signal from RTC Relay! {:#?}", e);
}
let future = async move {
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
match msg {
Message::Text(txt) => {
self.handle_message(&txt);
self.handle_message(&txt, ctx);
}
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) => {
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
fn process_message_from_relay(msg: &RTCSocketMessage) -> Res {
async fn process_message_from_relay(msg: &RTCSocketMessage) -> Res {
match msg.title.as_str() {
"signal" => {
events_helper::propagate_event(&Event::NewRTCRelayMessage(&NewRtcRelayMessage {
events_helper::propagate_event(Event::NewRTCRelayMessage(NewRtcRelayMessage {
call_hash: msg.callHash.clone().unwrap_or(String::new()),
peer_id: msg.peerId.clone().unwrap_or("0".to_string()),
data: serde_json::to_string(msg.data.as_ref().unwrap_or(&Value::Null))
.unwrap_or("failed to serialize signal data".to_string()),
}))?;
})).await?;
}
title => {

View File

@ -317,9 +317,16 @@ impl Actor for WsSession {
fn stopping(&mut self, ctx: &mut Self::Context) -> Running {
// Send an event (user_ws_closed)
if let Some(conn) = find_connection(ctx.address()) {
if let Err(e) = events_helper::propagate_event(&Event::UserWsClosed(&conn)) {
eprintln!("Failed to propagate web socket closed event ! {:#?}", e);
}
let future = async move {
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());
@ -495,10 +502,9 @@ pub fn send_to_client(conn: &UserWsConnection, msg: &UserWsMessage) -> Res {
}
/// 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,
M: Fn(&UserWsConnection) -> Res<UserWsMessage>,
A: Fn(&UserWsConnection) -> Res
M: Fn(&UserWsConnection) -> Res<UserWsMessage>
{
let connections = get_ws_connections_list()
.lock()
@ -508,15 +514,11 @@ pub fn send_message_to_specific_connections<F, M, A>(filter: F, msg_generator: M
.map(|f| f.clone())
.collect::<Vec<UserWsConnection>>();
for con in connections {
for con in &connections {
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
@ -576,6 +578,11 @@ pub fn foreach_connection<F>(mut f: F) -> Res
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
pub fn handle_event(e: &events_helper::Event) -> Res {
match e {

View File

@ -4,6 +4,7 @@
use crate::data::user::UserID;
#[derive(Debug, Clone)]
pub struct Comment {
pub id: 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
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
// (continue to destroy token even in case of failure)
push_notifications_helper::un_register_from_previous_service(access_tokens)?;
@ -110,20 +110,20 @@ pub fn destroy_login_tokens(access_tokens: &UserAccessToken) -> Res {
.exec()?;
// 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(())
}
/// 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)
.set_custom_where("last_refresh + timeout < ?")
.add_custom_where_argument_u64(time())
.exec(db_to_user_access_token)?;
for token in to_delete {
destroy_login_tokens(&token)?;
destroy_login_tokens(&token).await?;
}
Ok(())
@ -137,11 +137,11 @@ pub fn get_all_login_tokens(id: &UserID) -> Res<Vec<UserAccessToken>> {
}
/// 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)?;
for token in get_all_login_tokens(id)? {
destroy_login_tokens(&token)?;
destroy_login_tokens(&token).await?;
}
Ok(())
@ -365,18 +365,18 @@ pub fn export(user_id: &UserID) -> ResultBoxError<AccountExport> {
}
/// 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
destroy_all_user_tokens(user_id)?;
destroy_all_user_tokens(user_id).await?;
// 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
comments_helper::delete_all_user(user_id)?;
comments_helper::delete_all_user(user_id).await?;
// 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
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)?;
// 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
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
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
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)?;
// Delete connections to all services
destroy_all_user_tokens(user_id)?;
destroy_all_user_tokens(user_id).await?;
// Remove the user from the database
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
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);
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 {
delete(&user.id)?;
delete(&user.id).await?;
}
Ok(())

View File

@ -13,7 +13,7 @@ use crate::utils::date_utils::{mysql_date, time};
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
pub fn create(c: &Comment) -> ResultBoxError<u64> {
pub async fn create(c: &Comment) -> ResultBoxError<u64> {
let comment_id = database::InsertQuery::new(COMMENTS_TABLE)
.add_u64("ID_texte", c.post_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!"))?;
// 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)
}
@ -67,20 +67,20 @@ fn db_to_comment(row: &database::RowResult) -> ResultBoxError<Comment> {
}
/// 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)
.cond_u64("ID", comment_id)
.set_str("commentaire", new_content)
.exec()?;
// 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(())
}
/// Delete a single comment
pub fn delete(c: &Comment) -> ResultBoxError {
pub async fn delete(c: &Comment) -> ResultBoxError {
// Delete associated image (if any)
if let Some(image) = &c.image_path {
let path = user_data_path(image.as_ref());
@ -98,31 +98,32 @@ pub fn delete(c: &Comment) -> ResultBoxError {
.exec()?;
// Emit an event
events_helper::propagate_event(&Event::DeletedComment(c))?;
let c = (*c).clone();
events_helper::propagate_event(Event::DeletedComment(c)).await?;
Ok(())
}
/// 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)? {
delete(c)?;
delete(c).await?;
}
Ok(())
}
/// 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)? {
delete(comment)?;
delete(comment).await?;
}
Ok(())
}
/// 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);
if lifetime < 1 {
return Ok(());
@ -135,7 +136,7 @@ pub fn clean_old_comments(user: &User) -> Res {
.exec(db_to_comment)?;
for comment in comments {
delete(&comment)?;
delete(&comment).await?;
}
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;
/// 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
let conv_id = InsertQuery::new(CONV_LIST_TABLE)
.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
if conv.group_id.is_some() {
update_members_list_for_group_conversation(conv_id)?;
update_members_list_for_group_conversation(conv_id).await?;
} else {
// 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
for member in &conv.members {
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
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 {
owner_id: UserID::invalid(),
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,
members: Default::default(),
can_everyone_add_members: false,
})
}).await
}
/// 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)
.add_conv_id("conv_id", conv_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(),
}),
)
)?;
).await?;
} else {
send_message(&NewConversationMessage::new_server_message(
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
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)
.cond_conv_id("id", conv_id)
.set_u32("min_group_membership_level", level.to_db())
.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
@ -274,7 +275,7 @@ pub fn export_all_user_messages(user_id: &UserID) -> ResultBoxError<Vec<Conversa
}
/// 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);
if lifetime < 1 {
return Ok(());
@ -287,16 +288,16 @@ pub fn clean_old_messages(user: &User) -> Res {
.exec(db_to_conversation_message)?;
for message in messages {
delete_message(&message)?;
delete_message(&message).await?;
}
Ok(())
}
/// 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)? {
delete_message(msg)?;
delete_message(msg).await?;
}
// 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
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)? {
remove_user_from_conversation(user_id, conversation, user_id)?;
remove_user_from_conversation(user_id, conversation, user_id).await?;
}
Ok(())
@ -335,7 +336,7 @@ pub fn get_single_message(msg_id: u64) -> ResultBoxError<ConversationMessage> {
}
/// Send a new conversation message
pub fn send_message(msg: &NewConversationMessage) -> ResultBoxError<()> {
pub async fn send_message(msg: &NewConversationMessage) -> ResultBoxError<()> {
let t = time();
// Insert the message in the database
@ -378,33 +379,33 @@ pub fn send_message(msg: &NewConversationMessage) -> ResultBoxError<()> {
// Mark the user has seen his message
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)
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)
events_helper::propagate_event(&Event::NewConversationMessage(&new_message))?;
events_helper::propagate_event(Event::NewConversationMessage(new_message)).await?;
Ok(())
}
/// 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)
.cond_u64("id", msg_id)
.set_str("message", new_content)
.exec()?;
// 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(())
}
/// Remove a message from a conversation
pub fn delete_message(msg: &ConversationMessage) -> ResultBoxError<()> {
pub async fn delete_message(msg: &ConversationMessage) -> ResultBoxError<()> {
// Delete associated files
if let Some(file) = &msg.file {
@ -420,14 +421,14 @@ pub fn delete_message(msg: &ConversationMessage) -> ResultBoxError<()> {
.exec()?;
// Send en event (conv_message_deleted)
events_helper::propagate_event(&Event::DeleteConversationMessage(msg))?;
events_helper::propagate_event(Event::DeleteConversationMessage(msg.clone())).await?;
Ok(())
}
/// Delete a message with a specific ID
pub fn delete_message_by_id(id: u64) -> ResultBoxError<()> {
delete_message(&get_single_message(id)?)
pub async fn delete_message_by_id(id: u64) -> ResultBoxError<()> {
delete_message(&get_single_message(id)?).await
}
/// 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
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)
.cond_conv_id("conv_id", conv_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()?;
// 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)
events_helper::propagate_event(&Event::UpdatedNumberUnreadConversations(&vec![user_id.clone()]))?;
events_helper::propagate_event(Event::UpdatedNumberUnreadConversations(vec![user_id.clone()])).await?;
Ok(())
}
/// 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) {
delete_conversation(conv)
delete_conversation(conv).await
} 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
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)? {
update_members_list_for_group_conversation(conv.id)?;
update_members_list_for_group_conversation(conv.id).await?;
}
Ok(())
}
/// 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)?;
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
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
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
pub fn delete_conversation(conv: &Conversation) -> ResultBoxError<()> {
pub async fn delete_conversation(conv: &Conversation) -> ResultBoxError<()> {
// Delete all the messages of the conversations
for message in get_all_messages(conv.id)? {
delete_message(&message)?;
delete_message(&message).await?;
}
// Delete all the members of the conversation
@ -551,24 +552,24 @@ pub fn delete_conversation(conv: &Conversation) -> ResultBoxError<()> {
.exec()?;
// Propagate information
events_helper::propagate_event(&Event::DeletedConversation(conv.id))?;
events_helper::propagate_event(Event::DeletedConversation(conv.id)).await?;
Ok(())
}
/// 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)? {
delete_conversation(&conv)?;
delete_conversation(&conv).await?;
}
Ok(())
}
/// 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)? {
delete_message(&msg)?;
delete_message(&msg).await?;
}
// 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(
conv_id,
ConversationServerMessageType::UserLeftConversation(user_id.clone()),
))?;
)).await?;
} else {
send_message(&NewConversationMessage::new_server_message(
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_removed: user_id.clone(),
}),
))?;
)).await?;
}
}
// 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(())
}

View File

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

View File

@ -94,7 +94,7 @@ impl GroupPostsCreationLevel {
}
/// 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
let group_id = database::InsertQuery::new(GROUPS_LIST_TABLE)
.add_u64("time_create", time())
@ -111,13 +111,13 @@ pub fn create(group: &NewGroup) -> ResultBoxError<GroupID> {
time_create: time(),
level: GroupMembershipLevel::ADMINISTRATOR,
following: true,
})?;
}).await?;
Ok(group_id)
}
/// 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)
.add_group_id("groups_id", &m.group_id)
.add_user_id("user_id", &m.user_id)
@ -126,27 +126,27 @@ pub fn insert_member(m: &GroupMember) -> ResultBoxError<()> {
.insert_drop_result()?;
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(())
}
/// 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)
.cond_group_id("groups_id", group_id)
.cond_user_id("user_id", user_id)
.exec()?;
// 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(())
}
/// 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)
.cond_user_id("user_id", user_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()?;
// 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(())
}
@ -440,7 +440,7 @@ pub fn get_list_members(g: &GroupID) -> ResultBoxError<Vec<GroupMember>> {
}
/// 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 {
id: 0,
user_id: user_id.clone(),
@ -448,7 +448,7 @@ pub fn send_invitation(group_id: &GroupID, user_id: &UserID) -> ResultBoxError {
time_create: time(),
level: GroupMembershipLevel::INVITED,
following: true,
})
}).await
}
/// 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
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 {
true => update_membership_level(g, u, GroupMembershipLevel::MEMBER),
false => delete_member(g, u),
true => update_membership_level(g, u, GroupMembershipLevel::MEMBER).await,
false => delete_member(g, u).await,
}
}
/// 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 {
true => update_membership_level(&group_id, &user_id, GroupMembershipLevel::MEMBER),
false => delete_member(&group_id, &user_id),
true => update_membership_level(&group_id, &user_id, GroupMembershipLevel::MEMBER).await,
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
pub fn delete(group_id: &GroupID) -> ResultBoxError {
pub async fn delete(group_id: &GroupID) -> ResultBoxError {
// Delete all likes of the 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 all group posts
posts_helper::delete_all_group(group_id)?;
posts_helper::delete_all_group(group_id).await?;
// 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
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
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
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)? {
if is_last_admin(group_id, user_id)? {
delete(group_id)?;
delete(group_id).await?;
} 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;
/// 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()
.set_from_user_id(from_user)
.set_on_elem_id(post_id)
.set_on_elem_type(NotifElemType::POST)
.set_type(action);
push(&mut n)
push(&mut n).await
}
/// 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()
.set_from_user_id(from_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_type(action);
push(&mut n)
push(&mut n).await
}
/// 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_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()
.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
fn push(n: &mut PartialNotification) -> ResultBoxError
async fn push(n: &mut PartialNotification) -> ResultBoxError
{
if n.time_create.is_none()
{
@ -110,7 +110,7 @@ fn push(n: &mut PartialNotification) -> ResultBoxError
n.dest_user_id = Some(post.user_id);
}
return push_private(n);
return push_private(n).await;
}
// Posts on user page
@ -129,12 +129,12 @@ fn push(n: &mut PartialNotification) -> ResultBoxError
.map(|f| f.friend_id)
.collect();
return push_public(n, friends);
return push_public(n, friends).await;
}
// Posts on group pages
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
@ -148,7 +148,7 @@ fn push(n: &mut PartialNotification) -> ResultBoxError
n.container_id = 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,
// generally the target user of the membership request)
push_private(n)
push_private(n).await
} 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 {
unimplemented!();
@ -175,32 +175,32 @@ fn push(n: &mut PartialNotification) -> ResultBoxError
}
/// 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)?;
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
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: Vec<UserID> = list
.into_iter()
.filter(|e| e.is_moderator())
.map(|f| f.user_id)
.collect();
push_public(n, list)
push_public(n, list).await
}
/// 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);
for user_id in users {
n.dest_user_id = Some(user_id);
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)
fn push_private(n: &mut PartialNotification) -> ResultBoxError {
async fn push_private(n: &mut PartialNotification) -> Res {
n.visibility = Some(NotifEventVisibility::EVENT_PRIVATE);
if !similar_exists(n)? {
create(n)?;
create(n).await?;
}
Ok(())
}
/// 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()
{
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()?;
// 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(())
}
/// Delete notifications
pub fn delete(notification: &PartialNotification) -> ResultBoxError {
pub async fn delete(notification: &PartialNotification) -> ResultBoxError {
let conditions = notif_to_db(notification, false);
// Get the list of affected users
@ -252,23 +252,23 @@ pub fn delete(notification: &PartialNotification) -> ResultBoxError {
.exec()?;
// Send a notification (updated_number_conversations)
events_helper::propagate_event(&Event::UpdatedNotificationsNumber(&users))?;
events_helper::propagate_event(Event::UpdatedNotificationsNumber(users)).await?;
Ok(())
}
/// Delete all the notifications of a given user
pub fn delete_all_user(user_id: &UserID) -> ResultBoxError {
delete(&PartialNotification::new().set_dest_user_id(user_id))
pub async fn delete_all_user(user_id: &UserID) -> ResultBoxError {
delete(&PartialNotification::new().set_dest_user_id(user_id)).await
}
/// 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_user(user_id)?;
delete_all_user(user_id).await?;
// 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(())
}
@ -288,66 +288,66 @@ pub fn clean_old_user_notifications(user: &User) -> Res {
}
/// 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()
.set_on_elem_type(NotifElemType::GROUP_MEMBERSHIP)
.set_on_elem_id(group_id.id())
)?;
).await?;
delete(&PartialNotification::new()
.set_on_elem_type(NotifElemType::GROUP_PAGE)
.set_on_elem_id(group_id.id())
)
).await
}
/// 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()
.set_on_elem_type(NotifElemType::GROUP_MEMBERSHIP)
.set_on_elem_id(group_id.id());
n.dest_user_id = Some(user_id.clone());
n.from_user_id = None;
delete(&n)?;
delete(&n).await?;
n.dest_user_id = None;
n.from_user_id = Some(user_id.clone());
delete(&n)?;
delete(&n).await?;
Ok(())
}
/// 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()
.set_dest_user_id(user_id)
.set_on_elem_type(NotifElemType::POST)
.set_on_elem_id(post_id);
delete(&n)
delete(&n).await
}
/// 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()
.set_on_elem_type(NotifElemType::POST)
.set_on_elem_id(post_id);
delete(&n)
delete(&n).await
}
/// 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()
.set_on_elem_type(NotifElemType::FRIENDSHIP_REQUEST);
n.from_user_id = Some(user_one.clone());
n.dest_user_id = Some(user_two.clone());
delete(&n)?;
delete(&n).await?;
n.from_user_id = Some(user_two.clone());
n.dest_user_id = Some(user_one.clone());
delete(&n)
delete(&n).await
}
/// 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
pub fn delete(p: &Post) -> ResultBoxError {
pub async fn delete(p: &Post) -> ResultBoxError {
// 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
likes_helper::delete_all(p.id, LikeType::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)
match &p.kind {
@ -452,25 +452,25 @@ pub fn delete(p: &Post) -> ResultBoxError {
}
/// 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)? {
delete(&post)?;
delete(&post).await?;
}
Ok(())
}
/// 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)? {
delete(&post)?;
delete(&post).await?;
}
Ok(())
}
/// 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);
if lifetime < 1 {
return Ok(());
@ -484,7 +484,7 @@ pub fn clean_old_posts(user: &User) -> Res {
.exec(db_to_post)?;
for post in posts {
delete(&post)?;
delete(&post).await?;
}
Ok(())

View File

@ -413,7 +413,7 @@ pub async fn find_route(req_uri: &str, call: Option<&mut HttpRequestHandler>) ->
// 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

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)),
// Likes controller
"likes/update" => Some(likes_controller::update(handler)),
"likes/update" => Some(likes_controller::update(handler).await),
// 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/config" => Some(calls_controller::get_config(handler)),
"calls/join" => Some(calls_controller::join_call(handler)),
"calls/leave" => Some(calls_controller::leave_call(handler)),
"calls/members" => Some(calls_controller::get_members_list(handler)),
"calls/signal" => Some(calls_controller::on_client_signal(handler)),
"calls/mark_ready" => Some(calls_controller::mark_user_ready(handler)),
"calls/request_offer" => Some(calls_controller::request_offer(handler)),
"calls/stop_streaming" => Some(calls_controller::stop_streaming(handler)),
"calls/config" => Some(calls_controller::get_config(handler).await),
"calls/join" => Some(calls_controller::join_call(handler).await),
"calls/leave" => Some(calls_controller::leave_call(handler).await),
"calls/members" => Some(calls_controller::get_members_list(handler).await),
"calls/signal" => Some(calls_controller::on_client_signal(handler).await),
"calls/mark_ready" => Some(calls_controller::mark_user_ready(handler).await),
"calls/request_offer" => Some(calls_controller::request_offer(handler).await),
"calls/stop_streaming" => Some(calls_controller::stop_streaming(handler).await),
// Presence controller
"forez_presence/list" => Some(forez_controller::get_list(handler)),