function execute($par) { global $wgUser; /* wikia change */ /** * Some satellite ISPs use broken precaching schemes that log people out straight after * they're logged in (bug 17790). Luckily, there's a way to detect such requests. */ if (isset($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], '&') !== false) { wfDebug("Special:Userlogout request {$_SERVER['REQUEST_URI']} looks suspicious, denying.\n"); throw new HttpError(400, wfMessage('suspicious-userlogout'), wfMessage('loginerror')); } $this->setHeaders(); $this->outputHeader(); $user = $this->getUser(); $oldName = $user->getName(); $user->logout(); /* * Special pages use the new-style context-based user object. However, much of the rest of the world * (e.g. Global Nav) uses the old-style global wgUser object. As such, when we log out we need to * ensure that both copies of the user object are properly addressed, or else parts of the page will still * believe they have an authenticated user object. * * Once the old-style global wgUser object is fully deprecated, this line can be removed. */ $wgUser->logout(); /* wikia change */ // Wikia change // regenerate session ID on user logout to avoid race conditions with // long running requests logging the user back in (@see PLATFORM-1028) wfResetSessionID(); $out = $this->getOutput(); $out->addWikiMsg('logouttext'); // Hook. $injected_html = ''; wfRunHooks('UserLogoutComplete', array(&$user, &$injected_html, $oldName)); $out->addHTML($injected_html); $mReturnTo = $this->getRequest()->getVal('returnto'); $mReturnToQuery = $this->getRequest()->getVal('returntoquery'); $title = Title::newFromText($mReturnTo); if (!empty($title)) { $mResolvedReturnTo = strtolower(array_shift(SpecialPageFactory::resolveAlias($title->getDBKey()))); if (in_array($mResolvedReturnTo, array('userlogout', 'signup', 'connect'))) { $titleObj = Title::newMainPage(); $mReturnTo = $titleObj->getText(); $mReturnToQuery = ''; } } $out->returnToMain(false, $mReturnTo, $mReturnToQuery); }
/** * Renew the user's session id, using strong entropy */ private function renewSessionId() { global $wgSecureLogin, $wgCookieSecure; if ($wgSecureLogin && !$this->mStickHTTPS) { $wgCookieSecure = false; } wfResetSessionID(); }
/** * Logs in a user with given login name and password. If keeploggedin, sets a cookie. * * @requestParam string username * @requestParam string password * @requestParam string keeploggedin [true/false] * @responseParam string result [ok/error/unconfirm/resetpass] * @responseParam string msg - result message * @responseParam string errParam - error param */ public function login() { // Init session if necessary if (session_id() == '') { wfSetupSession(); } $loginForm = new LoginForm($this->wg->request); $loginForm->load(); // MW1.19 uses different form fields names // set variables if ($this->wg->request->getText('username', '') != '') { $loginForm->mUsername = $this->wg->request->getText('username'); } if ($this->wg->request->getText('password', '') != '') { $loginForm->mPassword = $this->wg->request->getText('password'); } if ($this->wg->request->getText('keeploggedin', '') != '') { $loginForm->mRemember = $this->wg->request->getCheck('keeploggedin'); } if ($this->wg->request->getVal('loginToken', '') != '') { $loginForm->mToken = $this->wg->request->getVal('loginToken'); } if ($this->wg->request->getVal('returnto', '') != '') { $loginForm->mReturnTo = $this->wg->request->getVal('returnto'); } $loginCase = $loginForm->authenticateUserData(); switch ($loginCase) { case LoginForm::SUCCESS: // first check if user has confirmed email after sign up if ($this->wg->User->getGlobalFlag(self::NOT_CONFIRMED_SIGNUP_OPTION_NAME) && $this->wg->User->getGlobalAttribute(self::NOT_CONFIRMED_LOGIN_OPTION_NAME) !== self::NOT_CONFIRMED_LOGIN_ALLOWED) { // User not confirmed on signup LoginForm::clearLoginToken(); $this->userLoginHelper->setNotConfirmedUserSession($this->wg->User->getId()); $this->userLoginHelper->clearPasswordThrottle($loginForm->mUsername); $this->response->setValues(['result' => 'unconfirm', 'msg' => wfMessage('usersignup-confirmation-email-sent', $this->wg->User->getEmail())->parse()]); } else { $result = ''; $resultMsg = ''; if (!wfRunHooks('WikiaUserLoginSuccess', array($this->wg->User, &$result, &$resultMsg))) { $this->response->setValues(['result' => $result, 'msg' => $resultMsg]); break; } // Login succesful $injected_html = ''; wfRunHooks('UserLoginComplete', array(&$this->wg->User, &$injected_html)); // set rememberpassword option if ((bool) $loginForm->mRemember != (bool) $this->wg->User->getGlobalPreference('rememberpassword')) { $this->wg->User->setGlobalPreference('rememberpassword', $loginForm->mRemember ? 1 : 0); $this->wg->User->saveSettings(); } else { $this->wg->User->invalidateCache(); } $this->wg->User->setCookies(); LoginForm::clearLoginToken(); UserLoginHelper::clearNotConfirmedUserSession(); $this->userLoginHelper->clearPasswordThrottle($loginForm->mUsername); // we're sure at this point we'll need the private field' // value in the template let's pass them then $this->response->setValues(['username' => $loginForm->mUsername, 'result' => 'ok']); // regenerate session ID on user login (the approach MW's core SpecialUserLogin uses) // to avoid race conditions with long running requests logging the user back in & out // @see PLATFORM-1028 wfResetSessionID(); } break; case LoginForm::NEED_TOKEN: case LoginForm::WRONG_TOKEN: $this->response->setValues(['result' => 'error', 'msg' => wfMessage('userlogin-error-sessionfailure')->escaped()]); break; case LoginForm::NO_NAME: $this->response->setValues(['result' => 'error', 'msg' => wfMessage('userlogin-error-noname')->escaped(), 'errParam' => 'username']); break; case LoginForm::NOT_EXISTS: case LoginForm::ILLEGAL: $this->response->setValues(['result' => 'error', 'msg' => wfMessage('userlogin-error-nosuchuser')->escaped(), 'errParam' => 'username']); break; case LoginForm::WRONG_PLUGIN_PASS: $this->response->setValues(['result' => 'error', 'msg' => wfMessage('userlogin-error-wrongpassword')->escaped(), 'errParam' => 'password']); break; case LoginForm::WRONG_PASS: $this->response->setValues(['result' => 'error', 'msg' => wfMessage('userlogin-error-wrongpassword')->escaped(), 'errParam' => 'password']); $attemptedUser = User::newFromName($loginForm->mUsername); if (!is_null($attemptedUser)) { $disOpt = $attemptedUser->getGlobalFlag('disabled'); if (!empty($disOpt) || defined('CLOSED_ACCOUNT_FLAG') && $attemptedUser->getRealName() == CLOSED_ACCOUNT_FLAG) { # either closed account flag was present, override fail message $this->response->setValues(['msg' => wfMessage('userlogin-error-edit-account-closed-flag')->escaped(), 'errParam' => '']); } } break; case LoginForm::EMPTY_PASS: $this->response->setValues(['result' => 'error', 'msg' => wfMessage('userlogin-error-wrongpasswordempty')->escaped(), 'errParam' => 'password']); break; case LoginForm::RESET_PASS: $this->response->setVal('result', 'resetpass'); break; case LoginForm::THROTTLED: $this->response->setValues(['result' => 'error', 'msg' => wfMessage('userlogin-error-login-throttled')->escaped()]); break; case LoginForm::CREATE_BLOCKED: $this->response->setValues(['result' => 'error', 'msg' => wfMessage('userlogin-error-cantcreateaccount-text')->escaped()]); break; case LoginForm::USER_BLOCKED: $this->response->setValues(['result' => 'error', 'msg' => wfMessage('userlogin-error-login-userblocked')->escaped()]); break; case LoginForm::ABORTED: $this->result = 'error'; $this->msg = wfMessage($loginForm->mAbortLoginErrorMsg)->escaped(); break; default: throw new MWException("Unhandled case value"); } }
/** * Renew the user's session id, using strong entropy */ private function renewSessionId() { global $wgSecureLogin, $wgCookieSecure; if ($wgSecureLogin && !$this->mStickHTTPS) { $wgCookieSecure = false; } // Always make sure edit token is regenerated. (T114419) $this->getRequest()->setSessionData('wsEditToken', null); wfResetSessionID(); }
/** * Clear the user's cookies and session, and reset the instance cache. * @see logout() */ public function doLogout() { $this->clearInstanceCache('defaults'); $this->getRequest()->setSessionData('wsUserID', 0); $this->getRequest()->setSessionData('wsEditToken', null); $this->clearCookie('UserID'); $this->clearCookie('Token'); $this->clearCookie('forceHTTPS', false, array('prefix' => '')); wfResetSessionID(); // Remember when user logged out, to prevent seeing cached pages $this->setCookie('LoggedOut', time(), time() + 86400); }
/** * Performs the request. * - bad titles * - read restriction * - local interwiki redirects * - redirect loop * - special pages * - normal pages * * @throws MWException|PermissionsError|BadTitleError|HttpError * @return void */ private function performRequest() { global $wgTitle; $request = $this->context->getRequest(); $requestTitle = $title = $this->context->getTitle(); $output = $this->context->getOutput(); $user = $this->context->getUser(); ### <SANDSTORM> global $wgAuth; $name = array_key_exists('HTTP_X_SANDSTORM_USERNAME', $_SERVER) ? $_SERVER['HTTP_X_SANDSTORM_USERNAME'] : '******'; $name = urldecode($name); $original_name = $name; $id = array_key_exists('HTTP_X_SANDSTORM_USER_ID', $_SERVER) ? $_SERVER['HTTP_X_SANDSTORM_USER_ID'] : ''; $count = 2; $isNew = false; if ($user->isAnon()) { $u = null; do { $u = User::newFromName($name, 'creatable'); // TODO if (!is_object($u)) { wfLogWarning('no name for ' . $name); throw new BadTitleError(); } if (0 != $u->idForName() && $u->getEmail() !== $id && !empty($id)) { $name = $original_name . $count; } $count++; } while (0 != $u->idForName() && $u->getEmail() !== $id && !empty($id)); if (0 == $u->idForName()) { $permissions = array_key_exists('HTTP_X_SANDSTORM_PERMISSIONS', $_SERVER) ? $_SERVER['HTTP_X_SANDSTORM_PERMISSIONS'] : ''; $pass = sha1(mt_rand()); $u->setRealName($name); $u->setEmail($id); if (!$wgAuth->addUser($u, $pass, "", $name)) { // TODO wfLogWarning('externaldberror'); } $this->initUser($u, $pass, false); if (strpos($permissions, 'admin') !== false) { wfLogWarning('setting user as admin: ' . $name); $u->addGroup('sysop'); $u->addGroup('bureaucrat'); $u->saveSettings(); } if (!empty($id)) { $u->addGroup('editor'); $u->saveSettings(); } $isNew = true; } // wfSetupSession(); // Not sure why, but I manually have to set session cookie setcookie(session_name(), MWCryptRand::generateHex(32), 0, '/'); $u->setCookies(); wfResetSessionID(); $this->context->setUser($u); $user = $this->context->getUser(); $wgUser = $u; } if ($isNew) { wfRunHooks('AddNewAccount', array($u, false)); $u->addNewUserLogEntry('create'); $injected_html = ''; wfRunHooks('UserLoginComplete', array(&$u, &$injected_html)); $welcome_creation_msg = 'welcomecreation-msg'; wfRunHooks('BeforeWelcomeCreation', array(&$welcome_creation_msg, &$injected_html)); } else { $injected_html = ''; wfRunHooks('UserLoginComplete', array(&$u, &$injected_html)); } # </SANDSTORM> if ($request->getVal('printable') === 'yes') { $output->setPrintable(); } $unused = null; // To pass it by reference Hooks::run('BeforeInitialize', array(&$title, &$unused, &$output, &$user, $request, $this)); // Invalid titles. Bug 21776: The interwikis must redirect even if the page name is empty. if (is_null($title) || $title->getDBkey() == '' && !$title->isExternal() || $title->isSpecial('Badtitle')) { $this->context->setTitle(SpecialPage::getTitleFor('Badtitle')); throw new BadTitleError(); } // Check user's permissions to read this page. // We have to check here to catch special pages etc. // We will check again in Article::view(). $permErrors = $title->isSpecial('RunJobs') ? array() : $title->getUserPermissionsErrors('read', $user); if (count($permErrors)) { // Bug 32276: allowing the skin to generate output with $wgTitle or // $this->context->title set to the input title would allow anonymous users to // determine whether a page exists, potentially leaking private data. In fact, the // curid and oldid request parameters would allow page titles to be enumerated even // when they are not guessable. So we reset the title to Special:Badtitle before the // permissions error is displayed. // // The skin mostly uses $this->context->getTitle() these days, but some extensions // still use $wgTitle. $badTitle = SpecialPage::getTitleFor('Badtitle'); $this->context->setTitle($badTitle); $wgTitle = $badTitle; throw new PermissionsError('read', $permErrors); } // Interwiki redirects if ($title->isExternal()) { $rdfrom = $request->getVal('rdfrom'); if ($rdfrom) { $url = $title->getFullURL(array('rdfrom' => $rdfrom)); } else { $query = $request->getValues(); unset($query['title']); $url = $title->getFullURL($query); } // Check for a redirect loop if (!preg_match('/^' . preg_quote($this->config->get('Server'), '/') . '/', $url) && $title->isLocal()) { // 301 so google et al report the target as the actual url. $output->redirect($url, 301); } else { $this->context->setTitle(SpecialPage::getTitleFor('Badtitle')); throw new BadTitleError(); } // Redirect loops, no title in URL, $wgUsePathInfo URLs, and URLs with a variant } elseif ($request->getVal('action', 'view') == 'view' && !$request->wasPosted() && ($request->getVal('title') === null || $title->getPrefixedDBkey() != $request->getVal('title')) && !count($request->getValueNames(array('action', 'title'))) && Hooks::run('TestCanonicalRedirect', array($request, $title, $output))) { if ($title->isSpecialPage()) { list($name, $subpage) = SpecialPageFactory::resolveAlias($title->getDBkey()); if ($name) { $title = SpecialPage::getTitleFor($name, $subpage); } } $targetUrl = wfExpandUrl($title->getFullURL(), PROTO_CURRENT); // Redirect to canonical url, make it a 301 to allow caching if ($targetUrl == $request->getFullRequestURL()) { $message = "Redirect loop detected!\n\n" . "This means the wiki got confused about what page was " . "requested; this sometimes happens when moving a wiki " . "to a new server or changing the server configuration.\n\n"; if ($this->config->get('UsePathInfo')) { $message .= "The wiki is trying to interpret the page " . "title from the URL path portion (PATH_INFO), which " . "sometimes fails depending on the web server. Try " . "setting \"\$wgUsePathInfo = false;\" in your " . "LocalSettings.php, or check that \$wgArticlePath " . "is correct."; } else { $message .= "Your web server was detected as possibly not " . "supporting URL path components (PATH_INFO) correctly; " . "check your LocalSettings.php for a customized " . "\$wgArticlePath setting and/or toggle \$wgUsePathInfo " . "to true."; } throw new HttpError(500, $message); } else { $output->setSquidMaxage(1200); $output->redirect($targetUrl, '301'); } // Special pages } elseif (NS_SPECIAL == $title->getNamespace()) { // Actions that need to be made when we have a special pages SpecialPageFactory::executePath($title, $this->context); } else { // ...otherwise treat it as an article view. The article // may be a redirect to another article or URL. $article = $this->initializeArticle(); if (is_object($article)) { $this->performAction($article, $requestTitle); } elseif (is_string($article)) { $output->redirect($article); } else { throw new MWException("Shouldn't happen: MediaWiki::initializeArticle()" . " returned neither an object nor a URL"); } } }
function execute($par) { global $wgMemc, $wgCentralAuthLoginWiki; $request = $this->getRequest(); $this->loginWiki = $wgCentralAuthLoginWiki; if (!$this->loginWiki) { // Ugh, no central wiki. If we're coming from an edge login, make // the logged-into wiki the de-facto central wiki for this request // so auto-login still works. $fromwiki = $request->getVal('from', $request->getVal('notifywiki')); if ($fromwiki !== null && WikiMap::getWiki($fromwiki)) { $this->loginWiki = $fromwiki; } } elseif ($request->getVal('from') === wfWikiId() && $wgCentralAuthLoginWiki !== wfWikiId()) { // Remote wiki must not have wgCentralAuthLoginWiki set, but we do. Redirect them. $this->do302Redirect($wgCentralAuthLoginWiki, $par, $request->getValues()); return; } $params = $request->getValues('type', 'from', 'return', 'returnto', 'returntoquery', 'proto', 'mobile'); switch (strval($par)) { case 'P3P': // Explain the bogus P3P header $this->setHeaders(); $this->getOutput()->addWikiMsg('centralauth-centralautologin-p3p-explanation'); return; case 'toolslist': // Do not cache this, we want updated Echo numbers and such. $this->getOutput()->enableClientCache(false); $user = $this->getUser(); if (!$user->isAnon()) { if (!CentralAuthHooks::isUIReloadRecommended($user)) { $html = $this->getSkin()->getPersonalToolsList(); $json = FormatJSON::encode(array('toolslist' => $html)); } else { $gender = $this->getUser()->getOption('gender'); if (strval($gender) === '') { $gender = 'unknown'; } $json = FormatJSON::encode(array('notify' => array('username' => $user->getName(), 'gender' => $gender))); } $this->doFinalOutput(true, 'OK', $json, 'json'); } else { $this->doFinalOutput(false, 'Not logged in', '', 'json'); } return; case 'refreshCookies': // Refresh central cookies (e.g. in case 'remember me' was set) // Do not cache this, we need to reset the cookies every time. $this->getOutput()->enableClientCache(false); if (!$wgCentralAuthLoginWiki || !$this->checkIsCentralWiki($wikiid)) { return; } CentralAuthUser::setP3P(); $centralUser = CentralAuthUser::getInstance($this->getUser()); if ($centralUser && $centralUser->getId()) { $centralSession = $this->getCentralSession($centralUser, $this->getUser()); // Refresh 'remember me' preference $remember = (bool) $centralSession['remember']; if ($remember != $this->getUser()->getBoolOption('rememberpassword')) { $this->getUser()->setOption('rememberpassword', $remember ? 1 : 0); $this->getUser()->saveSettings(); } $secureCookie = $centralSession['secureCookies']; $centralUser->setGlobalCookies($remember, false, $secureCookie, $centralSession); $this->doFinalOutput(true, 'success'); } else { $this->doFinalOutput(false, 'Not logged in'); } return; case 'deleteCookies': // Delete central cookies // Do not cache this, we need to reset the cookies every time. $this->getOutput()->enableClientCache(false); if ($this->getUser()->isLoggedIn()) { $this->doFinalOutput(false, 'Cannot delete cookies while still logged in'); return; } CentralAuthUser::setP3P(); CentralAuthUser::deleteGlobalCookies(); $this->doFinalOutput(true, 'success'); return; case 'start': // Main entry point // Note this is safe to cache, because the cache already varies on // the session cookies. $this->getOutput()->setSquidMaxage(1200); if (!$this->checkIsLocalWiki()) { return; } CentralAuthUser::setP3P(); $this->do302Redirect($this->loginWiki, 'checkLoggedIn', array('wikiid' => wfWikiID(), 'proto' => $request->detectProtocol()) + $params); return; case 'checkLoggedIn': // Check if we're logged in centrally // Note this is safe to cache, because the cache already varies on // the session cookies. $this->getOutput()->setSquidMaxage(1200); if (!$this->checkIsCentralWiki($wikiid)) { return; } CentralAuthUser::setP3P(); if ($this->getUser()->isLoggedIn()) { $centralUser = CentralAuthUser::getInstance($this->getUser()); } else { $this->doFinalOutput(false, 'Not centrally logged in', self::getInlineScript('anon-set.js')); return; } // We're pretty sure this user is logged in, so pass back // headers to prevent caching, just in case $this->getOutput()->enableClientCache(false); $memcData = array('gu_id' => $centralUser->getId()); $token = MWCryptRand::generateHex(32); $key = CentralAuthUser::memcKey('centralautologin-token', $token); $wgMemc->set($key, $memcData, 60); $this->do302Redirect($wikiid, 'createSession', array('token' => $token) + $params); return; case 'createSession': // Create the local session and shared memcache token if (!$this->checkIsLocalWiki()) { return; } CentralAuthUser::setP3P(); $token = $request->getVal('token', ''); $gid = $request->getVal('gu_id', ''); if ($token !== '') { // Load memc data $key = CentralAuthUser::memcKey('centralautologin-token', $token); $memcData = $wgMemc->get($key); $wgMemc->delete($key); if (!$memcData || !isset($memcData['gu_id'])) { $this->doFinalOutput(false, 'Invalid parameters'); return; } $gu_id = intval($memcData['gu_id']); } elseif ($gid !== '') { // Cached, or was logging in as we switched from gu_id to token $gu_id = intval($gid); } else { $this->doFinalOutput(false, 'Invalid parameters'); return; } if ($gu_id <= 0) { $this->doFinalOutput(false, 'Not centrally logged in', self::getInlineScript('anon-set.js')); return; } // At this point we can't cache anymore because we need to set // cookies and memc each time. $this->getOutput()->enableClientCache(false); // Ensure that a session exists if (session_id() == '') { wfSetupSession(); } // Create memc token $wikiid = wfWikiID(); $memcData = array('gu_id' => $gu_id, 'wikiid' => $wikiid); $token = MWCryptRand::generateHex(32); $key = CentralAuthUser::memcKey('centralautologin-token', $token, $wikiid); $wgMemc->set($key, $memcData, 60); // Save memc token for the 'setCookies' step $request->setSessionData('centralautologin-token', $token); $this->do302Redirect($this->loginWiki, 'validateSession', array('token' => $token, 'wikiid' => $wikiid) + $params); return; case 'validateSession': // Validate the shared memcached token // Do not cache this, we need to reset the cookies and memc every time. $this->getOutput()->enableClientCache(false); if (!$this->checkIsCentralWiki($wikiid)) { return; } if (!$this->getUser()->isLoggedIn()) { $this->doFinalOutput(false, 'Not logged in'); return; } CentralAuthUser::setP3P(); // Validate params $token = $request->getVal('token', ''); if ($token === '') { $this->doFinalOutput(false, 'Invalid parameters'); return; } // Load memc data $key = CentralAuthUser::memcKey('centralautologin-token', $token, $wikiid); $memcData = $wgMemc->get($key); $wgMemc->delete($key); // Check memc data $centralUser = CentralAuthUser::getInstance($this->getUser()); if (!$memcData || $memcData['wikiid'] !== $wikiid || !$centralUser || !$centralUser->getId() || $memcData['gu_id'] != $centralUser->getId()) { $this->doFinalOutput(false, 'Invalid parameters'); return; } // Write info for session creation into memc $centralSession = $this->getCentralSession($centralUser, $this->getUser()); $memcData += array('userName' => $centralUser->getName(), 'token' => $centralUser->getAuthToken(), 'finalProto' => $centralSession['finalProto'], 'secureCookies' => $centralSession['secureCookies'], 'remember' => $centralSession['remember'], 'sessionId' => $centralSession['sessionId']); $wgMemc->set($key, $memcData, 60); $this->do302Redirect($wikiid, 'setCookies', $params); return; case 'setCookies': // Check that memcached is validated, and set cookies // Do not cache this, we need to reset the cookies and memc every time. $this->getOutput()->enableClientCache(false); if (!$this->checkIsLocalWiki()) { return; } CentralAuthUser::setP3P(); // Check saved memc token $token = $this->getRequest()->getSessionData('centralautologin-token'); if ($token === null) { $this->doFinalOutput(false, 'Lost session'); return; } // Load memc data $wikiid = wfWikiID(); $key = CentralAuthUser::memcKey('centralautologin-token', $token, $wikiid); $memcData = $wgMemc->get($key); $wgMemc->delete($key); // Check memc data if (!$memcData || $memcData['wikiid'] !== $wikiid || !isset($memcData['userName']) || !isset($memcData['token'])) { $this->doFinalOutput(false, 'Lost session'); return; } // Load and check CentralAuthUser. But don't check if it's // attached, because then if the user is missing en.site they // won't be auto logged in to any of the non-en versions either. $centralUser = new CentralAuthUser($memcData['userName']); if (!$centralUser->getId() || $centralUser->getId() != $memcData['gu_id']) { $msg = "Wrong user: expected {$memcData['gu_id']}, got {$centralUser->getId()}"; wfDebug(__METHOD__ . ": {$msg}\n"); $this->doFinalOutput(false, 'Lost session'); return; } $loginResult = $centralUser->authenticateWithToken($memcData['token']); if ($loginResult != 'ok') { $msg = "Bad token: {$loginResult}"; wfDebug(__METHOD__ . ": {$msg}\n"); $this->doFinalOutput(false, 'Lost session'); return; } // Set a new session cookie, Just In Case™ wfResetSessionID(); // Set central cookies too, with a refreshed sessionid. Also, check if we // need to override the default cookie security policy $secureCookie = $memcData['secureCookies']; $centralUser->setGlobalCookies($memcData['remember'], $memcData['sessionId'], $secureCookie, array('finalProto' => $memcData['finalProto'], 'secureCookies' => $memcData['secureCookies'], 'remember' => $memcData['remember'])); // Now, figure out how to report this back to the user. // First, set to redo the edge login on the next pageview $request->setSessionData('CentralAuthDoEdgeLogin', true); // If it's not a script callback, just go for it. if ($request->getVal('type') !== 'script') { $this->doFinalOutput(true, 'success'); return; } // If it is a script callback, then we do want to create the user // if it doesn't already exist locally (and fail if that can't be // done). if (!User::idFromName($centralUser->getName())) { $user = new User(); $user->setName($centralUser->getName()); if (CentralAuthHooks::attemptAddUser($user)) { $centralUser->invalidateCache(); } } if (!$centralUser->isAttached()) { $this->doFinalOutput(false, 'Local user is not attached', self::getInlineScript('anon-set.js')); return; } $script = self::getInlineScript('anon-remove.js'); // If we're returning to returnto, do that if ($request->getCheck('return')) { global $wgRedirectOnLogin; if ($wgRedirectOnLogin !== null) { $returnTo = $wgRedirectOnLogin; $returnToQuery = array(); } else { $returnTo = $request->getVal('returnto', ''); $returnToQuery = wfCgiToArray($request->getVal('returntoquery', '')); } $returnToTitle = Title::newFromText($returnTo); if (!$returnToTitle) { $returnToTitle = Title::newMainPage(); $returnToQuery = array(); } $redirectUrl = $returnToTitle->getFullURL($returnToQuery); $script .= "\n" . 'location.href = ' . Xml::encodeJsVar($redirectUrl) . ';'; $this->doFinalOutput(true, 'success', $script); return; } // Otherwise, we need to rewrite p-personal and maybe notify the user too global $wgCentralAuthUseEventLogging; if ($wgCentralAuthUseEventLogging) { EventLogging::logEvent('CentralAuth', 5690875, array('version' => 1, 'userId' => $centralUser->getId(), 'action' => 'sul2-autologin-fallbacklogin')); } // Add a script to the page that will pull in the user's toolslist // via ajax, and update the UI. Don't write out the tools here (bug 57081). $code = $this->getUser()->getOption('language'); $code = RequestContext::sanitizeLangCode($code); Hooks::run('UserGetLanguageObject', array($this->getUser(), &$code, $this->getContext())); $script .= "\n" . Xml::encodeJsCall('mediaWiki.messages.set', array(array('centralauth-centralautologin-logged-in' => wfMessage('centralauth-centralautologin-logged-in')->inLanguage($code)->plain(), 'centralauth-centralautologin-logged-in-nouser' => wfMessage('centralauth-centralautologin-logged-in-nouser')->inLanguage($code)->plain(), 'centralautologin' => wfMessage('centralautologin')->inLanguage($code)->plain()))); $script .= "\n" . self::getInlineScript('autologin.js'); // And for good measure, add the edge login HTML images to the page. $script .= "\n" . Xml::encodeJsCall("jQuery( 'body' ).append", array(CentralAuthHooks::getEdgeLoginHTML())); $this->doFinalOutput(true, 'success', $script); return; default: $this->setHeaders(); $this->getOutput()->addWikiMsg('centralauth-centralautologin-desc'); return; } }