<?php /** * Copyright (C) 2010-2022 Tim Düsterhus * Copyright (C) 2010-2022 Woltlab GmbH * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ namespace chat\system\permission; use chat\data\room\Room; use chat\system\cache\builder\PermissionCacheBuilder; use wcf\data\user\UserProfile; use wcf\system\acl\ACLHandler; use wcf\system\database\util\PreparedStatementConditionBuilder; use wcf\system\user\storage\UserStorageHandler; use wcf\system\WCF; /** * Handles chat permissions. */ class PermissionHandler { /** * permissions set for the given user * @var boolean[] */ protected $chatPermissions = [ ]; /** * given user decorated in a user profile * @var \wcf\data\user\UserProfile */ protected $user; /** * Cache of PermissionHandlers. * @var \chat\system\permission\PermissionHandler[] */ protected static $cache = [ ]; public function __construct(?UserProfile $user = null) { if ($user === null) { $user = new UserProfile(WCF::getUser()); } $this->user = $user; $this->chatPermissions = PermissionCacheBuilder::getInstance()->getData($user->getGroupIDs()); // get user permissions if ($user->userID) { $ush = UserStorageHandler::getInstance(); // get ids $data = $ush->getField('chatUserPermissions', $user->userID); // cache does not exist or is outdated if ($data === null) { $userPermissions = [ ]; $conditionBuilder = new PreparedStatementConditionBuilder(); $conditionBuilder->add('acl_option.objectTypeID = ?', [ ACLHandler::getInstance()->getObjectTypeID('be.bastelstu.chat.room') ]); $conditionBuilder->add('option_to_user.userID = ?', [ $user->userID ]); $sql = "SELECT option_to_user.objectID AS roomID, option_to_user.optionValue, acl_option.optionName AS permission FROM wcf1_acl_option acl_option INNER JOIN wcf1_acl_option_to_user option_to_user ON option_to_user.optionID = acl_option.optionID " . $conditionBuilder; $statement = WCF::getDB()->prepare($sql); $statement->execute($conditionBuilder->getParameters()); while (($row = $statement->fetchArray())) { $userPermissions[$row['roomID']][$row['permission']] = $row['optionValue']; } // update cache $ush->update($user->userID, 'chatUserPermissions', \serialize($userPermissions)); } else { $userPermissions = \unserialize($data); } foreach ($userPermissions as $roomID => $permissions) { foreach ($permissions as $name => $value) { $this->chatPermissions[$roomID][$name] = $value; } } } } public static function get(?UserProfile $user = null) { if ($user === null) { $user = new UserProfile(WCF::getUser()); } if (!isset(static::$cache[$user->userID])) { static::$cache[$user->userID] = new static($user); } return static::$cache[$user->userID]; } /** * Fetches the given permission for the given room * * @param string $permission * @return boolean */ public function getPermission(Room $room, $permission) { $groupPermission = \str_replace( [ 'user.', 'mod.', ], [ 'user.chat.', 'mod.chat.', ], $permission ); if (\method_exists($this->user, 'getNeverPermission') && $this->user->getNeverPermission($groupPermission)) { return false; } if (!isset($this->chatPermissions[$room->roomID][$permission])) { return $this->user->getPermission($groupPermission); } return (bool)$this->chatPermissions[$room->roomID][$permission]; } /** * Clears the cache. */ public static function resetCache() { UserStorageHandler::getInstance()->resetAll('chatUserPermissions'); PermissionCacheBuilder::getInstance()->reset(); } }