1
0
mirror of https://gitlab.com/comunic/comunicapiv3 synced 2024-11-26 15:29:21 +00:00

Determine access level of a user over a group

This commit is contained in:
Pierre HUBERT 2020-06-24 14:08:46 +02:00
parent 4d844ccbad
commit b89a319cfb
5 changed files with 102 additions and 2 deletions

View File

@ -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,

View File

@ -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,

View File

@ -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)
}

View File

@ -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)?);

View File

@ -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)
}