diff --git a/src/controllers/conversations_controller.rs b/src/controllers/conversations_controller.rs index ad7cfa2..221def8 100644 --- a/src/controllers/conversations_controller.rs +++ b/src/controllers/conversations_controller.rs @@ -135,7 +135,7 @@ pub fn add_member(r: &mut HttpRequestHandler) -> RequestResult { } if conv.get_membership(&user_to_add).is_some() { - r.bad_request("This user is already a member of this group!".to_string())?; + r.bad_request("This user is already a member of this conversation!".to_string())?; } conversations_helper::add_member(conv.id, &user_to_add, true, false, r.user_id_ref()?)?; @@ -143,6 +143,30 @@ pub fn add_member(r: &mut HttpRequestHandler) -> RequestResult { r.success("The user was added to the conversation!") } +/// Remove a member from a conversation +pub fn remove_member(r: &mut HttpRequestHandler) -> RequestResult { + let conv_membership = r.post_conv("convID")?; + let conv = conversations_helper::get_single(conv_membership.conv_id)?; + + let user_to_add = r.post_user_id("userID")?; + + if conv.is_managed() { + r.bad_request("This conversation is managed, you can not manually change its members!".to_string())?; + } + + if !conv.can_user_remove_members(r.user_id_ref()?) { + r.forbidden("You are not allowed to remove members from this conversation!".to_string())?; + } + + if conv.get_membership(&user_to_add).is_none() { + r.bad_request("This user is not a member of this conversation!".to_string())?; + } + + conversations_helper::remove_member(&user_to_add, conv.id, r.user_id_ref()?)?; + + r.ok() +} + /// Find a private conversation pub fn find_private(r: &mut HttpRequestHandler) -> RequestResult { let other_user = r.post_user_id("otherUser")?; diff --git a/src/data/base_request_handler.rs b/src/data/base_request_handler.rs index ea3f732..45dd43c 100644 --- a/src/data/base_request_handler.rs +++ b/src/data/base_request_handler.rs @@ -5,6 +5,7 @@ use std::collections::HashSet; use std::error::Error; +use std::str::from_utf8; use exif::In; use image::{GenericImageView, ImageFormat}; @@ -31,7 +32,6 @@ use crate::utils::string_utils::{check_emoji_code, check_html_color, check_strin use crate::utils::user_data_utils::{generate_new_user_data_file_name, prepare_file_creation, user_data_path}; use crate::utils::virtual_directories_utils; use crate::utils::zip_utils::is_valid_zip; -use std::str::from_utf8; #[derive(Serialize)] struct SuccessMessage { @@ -80,6 +80,13 @@ pub trait BaseRequestHandler { }) } + /// Success without message + fn ok(&mut self) -> RequestResult { + self.set_response(SuccessMessage { + success: "OK.".to_string() + }) + } + /// Internal error response (500) fn internal_error(&mut self, error: Box) -> RequestResult { self.set_error(HttpError::internal_error("Internal server error.")); diff --git a/src/data/conversation.rs b/src/data/conversation.rs index ba717ef..a6997d9 100644 --- a/src/data/conversation.rs +++ b/src/data/conversation.rs @@ -75,6 +75,11 @@ impl Conversation { !self.is_managed() && (self.is_admin(user_id) || self.can_everyone_add_members) } + /// Check out whether a user can remove members from a conversation or not + pub fn can_user_remove_members(&self, user_id: &UserID) -> bool { + !self.is_managed() && self.is_admin(user_id) + } + /// Check out whether a user is the last administrator of a conversation or not pub fn is_last_admin(&self, user_id: &UserID) -> bool { let admins: Vec<&ConversationMember> = self.members diff --git a/src/routes.rs b/src/routes.rs index c6f583a..c731d06 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -195,6 +195,7 @@ pub fn get_routes() -> Vec { Route::post("/conversations/get_single", Box::new(conversations_controller::get_single)), Route::post("/conversations/updateSettings", Box::new(conversations_controller::update_settings)), Route::post("/conversations/addMember", Box::new(conversations_controller::add_member)), + Route::post("/conversations/removeMember", Box::new(conversations_controller::remove_member)), Route::post("/conversations/getPrivate", Box::new(conversations_controller::find_private)), Route::post("/conversations/refresh_single", Box::new(conversations_controller::refresh_single)), Route::post("/conversations/get_older_messages", Box::new(conversations_controller::get_older_messages)),