Example #1
0
 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();
 }
Example #5
0
 /**
  * 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;
     }
 }