public function executeGetUsers() { wfProfileIn(__METHOD__); $this->users = ChatEntryPoint::getChatUsersInfo(); if (count($this->users) === 0) { ChatHelper::info(__METHOD__ . ': Method called - no users'); // CONN-436: If there are no users in the chat, cache the response in varnish for CACHE_STANDARD and on the // browser for the default CACHE_DURATION time; // Note: Varnish cache will be purged when user opens the chat page $this->response->setCacheValidity(WikiaResponse::CACHE_STANDARD, self::CACHE_DURATION); } else { ChatHelper::info(__METHOD__ . ': Method called - found users', ['chatters' => count($this->users)]); // If there are users in the chat, cache both in varnish and browser for default CACHE_DURATION; $this->response->setCacheValidity(self::CACHE_DURATION); } wfProfileOut(__METHOD__); }
/** * Prepare a pre-rendered chat entry point for logged-in users */ public static function onMakeGlobalVariablesScript(&$vars) { global $wgUser, $wgLang; if ($wgUser->isLoggedIn()) { $vars['wgWikiaChatUsers'] = ChatEntryPoint::getChatUsersInfo(); if (empty($vars['wgWikiaChatUsers'])) { // we will need it to attract user to join chat $vars['wgWikiaChatProfileAvatarUrl'] = AvatarService::getAvatarUrl($wgUser->getName(), ChatRailController::AVATAR_SIZE); } $vars['wgWikiaChatMonts'] = $wgLang->getMonthAbbreviationsArray(); } else { $vars['wgWikiaChatUsers'] = ''; } $vars['wgWikiaChatWindowFeatures'] = ChatRailController::CHAT_WINDOW_FEATURES; return true; }
/** * This is the ajax-endpoint that the node server will connect to in order to get the currently logged-in user's info. * The node server will pass the same cookies that the client has set, and this will allow this ajax request to be * part of the same sesssion that the user already has going. By doing this, the user's existing wikia login session * can be used, so they don't need to re-login for us to know that they are legitimately authorized to use the chat or not. * * The returned info is just a custom subset of what the node server needs and does not contain an exhaustive list of rights. * * The 'isLoggedIn' field and 'canChat' field of the result should be checked by the calling code before allowing * the user to chat. This is the last line of security against any users attempting to circumvent our protections. Otherwise, * a banned user could copy the entire client code (HTML/JS/etc.) from an unblocked user, then run that code while logged in as * under a banned account, and they would still be given access. * * The returned 'isChatMod' field is boolean based on whether the user is a chat moderator on the current wiki. * * If the user is not allowed to chat, an error message is returned (which can be shown to the user). */ public static function getUserInfo() { ChatHelper::info(__METHOD__ . ': Method called'); global $wgMemc, $wgServer, $wgArticlePath, $wgRequest, $wgCityId, $wgContLang; wfProfileIn(__METHOD__); $data = $wgMemc->get($wgRequest->getVal('key'), false); if (empty($data)) { wfProfileOut(__METHOD__); return array('errorMsg' => "Key not found"); } $user = User::newFromId($data['user_id']); if (empty($user) || !$user->isLoggedIn() || $user->getName() != urldecode($wgRequest->getVal('name', ''))) { wfProfileOut(__METHOD__); return array('errorMsg' => "User not found"); } $isCanGiveChatMod = false; $userChangeableGroups = $user->changeableGroups(); if (in_array('chatmoderator', $userChangeableGroups['add'])) { $isCanGiveChatMod = true; } // First, check if they can chat on this wiki. $retVal = array('canChat' => Chat::canChat($user), 'isLoggedIn' => $user->isLoggedIn(), 'isChatMod' => $user->isAllowed('chatmoderator'), 'isCanGiveChatMod' => $isCanGiveChatMod, 'isStaff' => $user->isAllowed('chatstaff'), 'username' => $user->getName(), 'username_encoded' => rawurlencode($user->getName()), 'avatarSrc' => AvatarService::getAvatarUrl($user->getName(), self::CHAT_AVATAR_DIMENSION), 'editCount' => "", 'since' => '', 'activeBasket' => ChatHelper::getServerBasket(), 'wgCityId' => $wgCityId, 'wgServer' => $wgServer, 'wgArticlePath' => $wgArticlePath); // Figure out the error message to return (i18n is done on this side). if ($retVal['isLoggedIn'] === false) { $retVal['errorMsg'] = wfMsg('chat-no-login'); } else { if ($retVal['canChat'] === false) { $retVal['errorMsg'] = wfMsg('chat-you-are-banned-text'); } } // If the user is approved to chat, make sure the roomId provided is for this wiki. // Users may be banned on the wiki of the room, but not on this wiki for example, so this prevents cross-wiki chat hacks. if ($retVal['canChat']) { $roomId = $wgRequest->getVal('roomId'); $cityIdOfRoom = NodeApiClient::getCityIdForRoom($roomId); if ($wgCityId !== $cityIdOfRoom) { $retVal['canChat'] = false; // don't let the user chat in the room they requested. $retVal['errorMsg'] = wfMsg('chat-room-is-not-on-this-wiki'); } } // If the user can chat, dig up some other stats which are a little more expensive to compute. if ($retVal['canChat']) { // new user joins the chat, purge the cache ChatEntryPoint::purgeChatUsersCache(); $userStatsService = new UserStatsService($user->getId()); $stats = $userStatsService->getStats(); // NOTE: This is attached to the user so it will be in the wiki's content language instead of wgLang (which it normally will). $stats['edits'] = $wgContLang->formatNum($stats['edits']); if (empty($stats['date'])) { // If the user has not edited on this wiki, don't show anything $retVal['since'] = ""; } else { // this results goes to chat server, which obiously has no user lang // so we just return a short month name key - it has to be translated on client side $date = getdate(wfTimestamp(TS_UNIX, $stats['date'])); $retVal['since'] = $date; } $retVal['editCount'] = $stats['edits']; } wfProfileOut(__METHOD__); return $retVal; }