//! # Groups helper //! //! @author Pierre Hubert use crate::constants::database_tables_names::{GROUPS_LIST_TABLE, GROUPS_MEMBERS_TABLE}; use crate::data::error::{ExecError, ResultBoxError}; use crate::data::group::{GroupAccessLevel, GroupVisibilityLevel}; use crate::data::group_id::GroupID; use crate::data::group_member::{GroupMember, GroupMembershipLevel}; use crate::data::new_group::NewGroup; use crate::data::user::UserID; use crate::helpers::database; use crate::utils::date_utils::time; impl GroupVisibilityLevel { pub fn to_db(&self) -> u64 { match self { GroupVisibilityLevel::OPEN_GROUP => 0, GroupVisibilityLevel::PRIVATE_GROUP => 1, GroupVisibilityLevel::SECRETE_GROUP => 2, } } pub fn from_db(level: u32) -> GroupVisibilityLevel { match level { 0 => GroupVisibilityLevel::OPEN_GROUP, 1 => GroupVisibilityLevel::PRIVATE_GROUP, 2 => GroupVisibilityLevel::SECRETE_GROUP, _ => GroupVisibilityLevel::SECRETE_GROUP } } } impl GroupMembershipLevel { pub fn to_db(&self) -> u32 { match self { GroupMembershipLevel::ADMINISTRATOR => 0, GroupMembershipLevel::MODERATOR => 1, GroupMembershipLevel::MEMBER => 2, GroupMembershipLevel::INVITED => 3, GroupMembershipLevel::PENDING => 4, GroupMembershipLevel::VISITOR => 5, } } pub fn from_db(level: u32) -> GroupMembershipLevel { match level { 0 => GroupMembershipLevel::ADMINISTRATOR, 1 => GroupMembershipLevel::MODERATOR, 2 => GroupMembershipLevel::MEMBER, 3 => GroupMembershipLevel::INVITED, 4 => GroupMembershipLevel::PENDING, 5 => GroupMembershipLevel::VISITOR, _ => GroupMembershipLevel::VISITOR } } } /// Create a new group. Returns the ID of the new group pub fn create(group: &NewGroup) -> ResultBoxError { // First, create the group let group_id = database::InsertQuery::new(GROUPS_LIST_TABLE) .add_u64("time_create", time()) .add_user_id("userid_create", group.owner_id) .add_str("name", &group.name) .insert()?.ok_or(ExecError::new("Could not get group ID!"))?; let group_id = GroupID::new(group_id); // Insert first member insert_member(&GroupMember { id: 0, user_id: group.owner_id, group_id: group_id.clone(), time_create: time(), level: GroupMembershipLevel::ADMINISTRATOR, following: true, })?; Ok(group_id) } /// Insert a new group into the database pub fn insert_member(m: &GroupMember) -> ResultBoxError<()> { database::InsertQuery::new(GROUPS_MEMBERS_TABLE) .add_group_id("groups_id", &m.group_id) .add_user_id("user_id", m.user_id) .add_u64("time_create", m.time_create) .add_u32("level", m.level.to_db()) .insert_drop_result() } /// Get the list of groups of a user pub fn get_list_user(user_id: UserID, only_followed: bool) -> ResultBoxError> { let mut query = database::QueryInfo::new(GROUPS_MEMBERS_TABLE) .add_field("groups_id") .cond_user_id("user_id", user_id); if only_followed { query = query.cond_legacy_bool("following", true); } query.exec(|row| row.get_group_id("groups_id")) } /// Check out whether a group exists or not pub fn exists(group_id: &GroupID) -> ResultBoxError { database::QueryInfo::new(GROUPS_LIST_TABLE) .cond_group_id("id", group_id) .exec_count() .map(|m| m > 0) } /// Find a group id by virtual directory pub fn find_by_virtual_directory(dir: &str) -> ResultBoxError { database::QueryInfo::new(GROUPS_LIST_TABLE) .cond("virtual_directory", dir) .add_field("id") .query_row(|res| res.get_group_id("id")) } /// Search for group pub fn search_group(query: &str, limit: u64) -> ResultBoxError> { database::QueryInfo::new(GROUPS_LIST_TABLE) .set_custom_where("name LIKE ? AND visibility != ?") .add_custom_where_argument_str(format!("%{}%", query).as_str()) .add_custom_where_argument_u64(GroupVisibilityLevel::SECRETE_GROUP.to_db()) .set_limit(limit) .add_field("id") .exec(|row| row.get_group_id("id")) } /// Get the membership level of a user for a group pub fn get_membership_level(group_id: &GroupID, user_id: Option) -> ResultBoxError { match user_id { None => Ok(GroupMembershipLevel::VISITOR), Some(user_id) => { let level = database::QueryInfo::new(GROUPS_MEMBERS_TABLE) .cond_group_id("groups_id", group_id) .cond_user_id("user_id", user_id) .add_field("level") .query_row(|f| f.get_u32("level")) .unwrap_or(GroupMembershipLevel::VISITOR.to_db()); Ok(GroupMembershipLevel::from_db(level)) } } } /// Get the visibility level of a group pub fn get_visibility(group_id: &GroupID) -> ResultBoxError { let result = database::QueryInfo::new(GROUPS_LIST_TABLE) .cond_group_id("id", group_id) .add_field("visibility") .query_row(|f| f.get_u32("visibility"))?; Ok(GroupVisibilityLevel::from_db(result)) } /// Get the current access level of a user over a group pub fn get_access_level(group_id: &GroupID, user_id: Option) -> ResultBoxError { let membership_level = get_membership_level(group_id, user_id)?; // Check if the user is a confirmed member of group if membership_level == GroupMembershipLevel::ADMINISTRATOR { return Ok(GroupAccessLevel::ADMIN_ACCESS); } if membership_level == GroupMembershipLevel::MODERATOR { return Ok(GroupAccessLevel::MODERATOR_ACCESS); } if membership_level == GroupMembershipLevel::MEMBER { return Ok(GroupAccessLevel::MEMBER_ACCESS); } let visibility_level = get_visibility(group_id)?; //If the group is open, everyone has view access if visibility_level == GroupVisibilityLevel::OPEN_GROUP { return Ok(GroupAccessLevel::VIEW_ACCESS); } //Else, all pending and invited membership get limited access if membership_level == GroupMembershipLevel::PENDING || membership_level == GroupMembershipLevel::INVITED { return Ok(GroupAccessLevel::LIMITED_ACCESS); } //Private groups gives limited access if visibility_level == GroupVisibilityLevel::PRIVATE_GROUP { return Ok(GroupAccessLevel::LIMITED_ACCESS); } // Else the user can not see the group // Especially in the case of secrete group Ok(GroupAccessLevel::NO_ACCESS) }