Advertisement
Guest User

Untitled

a guest
Sep 17th, 2017
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 37.54 KB | None | 0 0
  1. <?php
  2. /**
  3.  * @file
  4.  * @ingroup SpecialPage
  5.  */
  6.  
  7. /**
  8.  * constructor
  9.  */
  10. function wfSpecialUserlogin( $par = '' ) {
  11.     global $wgRequest;
  12.     if( session_id() == '' ) {
  13.         wfSetupSession();
  14.     }
  15.  
  16.     $form = new LoginForm( $wgRequest, $par );
  17.     $form->execute();
  18. }
  19.  
  20. /**
  21.  * implements Special:Login
  22.  * @ingroup SpecialPage
  23.  */
  24. class LoginForm {
  25.  
  26.     const SUCCESS = 0;
  27.     const NO_NAME = 1;
  28.     const ILLEGAL = 2;
  29.     const WRONG_PLUGIN_PASS = 3;
  30.     const NOT_EXISTS = 4;
  31.     const WRONG_PASS = 5;
  32.     const EMPTY_PASS = 6;
  33.     const RESET_PASS = 7;
  34.     const ABORTED = 8;
  35.     const CREATE_BLOCKED = 9;
  36.     const THROTTLED = 10;
  37.     const USER_BLOCKED = 11;
  38.     const NEED_TOKEN = 12;
  39.     const WRONG_TOKEN = 13;
  40.  
  41.     var $mName, $mPassword, $mRetype, $mReturnTo, $mCookieCheck, $mPosted;
  42.     var $mAction, $mCreateaccount, $mCreateaccountMail, $mMailmypassword;
  43.     var $mLoginattempt, $mRemember, $mEmail, $mDomain, $mLanguage;
  44.     var $mSkipCookieCheck, $mReturnToQuery, $mToken;
  45.  
  46.     private $mExtUser = null;
  47.  
  48.     /**
  49.      * Constructor
  50.      * @param $request WebRequest: a WebRequest object passed by reference
  51.      * @param $par String: subpage parameter
  52.      */
  53.     function LoginForm( &$request, $par = '' ) {
  54.         global $wgAuth, $wgHiddenPrefs, $wgEnableEmail, $wgRedirectOnLogin;
  55.  
  56.         $this->mType = ( $par == 'signup' ) ? $par : $request->getText( 'type' ); # Check for [[Special:Userlogin/signup]]
  57.         $this->mName = $request->getText( 'wpName' );
  58.         $this->mPassword = $request->getText( 'wpPassword' );
  59.         $this->mRetype = $request->getText( 'wpRetype' );
  60.         $this->mDomain = $request->getText( 'wpDomain' );
  61.         $this->mReturnTo = $request->getVal( 'returnto' );
  62.         $this->mReturnToQuery = $request->getVal( 'returntoquery' );
  63.         $this->mCookieCheck = $request->getVal( 'wpCookieCheck' );
  64.         $this->mPosted = $request->wasPosted();
  65.         $this->mCreateaccount = $request->getCheck( 'wpCreateaccount' );
  66.         $this->mCreateaccountMail = $request->getCheck( 'wpCreateaccountMail' )
  67.                                     && $wgEnableEmail;
  68.         $this->mMailmypassword = $request->getCheck( 'wpMailmypassword' )
  69.                                  && $wgEnableEmail;
  70.         $this->mLoginattempt = $request->getCheck( 'wpLoginattempt' );
  71.         $this->mAction = $request->getVal( 'action' );
  72.         $this->mRemember = $request->getCheck( 'wpRemember' );
  73.         $this->mLanguage = $request->getText( 'uselang' );
  74.         $this->mSkipCookieCheck = $request->getCheck( 'wpSkipCookieCheck' );
  75.         $this->mToken = ($this->mType == 'signup' ) ? $request->getVal( 'wpCreateaccountToken' ) : $request->getVal( 'wpLoginToken' );
  76.  
  77.         if ( $wgRedirectOnLogin ) {
  78.             $this->mReturnTo = $wgRedirectOnLogin;
  79.             $this->mReturnToQuery = '';
  80.         }
  81.  
  82.         if( $wgEnableEmail ) {
  83.             $this->mEmail = $request->getText( 'wpEmail' );
  84.         } else {
  85.             $this->mEmail = '';
  86.         }
  87.         if( !in_array( 'realname', $wgHiddenPrefs ) ) {
  88.             $this->mRealName = $request->getText( 'wpRealName' );
  89.         } else {
  90.             $this->mRealName = '';
  91.         }
  92.  
  93.         if( !$wgAuth->validDomain( $this->mDomain ) ) {
  94.             $this->mDomain = 'invaliddomain';
  95.         }
  96.         $wgAuth->setDomain( $this->mDomain );
  97.  
  98.         # When switching accounts, it sucks to get automatically logged out
  99.         $returnToTitle = Title::newFromText( $this->mReturnTo );
  100.         if( is_object( $returnToTitle ) && $returnToTitle->isSpecial( 'Userlogout' ) ) {
  101.             $this->mReturnTo = '';
  102.             $this->mReturnToQuery = '';
  103.         }
  104.     }
  105.  
  106.     function execute() {
  107.         if ( !is_null( $this->mCookieCheck ) ) {
  108.             $this->onCookieRedirectCheck( $this->mCookieCheck );
  109.             return;
  110.         } else if( $this->mPosted ) {
  111.             if( $this->mCreateaccount ) {
  112.                 return $this->addNewAccount();
  113.             } else if ( $this->mCreateaccountMail ) {
  114.                 return $this->addNewAccountMailPassword();
  115.             } else if ( $this->mMailmypassword ) {
  116.                 return $this->mailPassword();
  117.             } else if ( ( 'submitlogin' == $this->mAction ) || $this->mLoginattempt ) {
  118.                 return $this->processLogin();
  119.             }
  120.         }
  121.         $this->mainLoginForm( '' );
  122.     }
  123.  
  124.     /**
  125.      * @private
  126.      */
  127.     function addNewAccountMailPassword() {
  128.         global $wgOut;
  129.  
  130.         if ( $this->mEmail == '' ) {
  131.             $this->mainLoginForm( wfMsg( 'noemail', htmlspecialchars( $this->mName ) ) );
  132.             return;
  133.         }
  134.  
  135.         $u = $this->addNewaccountInternal();
  136.  
  137.         if ($u == null) {
  138.             return;
  139.         }
  140.  
  141.         // Wipe the initial password and mail a temporary one
  142.         $u->setPassword( null );
  143.         $u->saveSettings();
  144.         $result = $this->mailPasswordInternal( $u, false, 'createaccount-title', 'createaccount-text' );
  145.  
  146.         wfRunHooks( 'AddNewAccount', array( $u, true ) );
  147.         $u->addNewUserLogEntry();
  148.  
  149.         $wgOut->setPageTitle( wfMsg( 'accmailtitle' ) );
  150.         $wgOut->setRobotPolicy( 'noindex,nofollow' );
  151.         $wgOut->setArticleRelated( false );
  152.  
  153.         if( WikiError::isError( $result ) ) {
  154.             $this->mainLoginForm( wfMsg( 'mailerror', $result->getMessage() ) );
  155.         } else {
  156.             $wgOut->addWikiMsg( 'accmailtext', $u->getName(), $u->getEmail() );
  157.             $wgOut->returnToMain( false );
  158.         }
  159.         $u = 0;
  160.     }
  161.  
  162.  
  163.     /**
  164.      * @private
  165.      */
  166.     function addNewAccount() {
  167.         global $wgUser, $wgEmailAuthentication;
  168.  
  169.         # Create the account and abort if there's a problem doing so
  170.         $u = $this->addNewAccountInternal();
  171.         if( $u == null )
  172.             return;
  173.  
  174.         # If we showed up language selection links, and one was in use, be
  175.         # smart (and sensible) and save that language as the user's preference
  176.         global $wgLoginLanguageSelector;
  177.         if( $wgLoginLanguageSelector && $this->mLanguage )
  178.             $u->setOption( 'language', $this->mLanguage );
  179.  
  180.         # Send out an email authentication message if needed
  181.         if( $wgEmailAuthentication && User::isValidEmailAddr( $u->getEmail() ) ) {
  182.             global $wgOut;
  183.             $error = $u->sendConfirmationMail();
  184.             if( WikiError::isError( $error ) ) {
  185.                 $wgOut->addWikiMsg( 'confirmemail_sendfailed', $error->getMessage() );
  186.             } else {
  187.                 $wgOut->addWikiMsg( 'confirmemail_oncreate' );
  188.             }
  189.         }
  190.  
  191.         # Save settings (including confirmation token)
  192.         $u->saveSettings();
  193.  
  194.         # If not logged in, assume the new account as the current one and set
  195.         # session cookies then show a "welcome" message or a "need cookies"
  196.         # message as needed
  197.         if( $wgUser->isAnon() ) {
  198.             $wgUser = $u;
  199.             $wgUser->setCookies();
  200.             wfRunHooks( 'AddNewAccount', array( $wgUser, false ) );
  201.             $wgUser->addNewUserLogEntry();
  202.             if( $this->hasSessionCookie() ) {
  203.                 return $this->successfulCreation();
  204.             } else {
  205.                 return $this->cookieRedirectCheck( 'new' );
  206.             }
  207.         } else {
  208.             # Confirm that the account was created
  209.             global $wgOut;
  210.             $self = SpecialPage::getTitleFor( 'Userlogin' );
  211.             $wgOut->setPageTitle( wfMsgHtml( 'accountcreated' ) );
  212.             $wgOut->setArticleRelated( false );
  213.             $wgOut->setRobotPolicy( 'noindex,nofollow' );
  214.             $wgOut->addHTML( wfMsgWikiHtml( 'accountcreatedtext', $u->getName() ) );
  215.             $wgOut->returnToMain( false, $self );
  216.             wfRunHooks( 'AddNewAccount', array( $u, false ) );
  217.             $u->addNewUserLogEntry();
  218.             return true;
  219.         }
  220.     }
  221.  
  222.     /**
  223.      * @private
  224.      */
  225.     function addNewAccountInternal() {
  226.         global $wgUser, $wgOut;
  227.         global $wgMemc, $wgAccountCreationThrottle;
  228.         global $wgAuth, $wgMinimalPasswordLength;
  229.         global $wgEmailConfirmToEdit;
  230.  
  231.         // If the user passes an invalid domain, something is fishy
  232.         if( !$wgAuth->validDomain( $this->mDomain ) ) {
  233.             $this->mainLoginForm( wfMsg( 'wrongpassword' ) );
  234.             return false;
  235.         }
  236.  
  237.         // If we are not allowing users to login locally, we should be checking
  238.         // to see if the user is actually able to authenticate to the authenti-
  239.         // cation server before they create an account (otherwise, they can
  240.         // create a local account and login as any domain user). We only need
  241.         // to check this for domains that aren't local.
  242.         if( 'local' != $this->mDomain && $this->mDomain != '' ) {
  243.             if( !$wgAuth->canCreateAccounts() && ( !$wgAuth->userExists( $this->mName ) || !$wgAuth->authenticate( $this->mName, $this->mPassword ) ) ) {
  244.                 $this->mainLoginForm( wfMsg( 'wrongpassword' ) );
  245.                 return false;
  246.             }
  247.         }
  248.  
  249.         if ( wfReadOnly() ) {
  250.             $wgOut->readOnlyPage();
  251.             return false;
  252.         }
  253.  
  254.         # Request forgery checks.
  255.         if ( !self::getCreateaccountToken() ) {
  256.             wfDebug( "getCreateaccountToken() check failed\n" );
  257.             self::setCreateaccountToken();
  258.             $this->mainLoginForm( wfMsg( 'sessionfailure' ) );
  259.             return false;
  260.         }
  261.        
  262.         # The user didn't pass a createaccount token
  263.         if ( !$this->mToken ) {
  264.             wfDebug( "The user didn't pass a createaccount token\n" );
  265.             $this->mainLoginForm( wfMsg( 'sessionfailure' ) );
  266.             return false;
  267.         }
  268.        
  269.         # Validate the createaccount token
  270.         if ( $this->mToken !== self::getCreateaccountToken() ) {
  271.             wfDebug( "Tokens don't match\n" );
  272.             $this->mainLoginForm( wfMsg( 'sessionfailure' ) );
  273.             return false;
  274.         }
  275.  
  276.         # Check permissions
  277.         if ( !$wgUser->isAllowed( 'createaccount' ) ) {
  278.             $this->userNotPrivilegedMessage();
  279.             return false;
  280.         } elseif ( $wgUser->isBlockedFromCreateAccount() ) {
  281.             $this->userBlockedMessage();
  282.             return false;
  283.         }
  284.  
  285.         $ip = wfGetIP();
  286.         if ( $wgUser->isDnsBlacklisted( $ip, true /* check $wgProxyWhitelist */ ) ) {
  287.             $this->mainLoginForm( wfMsg( 'sorbs_create_account_reason' ) . ' (' . htmlspecialchars( $ip ) . ')' );
  288.             return false;
  289.         }
  290.  
  291.         # Now create a dummy user ($u) and check if it is valid
  292.         $name = trim( $this->mName );
  293.         $u = User::newFromName( $name, 'creatable' );
  294.         if ( !is_object( $u ) ) {
  295.             $this->mainLoginForm( wfMsg( 'noname' ) );
  296.             return false;
  297.         }
  298.  
  299.         if ( 0 != $u->idForName() ) {
  300.             $this->mainLoginForm( wfMsg( 'userexists' ) );
  301.             return false;
  302.         }
  303.  
  304.         if ( 0 != strcmp( $this->mPassword, $this->mRetype ) ) {
  305.             $this->mainLoginForm( wfMsg( 'badretype' ) );
  306.             return false;
  307.         }
  308.  
  309.         # check for minimal password length
  310.         $valid = $u->getPasswordValidity( $this->mPassword );
  311.         if ( $valid !== true ) {
  312.             if ( !$this->mCreateaccountMail ) {
  313.                 $this->mainLoginForm( wfMsgExt( $valid, array( 'parsemag' ), $wgMinimalPasswordLength ) );
  314.                 return false;
  315.             } else {
  316.                 # do not force a password for account creation by email
  317.                 # set invalid password, it will be replaced later by a random generated password
  318.                 $this->mPassword = null;
  319.             }
  320.         }
  321.  
  322.         # if you need a confirmed email address to edit, then obviously you
  323.         # need an email address.
  324.         if ( $wgEmailConfirmToEdit && empty( $this->mEmail ) ) {
  325.             $this->mainLoginForm( wfMsg( 'noemailtitle' ) );
  326.             return false;
  327.         }
  328.  
  329.         if( !empty( $this->mEmail ) && !User::isValidEmailAddr( $this->mEmail ) ) {
  330.             $this->mainLoginForm( wfMsg( 'invalidemailaddress' ) );
  331.             return false;
  332.         }
  333.  
  334.         # Set some additional data so the AbortNewAccount hook can be used for
  335.         # more than just username validation
  336.         $u->setEmail( $this->mEmail );
  337.         $u->setRealName( $this->mRealName );
  338.  
  339.         $abortError = '';
  340.         if( !wfRunHooks( 'AbortNewAccount', array( $u, &$abortError ) ) ) {
  341.             // Hook point to add extra creation throttles and blocks
  342.             wfDebug( "LoginForm::addNewAccountInternal: a hook blocked creation\n" );
  343.             $this->mainLoginForm( $abortError );
  344.             return false;
  345.         }
  346.  
  347.         if ( $wgAccountCreationThrottle && $wgUser->isPingLimitable() ) {
  348.             $key = wfMemcKey( 'acctcreate', 'ip', $ip );
  349.             $value = $wgMemc->get( $key );
  350.             if ( !$value ) {
  351.                 $wgMemc->set( $key, 0, 86400 );
  352.             }
  353.             if ( $value >= $wgAccountCreationThrottle ) {
  354.                 $this->throttleHit( $wgAccountCreationThrottle );
  355.                 return false;
  356.             }
  357.             $wgMemc->incr( $key );
  358.         }
  359.  
  360.         if( !$wgAuth->addUser( $u, $this->mPassword, $this->mEmail, $this->mRealName ) ) {
  361.             $this->mainLoginForm( wfMsg( 'externaldberror' ) );
  362.             return false;
  363.         }
  364.  
  365.         self::clearCreateaccountToken();       
  366.         return $this->initUser( $u, false );
  367.     }
  368.  
  369.     /**
  370.      * Actually add a user to the database.
  371.      * Give it a User object that has been initialised with a name.
  372.      *
  373.      * @param $u User object.
  374.      * @param $autocreate boolean -- true if this is an autocreation via auth plugin
  375.      * @return User object.
  376.      * @private
  377.      */
  378.     function initUser( $u, $autocreate ) {
  379.         global $wgAuth;
  380.  
  381.         $u->addToDatabase();
  382.  
  383.         if ( $wgAuth->allowPasswordChange() ) {
  384.             $u->setPassword( $this->mPassword );
  385.         }
  386.  
  387.         $u->setEmail( $this->mEmail );
  388.         $u->setRealName( $this->mRealName );
  389.         $u->setToken();
  390.  
  391.         $wgAuth->initUser( $u, $autocreate );
  392.  
  393.         if ( $this->mExtUser ) {
  394.             $this->mExtUser->linkToLocal( $u->getId() );
  395.             $email = $this->mExtUser->getPref( 'emailaddress' );
  396.             if ( $email && !$this->mEmail ) {
  397.                 $u->setEmail( $email );
  398.             }
  399.         }
  400.  
  401.         $u->setOption( 'rememberpassword', $this->mRemember ? 1 : 0 );
  402.         $u->saveSettings();
  403.  
  404.         # Update user count
  405.         $ssUpdate = new SiteStatsUpdate( 0, 0, 0, 0, 1 );
  406.         $ssUpdate->doUpdate();
  407.  
  408.         return $u;
  409.     }
  410.  
  411.     /**
  412.      * Internally authenticate the login request.
  413.      *
  414.      * This may create a local account as a side effect if the
  415.      * authentication plugin allows transparent local account
  416.      * creation.
  417.      */
  418.     public function authenticateUserData() {
  419.         global $wgUser, $wgAuth;
  420.         if ( $this->mName == '' ) {
  421.             return self::NO_NAME;
  422.         }
  423.        
  424.         // We require a login token to prevent login CSRF
  425.         // Handle part of this before incrementing the throttle so
  426.         // token-less login attempts don't count towards the throttle
  427.         // but wrong-token attempts do.
  428.        
  429.         // If the user doesn't have a login token yet, set one.
  430.         if ( !self::getLoginToken() ) {
  431.             self::setLoginToken();
  432.             return self::NEED_TOKEN;
  433.         }
  434.         // If the user didn't pass a login token, tell them we need one
  435.         if ( !$this->mToken ) {
  436.             return self::NEED_TOKEN;
  437.         }
  438.        
  439.         global $wgPasswordAttemptThrottle;
  440.  
  441.         $throttleCount = 0;
  442.         if ( is_array( $wgPasswordAttemptThrottle ) ) {
  443.             $throttleKey = wfMemcKey( 'password-throttle', wfGetIP(), md5( $this->mName ) );
  444.             $count = $wgPasswordAttemptThrottle['count'];
  445.             $period = $wgPasswordAttemptThrottle['seconds'];
  446.            
  447.             global $wgMemc;
  448.             $throttleCount = $wgMemc->get( $throttleKey );
  449.             if ( !$throttleCount ) {
  450.                 $wgMemc->add( $throttleKey, 1, $period ); // start counter
  451.             } else if ( $throttleCount < $count ) {
  452.                 $wgMemc->incr($throttleKey);
  453.             } else if ( $throttleCount >= $count ) {
  454.                 return self::THROTTLED;
  455.             }
  456.         }
  457.        
  458.         // Validate the login token
  459.         if ( $this->mToken !== self::getLoginToken() ) {
  460.             return self::WRONG_TOKEN;
  461.         }
  462.  
  463.         // Load $wgUser now, and check to see if we're logging in as the same
  464.         // name. This is necessary because loading $wgUser (say by calling
  465.         // getName()) calls the UserLoadFromSession hook, which potentially
  466.         // creates the user in the database. Until we load $wgUser, checking
  467.         // for user existence using User::newFromName($name)->getId() below
  468.         // will effectively be using stale data.
  469.         if ( $wgUser->getName() === $this->mName ) {
  470.             wfDebug( __METHOD__.": already logged in as {$this->mName}\n" );
  471.             return self::SUCCESS;
  472.         }
  473.  
  474.         $this->mExtUser = ExternalUser::newFromName( $this->mName );
  475.  
  476.         # TODO: Allow some magic here for invalid external names, e.g., let the
  477.         # user choose a different wiki name.
  478.         $u = User::newFromName( $this->mName );
  479.         if( !( $u instanceof User ) || !User::isUsableName( $u->getName() ) ) {
  480.             return self::ILLEGAL;
  481.         }
  482.  
  483.         $isAutoCreated = false;
  484.         if ( 0 == $u->getID() ) {
  485.             $status = $this->attemptAutoCreate( $u );
  486.             if ( $status !== self::SUCCESS ) {
  487.                 return $status;
  488.             } else {
  489.                 $isAutoCreated = true;
  490.             }
  491.         } else {
  492.             global $wgExternalAuthType, $wgAutocreatePolicy;
  493.             if ( $wgExternalAuthType && $wgAutocreatePolicy != 'never'
  494.             && is_object( $this->mExtUser )
  495.             && $this->mExtUser->authenticate( $this->mPassword ) ) {
  496.                 # The external user and local user have the same name and
  497.                 # password, so we assume they're the same.
  498.                 $this->mExtUser->linkToLocal( $u->getID() );
  499.             }
  500.  
  501.             $u->load();
  502.         }
  503.  
  504.         // Give general extensions, such as a captcha, a chance to abort logins
  505.         $abort = self::ABORTED;
  506.         if( !wfRunHooks( 'AbortLogin', array( $u, $this->mPassword, &$abort ) ) ) {
  507.             return $abort;
  508.         }
  509.  
  510.         global $wgBlockDisablesLogin;
  511.         if (!$u->checkPassword( $this->mPassword )) {
  512.             if( $u->checkTemporaryPassword( $this->mPassword ) ) {
  513.                 // The e-mailed temporary password should not be used for actu-
  514.                 // al logins; that's a very sloppy habit, and insecure if an
  515.                 // attacker has a few seconds to click "search" on someone's o-
  516.                 // pen mail reader.
  517.                 //
  518.                 // Allow it to be used only to reset the password a single time
  519.                 // to a new value, which won't be in the user's e-mail ar-
  520.                 // chives.
  521.                 //
  522.                 // For backwards compatibility, we'll still recognize it at the
  523.                 // login form to minimize surprises for people who have been
  524.                 // logging in with a temporary password for some time.
  525.                 //
  526.                 // As a side-effect, we can authenticate the user's e-mail ad-
  527.                 // dress if it's not already done, since the temporary password
  528.                 // was sent via e-mail.
  529.                 if( !$u->isEmailConfirmed() ) {
  530.                     $u->confirmEmail();
  531.                     $u->saveSettings();
  532.                 }
  533.  
  534.                 // At this point we just return an appropriate code/ indicating
  535.                 // that the UI should show a password reset form; bot inter-
  536.                 // faces etc will probably just fail cleanly here.
  537.                 $retval = self::RESET_PASS;
  538.             } else {
  539.                 $retval = ($this->mPassword  == '') ? self::EMPTY_PASS : self::WRONG_PASS;
  540.             }
  541.         } elseif ( $wgBlockDisablesLogin && $u->isBlocked() ) {
  542.             // If we've enabled it, make it so that a blocked user cannot login
  543.             $retval = self::USER_BLOCKED;
  544.         } else {
  545.             $wgAuth->updateUser( $u );
  546.             $wgUser = $u;
  547.  
  548.             // Please reset throttle for successful logins, thanks!
  549.             if($throttleCount) {
  550.                 $wgMemc->delete($throttleKey);
  551.             }
  552.  
  553.             if ( $isAutoCreated ) {
  554.                 // Must be run after $wgUser is set, for correct new user log
  555.                 wfRunHooks( 'AuthPluginAutoCreate', array( $wgUser ) );
  556.             }
  557.  
  558.             $retval = self::SUCCESS;
  559.         }
  560.         wfRunHooks( 'LoginAuthenticateAudit', array( $u, $this->mPassword, $retval ) );
  561.         return $retval;
  562.     }
  563.  
  564.     /**
  565.      * Attempt to automatically create a user on login. Only succeeds if there
  566.      * is an external authentication method which allows it.
  567.      * @return integer Status code
  568.      */
  569.     function attemptAutoCreate( $user ) {
  570.         global $wgAuth, $wgUser, $wgAutocreatePolicy;
  571.  
  572.         if ( $wgUser->isBlockedFromCreateAccount() ) {
  573.             wfDebug( __METHOD__.": user is blocked from account creation\n" );
  574.             return self::CREATE_BLOCKED;
  575.         }
  576.  
  577.         /**
  578.          * If the external authentication plugin allows it, automatically cre-
  579.          * ate a new account for users that are externally defined but have not
  580.          * yet logged in.
  581.          */
  582.         if ( $this->mExtUser ) {
  583.             # mExtUser is neither null nor false, so use the new ExternalAuth
  584.             # system.
  585.             if ( $wgAutocreatePolicy == 'never' ) {
  586.                 return self::NOT_EXISTS;
  587.             }
  588.             if ( !$this->mExtUser->authenticate( $this->mPassword ) ) {
  589.                 return self::WRONG_PLUGIN_PASS;
  590.             }
  591.         } else {
  592.             # Old AuthPlugin.
  593.             if ( !$wgAuth->autoCreate() ) {
  594.                 return self::NOT_EXISTS;
  595.             }
  596.             if ( !$wgAuth->userExists( $user->getName() ) ) {
  597.                 wfDebug( __METHOD__.": user does not exist\n" );
  598.                 return self::NOT_EXISTS;
  599.             }
  600.             if ( !$wgAuth->authenticate( $user->getName(), $this->mPassword ) ) {
  601.                 wfDebug( __METHOD__.": \$wgAuth->authenticate() returned false, aborting\n" );
  602.                 return self::WRONG_PLUGIN_PASS;
  603.             }
  604.         }
  605.  
  606.         wfDebug( __METHOD__.": creating account\n" );
  607.         $user = $this->initUser( $user, true );
  608.         return self::SUCCESS;
  609.     }
  610.  
  611.     function processLogin() {
  612.         global $wgUser, $wgAuth;
  613.  
  614.         switch ( $this->authenticateUserData() ) {
  615.             case self::SUCCESS:
  616.                 # We've verified now, update the real record
  617.                 if( (bool)$this->mRemember != (bool)$wgUser->getOption( 'rememberpassword' ) ) {
  618.                     $wgUser->setOption( 'rememberpassword', $this->mRemember ? 1 : 0 );
  619.                     $wgUser->saveSettings();
  620.                 } else {
  621.                     $wgUser->invalidateCache();
  622.                 }
  623.                 $wgUser->setCookies();
  624.                 self::clearLoginToken();
  625.  
  626.                 // Reset the throttle
  627.                 $key = wfMemcKey( 'password-throttle', wfGetIP(), md5( $this->mName ) );
  628.                 global $wgMemc;
  629.                 $wgMemc->delete( $key );
  630.  
  631.                 if( $this->hasSessionCookie() || $this->mSkipCookieCheck ) {
  632.                     /* Replace the language object to provide user interface in
  633.                      * correct language immediately on this first page load.
  634.                      */
  635.                     global $wgLang, $wgRequest;
  636.                     $code = $wgRequest->getVal( 'uselang', $wgUser->getOption( 'language' ) );
  637.                     $wgLang = Language::factory( $code );
  638.                     return $this->successfulLogin();
  639.                 } else {
  640.                     return $this->cookieRedirectCheck( 'login' );
  641.                 }
  642.                 break;
  643.            
  644.             case self::NEED_TOKEN:
  645.             case self::WRONG_TOKEN:
  646.                 $this->mainLoginForm( wfMsg( 'sessionfailure' ) );
  647.                 break;
  648.             case self::NO_NAME:
  649.             case self::ILLEGAL:
  650.                 $this->mainLoginForm( wfMsg( 'noname' ) );
  651.                 break;
  652.             case self::WRONG_PLUGIN_PASS:
  653.                 $this->mainLoginForm( wfMsg( 'wrongpassword' ) );
  654.                 break;
  655.             case self::NOT_EXISTS:
  656.                 if( $wgUser->isAllowed( 'createaccount' ) ){
  657.                     $this->mainLoginForm( wfMsgWikiHtml( 'nosuchuser', htmlspecialchars( $this->mName ) ) );
  658.                 } else {
  659.                     $this->mainLoginForm( wfMsg( 'nosuchusershort', htmlspecialchars( $this->mName ) ) );
  660.                 }
  661.                 break;
  662.             case self::WRONG_PASS:
  663.                 $this->mainLoginForm( wfMsg( 'wrongpassword' ) );
  664.                 break;
  665.             case self::EMPTY_PASS:
  666.                 $this->mainLoginForm( wfMsg( 'wrongpasswordempty' ) );
  667.                 break;
  668.             case self::RESET_PASS:
  669.                 $this->resetLoginForm( wfMsg( 'resetpass_announce' ) );
  670.                 break;
  671.             case self::CREATE_BLOCKED:
  672.                 $this->userBlockedMessage();
  673.                 break;
  674.             case self::THROTTLED:
  675.                 $this->mainLoginForm( wfMsg( 'login-throttled' ) );
  676.                 break;
  677.             case self::USER_BLOCKED:
  678.                 $this->mainLoginForm( wfMsgExt( 'login-userblocked',
  679.                     array( 'parsemag', 'escape' ), $this->mName ) );
  680.                 break;
  681.             default:
  682.                 throw new MWException( "Unhandled case value" );
  683.         }
  684.     }
  685.  
  686.     function resetLoginForm( $error ) {
  687.         global $wgOut;
  688.         $wgOut->addHTML( Xml::element('p', array( 'class' => 'error' ), $error ) );
  689.         $reset = new SpecialResetpass();
  690.         $reset->execute( null );
  691.     }
  692.  
  693.     /**
  694.      * @private
  695.      */
  696.     function mailPassword() {
  697.         global $wgUser, $wgOut, $wgAuth;
  698.        
  699.         if ( wfReadOnly() ) {
  700.             $wgOut->readOnlyPage();
  701.             return false;
  702.         }
  703.        
  704.         if( !$wgAuth->allowPasswordChange() ) {
  705.             $this->mainLoginForm( wfMsg( 'resetpass_forbidden' ) );
  706.             return;
  707.         }
  708.  
  709.         # Check against blocked IPs so blocked users can't flood admins
  710.         # with password resets
  711.         if( $wgUser->isBlocked() ) {
  712.             $this->mainLoginForm( wfMsg( 'blocked-mailpassword' ) );
  713.             return;
  714.         }
  715.        
  716.         # Check for hooks
  717.         $error = null;
  718.         if ( ! wfRunHooks( 'UserLoginMailPassword', array( $this->mName, &$error ) ) ) {
  719.             $this->mainLoginForm( $error );
  720.             return;
  721.         }
  722.  
  723.         # If the user doesn't have a login token yet, set one.
  724.         if ( !self::getLoginToken() ) {
  725.             self::setLoginToken();
  726.             $this->mainLoginForm( wfMsg( 'sessionfailure' ) );
  727.             return;
  728.         }
  729.  
  730.         # If the user didn't pass a login token, tell them we need one
  731.         if ( !$this->mToken ) {
  732.             $this->mainLoginForm( wfMsg( 'sessionfailure' ) );
  733.             return;
  734.         }
  735.        
  736.         # Check against the rate limiter
  737.         if( $wgUser->pingLimiter( 'mailpassword' ) ) {
  738.             $wgOut->rateLimited();
  739.             return;
  740.         }
  741.  
  742.         if ( $this->mName == '' ) {
  743.             $this->mainLoginForm( wfMsg( 'noname' ) );
  744.             return;
  745.         }
  746.         $u = User::newFromName( $this->mName );
  747.         if( !$u instanceof User ) {
  748.             $this->mainLoginForm( wfMsg( 'noname' ) );
  749.             return;
  750.         }
  751.         if ( 0 == $u->getID() ) {
  752.             $this->mainLoginForm( wfMsgWikiHtml( 'nosuchuser', htmlspecialchars( $u->getName() ) ) );
  753.             return;
  754.         }
  755.  
  756.         # Validate the login token
  757.         if ( $this->mToken !== self::getLoginToken() ) {
  758.             $this->mainLoginForm( wfMsg( 'sessionfailure' ) );
  759.             return;
  760.         }
  761.  
  762.         # Check against password throttle
  763.         if ( $u->isPasswordReminderThrottled() ) {
  764.             global $wgPasswordReminderResendTime;
  765.             # Round the time in hours to 3 d.p., in case someone is specifying
  766.             # minutes or seconds.
  767.             $this->mainLoginForm( wfMsgExt( 'throttled-mailpassword', array( 'parsemag' ),
  768.                 round( $wgPasswordReminderResendTime, 3 ) ) );
  769.             return;
  770.         }
  771.  
  772.         $result = $this->mailPasswordInternal( $u, true, 'passwordremindertitle', 'passwordremindertext' );
  773.         if( WikiError::isError( $result ) ) {
  774.             $this->mainLoginForm( wfMsg( 'mailerror', $result->getMessage() ) );
  775.         } else {
  776.             $this->mainLoginForm( wfMsg( 'passwordsent', $u->getName() ), 'success' );
  777.             self::clearLoginToken();
  778.         }
  779.     }
  780.  
  781.  
  782.     /**
  783.      * @param $u User object
  784.      * @param $throttle Boolean
  785.      * @param $emailTitle String: message name of email title
  786.      * @param $emailText String: message name of email text
  787.      * @return Mixed: true on success, WikiError on failure
  788.      * @private
  789.      */
  790.     function mailPasswordInternal( $u, $throttle = true, $emailTitle = 'passwordremindertitle', $emailText = 'passwordremindertext' ) {
  791.         global $wgServer, $wgScript, $wgUser, $wgNewPasswordExpiry;
  792.  
  793.         if ( $u->getEmail() == '' ) {
  794.             return new WikiError( wfMsg( 'noemail', $u->getName() ) );
  795.         }
  796.         $ip = wfGetIP();
  797.         if( !$ip ) {
  798.             return new WikiError( wfMsg( 'badipaddress' ) );
  799.         }
  800.        
  801.         wfRunHooks( 'User::mailPasswordInternal', array(&$wgUser, &$ip, &$u) );
  802.  
  803.         $np = $u->randomPassword();
  804.         $u->setNewpassword( $np, $throttle );
  805.         $u->saveSettings();
  806.         $userLanguage = $u->getOption( 'language' );
  807.         $m = wfMsgExt( $emailText, array( 'parsemag', 'language' => $userLanguage ), $ip, $u->getName(), $np,
  808.                 $wgServer . $wgScript, round( $wgNewPasswordExpiry / 86400 ) );
  809.         $result = $u->sendMail( wfMsgExt( $emailTitle, array( 'parsemag', 'language' => $userLanguage ) ), $m );
  810.  
  811.         return $result;
  812.     }
  813.  
  814.  
  815.     /**
  816.      * Run any hooks registered for logins, then HTTP redirect to
  817.      * $this->mReturnTo (or Main Page if that's undefined).  Formerly we had a
  818.      * nice message here, but that's really not as useful as just being sent to
  819.      * wherever you logged in from.  It should be clear that the action was
  820.      * successful, given the lack of error messages plus the appearance of your
  821.      * name in the upper right.
  822.      *
  823.      * @private
  824.      */
  825.     function successfulLogin() {
  826.         global $wgUser, $wgOut;
  827.  
  828.         # Run any hooks; display injected HTML if any, else redirect
  829.         $injected_html = '';
  830.         wfRunHooks('UserLoginComplete', array(&$wgUser, &$injected_html));
  831.  
  832.         if( $injected_html !== '' ) {
  833.             $this->displaySuccessfulLogin( 'loginsuccess', $injected_html );
  834.         } else {
  835.             $titleObj = Title::newFromText( $this->mReturnTo );
  836.             if ( !$titleObj instanceof Title ) {
  837.                 $titleObj = Title::newMainPage();
  838.             }
  839.             $wgOut->redirect( $titleObj->getFullURL( $this->mReturnToQuery ) );
  840.         }
  841.     }
  842.  
  843.     /**
  844.      * Run any hooks registered for logins, then display a message welcoming
  845.      * the user.
  846.      *
  847.      * @private
  848.      */
  849.     function successfulCreation() {
  850.         global $wgUser, $wgOut;
  851.  
  852.         # Run any hooks; display injected HTML
  853.         $injected_html = '';
  854.         wfRunHooks('UserLoginComplete', array(&$wgUser, &$injected_html));
  855.  
  856.         $this->displaySuccessfulLogin( 'welcomecreation', $injected_html );
  857.     }
  858.  
  859.     /**
  860.      * Display a "login successful" page.
  861.      */
  862.     private function displaySuccessfulLogin( $msgname, $injected_html ) {
  863.         global $wgOut, $wgUser;
  864.  
  865.         $wgOut->setPageTitle( wfMsg( 'loginsuccesstitle' ) );
  866.         $wgOut->setRobotPolicy( 'noindex,nofollow' );
  867.         $wgOut->setArticleRelated( false );
  868.         $wgOut->addWikiMsg( $msgname, $wgUser->getName() );
  869.         $wgOut->addHTML( $injected_html );
  870.  
  871.         if ( !empty( $this->mReturnTo ) ) {
  872.             $wgOut->returnToMain( null, $this->mReturnTo, $this->mReturnToQuery );
  873.         } else {
  874.             $wgOut->returnToMain( null );
  875.         }
  876.     }
  877.  
  878.     /** */
  879.     function userNotPrivilegedMessage($errors) {
  880.         global $wgOut;
  881.  
  882.         $wgOut->setPageTitle( wfMsg( 'permissionserrors' ) );
  883.         $wgOut->setRobotPolicy( 'noindex,nofollow' );
  884.         $wgOut->setArticleRelated( false );
  885.  
  886.         $wgOut->addWikitext( $wgOut->formatPermissionsErrorMessage( $errors, 'createaccount' ) );
  887.         // Stuff that might want to be added at the end. For example, instruc-
  888.         // tions if blocked.
  889.         $wgOut->addWikiMsg( 'cantcreateaccount-nonblock-text' );
  890.  
  891.         $wgOut->returnToMain( false );
  892.     }
  893.  
  894.     /** */
  895.     function userBlockedMessage() {
  896.         global $wgOut, $wgUser;
  897.  
  898.         # Let's be nice about this, it's likely that this feature will be used
  899.         # for blocking large numbers of innocent people, e.g. range blocks on
  900.         # schools. Don't blame it on the user. There's a small chance that it
  901.         # really is the user's fault, i.e. the username is blocked and they
  902.         # haven't bothered to log out before trying to create an account to
  903.         # evade it, but we'll leave that to their guilty conscience to figure
  904.         # out.
  905.  
  906.         $wgOut->setPageTitle( wfMsg( 'cantcreateaccounttitle' ) );
  907.         $wgOut->setRobotPolicy( 'noindex,nofollow' );
  908.         $wgOut->setArticleRelated( false );
  909.  
  910.         $ip = wfGetIP();
  911.         $blocker = User::whoIs( $wgUser->mBlock->mBy );
  912.         $block_reason = $wgUser->mBlock->mReason;
  913.  
  914.         if ( strval( $block_reason ) === '' ) {
  915.             $block_reason = wfMsg( 'blockednoreason' );
  916.         }
  917.         $wgOut->addWikiMsg( 'cantcreateaccount-text', $ip, $block_reason, $blocker );
  918.         $wgOut->returnToMain( false );
  919.     }
  920.  
  921.     /**
  922.      * @private
  923.      */
  924.     function mainLoginForm( $msg, $msgtype = 'error' ) {
  925.         global $wgUser, $wgOut, $wgHiddenPrefs, $wgEnableEmail;
  926.         global $wgCookiePrefix, $wgLoginLanguageSelector;
  927.         global $wgAuth, $wgEmailConfirmToEdit, $wgCookieExpiration;
  928.        
  929.         $titleObj = SpecialPage::getTitleFor( 'Userlogin' );
  930.        
  931.         if ( $this->mType == 'signup' ) {
  932.             // Block signup here if in readonly. Keeps user from
  933.             // going through the process (filling out data, etc)
  934.             // and being informed later.
  935.             if ( wfReadOnly() ) {
  936.                 $wgOut->readOnlyPage();
  937.                 return;
  938.             } elseif ( $wgUser->isBlockedFromCreateAccount() ) {
  939.                 $this->userBlockedMessage();
  940.                 return;
  941.             } elseif ( count( $permErrors = $titleObj->getUserPermissionsErrors( 'createaccount', $wgUser, true ) )>0 ) {
  942.                 $wgOut->showPermissionsErrorPage( $permErrors, 'createaccount' );
  943.                 return;
  944.             }
  945.         }
  946.  
  947.         if ( $this->mName == '' ) {
  948.             if ( $wgUser->isLoggedIn() ) {
  949.                 $this->mName = $wgUser->getName();
  950.             } else {
  951.                 $this->mName = isset( $_COOKIE[$wgCookiePrefix.'UserName'] ) ? $_COOKIE[$wgCookiePrefix.'UserName'] : null;
  952.             }
  953.         }
  954.  
  955.         $titleObj = SpecialPage::getTitleFor( 'Userlogin' );
  956.  
  957.         if ( $this->mType == 'signup' ) {
  958.             $template = new UsercreateTemplate();
  959.             $q = 'action=submitlogin&type=signup';
  960.             $linkq = 'type=login';
  961.             $linkmsg = 'gotaccount';
  962.         } else {
  963.             $template = new UserloginTemplate();
  964.             $q = 'action=submitlogin&type=login';
  965.             $linkq = 'type=signup';
  966.             $linkmsg = 'nologin';
  967.         }
  968.  
  969.         if ( !empty( $this->mReturnTo ) ) {
  970.             $returnto = '&returnto=' . wfUrlencode( $this->mReturnTo );
  971.             if ( !empty( $this->mReturnToQuery ) )
  972.                 $returnto .= '&returntoquery=' .
  973.                     wfUrlencode( $this->mReturnToQuery );
  974.             $q .= $returnto;
  975.             $linkq .= $returnto;
  976.         }
  977.  
  978.         # Pass any language selection on to the mode switch link
  979.         if( $wgLoginLanguageSelector && $this->mLanguage )
  980.             $linkq .= '&uselang=' . $this->mLanguage;
  981.  
  982.         $link = '<a href="' . htmlspecialchars ( $titleObj->getLocalUrl( $linkq ) ) . '">';
  983.         $link .= wfMsgHtml( $linkmsg . 'link' ); # Calling either 'gotaccountlink' or 'nologinlink'
  984.         $link .= '</a>';
  985.  
  986.         # Don't show a "create account" link if the user can't
  987.         if( $this->showCreateOrLoginLink( $wgUser ) )
  988.             $template->set( 'link', wfMsgWikiHtml( $linkmsg, $link ) );
  989.         else
  990.             $template->set( 'link', '' );
  991.  
  992.         $template->set( 'header', '' );
  993.         $template->set( 'name', $this->mName );
  994.         $template->set( 'password', $this->mPassword );
  995.         $template->set( 'retype', $this->mRetype );
  996.         $template->set( 'email', $this->mEmail );
  997.         $template->set( 'realname', $this->mRealName );
  998.         $template->set( 'domain', $this->mDomain );
  999.  
  1000.         $template->set( 'action', $titleObj->getLocalUrl( $q ) );
  1001.         $template->set( 'message', $msg );
  1002.         $template->set( 'messagetype', $msgtype );
  1003.         $template->set( 'createemail', $wgEnableEmail && $wgUser->isLoggedIn() );
  1004.         $template->set( 'userealname', !in_array( 'realname', $wgHiddenPrefs ) );
  1005.         $template->set( 'useemail', $wgEnableEmail );
  1006.         $template->set( 'emailrequired', $wgEmailConfirmToEdit );
  1007.         $template->set( 'canreset', $wgAuth->allowPasswordChange() );
  1008.         $template->set( 'canremember', ( $wgCookieExpiration > 0 ) );
  1009.         $template->set( 'remember', $wgUser->getOption( 'rememberpassword' ) or $this->mRemember  );
  1010.  
  1011.         if ( $this->mType == 'signup' ) {
  1012.             if ( !self::getCreateaccountToken() ) {
  1013.                 self::setCreateaccountToken();
  1014.             }
  1015.             $template->set( 'token', self::getCreateaccountToken() );
  1016.         } else {
  1017.             if ( !self::getLoginToken() ) {
  1018.                 self::setLoginToken();
  1019.             }
  1020.             $template->set( 'token', self::getLoginToken() );
  1021.         }
  1022.        
  1023.         # Prepare language selection links as needed
  1024.         if( $wgLoginLanguageSelector ) {
  1025.             $template->set( 'languages', $this->makeLanguageSelector() );
  1026.             if( $this->mLanguage )
  1027.                 $template->set( 'uselang', $this->mLanguage );
  1028.         }
  1029.  
  1030.         // Give authentication and captcha plugins a chance to modify the form
  1031.         $wgAuth->modifyUITemplate( $template, $this->mType );
  1032.         if ( $this->mType == 'signup' ) {
  1033.             wfRunHooks( 'UserCreateForm', array( &$template ) );
  1034.         } else {
  1035.             wfRunHooks( 'UserLoginForm', array( &$template ) );
  1036.         }
  1037.  
  1038.         //Changes the title depending on permissions for creating account
  1039.         if ( $wgUser->isAllowed( 'createaccount' ) ) {
  1040.             $wgOut->setPageTitle( wfMsg( 'userlogin' ) );
  1041.         } else {
  1042.             $wgOut->setPageTitle( wfMsg( 'userloginnocreate' ) );
  1043.         }
  1044.  
  1045.         $wgOut->setRobotPolicy( 'noindex,nofollow' );
  1046.         $wgOut->setArticleRelated( false );
  1047.         $wgOut->disallowUserJs();  // just in case...
  1048.         $wgOut->addTemplate( $template );
  1049.     }
  1050.  
  1051.     /**
  1052.      * @private
  1053.      */
  1054.     function showCreateOrLoginLink( &$user ) {
  1055.         if( $this->mType == 'signup' ) {
  1056.             return( true );
  1057.         } elseif( $user->isAllowed( 'createaccount' ) ) {
  1058.             return( true );
  1059.         } else {
  1060.             return( false );
  1061.         }
  1062.     }
  1063.  
  1064.     /**
  1065.      * Check if a session cookie is present.
  1066.      *
  1067.      * This will not pick up a cookie set during _this_ request, but is meant
  1068.      * to ensure that the client is returning the cookie which was set on a
  1069.      * previous pass through the system.
  1070.      *
  1071.      * @private
  1072.      */
  1073.     function hasSessionCookie() {
  1074.         global $wgDisableCookieCheck, $wgRequest;
  1075.         return $wgDisableCookieCheck ? true : $wgRequest->checkSessionCookie();
  1076.     }
  1077.    
  1078.     /**
  1079.      * Get the login token from the current session
  1080.      */
  1081.     public static function getLoginToken() {
  1082.         global $wgRequest;
  1083.         return $wgRequest->getSessionData( 'wsLoginToken' );
  1084.     }
  1085.    
  1086.     /**
  1087.      * Randomly generate a new login token and attach it to the current session
  1088.      */
  1089.     public static function setLoginToken() {
  1090.         global $wgRequest;
  1091.         // Use User::generateToken() instead of $user->editToken()
  1092.         // because the latter reuses $_SESSION['wsEditToken']
  1093.         $wgRequest->setSessionData( 'wsLoginToken', User::generateToken() );
  1094.     }
  1095.    
  1096.     /**
  1097.      * Remove any login token attached to the current session
  1098.      */
  1099.     public static function clearLoginToken() {
  1100.         global $wgRequest;
  1101.         $wgRequest->setSessionData( 'wsLoginToken', null );
  1102.     }
  1103.  
  1104.     /**
  1105.      * Get the createaccount token from the current session
  1106.      */
  1107.     public static function getCreateaccountToken() {
  1108.         global $wgRequest;
  1109.         return $wgRequest->getSessionData( 'wsCreateaccountToken' );
  1110.     }
  1111.    
  1112.     /**
  1113.      * Randomly generate a new createaccount token and attach it to the current session
  1114.      */
  1115.     public static function setCreateaccountToken() {
  1116.         global $wgRequest;
  1117.         $wgRequest->setSessionData( 'wsCreateaccountToken', User::generateToken() );
  1118.     }
  1119.    
  1120.     /**
  1121.      * Remove any createaccount token attached to the current session
  1122.      */
  1123.     public static function clearCreateaccountToken() {
  1124.         global $wgRequest;
  1125.         $wgRequest->setSessionData( 'wsCreateaccountToken', null );
  1126.     }
  1127.  
  1128.     /**
  1129.      * @private
  1130.      */
  1131.     function cookieRedirectCheck( $type ) {
  1132.         global $wgOut;
  1133.  
  1134.         $titleObj = SpecialPage::getTitleFor( 'Userlogin' );
  1135.         $query = array( 'wpCookieCheck' => $type );
  1136.         if ( $this->mReturnTo ) $query['returnto'] = $this->mReturnTo;
  1137.         $check = $titleObj->getFullURL( $query );
  1138.  
  1139.         return $wgOut->redirect( $check );
  1140.     }
  1141.  
  1142.     /**
  1143.      * @private
  1144.      */
  1145.     function onCookieRedirectCheck( $type ) {
  1146.         if ( !$this->hasSessionCookie() ) {
  1147.             if ( $type == 'new' ) {
  1148.                 return $this->mainLoginForm( wfMsgExt( 'nocookiesnew', array( 'parseinline' ) ) );
  1149.             } else if ( $type == 'login' ) {
  1150.                 return $this->mainLoginForm( wfMsgExt( 'nocookieslogin', array( 'parseinline' ) ) );
  1151.             } else {
  1152.                 # shouldn't happen
  1153.                 return $this->mainLoginForm( wfMsg( 'error' ) );
  1154.             }
  1155.         } else {
  1156.             return $this->successfulLogin();
  1157.         }
  1158.     }
  1159.  
  1160.     /**
  1161.      * @private
  1162.      */
  1163.     function throttleHit( $limit ) {
  1164.         $this->mainLoginForm( wfMsgExt( 'acct_creation_throttle_hit', array( 'parseinline' ), $limit ) );
  1165.     }
  1166.  
  1167.     /**
  1168.      * Produce a bar of links which allow the user to select another language
  1169.      * during login/registration but retain "returnto"
  1170.      *
  1171.      * @return string
  1172.      */
  1173.     function makeLanguageSelector() {
  1174.         global $wgLang;
  1175.  
  1176.         $msg = wfMsgForContent( 'loginlanguagelinks' );
  1177.         if( $msg != '' && !wfEmptyMsg( 'loginlanguagelinks', $msg ) ) {
  1178.             $langs = explode( "\n", $msg );
  1179.             $links = array();
  1180.             foreach( $langs as $lang ) {
  1181.                 $lang = trim( $lang, '* ' );
  1182.                 $parts = explode( '|', $lang );
  1183.                 if (count($parts) >= 2) {
  1184.                     $links[] = $this->makeLanguageSelectorLink( $parts[0], $parts[1] );
  1185.                 }
  1186.             }
  1187.             return count( $links ) > 0 ? wfMsgHtml( 'loginlanguagelabel', $wgLang->pipeList( $links ) ) : '';
  1188.         } else {
  1189.             return '';
  1190.         }
  1191.     }
  1192.  
  1193.     /**
  1194.      * Create a language selector link for a particular language
  1195.      * Links back to this page preserving type and returnto
  1196.      *
  1197.      * @param $text Link text
  1198.      * @param $lang Language code
  1199.      */
  1200.     function makeLanguageSelectorLink( $text, $lang ) {
  1201.         global $wgUser;
  1202.         $self = SpecialPage::getTitleFor( 'Userlogin' );
  1203.         $attr = array( 'uselang' => $lang );
  1204.         if( $this->mType == 'signup' )
  1205.             $attr['type'] = 'signup';
  1206.         if( $this->mReturnTo )
  1207.             $attr['returnto'] = $this->mReturnTo;
  1208.         $skin = $wgUser->getSkin();
  1209.         return $skin->linkKnown(
  1210.             $self,
  1211.             htmlspecialchars( $text ),
  1212.             array(),
  1213.             $attr
  1214.         );
  1215.     }
  1216. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement