1
0
mirror of https://gitlab.com/comunic/comunicapiv3 synced 2025-09-19 03:18:46 +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

@@ -5,7 +5,7 @@
use std::collections::{HashMap, HashSet};
use crate::data::comment::Comment;
use crate::data::conversation::Conversation;
use crate::data::conversation::{Conversation, ConvID};
use crate::data::conversation_message::ConversationMessage;
use crate::data::error::ResultBoxError;
use crate::data::friend::Friend;
@@ -24,7 +24,7 @@ pub struct AccountExport {
pub survey_responses: Vec<SurveyResponse>,
pub all_conversation_messages: Vec<ConversationMessage>,
pub conversations: Vec<Conversation>,
pub conversation_messages: HashMap<u64, Vec<ConversationMessage>>,
pub conversation_messages: HashMap<ConvID, Vec<ConversationMessage>>,
pub friends_list: Vec<Friend>,
pub groups: Vec<GroupID>,
}
@@ -56,7 +56,7 @@ impl AccountExport {
// Conversation members
for conv in &self.conversations {
conv.members.iter().for_each(|f| { set.insert(f.clone()); });
conv.members_ids().into_iter().for_each(|f| { set.insert(f); });
}
// Conversation messages

View File

@@ -12,7 +12,7 @@ use serde::Serialize;
use crate::api_data::http_error::HttpError;
use crate::constants::PASSWORD_MIN_LENGTH;
use crate::data::comment::Comment;
use crate::data::conversation::ConvID;
use crate::data::conversation::{ConversationMember, ConvID};
use crate::data::custom_emoji::CustomEmoji;
use crate::data::error::{ExecError, Res, ResultBoxError};
use crate::data::group::GroupAccessLevel;
@@ -24,9 +24,10 @@ use crate::helpers::{account_helper, comments_helper, conversations_helper, cust
use crate::helpers::virtual_directory_helper::VirtualDirType;
use crate::routes::RequestResult;
use crate::utils::pdf_utils::is_valid_pdf;
use crate::utils::string_utils::{check_emoji_code, check_string_before_insert, check_url, remove_html_nodes};
use crate::utils::string_utils::{check_emoji_code, check_string_before_insert, check_url, remove_html_nodes, check_html_color};
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 std::collections::HashSet;
#[derive(Serialize)]
struct SuccessMessage {
@@ -239,6 +240,18 @@ pub trait BaseRequestHandler {
}
}
/// Get a string included in the request. If none found, or if string is empty, returns [None]
fn post_string_optional(&mut self, name: &str) -> Option<String> {
match self.post_parameter_opt(name) {
Some(RequestValue::String(s)) => {
if s.is_empty() {
None
} else { Some(s.to_string()) }
}
_ => None
}
}
/// Check out whether a file was included in the request or not
fn has_file(&self, name: &str) -> bool {
self.post_parameter_opt(name)
@@ -420,6 +433,22 @@ pub trait BaseRequestHandler {
Ok(user_id)
}
/// Get a list of users ID included in the request
fn post_users_id(&mut self, name: &str) -> ResultBoxError<HashSet<UserID>> {
let users = self.post_numbers_list(name, 1)?
.iter()
.map(|u| UserID::new(u.clone()))
.collect::<HashSet<UserID>>();
for user in &users {
if !user_helper::exists(user)? {
self.not_found(format!("User {} not found!", user.id()))?;
}
}
Ok(users)
}
/// Get the ID of a friend included in a POST request
///
/// *Note :* This function does not check whether the user exists or not before checking if the
@@ -461,14 +490,14 @@ pub trait BaseRequestHandler {
}
/// Get & return the ID of the conversation included in the POST request
fn post_conv_id(&mut self, name: &str) -> ResultBoxError<ConvID> {
let conv_id = self.post_u64(name)?;
fn post_conv(&mut self, name: &str) -> ResultBoxError<ConversationMember> {
let conv_id = ConvID::new(self.post_u64(name)?);
let membership = self.ok_or_forbidden(
conversations_helper::get_user_membership(&self.user_id()?, conv_id),
&format!("You do not belong to conversation {} !", conv_id.id()),
)?;
if !conversations_helper::does_user_belongs_to(&self.user_id()?, conv_id)? {
self.forbidden(format!("You do not belong to conversation {} !", conv_id))?;
}
Ok(conv_id)
Ok(membership)
}
/// Get the ID
@@ -624,4 +653,20 @@ pub trait BaseRequestHandler {
Ok(info)
}
/// Get a color included in the request
fn post_color_opt(&mut self, field: &str) -> Res<Option<String>> {
let color = self.post_string_optional(field);
match color {
None => Ok(None),
Some(color) => {
if !check_html_color(&color) {
self.bad_request(format!("Invalid color specified in '{}' !", field))?;
}
Ok(Some(color))
}
}
}
}

View File

@@ -2,20 +2,94 @@
//!
//! @author Pierre Hubert
use crate::data::group_id::GroupID;
use crate::data::user::UserID;
pub type ConvID = u64;
#[derive(Copy, Debug, PartialEq, Eq, Clone, Hash)]
pub struct ConvID(u64);
#[derive(Debug, PartialEq, Eq)]
impl ConvID {
pub fn new(id: u64) -> Self {
ConvID(id)
}
pub fn id(&self) -> u64 {
self.0.clone()
}
}
#[derive(Debug)]
pub struct ConversationMember {
pub member_id: u64,
pub conv_id: ConvID,
pub user_id: UserID,
pub added_on: u64,
pub following: bool,
pub is_admin: bool,
pub last_message_seen: u64,
}
#[derive(Debug)]
pub struct Conversation {
pub id: ConvID,
pub owner_id: UserID,
pub name: Option<String>,
pub members: Vec<UserID>,
pub color: Option<String>,
pub background: Option<String>,
pub creation_time: u64,
pub group_id: Option<GroupID>,
pub can_everyone_add_members: bool,
pub last_active: u64,
pub time_create: u64,
pub last_activity: u64,
pub members: Vec<ConversationMember>,
}
pub following: bool,
pub saw_last_message: bool,
impl PartialEq for Conversation {
fn eq(&self, other: &Self) -> bool {
self.id.eq(&other.id)
}
}
impl Eq for Conversation {}
impl Conversation {
/// Get the IDs of the members in the conversation
pub fn members_ids(&self) -> Vec<UserID> {
self.members.iter().map(|m| m.user_id.clone()).collect()
}
/// Check out whether this conversation is managed or not
pub fn is_managed(&self) -> bool {
self.group_id.is_some()
}
/// Check out whether a given user is an admin of a conversation or not
pub fn is_admin(&self, user_id: &UserID) -> bool {
self
.members
.iter()
.any(|m| m.user_id == user_id && m.is_admin)
}
/// 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
.iter()
.filter(|m| m.is_admin)
.collect();
admins.len() == 1 && admins[0].user_id == user_id
}
}
/// Structure used to update the list of members of the conversation
pub struct ConversationMemberSetting {
pub user_id: UserID,
pub set_admin: bool,
}
/// Structure used to update conversation settings
pub struct NewConversationSettings {
pub conv_id: ConvID,
pub color: Option<String>,
pub name: Option<String>,
pub can_everyone_add_members: bool,
}

View File

@@ -6,6 +6,7 @@ use std::collections::HashSet;
use crate::data::error::{ExecError, Res};
use crate::data::user::UserID;
use crate::data::conversation::ConvID;
pub type ConvMessageID = u64;
@@ -101,7 +102,7 @@ impl ConversationServerMessageType {
pub struct ConversationMessage {
pub id: ConvMessageID,
pub time_sent: u64,
pub conv_id: u64,
pub conv_id: ConvID,
pub user_id: Option<UserID>,
pub message: Option<String>,
pub server_message: Option<ConversationServerMessageType>,

View File

@@ -3,11 +3,15 @@
//! @author Pierre Huber
use crate::data::user::UserID;
use crate::data::group_id::GroupID;
#[derive(Debug)]
pub struct NewConversation {
pub owner_id: UserID,
pub name: Option<String>,
pub group_id: Option<GroupID>,
pub color: Option<String>,
pub background: Option<String>,
pub owner_following: bool,
pub members: Vec<UserID>,
pub can_everyone_add_members: bool

View File

@@ -3,11 +3,14 @@
//! @author Pierre Hubert
use crate::data::user::UserID;
use crate::data::conversation::ConvID;
use crate::data::conversation_message::{ConversationMessageFile, ConversationServerMessageType};
/// Information about a new conversation message
pub struct NewConversationMessage {
pub user_id: UserID,
pub conv_id: u64,
pub message: String,
pub image_path: Option<String>
pub user_id: Option<UserID>,
pub conv_id: ConvID,
pub message: Option<String>,
pub file: Option<ConversationMessageFile>,
pub server_message: Option<ConversationServerMessageType>
}

View File

@@ -20,7 +20,7 @@ impl UserMembership {
match self {
UserMembership::Group(_, last_active) => *last_active,
UserMembership::Friend(f) => f.last_activity_time,
UserMembership::Conversation(c) => c.last_active,
UserMembership::Conversation(c) => c.last_activity,
}
}
}