From 926892a29b95d52b706dcdeac4f3825ad45541b7 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Sat, 27 Jun 2020 18:28:38 +0200 Subject: [PATCH] Can delete group members --- src/controllers/groups_controller.rs | 24 +++++++++++++++++++++++- src/data/group_member.rs | 28 +++++++++++++++++++++++----- src/helpers/groups_helper.rs | 14 ++++++++++++++ 3 files changed, 60 insertions(+), 6 deletions(-) diff --git a/src/controllers/groups_controller.rs b/src/controllers/groups_controller.rs index c928e72..3e1128f 100644 --- a/src/controllers/groups_controller.rs +++ b/src/controllers/groups_controller.rs @@ -245,5 +245,27 @@ pub fn cancel_request(r: &mut HttpRequestHandler) -> RequestResult { /// Remove a member from a group (as a moderator or an admin) pub fn delete_member(r: &mut HttpRequestHandler) -> RequestResult { - r.success("Implement me") + let group_id = r.post_group_id_with_access("groupID", GroupAccessLevel::MODERATOR_ACCESS)?; + + // Get the membership of the user making the request + let curr_user_membership = groups_helper::get_membership(&group_id, r.user_id_opt())?; + + // Get information about the member to delete + let user_id = r.post_user_id("userID")?; + let membership = groups_helper::get_membership(&group_id, Some(user_id.clone()))?; + + if user_id == r.user_id()? && groups_helper::is_last_admin(&group_id, &r.user_id()?)? { + r.forbidden("You are the last administrator of this group!".to_string())?; + } + + // Only administrator can delete members that are more than members (moderators & administrators) + if membership.level < GroupMembershipLevel::MEMBER && curr_user_membership.level != GroupMembershipLevel::ADMINISTRATOR { + r.forbidden("Only administrators can delete this membership!".to_string())?; + } + + groups_helper::delete_member(&group_id, &user_id)?; + + // TODO : Delete related notifications + + r.success("Membership of the user has been successfully deleted!") } \ No newline at end of file diff --git a/src/data/group_member.rs b/src/data/group_member.rs index bc617d0..6e86abd 100644 --- a/src/data/group_member.rs +++ b/src/data/group_member.rs @@ -2,17 +2,21 @@ //! //! @author Pierre Hubert -use crate::data::user::UserID; use crate::data::group_id::GroupID; +use crate::data::user::UserID; -#[derive(PartialEq, Eq)] +#[derive(PartialEq, Eq, PartialOrd)] pub enum GroupMembershipLevel { ADMINISTRATOR = 0, MODERATOR = 1, MEMBER = 2, INVITED = 3, - PENDING = 4, //When the group membership has not been approved yet - VISITOR = 5, //Simple visit + + // When the group membership has not been approved yet + PENDING = 4, + + // Simple visit + VISITOR = 5, } impl GroupMembershipLevel { @@ -34,5 +38,19 @@ pub struct GroupMember { pub group_id: GroupID, pub time_create: u64, pub level: GroupMembershipLevel, - pub following: bool + pub following: bool, +} + +#[cfg(test)] +mod tests { + use crate::data::group_member::GroupMembershipLevel; + + #[test] + fn membership_level_coherence() { + assert!(GroupMembershipLevel::ADMINISTRATOR < GroupMembershipLevel::MODERATOR); + assert!(GroupMembershipLevel::MODERATOR < GroupMembershipLevel::MEMBER); + assert!(GroupMembershipLevel::MEMBER < GroupMembershipLevel::INVITED); + assert!(GroupMembershipLevel::INVITED < GroupMembershipLevel::PENDING); + assert!(GroupMembershipLevel::PENDING < GroupMembershipLevel::VISITOR); + } } \ No newline at end of file diff --git a/src/helpers/groups_helper.rs b/src/helpers/groups_helper.rs index bdff711..00105e6 100644 --- a/src/helpers/groups_helper.rs +++ b/src/helpers/groups_helper.rs @@ -297,6 +297,20 @@ pub fn count_members(group_id: &GroupID) -> ResultBoxError { .exec_count() } +/// Count the number of group's members at a specific level +pub fn count_members_at_level(group_id: &GroupID, level: GroupMembershipLevel) -> ResultBoxError { + database::QueryInfo::new(GROUPS_MEMBERS_TABLE) + .cond_group_id("groups_id", group_id) + .cond_u32("level", level.to_db()) + .exec_count() +} + +/// Check out whether a user is the last administrator of a group +pub fn is_last_admin(group_id: &GroupID, user_id: &UserID) -> ResultBoxError { + Ok(get_membership_level(group_id, Some(user_id.clone()))? == GroupMembershipLevel::ADMINISTRATOR && + count_members_at_level(&group_id, GroupMembershipLevel::ADMINISTRATOR)? == 1) +} + /// Check the availability of a virtual directory for a group pub fn check_directory_availability(dir: &str, group_id: Option) -> ResultBoxError { let group = find_by_virtual_directory(dir);