diff --git a/src/mibew/libs/chat.php b/src/mibew/libs/chat.php index b8709dfe..eb62ab0a 100644 --- a/src/mibew/libs/chat.php +++ b/src/mibew/libs/chat.php @@ -736,6 +736,12 @@ function chat_start_for_user( $_SESSION['threadid'] = $thread->id; + // Store own thread ids to restrict access for other people + if (!isset($_SESSION['own_threads'])) { + $_SESSION['own_threads'] = array(); + } + $_SESSION['own_threads'][] = $thread->id; + // Bind thread to the visitor if (Settings::get('enabletracking')) { track_visitor_bind_thread($visitor_id, $thread); diff --git a/src/mibew/libs/classes/Mibew/Controller/Chat/UserChatController.php b/src/mibew/libs/classes/Mibew/Controller/Chat/UserChatController.php index 8b68a98f..f2deb14e 100644 --- a/src/mibew/libs/classes/Mibew/Controller/Chat/UserChatController.php +++ b/src/mibew/libs/classes/Mibew/Controller/Chat/UserChatController.php @@ -43,8 +43,12 @@ class UserChatController extends AbstractController $thread_id = $request->attributes->getInt('thread_id'); $token = $request->attributes->get('token'); + // We have to check that the thread is owned by the user. + $is_own_thread = isset($_SESSION['own_threads']) + && in_array($thread_id, $_SESSION['own_threads']); + $thread = Thread::load($thread_id, $token); - if (!$thread) { + if (!$thread || !$is_own_thread) { throw new NotFoundException('The thread is not found.'); } @@ -257,6 +261,12 @@ class UserChatController extends AbstractController $thread = Thread::load($invitation_state['threadid']); + // Store own thread ids to restrict access for other people + if (!isset($_SESSION['own_threads'])) { + $_SESSION['own_threads'] = array(); + } + $_SESSION['own_threads'][] = $thread->id; + // Prepare page $page = setup_invitation_view($thread); diff --git a/src/mibew/libs/classes/Mibew/RequestProcessor/ThreadProcessor.php b/src/mibew/libs/classes/Mibew/RequestProcessor/ThreadProcessor.php index 2ebd3ef1..ab48cd13 100644 --- a/src/mibew/libs/classes/Mibew/RequestProcessor/ThreadProcessor.php +++ b/src/mibew/libs/classes/Mibew/RequestProcessor/ThreadProcessor.php @@ -22,6 +22,7 @@ namespace Mibew\RequestProcessor; // Import namespaces and classes of the core use Mibew\Authentication\AuthenticationManagerAwareInterface; use Mibew\Authentication\AuthenticationManagerInterface; +use Mibew\Http\Exception\AccessDeniedException; use Mibew\Settings; use Mibew\Thread; use Mibew\API\API as MibewAPI; @@ -274,6 +275,34 @@ class ThreadProcessor extends ClientSideProcessor implements } } + /** + * {@inheritdoc} + */ + protected function processFunction($function, \Mibew\API\ExecutionContext &$context) + { + // Check if a function can be called. Operators can call anythig, thus + // we should continue validation only for users. + if (!$this->getAuthenticationManager()->getOperator()) { + // A function is called by a user. We need to check that the thread + // is related with the user. + $arguments = $context->getArgumentsList($function); + $thread_id = $arguments['threadid']; + // As defined in Mibew\API\Interaction\ChatInteraction "threadid" + // argument is mandatory, but some function allows it to be null. In + // such cases there is no thread and there is nothing to check. + if (!is_null($thread_id)) { + $is_own_thread = isset($_SESSION['own_threads']) + && in_array($thread_id, $_SESSION['own_threads']); + if (!$is_own_thread) { + throw new AccessDeniedException(); + } + } + } + + // The function can be called. Process it. + parent::processFunction($function, $context); + } + /** * Update chat window state. API function *