2020-06-23 17:04:32 +00:00
|
|
|
//! # Groups controller
|
|
|
|
//!
|
|
|
|
//! @author Pierre Hubert
|
|
|
|
|
2020-06-25 07:26:58 +00:00
|
|
|
use std::collections::HashMap;
|
|
|
|
|
2020-06-25 11:45:21 +00:00
|
|
|
use crate::api_data::advanced_group_api::AdvancedGroupApi;
|
2020-06-25 07:26:58 +00:00
|
|
|
use crate::api_data::group_api::GroupApi;
|
2020-06-27 05:23:38 +00:00
|
|
|
use crate::api_data::group_member_api::GroupMemberAPI;
|
2020-06-26 08:35:54 +00:00
|
|
|
use crate::api_data::res_change_group_logo::ResChangeGroupLogo;
|
2020-06-24 07:08:31 +00:00
|
|
|
use crate::api_data::res_create_group::GroupCreationResult;
|
2020-06-26 08:53:05 +00:00
|
|
|
use crate::constants::{DEFAULT_GROUP_LOGO, PATH_GROUPS_LOGOS};
|
2020-06-23 17:04:32 +00:00
|
|
|
use crate::controllers::routes::RequestResult;
|
2020-06-26 06:58:00 +00:00
|
|
|
use crate::data::group::{Group, GroupAccessLevel, GroupPostsCreationLevel, GroupRegistrationLevel, GroupVisibilityLevel};
|
2020-06-25 07:26:58 +00:00
|
|
|
use crate::data::group_id::GroupID;
|
2020-06-27 12:37:49 +00:00
|
|
|
use crate::data::group_member::{GroupMember, GroupMembershipLevel};
|
2020-06-23 17:04:32 +00:00
|
|
|
use crate::data::http_request_handler::HttpRequestHandler;
|
2020-06-24 07:08:31 +00:00
|
|
|
use crate::data::new_group::NewGroup;
|
2020-06-26 07:52:19 +00:00
|
|
|
use crate::helpers::{groups_helper, virtual_directory_helper};
|
2020-06-26 06:58:00 +00:00
|
|
|
use crate::helpers::virtual_directory_helper::VirtualDirType;
|
2020-06-27 12:37:49 +00:00
|
|
|
use crate::utils::date_utils::time;
|
2020-06-23 17:04:32 +00:00
|
|
|
|
|
|
|
/// Create a new group
|
|
|
|
pub fn create(r: &mut HttpRequestHandler) -> RequestResult {
|
2020-06-24 07:08:31 +00:00
|
|
|
let new_group = NewGroup {
|
|
|
|
name: r.post_string_opt("name", 3, true)?,
|
|
|
|
owner_id: r.user_id()?,
|
|
|
|
};
|
|
|
|
|
|
|
|
let group_id = groups_helper::create(&new_group)?;
|
|
|
|
|
|
|
|
r.set_response(GroupCreationResult::new(&group_id))
|
2020-06-24 07:21:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get the list of groups of the current user
|
|
|
|
pub fn get_list_user(r: &mut HttpRequestHandler) -> RequestResult {
|
|
|
|
let list = groups_helper::get_list_user(r.user_id()?, false)?
|
|
|
|
.iter()
|
|
|
|
.map(|f| f.id())
|
|
|
|
.collect::<Vec<u64>>();
|
|
|
|
|
|
|
|
r.set_response(list)
|
2020-06-24 11:34:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get information about a single group
|
|
|
|
pub fn get_info_single(r: &mut HttpRequestHandler) -> RequestResult {
|
|
|
|
let group_id = r.post_group_id_with_access("id", GroupAccessLevel::LIMITED_ACCESS)?;
|
2020-06-24 16:23:44 +00:00
|
|
|
let group = groups_helper::get_info(&group_id)?;
|
2020-06-24 11:34:09 +00:00
|
|
|
|
2020-06-25 06:16:20 +00:00
|
|
|
r.set_response(GroupApi::new(&group, r.user_id_opt())?)
|
2020-06-25 07:26:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get information about multiple users
|
|
|
|
pub fn get_info_multiple(r: &mut HttpRequestHandler) -> RequestResult {
|
|
|
|
let groups_id = r.post_numbers_list("list", 1)?;
|
|
|
|
|
|
|
|
let mut list = HashMap::new();
|
|
|
|
|
|
|
|
for id in groups_id {
|
|
|
|
let id = GroupID::new(id as u64);
|
|
|
|
|
|
|
|
if !groups_helper::exists(&id)? ||
|
|
|
|
groups_helper::get_access_level(&id, r.user_id_opt())? < GroupAccessLevel::LIMITED_ACCESS {
|
|
|
|
r.not_found(format!("Group {} not found!", id.id()))?;
|
|
|
|
}
|
|
|
|
|
|
|
|
let group = groups_helper::get_info(&id)?;
|
|
|
|
|
|
|
|
list.insert(id.id().to_string(), GroupApi::new(&group, r.user_id_opt())?);
|
|
|
|
}
|
|
|
|
|
|
|
|
r.set_response(list)
|
2020-06-25 11:39:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get advanced information about a user
|
|
|
|
pub fn get_advanced_info(r: &mut HttpRequestHandler) -> RequestResult {
|
|
|
|
let group_id = r.post_group_id_with_access("id", GroupAccessLevel::VIEW_ACCESS)?;
|
|
|
|
let group = groups_helper::get_info(&group_id)?;
|
|
|
|
|
|
|
|
r.set_response(AdvancedGroupApi::new(&group, r.user_id_opt())?)
|
2020-06-25 11:45:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get the settings of the group
|
|
|
|
pub fn get_settings(r: &mut HttpRequestHandler) -> RequestResult {
|
2020-06-25 15:52:52 +00:00
|
|
|
let group_id = r.post_group_id_with_access("id", GroupAccessLevel::ADMIN_ACCESS)?;
|
|
|
|
let group = groups_helper::get_info(&group_id)?;
|
|
|
|
|
|
|
|
// For now, this method is the same as the get advanced info method,
|
|
|
|
// but this might change in the future...
|
|
|
|
r.set_response(AdvancedGroupApi::new(&group, r.user_id_opt())?)
|
2020-06-25 15:55:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Set new settings to the group
|
|
|
|
pub fn set_settings(r: &mut HttpRequestHandler) -> RequestResult {
|
2020-06-26 06:58:00 +00:00
|
|
|
let group_id = r.post_group_id_with_access("id", GroupAccessLevel::ADMIN_ACCESS)?;
|
|
|
|
|
|
|
|
let new_settings = Group {
|
|
|
|
id: group_id.clone(),
|
|
|
|
name: r.post_string_without_html("name", 3, true)?,
|
|
|
|
visibility: GroupVisibilityLevel::from_api(&r.post_string("visibility")?),
|
|
|
|
registration_level: GroupRegistrationLevel::from_api(&r.post_string("registration_level")?),
|
|
|
|
posts_creation_level: GroupPostsCreationLevel::from_api(&r.post_string("posts_level")?),
|
|
|
|
logo: None,
|
|
|
|
virtual_directory: r.post_checked_virtual_directory_opt("virtual_directory", group_id.id(), VirtualDirType::GROUP)?,
|
|
|
|
time_create: 0,
|
|
|
|
description: r.post_string_without_html_opt("description", 0)?,
|
|
|
|
url: r.post_url_opt("url", false)?,
|
|
|
|
};
|
|
|
|
|
2020-06-26 07:27:32 +00:00
|
|
|
groups_helper::set_settings(&new_settings)?;
|
2020-06-26 06:58:00 +00:00
|
|
|
|
2020-06-26 07:27:32 +00:00
|
|
|
r.success("Group settings have been successfully updated!")
|
2020-06-26 07:52:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Check out whether a virtual directory is available for a group or not
|
|
|
|
pub fn check_virtual_dir(r: &mut HttpRequestHandler) -> RequestResult {
|
|
|
|
let group_id = r.post_group_id_with_access("groupID", GroupAccessLevel::ADMIN_ACCESS)?;
|
|
|
|
let dir = r.post_virtual_directory("directory")?;
|
|
|
|
|
|
|
|
if !virtual_directory_helper::check_availability(&dir, group_id.id(), VirtualDirType::GROUP)? {
|
|
|
|
r.forbidden("The requested virtual directory seems not to be available!".to_string())?;
|
|
|
|
}
|
|
|
|
|
|
|
|
r.success("Requested virtual directory seems to be available!")
|
2020-06-26 07:55:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Change a group's logo
|
|
|
|
pub fn upload_logo(r: &mut HttpRequestHandler) -> RequestResult {
|
2020-06-26 08:53:05 +00:00
|
|
|
let group_id = r.post_group_id_with_access("id", GroupAccessLevel::ADMIN_ACCESS)?;
|
|
|
|
|
|
|
|
if !r.has_file("logo") {
|
|
|
|
r.bad_request("Did not receive logo!".to_string())?;
|
|
|
|
}
|
|
|
|
|
|
|
|
groups_helper::delete_logo(&group_id)?;
|
|
|
|
|
|
|
|
let logo_path = r.save_post_image("logo", PATH_GROUPS_LOGOS, 500, 500)?;
|
|
|
|
|
|
|
|
groups_helper::set_logo_path(&group_id, Some(logo_path.clone()))?;
|
|
|
|
|
|
|
|
r.set_response(ResChangeGroupLogo::new(&logo_path))
|
2020-06-26 08:35:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Delete a group's logo
|
|
|
|
pub fn delete_logo(r: &mut HttpRequestHandler) -> RequestResult {
|
2020-06-26 08:41:14 +00:00
|
|
|
let group_id = r.post_group_id_with_access("id", GroupAccessLevel::ADMIN_ACCESS)?;
|
2020-06-26 08:35:54 +00:00
|
|
|
|
|
|
|
groups_helper::delete_logo(&group_id)?;
|
|
|
|
|
|
|
|
r.set_response(ResChangeGroupLogo::new(DEFAULT_GROUP_LOGO))
|
2020-06-26 09:00:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get the list of members of a group
|
|
|
|
pub fn get_members(r: &mut HttpRequestHandler) -> RequestResult {
|
2020-06-27 05:23:38 +00:00
|
|
|
let group_id = r.post_group_id_with_access("id", GroupAccessLevel::MODERATOR_ACCESS)?;
|
|
|
|
|
|
|
|
let members = groups_helper::get_list_members(&group_id)?;
|
|
|
|
|
|
|
|
r.set_response(GroupMemberAPI::for_list(&members))
|
2020-06-27 05:29:23 +00:00
|
|
|
}
|
|
|
|
|
2020-06-29 06:46:57 +00:00
|
|
|
/// Cancel an invitation sent to a user
|
|
|
|
pub fn cancel_invitation(r: &mut HttpRequestHandler) -> RequestResult {
|
|
|
|
let group_id = r.post_group_id_with_access("groupID", GroupAccessLevel::MODERATOR_ACCESS)?;
|
|
|
|
let user_id = r.post_user_id("userID")?;
|
|
|
|
|
|
|
|
if groups_helper::get_membership_level(&group_id, Some(user_id.clone()))? != GroupMembershipLevel::INVITED {
|
|
|
|
r.forbidden("This user has not been invited to join this group!".to_string())?;
|
|
|
|
}
|
|
|
|
|
|
|
|
groups_helper::delete_member(&group_id, &user_id)?;
|
|
|
|
|
|
|
|
// TODO : delete related notifications
|
|
|
|
|
|
|
|
r.success("Membership invitation has been cancelled!")
|
|
|
|
}
|
|
|
|
|
2020-06-27 05:29:23 +00:00
|
|
|
/// Invite a user to join a group
|
|
|
|
pub fn invite_user(r: &mut HttpRequestHandler) -> RequestResult {
|
2020-06-27 10:56:03 +00:00
|
|
|
let group_id = r.post_group_id_with_access("group_id", GroupAccessLevel::MODERATOR_ACCESS)?;
|
|
|
|
let user_id = r.post_user_id("userID")?;
|
|
|
|
|
|
|
|
if groups_helper::get_membership_level(&group_id, Some(user_id.clone()))? != GroupMembershipLevel::VISITOR {
|
|
|
|
r.bad_request("The user is not a visitor of the group!".to_string())?;
|
|
|
|
}
|
|
|
|
|
|
|
|
groups_helper::send_invitation(&group_id, &user_id)?;
|
|
|
|
|
|
|
|
// TODO : send a notification
|
|
|
|
|
|
|
|
r.success("The user has been successfully invited to join the group!")
|
2020-06-27 11:19:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Respond to a user invitation
|
|
|
|
pub fn respond_invitation(r: &mut HttpRequestHandler) -> RequestResult {
|
|
|
|
let group_id = r.post_group_id_with_access("id", GroupAccessLevel::LIMITED_ACCESS)?;
|
|
|
|
let accept = r.post_bool("accept")?;
|
|
|
|
|
|
|
|
if !groups_helper::received_invitation(&group_id, &r.user_id()?)? {
|
|
|
|
r.not_found("Invitation not found!".to_string())?
|
|
|
|
}
|
|
|
|
|
|
|
|
groups_helper::respond_invitation(&group_id, &r.user_id()?, accept)?;
|
|
|
|
|
|
|
|
if accept {
|
|
|
|
groups_helper::set_following(&group_id, &r.user_id()?, true)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO : Create a notification
|
|
|
|
|
|
|
|
r.success("Response to the invitation was successfully saved!")
|
2020-06-27 12:37:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Send a request to join a group
|
|
|
|
pub fn send_request(r: &mut HttpRequestHandler) -> RequestResult {
|
|
|
|
let group_id = r.post_group_id_with_access("id", GroupAccessLevel::LIMITED_ACCESS)?;
|
|
|
|
|
|
|
|
if groups_helper::get_membership_level(&group_id, r.user_id_opt())? != GroupMembershipLevel::VISITOR {
|
|
|
|
r.forbidden("You are not currently a visitor of the group!".to_string())?;
|
|
|
|
}
|
|
|
|
|
|
|
|
let group = groups_helper::get_info(&group_id)?;
|
|
|
|
|
|
|
|
let level = match group.registration_level {
|
|
|
|
GroupRegistrationLevel::OPEN_REGISTRATION => GroupMembershipLevel::MEMBER,
|
|
|
|
GroupRegistrationLevel::MODERATED_REGISTRATION => GroupMembershipLevel::PENDING,
|
|
|
|
GroupRegistrationLevel::CLOSED_REGISTRATION => {
|
|
|
|
r.forbidden("You are not authorized to send a registration request for this group!".to_string())?;
|
|
|
|
unreachable!();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
groups_helper::insert_member(&GroupMember {
|
|
|
|
id: 0,
|
|
|
|
user_id: r.user_id()?,
|
|
|
|
group_id,
|
|
|
|
time_create: time(),
|
|
|
|
level,
|
|
|
|
following: true,
|
|
|
|
})?;
|
|
|
|
|
|
|
|
// TODO : Send a notification, if required
|
|
|
|
|
|
|
|
r.success("The membership has been successfully saved!")
|
2020-06-27 12:50:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Cancel a group membership request
|
|
|
|
pub fn cancel_request(r: &mut HttpRequestHandler) -> RequestResult {
|
|
|
|
let group_id = r.post_group_id_with_access("id", GroupAccessLevel::LIMITED_ACCESS)?;
|
|
|
|
|
|
|
|
if groups_helper::get_membership_level(&group_id, r.user_id_opt())? != GroupMembershipLevel::PENDING {
|
|
|
|
r.forbidden("You did not send a membership request to this group!".to_string())?;
|
|
|
|
}
|
|
|
|
|
|
|
|
groups_helper::delete_member(&group_id, &r.user_id()?)?;
|
|
|
|
|
|
|
|
// TODO : delete any related notification
|
|
|
|
|
|
|
|
r.success("The request has been successfully cancelled!")
|
2020-06-27 16:06:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Remove a member from a group (as a moderator or an admin)
|
|
|
|
pub fn delete_member(r: &mut HttpRequestHandler) -> RequestResult {
|
2020-06-27 16:28:38 +00:00
|
|
|
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!")
|
2020-06-27 16:36:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Update a user's membership
|
|
|
|
pub fn update_membership(r: &mut HttpRequestHandler) -> RequestResult {
|
2020-06-29 06:17:51 +00:00
|
|
|
let group_id = r.post_group_id_with_access("groupID", GroupAccessLevel::ADMIN_ACCESS)?;
|
|
|
|
let user_id = r.post_user_id("userID")?;
|
|
|
|
|
|
|
|
if user_id == r.user_id()? {
|
|
|
|
r.bad_request("You can not update your own membership!".to_string())?;
|
|
|
|
}
|
|
|
|
|
|
|
|
let level = groups_helper::get_membership_level(&group_id, Some(user_id.clone()))?;
|
|
|
|
|
|
|
|
if level > GroupMembershipLevel::MEMBER {
|
|
|
|
r.forbidden("This user is not a member of the group!".to_string())?;
|
|
|
|
}
|
|
|
|
|
|
|
|
let new_level = GroupMembershipLevel::from_api(&r.post_string("level")?);
|
|
|
|
|
|
|
|
if new_level > GroupMembershipLevel::MEMBER {
|
|
|
|
r.forbidden("You can not assign this visibility level!".to_string())?;
|
|
|
|
}
|
|
|
|
|
|
|
|
groups_helper::update_membership_level(&group_id, &user_id, new_level)?;
|
|
|
|
|
|
|
|
r.success("User membership has been successfully updated!")
|
2020-06-29 06:31:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Respond to a group membership request
|
|
|
|
pub fn respond_request(r: &mut HttpRequestHandler) -> RequestResult {
|
|
|
|
let group_id = r.post_group_id_with_access("groupID", GroupAccessLevel::MODERATOR_ACCESS)?;
|
|
|
|
let user_id = r.post_user_id("userID")?;
|
|
|
|
let accept = r.post_bool("accept")?;
|
|
|
|
|
|
|
|
if groups_helper::get_membership_level(&group_id, Some(user_id.clone()))? != GroupMembershipLevel::PENDING {
|
|
|
|
r.forbidden("This user has not requested a membership for this group!".to_string())?;
|
|
|
|
}
|
|
|
|
|
|
|
|
groups_helper::respond_request(&group_id, &user_id, accept)?;
|
|
|
|
|
|
|
|
// TODO : Create a notification
|
|
|
|
|
|
|
|
r.success("The response to the request has been successfully saved!")
|
2020-06-29 06:39:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get information about a single user membership over a group
|
|
|
|
pub fn get_membership(r: &mut HttpRequestHandler) -> RequestResult {
|
|
|
|
let group_id = r.post_group_id_with_access("groupID", GroupAccessLevel::MODERATOR_ACCESS)?;
|
|
|
|
let user_id = r.post_user_id("userID")?;
|
|
|
|
|
|
|
|
let membership = groups_helper::get_membership(&group_id, Some(user_id))?;
|
|
|
|
|
|
|
|
r.set_response(GroupMemberAPI::new(&membership))
|
2020-06-23 17:04:32 +00:00
|
|
|
}
|