From 796a325590f0bbf0cd84c84de5f484cbe5b5cf14 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Wed, 4 Jul 2018 17:28:29 +0200 Subject: [PATCH] Upgraded groups visibility system. --- RestControllers/GroupsController.php | 44 +++--------- classes/components/GroupsComponent.php | 92 +++++++++++++++++++++++++- classes/models/GroupInfo.php | 16 ++++- functions/requests.php | 28 +++++++- 4 files changed, 144 insertions(+), 36 deletions(-) diff --git a/RestControllers/GroupsController.php b/RestControllers/GroupsController.php index 5590f2b..8ff00d4 100644 --- a/RestControllers/GroupsController.php +++ b/RestControllers/GroupsController.php @@ -11,11 +11,11 @@ class GroupsController { * API groups membership levels */ const GROUPS_MEMBERSHIP_LEVELS = array( - 0 => "administrator", - 1 => "moderator", - 2 => "member", - 3 => "pending", - 4 => "visitor" + GroupInfo::ADMINISTRATOR => "administrator", + GroupInfo::MODERATOR => "moderator", + GroupInfo::MEMBER => "member", + GroupInfo::PENDING => "pending", + GroupInfo::VISITOR => "visitor" ); /** @@ -68,7 +68,7 @@ class GroupsController { public function getInfo(){ //Get the ID of the requested group - $id = getPostGroupId("id"); + $groupID = getPostGroupIdWithAccess("id", GroupInfo::LIMITED_ACCESS); //Get information about the group $group = components()->groups->get_info($id); @@ -89,7 +89,7 @@ class GroupsController { public function getAdvancedInfo(){ //Get the ID of the requested group - $id = getPostGroupId("id"); + $groupID = getPostGroupIdWithAccess("id", GroupInfo::VIEW_ACCESS); //Get information about the group $group = components()->groups->get_advanced_info($id); @@ -110,7 +110,7 @@ class GroupsController { public function getSettings(){ //Get the ID of the group (with admin access) - $groupID = $this->getPostGroupIDWithAdmin("id"); + $groupID = getPostGroupIdWithAccess("id", GroupInfo::ADMIN_ACCESS); //Retrieve the settings of the group $settings = components()->groups->get_settings($groupID); @@ -131,7 +131,7 @@ class GroupsController { public function setSettings(){ //Get the ID of the group (with admin access) - $groupID = $this->getPostGroupIDWithAdmin("id"); + $groupID = getPostGroupIdWithAccess("id", GroupInfo::ADMIN_ACCESS); //Create and fill a GroupSettings object with new values $settings = new GroupSettings(); @@ -160,7 +160,7 @@ class GroupsController { public function uploadLogo(){ //Get the ID of the group (with admin access) - $groupID = $this->getPostGroupIDWithAdmin("id"); + $groupID = getPostGroupIdWithAccess("id", GroupInfo::ADMIN_ACCESS); //Check if it is a valid file if(!check_post_file("logo")) @@ -195,7 +195,7 @@ class GroupsController { public function deleteLogo(){ //Get the ID of the group (with admin access) - $groupID = $this->getPostGroupIDWithAdmin("id"); + $groupID = getPostGroupIdWithAccess("id", GroupInfo::ADMIN_ACCESS); //Try to delete group logo if(!components()->groups->deleteLogo($groupID)) @@ -208,28 +208,6 @@ class GroupsController { ); } - /** - * Get and return a group ID specified in the POST request - * in which the current user has admin rigths - * - * @param string $name The name of the POST field - * @return int The ID of the group - */ - private function getPostGroupIDWithAdmin(string $name) : int { - - //User must be signed in - user_login_required(); - - //Get the ID of the group - $groupID = getPostGroupId($name); - - //Check if the user is an admin of the group or not - if(!components()->groups->isAdmin(userID, $groupID)) - Rest_fatal_error(401, "You are not an administrator of this group!"); - - return $groupID; - } - /** * Parse a GroupInfo object into an array for the API * diff --git a/classes/components/GroupsComponent.php b/classes/components/GroupsComponent.php index b19bcad..5af595f 100644 --- a/classes/components/GroupsComponent.php +++ b/classes/components/GroupsComponent.php @@ -67,6 +67,26 @@ class GroupsComponent { } + /** + * Get the visibility level of a group + * + * @param int $id The ID of the target group + * @return int The visibility level of the group + */ + public function getVisiblity(int $id) : int { + $data = db()->select( + self::GROUPS_LIST_TABLE, + "WHERE id = ?", + array($id), + array("visibility") + ); + + if(count($data) < 1) + throw new Exception("Group " + $id + " does not exists!"); + + return $data[0]["visibility"]; + } + /** * Get and return information about a group * @@ -210,13 +230,40 @@ class GroupsComponent { * or not * * @param int $userID Requested user ID to check + * @param int $groupID Requested group to check * @return bool TRUE if the user is an admin / FALSE else */ - public function isAdmin(int $userID, int $groupID){ + public function isAdmin(int $userID, int $groupID) : bool { return $this->getMembershipLevel($userID, $groupID) == GroupMember::ADMINISTRATOR; } + /** + * Check whether a group is open or not + * + * @param int $groupID The ID of the target group + * @return bool TRUE if the group is open / FALSE else + */ + public function isOpen(int $groupID) : bool { + return db()->count( + self::GROUPS_LIST_TABLE, + "WHERE id = ? AND visibility = ?", + array($groupID, GroupInfo::OPEN_GROUP)) > 0; + } + + /** + * Check whether a group is secret or not + * + * @param int $groupID The ID of the target group + * @return bool TRUE if the group is open / FALSE else + */ + public function isSecret(int $groupID) : bool { + return db()->count( + self::GROUPS_LIST_TABLE, + "WHERE id = ? AND visibility = ?", + array($groupID, GroupInfo::SECRET_GROUP)) > 0; + } + /** * Count the number of members of a group * @@ -229,6 +276,49 @@ class GroupsComponent { array($id)); } + /** + * Get and return the access level of a user over a group + * + * @param int $groupID The ID of the target group + * @param int $userID The ID of the user + * @return int The visiblity access level of the user + */ + public function getAccessLevel(int $groupID, int $userID) : int { + + if($userID > 0) + //Get the membership level of the user + $membership_level = $this->getMembershipLevel($userID, $groupID); + + else + $membership_level = GroupInfo::VISITOR; //Signed out users are all visitors + + //Check if the user is a confirmed member of group + if($membership_level == GroupInfo::ADMINISTRATOR) + return GroupInfo::ADMIN_ACCESS; + if($membership_level == GroupInfo::MODERATOR) + return GroupInfo::MODERATOR_ACCESS; + if($membership_level == GroupInfo::MEMBER) + return GroupInfo::MEMBER_ACCESS; + + //Get the visibility level of the group + $group_visibility_level = $this->getVisiblity($groupID); + + //If the group is open, everyone has view access + if($group_visibility_level == GroupInfo::OPEN_GROUP) + return GroupInfo::VIEW_ACCESS; + + //Else, all pending membership gives limited access + if($membership_level == GroupInfo::PENDING) + return GroupInfo::LIMITED_ACCESS; + + //Private groups gives limited access + if($group_visibility_level == GroupInfo::PRIVATE_GROUP) + return GroupInfo::LIMITED_ACCESS; + + //Else the user can not see the group + return GroupInfo::NO_ACCESS; + } + /** * Delete current group logo (if any) * diff --git a/classes/models/GroupInfo.php b/classes/models/GroupInfo.php index 9df7cf8..02d9edd 100644 --- a/classes/models/GroupInfo.php +++ b/classes/models/GroupInfo.php @@ -21,7 +21,21 @@ class GroupInfo extends BaseUniqueObject { private $logo; private $membership_level = -1; private $visiblity = -1; - + + //User access to a group + const NO_ACCESS = 0; //Can not even know if the group exists or not + const LIMITED_ACCESS = 1; //Access to the name of the group only + const VIEW_ACCESS = 2; //Can see the posts of the group, but not a member of the group + const MEMBER_ACCESS = 3; //Member access (same as view access but as member) + const MODERATOR_ACCESS = 4; //Can create posts, even if posts creation is restricted + const ADMIN_ACCESS = 5; //Can do everything + + //Membership levels + const ADMINISTRATOR = 0; + const MODERATOR = 1; + const MEMBER = 2; + const PENDING = 3; + const VISITOR = 4; //Get and set the name of group public function set_name(string $name){ diff --git a/functions/requests.php b/functions/requests.php index dfe9b86..279f52c 100644 --- a/functions/requests.php +++ b/functions/requests.php @@ -570,7 +570,7 @@ function getPostUserDirectory(string $name) : string { * * @param string $name The name of variable in the $_POST request * @return int The ID of the group - * @throws RESTException If the directory is missing + * @throws RESTException If the value is missing */ function getPostGroupId(string $name) : int { @@ -583,4 +583,30 @@ function getPostGroupId(string $name) : int { //Return the ID of the group return $id; +} + +/** + * Get a POST group ID with a check for the minimal access requested + * + * @param string $name The name of the post field containing group ID + * @param int $minAccess The minimal access required + * @return int The ID of the group + */ +function getPostGroupIdWithAccess(string $name, int $minVisibility) : int { + + //Get the ID of the group + $groupID = getPostGroupId($name); + + //Get the access level of the current user over the group + $accessLevel = components()->groups->getAccessLevel($groupID, userID); + + //Check if the user has no access + if($accessLevel == GroupInfo::NO_ACCESS) + Rest_fatal_error(404, "Specified group does not exists !"); //Act like if the group did not exists + + //Check access level + if($accessLevel < $minVisibility) + Rest_fatal_error(401, "You do not have enough rights to perform what you intend to do on this group!"); + + return $groupID; } \ No newline at end of file