mirror of
				https://gitlab.com/comunic/comunicapiv3
				synced 2025-10-30 23:24:42 +00:00 
			
		
		
		
	Determine access level of a user over a group
This commit is contained in:
		| @@ -11,7 +11,7 @@ pub enum GroupVisibilityLevel { | ||||
| } | ||||
|  | ||||
| #[allow(non_camel_case_types)] | ||||
| #[derive(Eq, PartialEq, Hash)] | ||||
| #[derive(Eq, PartialEq, Hash, Debug)] | ||||
| pub enum GroupAccessLevel { | ||||
|     //Can not even know if the group exists or not | ||||
|     NO_ACCESS = 0, | ||||
|   | ||||
| @@ -5,6 +5,7 @@ | ||||
| use crate::data::user::UserID; | ||||
| use crate::data::group_id::GroupID; | ||||
|  | ||||
| #[derive(PartialEq, Eq)] | ||||
| pub enum GroupMembershipLevel { | ||||
|     ADMINISTRATOR = 0, | ||||
|     MODERATOR = 1, | ||||
|   | ||||
| @@ -465,8 +465,10 @@ impl HttpRequestHandler { | ||||
|     /// Get the ID of a group included in a request with a check for access level of current user | ||||
|     pub fn post_group_id_with_access(&mut self, name: &str, min_level: GroupAccessLevel) -> ResultBoxError<GroupID> { | ||||
|         let group_id = self.post_group_id(name)?; | ||||
|         let access_level = groups_helper::get_access_level(&group_id, self.user_id_opt())?; | ||||
|  | ||||
|         // TODO : add security checks | ||||
|         println!("Curr access level: {:?} / Expected: {:?}", access_level, min_level); | ||||
|  | ||||
|         Ok(group_id) | ||||
|     } | ||||
|   | ||||
| @@ -261,6 +261,16 @@ impl<'a> RowResult<'a> { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn get_u32(&self, name: &str) -> ResultBoxError<u32> { | ||||
|         let value = self.row.get_opt(self.find_col(name)?); | ||||
|  | ||||
|         match value { | ||||
|             None => Err(ExecError::boxed_string( | ||||
|                 format!("Could not extract integer field {} !", name))), | ||||
|             Some(s) => Ok(s?) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// Find an integer included in the request | ||||
|     pub fn get_usize(&self, name: &str) -> Result<usize, Box<dyn Error>> { | ||||
|         let value = self.row.get_opt(self.find_col(name)?); | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  | ||||
| use crate::constants::database_tables_names::{GROUPS_LIST_TABLE, GROUPS_MEMBERS_TABLE}; | ||||
| use crate::data::error::{ExecError, ResultBoxError}; | ||||
| use crate::data::group::GroupVisibilityLevel; | ||||
| 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; | ||||
| @@ -20,6 +20,15 @@ impl GroupVisibilityLevel { | ||||
|             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 { | ||||
| @@ -33,6 +42,18 @@ impl GroupMembershipLevel { | ||||
|             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 | ||||
| @@ -106,4 +127,70 @@ pub fn search_group(query: &str, limit: u64) -> ResultBoxError<Vec<GroupID>> { | ||||
|         .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<UserID>) -> ResultBoxError<GroupMembershipLevel> { | ||||
|     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<GroupVisibilityLevel> { | ||||
|     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<UserID>) -> ResultBoxError<GroupAccessLevel> { | ||||
|     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) | ||||
| } | ||||
		Reference in New Issue
	
	Block a user