1
0
mirror of https://gitlab.com/comunic/comunicapiv3 synced 2025-06-21 00:45:18 +00:00

Continue refactoring

This commit is contained in:
2021-03-04 18:51:52 +01:00
parent 2cc8984dfa
commit fbf4728347
27 changed files with 527 additions and 355 deletions

View File

@ -13,7 +13,6 @@ use crate::api_data::joined_call_message::JoinedCallMessage;
use crate::api_data::left_call_message::LeftCallMessage;
use crate::api_data::new_call_signal::NewCallSignalAPI;
use crate::api_data::user_calls_config::UserCallsConfig;
use crate::routes::RequestResult;
use crate::controllers::user_ws_controller;
use crate::data::base_request_handler::BaseRequestHandler;
use crate::data::call_signal::{CallSignal, CloseCallStream, IceCandidate, NewUserCallSignal, SdpType, UserCallOfferRequest};
@ -27,11 +26,12 @@ use crate::data::user_ws_message::UserWsMessage;
use crate::data::user_ws_request_handler::UserWsRequestHandler;
use crate::helpers::{calls_helper, conversations_helper, events_helper};
use crate::helpers::events_helper::Event;
use crate::routes::RequestResult;
impl UserWsRequestHandler {
/// Get the ID of a call included in a WebSocket request
fn post_call_id(&mut self, name: &str) -> Res<ConvID> {
let conv_id = self.post_u64(name)?;
let conv_id = ConvID::new(self.post_u64(name)?);
if !self.get_conn().is_having_call_with_conversation(&conv_id) {
self.forbidden("You do not belong to this call!".to_string())?;
@ -125,7 +125,7 @@ pub fn is_conversation_having_call(conv_id: &ConvID) -> bool {
});
if let Err(e) = res {
eprintln!("Failed to check if a conversation is having call! Conversation: {} / Error: {:#?}", conv_id, e);
eprintln!("Failed to check if a conversation is having call! Conversation: {} / Error: {:#?}", conv_id.id(), e);
}
found
@ -133,10 +133,10 @@ pub fn is_conversation_having_call(conv_id: &ConvID) -> bool {
/// Join a call
pub fn join_call(r: &mut UserWsRequestHandler) -> RequestResult {
let conv_id = r.post_conv_id("convID")?;
let conv_id = r.post_conv("convID")?.conv_id;
// Check if the conversation can have a call
let conv = conversations_helper::get_single(conv_id, r.user_id_ref()?)?;
let conv = conversations_helper::get_single(conv_id)?;
if !calls_helper::can_have_call(&conv) {
r.forbidden("This conversation can not be used to make calls!".to_string())?;
}
@ -177,7 +177,7 @@ pub 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
let conv_id = r.post_u64("convID")?;
let conv_id = ConvID::new(r.post_u64("convID")?);
// Check if the user was not in the conversation
if !r.get_conn().is_having_call_with_conversation(&conv_id) {
@ -208,7 +208,7 @@ pub fn get_members_list(r: &mut UserWsRequestHandler) -> RequestResult {
/// Get the hash associated to a call
pub fn gen_call_hash(call_id: &ConvID, peer_id: &UserID) -> String {
format!("{}-{}", call_id, peer_id.id())
format!("{}-{}", call_id.id(), peer_id.id())
}
/// Handles client signal
@ -357,7 +357,7 @@ pub fn make_user_leave_call(conv_id: &ConvID, connection: &UserWsConnection) ->
// Notify user (if possible)
if connection.session.connected() {
user_ws_controller::send_to_client(connection, &UserWsMessage::no_id_message("call_closed", conv_id)?)?;
user_ws_controller::send_to_client(connection, &UserWsMessage::no_id_message("call_closed", conv_id.id())?)?;
}
// Close main stream (sender)
@ -418,7 +418,7 @@ pub fn handle_event(e: &events_helper::Event) -> Res {
return Ok(());
}
let call_id = split[0].parse::<u64>()?;
let call_id = ConvID::new(split[0].parse::<u64>()?);
let peer_id = UserID::new(split[1].parse::<u64>()?);
let target_user = UserID::new(msg.peer_id.parse::<u64>()?);

View File

@ -2,18 +2,18 @@
//!
//! @author Pierre Hubert
use std::collections::HashMap;
use crate::api_data::conversation_api::ConversationAPI;
use crate::api_data::conversation_message_api::ConversationMessageAPI;
use crate::api_data::conversations_refresh_api::ConversationRefreshResultAPI;
use crate::api_data::list_unread_conversations_api::UnreadConversationAPI;
use crate::api_data::res_count_unread_conversations::ResultCountUnreadConversations;
use crate::api_data::res_create_conversation::ResCreateConversation;
use crate::api_data::res_find_private_conversations::ResFindPrivateConversations;
use crate::routes::RequestResult;
use crate::constants::MIN_CONVERSATION_MESSAGE_LENGTH;
use crate::controllers::user_ws_controller;
use crate::data::base_request_handler::BaseRequestHandler;
use crate::data::conversation::{ConversationMemberSetting, NewConversationSettings};
use crate::data::conversation_message::ConversationMessageFile;
use crate::data::error::Res;
use crate::data::http_request_handler::HttpRequestHandler;
use crate::data::new_conversation::NewConversation;
@ -23,6 +23,7 @@ use crate::data::user_ws_connection::UserWsConnection;
use crate::data::user_ws_message::UserWsMessage;
use crate::helpers::{conversations_helper, events_helper, user_helper};
use crate::helpers::events_helper::Event;
use crate::routes::RequestResult;
use crate::utils::string_utils::remove_html_nodes;
/// Create a new conversation
@ -58,6 +59,9 @@ pub fn create(r: &mut HttpRequestHandler) -> RequestResult {
owner_following: r.post_bool("follow")?,
members,
can_everyone_add_members: r.post_bool_opt("canEveryoneAddMembers", true),
color: r.post_color_opt("color")?,
group_id: None,
background: None,// TODO : add support for background
};
// Create the conversation
@ -74,77 +78,94 @@ pub fn get_list(r: &mut HttpRequestHandler) -> RequestResult {
/// Get information about a single conversation
pub fn get_single(r: &mut HttpRequestHandler) -> RequestResult {
let conversation_id = r.post_conv_id("conversationID")?;
let conv = conversations_helper::get_single(conversation_id, &r.user_id()?)?;
let conv = r.post_conv("conversationID")?;
let conv = conversations_helper::get_single(conv.conv_id)?;
r.set_response(ConversationAPI::new(&conv))
}
/// Update the settings of a conversation
pub fn update_settings(r: &mut HttpRequestHandler) -> RequestResult {
let conv_id = r.post_conv_id("conversationID")?;
let is_moderator = conversations_helper::is_user_moderator(&r.user_id()?, conv_id)?;
let conv_membership = r.post_conv("conversationID")?;
let conv = conversations_helper::get_single(conv_membership.conv_id)?;
// Update following state, if required
if r.has_post_parameter("following") {
conversations_helper::set_following(
&r.user_id()?,
conv_id,
conv_membership.member_id,
r.post_bool("following")?,
)?;
}
// Update members list
if r.has_post_parameter("members") {
let mut members = r.post_numbers_list("members", 1)?
.iter()
.map(|f| UserID::new(f.clone()))
.collect::<Vec<UserID>>();
if r.has_post_parameter("members") && !conv.is_managed() {
let mut members = r.post_users_id("members")?
.into_iter()
.map(|user_id| ConversationMemberSetting { user_id, set_admin: false })
.collect::<Vec<ConversationMemberSetting>>();
let admins = r.post_users_id("admins")?;
let can_everyone_add_members = conversations_helper::can_everyone_add_members(conv_id)?;
let can_everyone_add_members = conversations_helper::can_everyone_add_members(conv_membership.conv_id)?;
if !is_moderator && !can_everyone_add_members {
if !conv_membership.is_admin && !can_everyone_add_members {
r.forbidden("You can not update the list of members of this conversation!".to_string())?;
}
// Check if the members of the conversation really exists
for member in &members {
if !user_helper::exists(member)? {
r.not_found(format!("User {} not found!", member.id()))?;
}
// Set same admin status as earlier
if !conv_membership.is_admin {
members = members
.into_iter()
.map(|mut n| {
n.set_admin = conv.is_admin(&n.user_id);
n
})
.collect()
}
if !members.contains(&r.user_id()?) {
members.push(r.user_id()?);
// If the user is an admin, use the values he gave
else {
members = members
.into_iter()
.map(|mut n| {
n.set_admin = admins.contains(&n.user_id);
n
})
.collect()
}
conversations_helper::set_members(conv_id, &members, is_moderator)?;
// Current user can not touch his own membership, so revert it back forcefully
members = members
.into_iter()
.filter(|m| !m.user_id.eq(&conv_membership.user_id))
.collect::<Vec<ConversationMemberSetting>>();
members.push(ConversationMemberSetting {
user_id: r.user_id()?,
set_admin: conv_membership.is_admin,
});
conversations_helper::set_members(conv_membership.conv_id, &members, conv_membership.is_admin)?;
}
// Change moderator settings
if r.has_post_parameter("name") || r.has_post_parameter("canEveryoneAddMembers") {
if !is_moderator {
if r.has_post_parameter("name")
&& r.has_post_parameter("canEveryoneAddMembers")
&& r.has_post_parameter("color") {
if !conv_membership.is_admin {
r.forbidden("You are not allowed to perform changes on this conversation!".to_string())?;
}
// Change conversation name
if r.has_post_parameter("name") {
let name = r.post_string_opt("name", 0, true)?;
let name = if name.eq("false") || name.is_empty() {
None
} else {
Some(remove_html_nodes(&name))
};
conversations_helper::set_name(conv_id, name)?;
}
let new_settings = NewConversationSettings {
conv_id: conv_membership.conv_id,
name: r.post_string_optional("name").map(|s| remove_html_nodes(&s)),
color: r.post_color_opt("color")?,
can_everyone_add_members: r.post_bool("canEveryoneAddMembers")?,
};
// Change "canEveryoneAddMembers" parameter
if r.has_post_parameter("canEveryoneAddMembers") {
conversations_helper::set_can_everyone_add_members(
conv_id, r.post_bool("canEveryoneAddMembers")?)?;
}
conversations_helper::set_settings(new_settings)?;
}
r.success("Conversation information successfully updated!")
@ -169,6 +190,9 @@ pub fn find_private(r: &mut HttpRequestHandler) -> RequestResult {
owner_following: true,
members: vec![r.user_id()?, other_user],
can_everyone_add_members: true,
color: r.post_color_opt("color")?,
background: None,
group_id: None,
};
let conv_id = conversations_helper::create(&new_conv)?;
list.push(conv_id);
@ -177,80 +201,25 @@ pub fn find_private(r: &mut HttpRequestHandler) -> RequestResult {
r.set_response(ResFindPrivateConversations::new(list))
}
/// DEPRECATED : refresh current user conversations
///
/// This method was used only by ComunicWeb before the introduction of WebSockets
pub fn refresh_list(r: &mut HttpRequestHandler) -> RequestResult {
let mut list = HashMap::new();
// Check for new conversations
if r.has_post_parameter("newConversations") {
for conv_id in r.post_numbers_list("newConversations", 0)? {
if !conversations_helper::does_user_belongs_to(&r.user_id()?, conv_id)? {
r.forbidden(format!("Your do not belongs to conversation {} !", conv_id))?;
}
let list_conv = conversations_helper::get_last_messages(conv_id, 10)?;
list.insert(conv_id as u64, list_conv);
conversations_helper::mark_user_seen(conv_id as u64, &r.user_id()?)?;
}
}
// Check for refresh of already initialized conversations
if r.has_post_parameter("toRefresh") {
let v: HashMap<String, HashMap<String, serde_json::Value>> =
serde_json::from_str(r.post_string("toRefresh")?.as_str())?;
for (k, v) in v {
// Get conversation ID
if !k.starts_with("conversation-") {
return r.bad_request("Entries of 'toRefresh' must start with 'conversation-'!".to_string());
}
let conv_id = k.replace("conversation-", "").parse::<u64>()?;
// Extract last message id
if !v.contains_key("last_message_id") {
return r.bad_request(format!("Missing 'last_message_id' in conversation {}!", conv_id));
}
let last_message_id = v["last_message_id"].as_u64().unwrap_or(0);
// Check user rights
if !conversations_helper::does_user_belongs_to(&r.user_id()?, conv_id)? {
return r.forbidden(format!("You do not belong to conversation {}!", conv_id));
}
let list_conv = conversations_helper::get_new_messages(conv_id, last_message_id)?;
list.insert(conv_id, list_conv);
conversations_helper::mark_user_seen(conv_id as u64, &r.user_id()?)?;
}
}
r.set_response(ConversationRefreshResultAPI::new(list))
}
/// Refresh a single conversation
pub fn refresh_single(r: &mut HttpRequestHandler) -> RequestResult {
let conv_id = r.post_conv_id("conversationID")?;
let conv = r.post_conv("conversationID")?;
let last_message_id = r.post_u64("last_message_id")?;
let messages = match last_message_id {
// Get latest messages of the conversation
0 => conversations_helper::get_last_messages(conv_id, 10)?,
0 => conversations_helper::get_last_messages(conv.member_id, 10)?,
// Get new messages
_ => conversations_helper::get_new_messages(conv_id, last_message_id)?,
_ => conversations_helper::get_new_messages(conv.member_id, last_message_id)?,
};
conversations_helper::mark_user_seen(conv_id, &r.user_id()?)?;
r.set_response(ConversationMessageAPI::for_list(&messages))
}
/// Get older messages of a conversation
pub fn get_older_messages(r: &mut HttpRequestHandler) -> RequestResult {
let conv_id = r.post_conv_id("conversationID")?;
let conv = r.post_conv("conversationID")?;
let max_id = r.post_u64("oldest_message_id")? - 1;
// Determine limit
@ -261,31 +230,44 @@ pub fn get_older_messages(r: &mut HttpRequestHandler) -> RequestResult {
_ => 60
};
let messages = conversations_helper::get_older_messages(conv_id, max_id, limit)?;
let messages = conversations_helper::get_older_messages(conv.member_id, max_id, limit)?;
r.set_response(ConversationMessageAPI::for_list(&messages))
}
/// Send a new message
pub fn send_message(r: &mut HttpRequestHandler) -> RequestResult {
let conv_id = r.post_conv_id("conversationID")?;
let message = r.post_string_without_html("message", 0, false)?;
let conv = r.post_conv("conversationID")?;
// TODO : add support for other files type
// Get image
let image_path = match r.has_file("image") {
let file = match r.has_file("image") {
false => None,
true => Some(r.save_post_image("image", "conversations", 1200, 1200)?)
true => {
let path = r.save_post_image("image", "conversations", 1200, 1200)?;
Some(ConversationMessageFile {
path: path.clone(),
size: std::fs::metadata(&path)?.len(),
name: "picture.png".to_string(),
thumbnail: Some(r.save_post_image("image", "conversations", 50, 50)?),
r#type: "image/png".to_string(),
})
}
};
if image_path == None && message.len() < 3 {
r.bad_request("Message is empty!".to_string())?;
}
let message = if let None = file {
Some(r.post_string_without_html("message", MIN_CONVERSATION_MESSAGE_LENGTH, true)?)
} else {
None
};
conversations_helper::send_message(&NewConversationMessage {
user_id: r.user_id()?,
conv_id,
user_id: Some(r.user_id()?),
conv_id: conv.conv_id,
message,
image_path,
file,
server_message: None,
})?;
r.success("Conversation message was successfully sent!")
@ -307,9 +289,14 @@ pub fn list_unread(r: &mut HttpRequestHandler) -> RequestResult {
/// Delete a conversation
pub fn delete_conversation(r: &mut HttpRequestHandler) -> RequestResult {
let conv_id = r.post_conv_id("conversationID")?;
let conv_membership = r.post_conv("conversationID")?;
let conv = conversations_helper::get_single(conv_membership.conv_id)?;
conversations_helper::remove_user_from_conversation(&r.user_id()?, conv_id)?;
if conv.is_managed() {
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()?)?;
r.success("The conversation has been deleted")
}
@ -362,7 +349,7 @@ 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("new_conv_message", ConversationMessageAPI::new(msg)),
Some(|conn: &UserWsConnection| conversations_helper::mark_user_seen(msg.conv_id, conn.user_id())),
Some(|conn: &UserWsConnection| conversations_helper::mark_user_seen(msg.conv_id, conn.user_id(), msg.id)),
)?;
}

View File

@ -6,6 +6,7 @@ use crate::data::base_request_handler::BaseRequestHandler;
use crate::data::error::Res;
use crate::data::post::PostAccessLevel;
use crate::data::user_ws_request_handler::UserWsRequestHandler;
use crate::data::conversation::ConvID;
/// Update incognito status of the connection
pub fn set_incognito(r: &mut UserWsRequestHandler) -> Res {
@ -17,14 +18,14 @@ pub fn set_incognito(r: &mut UserWsRequestHandler) -> Res {
/// Register a conversation
pub fn register_conv(r: &mut UserWsRequestHandler) -> Res {
let conv_id = r.post_conv_id("convID")?;
let conv_id = r.post_conv("convID")?.conv_id;
r.update_conn(|c| { c.conversations.insert(conv_id); })?;
r.success("ok")
}
/// Un-register a conversation
pub fn unregister_conv(r: &mut UserWsRequestHandler) -> Res {
let conv_id = r.post_u64("convID")?;
let conv_id = ConvID::new(r.post_u64("convID")?);
r.update_conn(|c| { c.conversations.remove(&conv_id); })?;
r.success("ok")
}