2020-06-03 11:36:19 +00:00
|
|
|
//! # Conversations controller
|
|
|
|
//!
|
|
|
|
//! @author Pierre Hubert
|
|
|
|
|
2020-06-18 12:15:17 +00:00
|
|
|
use std::collections::HashMap;
|
|
|
|
|
2020-06-15 12:42:02 +00:00
|
|
|
use crate::api_data::conversation_api::ConversationAPI;
|
2020-06-20 05:54:30 +00:00
|
|
|
use crate::api_data::conversation_message_api::ConversationMessageAPI;
|
2020-06-18 12:15:17 +00:00
|
|
|
use crate::api_data::conversations_refresh_api::ConversationRefreshResultAPI;
|
2020-06-22 12:41:14 +00:00
|
|
|
use crate::api_data::res_count_unread_conversations::ResultCountUnreadConversations;
|
2020-06-15 12:42:02 +00:00
|
|
|
use crate::api_data::res_create_conversation::ResCreateConversation;
|
2020-06-18 07:40:18 +00:00
|
|
|
use crate::api_data::res_find_private_conversations::ResFindPrivateConversations;
|
2020-06-03 11:36:19 +00:00
|
|
|
use crate::controllers::routes::RequestResult;
|
2020-06-15 12:42:02 +00:00
|
|
|
use crate::data::http_request_handler::HttpRequestHandler;
|
2020-06-03 16:34:01 +00:00
|
|
|
use crate::data::new_conversation::NewConversation;
|
2020-06-22 12:16:52 +00:00
|
|
|
use crate::data::new_conversation_message::NewConversationMessage;
|
2020-06-15 12:42:02 +00:00
|
|
|
use crate::helpers::{conversations_helper, user_helper};
|
|
|
|
use crate::utils::string_utils::remove_html_nodes;
|
2020-06-22 16:55:24 +00:00
|
|
|
use crate::api_data::list_unread_conversations_api::UnreadConversationAPI;
|
2020-06-03 11:36:19 +00:00
|
|
|
|
|
|
|
/// Create a new conversation
|
|
|
|
pub fn create(r: &mut HttpRequestHandler) -> RequestResult {
|
2020-06-03 16:34:01 +00:00
|
|
|
let name = r.post_string("name")?;
|
|
|
|
let mut members = r.post_numbers_list("users", 1)?;
|
|
|
|
|
|
|
|
// Adapt name
|
|
|
|
let name = match name.as_str() {
|
|
|
|
"false" => None,
|
|
|
|
s => Some(s.to_string())
|
|
|
|
};
|
|
|
|
|
|
|
|
// Check if members exists
|
|
|
|
for user in &members {
|
|
|
|
if !user_helper::exists(user.clone())? {
|
|
|
|
r.not_found(format!("User {} not found!", user))?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add current user ID if required
|
|
|
|
let curr_user_id = r.user_id()? as i64;
|
|
|
|
if !members.contains(&curr_user_id) {
|
|
|
|
members.push(curr_user_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
let conv = NewConversation {
|
|
|
|
owner_id: r.user_id()?,
|
|
|
|
name,
|
|
|
|
owner_following: r.post_bool("follow")?,
|
|
|
|
members,
|
2020-06-04 15:47:52 +00:00
|
|
|
can_everyone_add_members: r.post_bool_opt("canEveryoneAddMembers", true),
|
2020-06-03 16:34:01 +00:00
|
|
|
};
|
|
|
|
|
2020-06-04 15:47:52 +00:00
|
|
|
// Create the conversation
|
2020-06-04 11:36:57 +00:00
|
|
|
let conv_id = conversations_helper::create(&conv)?;
|
2020-06-04 15:47:52 +00:00
|
|
|
r.set_response(ResCreateConversation::new(conv_id))
|
2020-06-04 15:51:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get the list of conversations of a user
|
|
|
|
pub fn get_list(r: &mut HttpRequestHandler) -> RequestResult {
|
2020-06-04 17:01:35 +00:00
|
|
|
let list = conversations_helper::get_list_user(r.user_id()?)?;
|
|
|
|
|
|
|
|
r.set_response(list.iter().map(|c| ConversationAPI::new(c)).collect::<Vec<ConversationAPI>>())
|
2020-06-12 06:50:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get information about a single conversation
|
|
|
|
pub fn get_single(r: &mut HttpRequestHandler) -> RequestResult {
|
2020-06-12 07:04:43 +00:00
|
|
|
let conversation_id = r.post_conv_id("conversationID")?;
|
2020-06-12 07:20:32 +00:00
|
|
|
let conv = conversations_helper::get_single(conversation_id, r.user_id()?)?;
|
2020-06-12 07:04:43 +00:00
|
|
|
|
2020-06-12 07:20:32 +00:00
|
|
|
r.set_response(ConversationAPI::new(&conv))
|
2020-06-12 07:23:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Update the settings of a conversation
|
|
|
|
pub fn update_settings(r: &mut HttpRequestHandler) -> RequestResult {
|
2020-06-12 09:26:12 +00:00
|
|
|
let conv_id = r.post_conv_id("conversationID")?;
|
|
|
|
let is_moderator = conversations_helper::is_user_moderator(r.user_id()?, conv_id)?;
|
|
|
|
|
2020-06-15 06:23:23 +00:00
|
|
|
// Update following state, if required
|
|
|
|
if r.has_post_parameter("following") {
|
|
|
|
conversations_helper::set_following(
|
|
|
|
r.user_id()?,
|
|
|
|
conv_id,
|
2020-06-15 08:46:10 +00:00
|
|
|
r.post_bool("following")?,
|
2020-06-15 06:23:23 +00:00
|
|
|
)?;
|
|
|
|
}
|
2020-06-12 09:26:12 +00:00
|
|
|
|
2020-06-15 07:29:38 +00:00
|
|
|
// Update members list
|
|
|
|
if r.has_post_parameter("members") {
|
2020-06-15 08:46:10 +00:00
|
|
|
let mut members = r.post_numbers_list("members", 1)?;
|
2020-06-15 07:29:38 +00:00
|
|
|
let can_everyone_add_members = conversations_helper::can_everyone_add_members(conv_id)?;
|
|
|
|
|
|
|
|
if !is_moderator && !can_everyone_add_members {
|
|
|
|
r.forbidden("You can not update the list of members of this conversation!".to_string())?;
|
|
|
|
}
|
2020-06-15 08:46:10 +00:00
|
|
|
|
2020-06-15 09:09:16 +00:00
|
|
|
// Check if the members of the conversation really exists
|
|
|
|
for member in &members {
|
|
|
|
if !user_helper::exists(member.clone())? {
|
|
|
|
r.not_found(format!("User {} not found!", member))?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-15 08:46:10 +00:00
|
|
|
if !members.contains(&r.user_id()?) {
|
|
|
|
members.push(r.user_id()?);
|
|
|
|
}
|
|
|
|
|
2020-06-15 08:53:50 +00:00
|
|
|
conversations_helper::set_members(conv_id, &members, is_moderator)?;
|
2020-06-15 07:29:38 +00:00
|
|
|
}
|
|
|
|
|
2020-06-15 12:30:01 +00:00
|
|
|
// Change moderator settings
|
|
|
|
if r.has_post_parameter("name") || r.has_post_parameter("canEveryoneAddMembers") {
|
|
|
|
if !is_moderator {
|
|
|
|
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 {
|
2020-06-15 12:42:02 +00:00
|
|
|
Some(remove_html_nodes(&name))
|
2020-06-15 12:30:01 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
conversations_helper::set_name(conv_id, name)?;
|
|
|
|
}
|
2020-06-15 12:52:23 +00:00
|
|
|
|
|
|
|
|
|
|
|
// Change "canEveryoneAddMembers" parameter
|
|
|
|
if r.has_post_parameter("canEveryoneAddMembers") {
|
|
|
|
conversations_helper::set_can_everyone_add_members(
|
|
|
|
conv_id, r.post_bool("canEveryoneAddMembers")?)?;
|
|
|
|
}
|
2020-06-15 12:30:01 +00:00
|
|
|
}
|
|
|
|
|
2020-06-15 06:23:23 +00:00
|
|
|
r.success("Conversation information successfully updated!")
|
2020-06-18 07:06:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Find a private conversation
|
|
|
|
pub fn find_private(r: &mut HttpRequestHandler) -> RequestResult {
|
2020-06-18 07:26:25 +00:00
|
|
|
let other_user = r.post_user_id("otherUser")?;
|
|
|
|
let allow_create = r.post_bool_opt("allowCreate", false);
|
|
|
|
|
|
|
|
// Query the database
|
2020-06-18 07:44:34 +00:00
|
|
|
let mut list = conversations_helper::find_private(r.user_id()?, other_user)?;
|
2020-06-18 07:26:25 +00:00
|
|
|
|
2020-06-18 07:40:18 +00:00
|
|
|
if list.is_empty() {
|
|
|
|
if !allow_create {
|
|
|
|
return r.not_found(format!("Not any private conversation was found. The server was not allowed to create a new one..."));
|
|
|
|
}
|
2020-06-18 07:44:34 +00:00
|
|
|
|
|
|
|
let new_conv = NewConversation {
|
|
|
|
owner_id: r.user_id()?,
|
|
|
|
name: None,
|
|
|
|
owner_following: true,
|
|
|
|
members: vec![r.user_id()?, other_user],
|
|
|
|
can_everyone_add_members: true,
|
|
|
|
};
|
|
|
|
let conv_id = conversations_helper::create(&new_conv)?;
|
|
|
|
list.push(conv_id);
|
2020-06-18 07:40:18 +00:00
|
|
|
}
|
2020-06-18 07:26:25 +00:00
|
|
|
|
2020-06-18 07:40:18 +00:00
|
|
|
r.set_response(ResFindPrivateConversations::new(list))
|
2020-06-18 07:55:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// 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 {
|
2020-06-18 12:15:17 +00:00
|
|
|
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 as u64)? {
|
|
|
|
r.forbidden(format!("Your do not belongs to conversation {} !", conv_id))?;
|
|
|
|
}
|
|
|
|
|
2020-06-18 12:33:43 +00:00
|
|
|
let list_conv = conversations_helper::get_last_messages(conv_id as u64, 10)?;
|
|
|
|
list.insert(conv_id as u64, list_conv);
|
2020-06-18 12:15:17 +00:00
|
|
|
|
2020-06-18 12:33:43 +00:00
|
|
|
conversations_helper::mark_user_seen(conv_id as u64, r.user_id()?)?;
|
2020-06-18 12:15:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-18 16:16:46 +00:00
|
|
|
// 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()?)?;
|
|
|
|
}
|
|
|
|
}
|
2020-06-18 12:15:17 +00:00
|
|
|
|
|
|
|
r.set_response(ConversationRefreshResultAPI::new(list))
|
2020-06-20 05:42:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Refresh a single conversation
|
|
|
|
pub fn refresh_single(r: &mut HttpRequestHandler) -> RequestResult {
|
2020-06-20 05:54:30 +00:00
|
|
|
let conv_id = r.post_conv_id("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)?,
|
|
|
|
|
|
|
|
// Get new messages
|
|
|
|
_ => conversations_helper::get_new_messages(conv_id, last_message_id)?,
|
|
|
|
};
|
|
|
|
|
|
|
|
conversations_helper::mark_user_seen(conv_id, r.user_id()?)?;
|
|
|
|
|
|
|
|
r.set_response(ConversationMessageAPI::for_list(&messages))
|
2020-06-20 09:55:39 +00:00
|
|
|
}
|
|
|
|
|
2020-06-22 12:16:52 +00:00
|
|
|
/// Get older messages of a conversation
|
|
|
|
pub fn get_older_messages(r: &mut HttpRequestHandler) -> RequestResult {
|
|
|
|
let conv_id = r.post_conv_id("conversationID")?;
|
|
|
|
let max_id = r.post_u64("oldest_message_id")? - 1;
|
|
|
|
|
|
|
|
// Determine limit
|
|
|
|
let limit = r.post_u64("limit")?;
|
|
|
|
let limit = match limit {
|
|
|
|
0 => 1,
|
|
|
|
1..=60 => limit,
|
|
|
|
_ => 60
|
|
|
|
};
|
|
|
|
|
|
|
|
let messages = conversations_helper::get_older_messages(conv_id, max_id, limit)?;
|
|
|
|
|
|
|
|
r.set_response(ConversationMessageAPI::for_list(&messages))
|
|
|
|
}
|
|
|
|
|
2020-06-20 09:55:39 +00:00
|
|
|
/// Send a new message
|
|
|
|
pub fn send_message(r: &mut HttpRequestHandler) -> RequestResult {
|
2020-06-22 10:19:13 +00:00
|
|
|
let conv_id = r.post_conv_id("conversationID")?;
|
|
|
|
let message = r.post_string_without_html("message", 0, false)?;
|
|
|
|
|
|
|
|
// Get image
|
|
|
|
let image_path = match r.has_file("image") {
|
|
|
|
false => None,
|
|
|
|
true => Some(r.save_post_image("image", "conversations", 1200, 1200)?)
|
|
|
|
};
|
2020-06-20 12:06:59 +00:00
|
|
|
|
2020-06-22 10:19:13 +00:00
|
|
|
if image_path == None && message.len() < 3 {
|
|
|
|
r.bad_request("Message is empty!".to_string())?;
|
2020-06-20 12:06:59 +00:00
|
|
|
}
|
|
|
|
|
2020-06-22 10:19:13 +00:00
|
|
|
conversations_helper::send_message(&NewConversationMessage {
|
|
|
|
user_id: r.user_id()?,
|
|
|
|
conv_id,
|
|
|
|
message,
|
|
|
|
image_path,
|
|
|
|
})?;
|
2020-06-20 13:22:41 +00:00
|
|
|
|
2020-06-22 10:19:13 +00:00
|
|
|
r.success("Conversation message was successfully sent!")
|
2020-06-22 12:32:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Count the number of unread conversation of the user
|
|
|
|
pub fn count_unread(r: &mut HttpRequestHandler) -> RequestResult {
|
|
|
|
let num = conversations_helper::count_unread_for_user(r.user_id()?)?;
|
|
|
|
|
|
|
|
r.set_response(ResultCountUnreadConversations::new(num))
|
2020-06-22 12:41:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get the list of unread conversations of a user
|
|
|
|
pub fn list_unread(r: &mut HttpRequestHandler) -> RequestResult {
|
2020-06-22 16:55:24 +00:00
|
|
|
let list = conversations_helper::get_list_unread(r.user_id()?)?;
|
|
|
|
|
|
|
|
r.set_response(UnreadConversationAPI::for_list(&list))
|
2020-06-03 11:36:19 +00:00
|
|
|
}
|