http://www.mediawiki.org/wiki/Special:Code/MediaWiki/56256

Revision: 56256
Author:   happy-melon
Date:     2009-09-13 12:51:07 +0000 (Sun, 13 Sep 2009)

Log Message:
-----------
Lots of tweaks to the Login rewrite stuff

Modified Paths:
--------------
    branches/happy-melon/phase3/includes/Login.php
    branches/happy-melon/phase3/includes/User.php
    branches/happy-melon/phase3/includes/api/ApiLogin.php
    branches/happy-melon/phase3/includes/specials/SpecialCreateAccount.php
    branches/happy-melon/phase3/includes/specials/SpecialResetpass.php
    branches/happy-melon/phase3/includes/specials/SpecialUserlogin.php
    branches/happy-melon/phase3/languages/messages/MessagesEn.php

Modified: branches/happy-melon/phase3/includes/Login.php
===================================================================
--- branches/happy-melon/phase3/includes/Login.php      2009-09-13 07:15:54 UTC 
(rev 56255)
+++ branches/happy-melon/phase3/includes/Login.php      2009-09-13 12:51:07 UTC 
(rev 56256)
@@ -14,25 +14,41 @@
        const EMPTY_PASS = 6;
        const RESET_PASS = 7;
        const ABORTED = 8;
-       const CREATE_BLOCKED = 9;
        const THROTTLED = 10;
+       const FAILED = 11;
+       const READ_ONLY = 12;
        
-       const MAIL_READ_ONLY = 11;
-       const MAIL_PASSCHANGE_FORBIDDEN = 12;
-       const MAIL_BLOCKED = 13;
-       const MAIL_PING_THROTTLED = 14;
-       const MAIL_PASS_THROTTLED = 15;
-       const MAIL_EMPTY_EMAIL = 16;
-       const MAIL_BAD_IP = 17;
-       const MAIL_ERROR = 18;
+       const MAIL_PASSCHANGE_FORBIDDEN = 21;
+       const MAIL_BLOCKED = 22;
+       const MAIL_PING_THROTTLED = 23;
+       const MAIL_PASS_THROTTLED = 24;
+       const MAIL_EMPTY_EMAIL = 25;
+       const MAIL_BAD_IP = 26;
+       const MAIL_ERROR = 27;
+       
+       const CREATE_BLOCKED = 40;
+       const CREATE_EXISTS = 41;
+       const CREATE_SORBS = 42;
+       const CREATE_BADDOMAIN = 43;
+       const CREATE_BADNAME = 44;
+       const CREATE_BADPASS = 45;
+       const CREATE_NEEDEMAIL = 46;
+       const CREATE_BADEMAIL = 47;
 
-       var $mName, $mPassword,  $mPosted;
-       var $mLoginattempt, $mRemember, $mEmail, $mDomain, $mLanguage;
+       protected $mName;
+       protected $mPassword;
+       public $mRemember; # 0 or 1
+       public $mEmail;
+       public $mDomain;
+       public $mRealname;
 
        private $mExtUser = null;
        
        public $mUser;
-       public $mMailResult;
+       
+       public $mLoginResult = '';
+       public $mMailResult = '';
+       public $mCreateResult = '';
 
        /**
         * Constructor
@@ -46,8 +62,7 @@
                $this->mName = $request->getText( 'wpName' );
                $this->mPassword = $request->getText( 'wpPassword' );
                $this->mDomain = $request->getText( 'wpDomain' );
-               $this->mPosted = $request->wasPosted();
-               $this->mRemember = $request->getCheck( 'wpRemember' );
+               $this->mRemember = $request->getCheck( 'wpRemember' ) ? 1 : 0;
 
                if( $wgEnableEmail ) {
                        $this->mEmail = $request->getText( 'wpEmail' );
@@ -65,57 +80,28 @@
                }
                $wgAuth->setDomain( $this->mDomain );
 
-               # Attempt to generate the User
-               $this->mUser = User::newFromName( $this->mName );
+               # Load the user, if they exist in the local database.
+               $this->mUser = User::newFromName( trim( $this->mName ), 
'usable' );
        }
-
+       
        /**
-        * Actually add a user to the database.
-        * Give it a User object that has been initialised with a name.
-        *
-        * @param $u User object.
-        * @param $autocreate boolean -- true if this is an autocreation via 
auth plugin
-        * @return User object.
+        * Having initialised the Login object with (at least) the wpName
+        * and wpPassword pair, attempt to authenticate the user and log
+        * them into the wiki.  Authentication may come from the local 
+        * user database, or from an AuthPlugin- or ExternalUser-based
+        * foreign database; in the latter case, a local user record may
+        * or may not be created and initialised.  
+        * @return a Login class constant representing the status.
         */
-       public function initUser( $autocreate ) {
-               global $wgAuth;
-
-               $this->mUser->addToDatabase();
-
-               if ( $wgAuth->allowPasswordChange() ) {
-                       $this->mUser->setPassword( $this->mPassword );
-               }
-
-               $this->mUser->setEmail( $this->mEmail );
-               $this->mUser->setRealName( $this->mRealName );
-               $this->mUser->setToken();
-
-               $wgAuth->initUser( $this->mUser, $autocreate );
-
-               if( $this->mExtUser ) {
-                       $this->mExtUser->link( $this->mUser->getId() );
-                       $email = $this->mExtUser->getPref( 'emailaddress' );
-                       if( $email && !$this->mEmail ) {
-                               $this->mUser->setEmail( $email );
-                       }
-               }
-
-               $this->mUser->setOption( 'rememberpassword', $this->mRemember ? 
1 : 0 );
-               $this->mUser->saveSettings();
-
-               # Update user count
-               $ssUpdate = new SiteStatsUpdate( 0, 0, 0, 0, 1 );
-               $ssUpdate->doUpdate();
-
-               return $this->mUser;
-       }
-       
        public function attemptLogin(){
                global $wgUser;
+               
                $code = $this->authenticateUserData();
-               if( !$code == self::SUCCESS ){
+               if( $code != self::SUCCESS ){
                        return $code;
                }
+               
+               # Log the user in and remember them if they asked for that.
                if( (bool)$this->mRemember != (bool)$wgUser->getOption( 
'rememberpassword' ) ) {
                        $wgUser->setOption( 'rememberpassword', 
$this->mRemember ? 1 : 0 );
                        $wgUser->saveSettings();
@@ -124,32 +110,76 @@
                }
                $wgUser->setCookies();
 
-               # Reset the throttle
+               # Reset the password throttle
                $key = wfMemcKey( 'password-throttle', wfGetIP(), md5( 
$this->mName ) );
                global $wgMemc;
                $wgMemc->delete( $key );
                
-               $injected_html = '';
-               wfRunHooks('UserLoginComplete', array(&$wgUser, 
&$injected_html));
+               wfRunHooks( 'UserLoginComplete', array( &$wgUser, 
&$this->mLoginResult ) );
                
                return self::SUCCESS;
        }
 
        /**
+        * Check whether there is an external authentication mechanism from
+        * which we can automatically authenticate the user and create a 
+        * local account for them. 
+        * @return integer Status code.  Login::SUCCESS == clear to proceed
+        *    with user creation.
+        */
+       protected function canAutoCreate() {
+               global $wgAuth, $wgUser, $wgAutocreatePolicy;
+
+               if( $wgUser->isBlockedFromCreateAccount() ) {
+                       wfDebug( __METHOD__.": user is blocked from account 
creation\n" );
+                       return self::CREATE_BLOCKED;
+               }
+
+               # If the external authentication plugin allows it, 
automatically 
+               # create a new account for users that are externally defined 
but 
+               # have not yet logged in.
+               if( $this->mExtUser ) {
+                       # mExtUser is neither null nor false, so use the new 
+                       # ExternalAuth system.
+                       if( $wgAutocreatePolicy == 'never' ) {
+                               return self::NOT_EXISTS;
+                       }
+                       if( !$this->mExtUser->authenticate( $this->mPassword ) 
) {
+                               return self::WRONG_PLUGIN_PASS;
+                       }
+               } else {
+                       # Old AuthPlugin.
+                       if( !$wgAuth->autoCreate() ) {
+                               return self::NOT_EXISTS;
+                       }
+                       if( !$wgAuth->userExists( $this->mUser->getName() ) ) {
+                               wfDebug( __METHOD__.": user does not exist\n" );
+                               return self::NOT_EXISTS;
+                       }
+                       if( !$wgAuth->authenticate( $this->mUser->getName(), 
$this->mPassword ) ) {
+                               wfDebug( __METHOD__.": \$wgAuth->authenticate() 
returned false, aborting\n" );
+                               return self::WRONG_PLUGIN_PASS;
+                       }
+               }
+
+               return self::SUCCESS;
+       }
+
+       /**
         * Internally authenticate the login request.
         *
         * This may create a local account as a side effect if the
         * authentication plugin allows transparent local account
         * creation.
         */
-       public function authenticateUserData() {
+       protected function authenticateUserData() {
                global $wgUser, $wgAuth;
+               
                if ( '' == $this->mName ) {
                        return self::NO_NAME;
                }
                
                global $wgPasswordAttemptThrottle;
-
                $throttleCount = 0;
                if ( is_array( $wgPasswordAttemptThrottle ) ) {
                        $throttleKey = wfMemcKey( 'password-throttle', 
wfGetIP(), md5( $this->mName ) );
@@ -159,7 +189,7 @@
                        global $wgMemc;
                        $throttleCount = $wgMemc->get( $throttleKey );
                        if ( !$throttleCount ) {
-                               $wgMemc->add( $throttleKey, 1, $period ); // 
start counter
+                               $wgMemc->add( $throttleKey, 1, $period ); # 
Start counter
                        } else if ( $throttleCount < $count ) {
                                $wgMemc->incr($throttleKey);
                        } else if ( $throttleCount >= $count ) {
@@ -167,8 +197,8 @@
                        }
                }
 
-               # Load $wgUser now, and check to see if we're logging in as the 
same
-               # name. This is necessary because loading $wgUser (say by 
calling
+               # Unstub $wgUser now, and check to see if we're logging in as 
the same
+               # name. As well as the obvious, unstubbing $wgUser (say by 
calling
                # getName()) calls the UserLoadFromSession hook, which 
potentially
                # creates the user in the database. Until we load $wgUser, 
checking
                # for user existence using User::newFromName($name)->getId() 
below
@@ -186,15 +216,18 @@
                        return self::ILLEGAL;
                }
 
-               $isAutoCreated = false;
-               if ( 0 == $this->mUser->getID() ) {
-                       $status = $this->attemptAutoCreate( $this->mUser );
-                       if ( $status !== self::SUCCESS ) {
-                               return $status;
+               # If the user doesn't exist in the local database, our only 
chance 
+               # is for an external auth plugin to autocreate the local user.
+               if ( $this->mUser->getID() == 0 ) {
+                       if ( $this->canAutoCreate() == self::SUCCESS ) {
+                               $isAutoCreated = true;
+                               wfDebug( __METHOD__.": creating account\n" );
+                               $this->initUser( true );
                        } else {
-                               $isAutoCreated = true;
+                               return $this->canAutoCreate();
                        }
                } else {
+                       $isAutoCreated = false;
                        $this->mUser->load();
                }
 
@@ -231,7 +264,7 @@
                                # etc will probably just fail cleanly here.
                                $retval = self::RESET_PASS;
                        } else {
-                               $retval = '' == $this->mPassword ? 
self::EMPTY_PASS : self::WRONG_PASS;
+                               $retval = ( $this->mPassword === '' ) ? 
self::EMPTY_PASS : self::WRONG_PASS;
                        }
                } else {
                        $wgAuth->updateUser( $this->mUser );
@@ -254,48 +287,200 @@
        }
 
        /**
-        * Attempt to automatically create a user on login. Only succeeds if 
there
-        * is an external authentication method which allows it.
-        * @return integer Status code
+        * Actually add a user to the database.
+        * Give it a User object that has been initialised with a name.
+        *
+        * @param $autocreate Bool is this is an autocreation from an external
+        *   authentication database?
+        * @param $byEmail Bool is this request going to be handled by sending
+        *   the password by email?
+        * @return Bool whether creation was successful (should only fail for
+        *   Db errors etc).
         */
-       public function attemptAutoCreate( $user ) {
-               global $wgAuth, $wgUser, $wgAutocreatePolicy;
+       protected function initUser( $autocreate=false, $byEmail=false ) {
+               global $wgAuth;
 
-               if( $wgUser->isBlockedFromCreateAccount() ) {
-                       wfDebug( __METHOD__.": user is blocked from account 
creation\n" );
-                       return self::CREATE_BLOCKED;
+               $fields = array(
+                       'name' => $this->mName,
+                       'password' => $byEmail ? null : $this->mPassword,
+                       'email' => $this->mEmail,
+                       'options' => array(
+                               'rememberpassword' => $this->mRemember ? 1 : 0,
+                       ),
+               );
+               
+               $this->mUser = User::createNew( $this->mName, $fields );
+               
+               if( $this->mUser === null ){
+                       return null;
                }
 
-               # If the external authentication plugin allows it, 
automatically cre-
-               # ate a new account for users that are externally defined but 
have not
-               # yet logged in.
+               # Let old AuthPlugins play with the user
+               $wgAuth->initUser( $this->mUser, $autocreate );
+
+               # Or new ExternalUser plugins
                if( $this->mExtUser ) {
-                       # mExtUser is neither null nor false, so use the new 
ExternalAuth
-                       # system.
-                       if( $wgAutocreatePolicy == 'never' ) {
-                               return self::NOT_EXISTS;
+                       $this->mExtUser->link( $this->mUser->getId() );
+                       $email = $this->mExtUser->getPref( 'emailaddress' );
+                       if( $email && !$this->mEmail ) {
+                               $this->mUser->setEmail( $email );
                        }
-                       if( !$this->mExtUser->authenticate( $this->mPassword ) 
) {
-                               return self::WRONG_PLUGIN_PASS;
+               }
+
+               # Update user count and newuser logs
+               $ssUpdate = new SiteStatsUpdate( 0, 0, 0, 0, 1 );
+               $ssUpdate->doUpdate();
+               if( $autocreate )
+                       $this->mUser->addNewUserLogEntryAutoCreate();
+               else
+                       $this->mUser->addNewUserLogEntry( $byEmail );
+               
+               # Run hooks
+               wfRunHooks( 'AddNewAccount', array( $this->mUser ) );
+
+               return true;
+       }
+
+       /**
+        * Entry point to create a new local account from user-supplied
+        * data loaded from the WebRequest.  We handle initialising the 
+        * email here because it's needed for some backend things; frontend
+        * interfaces calling this should handle recording things like 
+        * preference options
+        * @param $byEmail Bool whether to email the user their new password
+        * @return Status code; Login::SUCCESS == the user was successfully 
created
+        */
+       public function attemptCreation( $byEmail=false ) {
+               global $wgUser, $wgOut;
+               global $wgEnableSorbs, $wgProxyWhitelist;
+               global $wgMemc, $wgAccountCreationThrottle;
+               global $wgAuth;
+               global $wgEmailAuthentication, $wgEmailConfirmToEdit;
+
+               if( wfReadOnly() ) 
+                       return self::READ_ONLY;
+                       
+               # If the user passes an invalid domain, something is fishy
+               if( !$wgAuth->validDomain( $this->mDomain ) ) {
+                       $this->mCreateResult = 'wrongpassword';
+                       return self::CREATE_BADDOMAIN;
+               }
+
+               # If we are not allowing users to login locally, we should be 
checking
+               # to see if the user is actually able to authenticate to the 
authenti-
+               # cation server before they create an account (otherwise, they 
can
+               # create a local account and login as any domain user). We only 
need
+               # to check this for domains that aren't local.
+               if(    !in_array( $this->mDomain, array( 'local', '' ) ) 
+                       && !$wgAuth->canCreateAccounts() 
+                       && ( !$wgAuth->userExists( $this->mUsername ) 
+                               || !$wgAuth->authenticate( $this->mUsername, 
$this->mPassword ) 
+                       ) ) 
+               {
+                       $this->mCreateResult = 'wrongpassword';
+                       return self::WRONG_PLUGIN_PASS;
+               }
+
+               $ip = wfGetIP();
+               if ( $wgEnableSorbs && !in_array( $ip, $wgProxyWhitelist ) &&
+                 $wgUser->inSorbsBlacklist( $ip ) )
+               {
+                       $this->mCreateResult = 'sorbs_create_account_reason';
+                       return self::CREATE_SORBS;
+               }
+
+               # Now create a dummy user ($user) and check if it is valid
+               $name = trim( $this->mName );
+               $user = User::newFromName( $name, 'creatable' );
+               if ( is_null( $user ) ) {
+                       $this->mCreateResult = 'noname';
+                       return self::CREATE_BADNAME;
+               }
+
+               if ( $this->mUser->idForName() != 0 ) {
+                       $this->mCreateResult = 'userexists';
+                       return self::CREATE_EXISTS;
+               }
+
+               # Check that the password is acceptable, if we're actually
+               # going to use it
+               if( !$byEmail ){
+                       $valid = $this->mUser->isValidPassword( 
$this->mPassword );
+                       if ( $valid !== true ) {
+                               $this->mCreateResult = $valid;
+                               return self::CREATE_BADPASS;
                        }
-               } else {
-                       # Old AuthPlugin.
-                       if( !$wgAuth->autoCreate() ) {
-                               return self::NOT_EXISTS;
+               }
+
+               # if you need a confirmed email address to edit, then obviously 
you
+               # need an email address. Equally if we're going to send the 
password to it.
+               if ( $wgEmailConfirmToEdit && empty( $this->mEmail ) || 
$byEmail ) {
+                       $this->mCreateResult = 'noemailcreate';
+                       return self::CREATE_NEEDEMAIL;
+               }
+
+               if( !empty( $this->mEmail ) && !User::isValidEmailAddr( 
$this->mEmail ) ) {
+                       $this->mCreateResult = 'invalidemailaddress';
+                       return self::CREATE_BADEMAIL;
+               }
+
+               # Set some additional data so the AbortNewAccount hook can be 
used for
+               # more than just username validation
+               $this->mUser->setEmail( $this->mEmail );
+               $this->mUser->setRealName( $this->mRealName );
+
+               if( !wfRunHooks( 'AbortNewAccount', array( $this->mUser, 
&$this->mCreateResult ) ) ) {
+                       # Hook point to add extra creation throttles and blocks
+                       wfDebug( "LoginForm::addNewAccountInternal: a hook 
blocked creation\n" );
+                       return self::ABORTED;
+               }
+
+               if ( $wgAccountCreationThrottle && $wgUser->isPingLimitable() ) 
{
+                       $key = wfMemcKey( 'acctcreate', 'ip', $ip );
+                       $value = $wgMemc->get( $key );
+                       if ( !$value ) {
+                               $wgMemc->set( $key, 0, 86400 );
                        }
-                       if( !$wgAuth->userExists( $user->getName() ) ) {
-                               wfDebug( __METHOD__.": user does not exist\n" );
-                               return self::NOT_EXISTS;
+                       if ( $value >= $wgAccountCreationThrottle ) {
+                               return self::THROTTLED;
                        }
-                       if( !$wgAuth->authenticate( $user->getName(), 
$this->mPassword ) ) {
-                               wfDebug( __METHOD__.": \$wgAuth->authenticate() 
returned false, aborting\n" );
-                               return self::WRONG_PLUGIN_PASS;
+                       $wgMemc->incr( $key );
+               }
+
+               # Since we're creating a new local user, give the external 
+               # database a chance to synchronise.
+               if( !$wgAuth->addUser( $this->mUser, $this->mPassword, 
$this->mEmail, $this->mRealName ) ) {
+                       $this->mCreateResult = 'externaldberror';
+                       return self::ABORTED;
+               }
+
+               $result = $this->initUser( false, $byEmail );
+               if( $result === null )
+                       # It's unlikely we'd get here without some exception 
+                       # being thrown, but it's probably possible...
+                       return self::FAILED;
+                       
+       
+               # Send out an email message if needed
+               if( $byEmail ){
+                       $this->mailPassword( 'createaccount-title', 
'createaccount-text' );
+                       if( WikiError::isError( $this->mMailResult ) ){
+                               # FIXME: If the password email hasn't gone out, 
+                               # then the account is inaccessible :(
+                               return self::MAIL_ERROR;
+                       } else {
+                               return self::SUCCESS;
                        }
+               } else {
+                       if( $wgEmailAuthentication && User::isValidEmailAddr( 
$this->mUser->getEmail() ) ) 
+                       {
+                               $this->mMailResult = 
$this->mUser->sendConfirmationMail();
+                               return WikiError::isError( $this->mMailResult ) 
+                                       ? self::MAIL_ERROR 
+                                       : self::SUCCESS;
+                       }
                }
-
-               wfDebug( __METHOD__.": creating account\n" );
-               $this->initUser( true );
-               return self::SUCCESS;
+               return true;
        }
 
        /**
@@ -308,8 +493,11 @@
                global $wgUser, $wgOut, $wgAuth, $wgServer, $wgScript, 
$wgNewPasswordExpiry;
 
                if( wfReadOnly() ) 
-                       return self::MAIL_READ_ONLY;
+                       return self::READ_ONLY;
 
+               # If we let the email go out, it will take users to a form where
+               # they are forced to change their password, so don't let us go 
+               # there if we don't want passwords changed.
                if( !$wgAuth->allowPasswordChange() ) 
                        return self::MAIL_PASSCHANGE_FORBIDDEN;
 
@@ -319,23 +507,22 @@
                        return self::MAIL_BLOCKED;
 
                # Check for hooks
-               $error = null;
-               if ( ! wfRunHooks( 'UserLoginMailPassword', array( 
$this->mName, &$error ) ) )
-                       return $error;
+               if( !wfRunHooks( 'UserLoginMailPassword', array( $this->mName, 
&$this->mMailResult ) ) )
+                       return self::ABORTED;
 
                # Check against the rate limiter
                if( $wgUser->pingLimiter( 'mailpassword' ) )
                        return self::MAIL_PING_THROTTLED;
 
                # Check for a valid name
-               if ( '' == $this->mName )
+               if ($this->mName === '' )
                        return self::NO_NAME;
                $this->mUser = User::newFromName( $this->mName );
                if( is_null( $this->mUser ) )
                        return self::NO_NAME;
 
                # And that the resulting user actually exists
-               if ( 0 == $this->mUser->getId() )
+               if ( $this->mUser->getId() === 0 )
                        return self::NOT_EXISTS;
 
                # Check against password throttle
@@ -343,7 +530,7 @@
                        return self::MAIL_PASS_THROTTLED;
                
                # User doesn't have email address set
-               if ( '' == $this->mUser->getEmail() )
+               if ( $this->mUser->getEmail() === '' )
                        return self::MAIL_EMPTY_EMAIL;
 
                # Don't send to people who are acting fishily by hiding their IP
@@ -363,7 +550,9 @@
                $this->mMailResult = $this->mUser->sendMail( wfMsg( $title ), 
$message );
                
                if( WikiError::isError( $this->mMailResult ) ) {
-                       return self::MAIL_ERROR;
+                       #XXX
+                       var_dump($message);
+                       return self::SUCCESS;
                } else {
                        return self::SUCCESS;
                }

Modified: branches/happy-melon/phase3/includes/User.php
===================================================================
--- branches/happy-melon/phase3/includes/User.php       2009-09-13 07:15:54 UTC 
(rev 56255)
+++ branches/happy-melon/phase3/includes/User.php       2009-09-13 12:51:07 UTC 
(rev 56256)
@@ -2483,7 +2483,7 @@
                $user = new User;
                $user->load();
                if ( isset( $params['options'] ) ) {
-                       $user->mOptions = $params['options'] + $user->mOptions;
+                       $user->mOptions = $params['options'] + 
(array)$user->mOptions;
                        unset( $params['options'] );
                }
                $dbw = wfGetDB( DB_MASTER );

Modified: branches/happy-melon/phase3/includes/api/ApiLogin.php
===================================================================
--- branches/happy-melon/phase3/includes/api/ApiLogin.php       2009-09-13 
07:15:54 UTC (rev 56255)
+++ branches/happy-melon/phase3/includes/api/ApiLogin.php       2009-09-13 
12:51:07 UTC (rev 56256)
@@ -106,10 +106,10 @@
                        case Login::THROTTLED :
                                global $wgPasswordAttemptThrottle;
                                $result['result'] = 'Throttled';
-                               $result['wait'] = 
intval($wgPasswordAttemptThrottle['seconds']);
+                               $result['wait'] = intval( 
$wgPasswordAttemptThrottle['seconds'] );
                                break;
                        default :
-                               ApiBase::dieDebug(__METHOD__, "Unhandled case 
value: {$authRes}");
+                               ApiBase::dieDebug( __METHOD__, "Unhandled case 
value: {$authRes}" );
                }
 
                $this->getResult()->addValue(null, 'login', $result);

Modified: branches/happy-melon/phase3/includes/specials/SpecialCreateAccount.php
===================================================================
--- branches/happy-melon/phase3/includes/specials/SpecialCreateAccount.php      
2009-09-13 07:15:54 UTC (rev 56255)
+++ branches/happy-melon/phase3/includes/specials/SpecialCreateAccount.php      
2009-09-13 12:51:07 UTC (rev 56256)
@@ -8,6 +8,8 @@
        var $mUsername, $mPassword, $mRetype, $mReturnTo, $mPosted;
        var $mCreateaccountMail, $mRemember, $mEmail, $mDomain, $mLanguage;
        var $mReturnToQuery;
+       
+       protected $mLogin;
 
        public $mDomains = array();
        
@@ -94,17 +96,12 @@
                        $this->userBlockedMessage();
                        return;
                } elseif ( count( $permErrors = 
$this->getTitle()->getUserPermissionsErrors( 'createaccount', $wgUser, true ) 
)>0 ) {
-                       var_dump('error');
                        $wgOut->showPermissionsErrorPage( $permErrors, 
'createaccount' );
                        return;
                }       
                
                if( $this->mPosted ) {
-                       if ( $this->mCreateaccountMail ) {
-                               return $this->addNewAccountMailPassword();
-                       } else {
-                               return $this->addNewAccount();
-                       }
+                       $this->addNewAccount( $this->mCreateaccountMail );
                } else {
                        $this->showMainForm('');
                }
@@ -160,223 +157,103 @@
        }
 
        /**
-        * Add a new account, and mail its password to the user
+        * Create a new user account from the provided data
         */
-       protected function addNewAccountMailPassword() {
-               global $wgOut;
-
-               if( !$this->mEmail ) {
-                       $this->showMainForm( wfMsg( 'noemail', 
htmlspecialchars( $this->mUsername ) ) );
-                       return;
+       protected function addNewAccount( $byEmail=false ) {
+               global $wgUser, $wgEmailAuthentication;
+       
+               # Do a quick check that the user actually managed to type
+               # the password in the same both times
+               if ( 0 != strcmp( $this->mPassword, $this->mRetype ) ) {
+                       return $this->showMainForm( wfMsg( 'badretype' ) );
                }
-
-               if( !$this->addNewaccountInternal() ) {
-                       return;
-               }
-
-               # Wipe the initial password 
-               $this->mLogin->mUser->setPassword( null );
-               $this->mLogin->mUser->saveSettings();
                
-               # And mail them a temporary one
-               $result = $this->mLogin->mailPassword( 'createaccount-title', 
'createaccount-text' );
-
-               wfRunHooks( 'AddNewAccount', array( $this->mLogin->mUser, true 
) );
-               $this->mLogin->mUser->addNewUserLogEntry();
-
-               $wgOut->setPageTitle( wfMsg( 'accmailtitle' ) );
-               $wgOut->setRobotPolicy( 'noindex,nofollow' );
-               $wgOut->setArticleRelated( false );
-
-               if( $result != Login::SUCCESS ) {
-                       if( $result == Login::MAIL_ERROR ){
-                               $this->showMainForm( wfMsg( 'mailerror', 
$this->mLogin->mMailResult->getMessage() ) );
-                       } else {
-                               $this->showMainForm( wfMsg( 'mailerror' ) );
-                       }
-               } else {
-                       $wgOut->addWikiMsg( 'accmailtext', 
$this->mLogin->mUser->getName(), $this->mLogin->mUser->getEmail() );
-                       $wgOut->returnToMain( false );
+               # Create the account and abort if there's a problem doing so
+               $status = $this->mLogin->attemptCreation( $byEmail );
+               switch( $status ){
+                       case Login::SUCCESS: 
+                       case Login::MAIL_ERROR: 
+                               break;
+                               
+                       case Login::CREATE_BADDOMAIN: 
+                       case Login::CREATE_EXISTS: 
+                       case Login::NO_NAME:
+                       case Login::CREATE_NEEDEMAIL: 
+                       case Login::CREATE_BADEMAIL: 
+                       case Login::CREATE_BADNAME:
+                       case Login::WRONG_PLUGIN_PASS:
+                       case Login::ABORTED:
+                               return $this->showMainForm( wfMsg( 
$this->mLogin->mCreateResult ) );
+                       
+                       case Login::CREATE_SORBS: 
+                               return $this->showMainForm( wfMsg( 
'sorbs_create_account_reason' ) . ' (' . wfGetIP() . ')' );
+                               
+                       case Login::CREATE_BLOCKED:
+                               return $this->userBlockedMessage();
+                               
+                       case Login::CREATE_BADPASS:
+                               global $wgMinimalPasswordLength;
+                               return $this->showMainForm( wfMsgExt( 
$this->mLogin->mCreateResult, array( 'parsemag' ), $wgMinimalPasswordLength ) );
+                               
+                       case Login::THROTTLED: 
+                               global $wgAccountCreationThrottle;
+                               return $this->showMainForm( wfMsgExt( 
'acct_creation_throttle_hit', array( 'parseinline' ), 
$wgAccountCreationThrottle ) ); 
+                       
+                       default: 
+                               throw new MWException( "Unhandled status code 
$status in " . __METHOD__ );
                }
-       }
 
-       /**
-        * Create a new user account from the provided data
-        */
-       protected function addNewAccount() {
-               global $wgUser, $wgEmailAuthentication;
-
-               # Create the account and abort if there's a problem doing so
-               if( !$this->addNewAccountInternal() )
-                       return;
-               $user = $this->mLogin->mUser;
-
                # If we showed up language selection links, and one was in use, 
be
                # smart (and sensible) and save that language as the user's 
preference
                global $wgLoginLanguageSelector;
                if( $wgLoginLanguageSelector && $this->mLanguage )
-                       $user->setOption( 'language', $this->mLanguage );
-
-               # Send out an email authentication message if needed
-               if( $wgEmailAuthentication && User::isValidEmailAddr( 
$user->getEmail() ) ) {
-                       global $wgOut;
-                       $error = $user->sendConfirmationMail();
-                       if( WikiError::isError( $error ) ) {
-                               $wgOut->addWikiMsg( 'confirmemail_sendfailed', 
$error->getMessage() );
+                       $this->mLogin->mUser->setOption( 'language', 
$this->mLanguage );
+               $this->mLogin->mUser->saveSettings();
+       
+               if( $byEmail ) {
+                       if( $result == Login::MAIL_ERROR ){
+                               # FIXME: we are totally screwed if we end up 
here...
+                               $this->showMainForm( wfMsg( 'mailerror', 
$this->mLogin->mMailResult->getMessage() ) );
                        } else {
-                               $wgOut->addWikiMsg( 'confirmemail_oncreate' );
+                               $wgOut->setPageTitle( wfMsg( 'accmailtitle' ) );
+                               $wgOut->addWikiMsg( 'accmailtext', 
$this->mLogin->mUser->getName(), $this->mLogin->mUser->getEmail() );
+                               $wgOut->returnToMain( false );
                        }
-               }
-
-               # Save settings (including confirmation token)
-               $user->saveSettings();
-
-               # If not logged in, assume the new account as the current one 
and set
-               # session cookies then show a "welcome" message or a "need 
cookies"
-               # message as needed
-               if( $wgUser->isAnon() ) {
-                       $wgUser = $user;
-                       $wgUser->setCookies();
-                       wfRunHooks( 'AddNewAccount', array( $wgUser ) );
-                       $wgUser->addNewUserLogEntry();
-                       if( $this->hasSessionCookie() ) {
-                               return $this->successfulCreation();
-                       } else {
-                               return $this->cookieRedirectCheck();
-                       }
+                       
                } else {
-                       # Confirm that the account was created
-                       global $wgOut;
-                       $self = SpecialPage::getTitleFor( 'Userlogin' );
-                       $wgOut->setPageTitle( wfMsgHtml( 'accountcreated' ) );
-                       $wgOut->setArticleRelated( false );
-                       $wgOut->setRobotPolicy( 'noindex,nofollow' );
-                       $wgOut->addHTML( wfMsgWikiHtml( 'accountcreatedtext', 
$user->getName() ) );
-                       $wgOut->returnToMain( false, $self );
-                       wfRunHooks( 'AddNewAccount', array( $user ) );
-                       $user->addNewUserLogEntry();
-                       return true;
-               }
-       }
 
-       /**
-        * Deeper mechanics of initialising a new user and passing it
-        * off to Login::initUser()
-        * return Bool whether the user was successfully created
-        */
-       protected function addNewAccountInternal() {
-               global $wgUser, $wgOut;
-               global $wgEnableSorbs, $wgProxyWhitelist;
-               global $wgMemc, $wgAccountCreationThrottle;
-               global $wgAuth, $wgMinimalPasswordLength;
-               global $wgEmailConfirmToEdit;
-
-               # If the user passes an invalid domain, something is fishy
-               if( !$wgAuth->validDomain( $this->mDomain ) ) {
-                       $this->showMainForm( wfMsg( 'wrongpassword' ) );
-                       return false;
-               }
-
-               # If we are not allowing users to login locally, we should be 
checking
-               # to see if the user is actually able to authenticate to the 
authenti-
-               # cation server before they create an account (otherwise, they 
can
-               # create a local account and login as any domain user). We only 
need
-               # to check this for domains that aren't local.
-               if(    !in_array( $this->mDomain, array( 'local', '' ) ) 
-                       && !$wgAuth->canCreateAccounts() 
-                       && ( !$wgAuth->userExists( $this->mUsername ) 
-                               || !$wgAuth->authenticate( $this->mUsername, 
$this->mPassword ) 
-                       ) ) 
-               {
-                       $this->showMainForm( wfMsg( 'wrongpassword' ) );
-                       return false;
-               }
-
-               $ip = wfGetIP();
-               if ( $wgEnableSorbs && !in_array( $ip, $wgProxyWhitelist ) &&
-                 $wgUser->inSorbsBlacklist( $ip ) )
-               {
-                       $this->showMainForm( wfMsg( 
'sorbs_create_account_reason' ) . ' (' . htmlspecialchars( $ip ) . ')' );
-                       return false;
-               }
-
-               # Now create a dummy user ($user) and check if it is valid
-               $name = trim( $this->mUsername );
-               $user = User::newFromName( $name, 'creatable' );
-               if ( is_null( $user ) ) {
-                       $this->showMainForm( wfMsg( 'noname' ) );
-                       return false;
-               }
-
-               if ( 0 != $user->idForName() ) {
-                       $this->showMainForm( wfMsg( 'userexists' ) );
-                       return false;
-               }
-
-               if ( 0 != strcmp( $this->mPassword, $this->mRetype ) ) {
-                       $this->showMainForm( wfMsg( 'badretype' ) );
-                       return false;
-               }
-
-               # check for minimal password length
-               $valid = $user->isValidPassword( $this->mPassword );
-               if ( $valid !== true ) {
-                       if ( !$this->mCreateaccountMail ) {
-                               $this->showMainForm( wfMsgExt( $valid, array( 
'parsemag' ), $wgMinimalPasswordLength ) );
-                               return false;
+                       # There might be a message stored from the confirmation 
mail
+                       # send, which we can display.
+                       if( $wgEmailAuthentication && 
$this->mLogin->mMailResult ) {
+                               global $wgOut;
+                               if( WikiError::isError( 
$this->mLogin->mMailResult ) ) {
+                                       $wgOut->addWikiMsg( 
'confirmemail_sendfailed', $this->mLogin->mMailResult->getMessage() );
+                               } else {
+                                       $wgOut->addWikiMsg( 
'confirmemail_oncreate' );
+                               }
+                       }
+                       
+                       # If not logged in, assume the new account as the 
current 
+                       # one and set session cookies then show a "welcome" 
message 
+                       # or a "need cookies" message as needed
+                       if( $wgUser->isAnon() ) {
+                               $wgUser = $this->mLogin->mUser;
+                               $wgUser->setCookies();
+                               if( $this->hasSessionCookie() ) {
+                                       return $this->successfulCreation();
+                               } else {
+                                       return $this->cookieRedirectCheck();
+                               }
                        } else {
-                               # do not force a password for account creation 
by email
-                               # set invalid password, it will be replaced 
later by a random generated password
-                               $this->mPassword = null;
+                               # Show confirmation that the account was created
+                               global $wgOut;
+                               $self = SpecialPage::getTitleFor( 'Userlogin' );
+                               $wgOut->setPageTitle( wfMsgHtml( 
'accountcreated' ) );
+                               $wgOut->addHTML( wfMsgWikiHtml( 
'accountcreatedtext', $this->mLogin->mUser->getName() ) );
+                               $wgOut->returnToMain( false, $self );
+                               return true;
                        }
                }
-
-               # if you need a confirmed email address to edit, then obviously 
you
-               # need an email address.
-               if ( $wgEmailConfirmToEdit && empty( $this->mEmail ) ) {
-                       $this->showMainForm( wfMsg( 'noemailtitle' ) );
-                       return false;
-               }
-
-               if( !empty( $this->mEmail ) && !User::isValidEmailAddr( 
$this->mEmail ) ) {
-                       $this->showMainForm( wfMsg( 'invalidemailaddress' ) );
-                       return false;
-               }
-
-               # Set some additional data so the AbortNewAccount hook can be 
used for
-               # more than just username validation
-               $user->setEmail( $this->mEmail );
-               $user->setRealName( $this->mRealName );
-
-               $abortError = '';
-               if( !wfRunHooks( 'AbortNewAccount', array( $user, &$abortError 
) ) ) {
-                       # Hook point to add extra creation throttles and blocks
-                       wfDebug( "LoginForm::addNewAccountInternal: a hook 
blocked creation\n" );
-                       $this->showMainForm( $abortError );
-                       return false;
-               }
-
-               if ( $wgAccountCreationThrottle && $wgUser->isPingLimitable() ) 
{
-                       $key = wfMemcKey( 'acctcreate', 'ip', $ip );
-                       $value = $wgMemc->get( $key );
-                       if ( !$value ) {
-                               $wgMemc->set( $key, 0, 86400 );
-                       }
-                       if ( $value >= $wgAccountCreationThrottle ) {
-                               $this->showMainForm( wfMsgExt( 
'acct_creation_throttle_hit', array( 'parseinline' ), 
$wgAccountCreationThrottle ) ); 
-                               return false;
-                       }
-                       $wgMemc->incr( $key );
-               }
-
-               if( !$wgAuth->addUser( $user, $this->mPassword, $this->mEmail, 
$this->mRealName ) ) {
-                       $this->showMainForm( wfMsg( 'externaldberror' ) );
-                       return false;
-               }
-
-               $this->mLogin->mUser = $user;
-               $this->mLogin->initUser( false );
-               return true;
        }
 
        /**
@@ -617,10 +494,11 @@
                if ( !$this->hasSessionCookie() ) {
                        return $this->mainLoginForm( wfMsgExt( 'nocookiesnew', 
array( 'parseinline' ) ) );
                } else {
-                       return SpecialUserLogin::successfulLogin( 
-                               'welcomecreate', 
+                       return SpecialUserlogin::successfulLogin( 
+                               array( 'welcomecreate' ), 
                                $this->mReturnTo, 
-                               $this->mReturnToQuery );
+                               $this->mReturnToQuery
+                       );
                }
        }
        

Modified: branches/happy-melon/phase3/includes/specials/SpecialResetpass.php
===================================================================
--- branches/happy-melon/phase3/includes/specials/SpecialResetpass.php  
2009-09-13 07:15:54 UTC (rev 56255)
+++ branches/happy-melon/phase3/includes/specials/SpecialResetpass.php  
2009-09-13 12:51:07 UTC (rev 56256)
@@ -12,6 +12,48 @@
        public function __construct() {
                parent::__construct( 'Resetpass' );
        }
+       
+       public $mFormFields = array(
+               'Name' => array(
+                       'type'          => 'info',
+                       'label-message' => 'yourname',
+                       'default'       => '',
+               ),
+               'Password' => array(
+                       'type'          => 'password',
+                       'label-message' => 'oldpassword',
+                       'size'          => '20',
+                       'id'            => 'wpPassword',
+                       'required'      => '',
+               ),
+               'NewPassword' => array(
+                       'type'          => 'password',
+                       'label-message' => 'newpassword',
+                       'size'          => '20',
+                       'id'            => 'wpNewPassword',
+                       'required'      => '',
+               ),
+               'Retype' => array(
+                       'type'          => 'password',
+                       'label-message' => 'retypenew',
+                       'size'          => '20',
+                       'id'            => 'wpRetype',
+                       'required'      => '',
+               ),
+               'Remember' => array(
+                       'type'          => 'check',
+                       'label-message' => 'remembermypassword',
+                       'id'            => 'wpRemember',
+               ),
+       );
+       public $mSubmitMsg = 'resetpass-submit-loggedin';
+       public $mHeaderMsg = '';
+       public $mHeaderMsgType = 'error';
+       
+       protected $mUsername;
+       protected $mOldpass;
+       protected $mNewpass;
+       protected $mRetype;
 
        /**
         * Main execution point
@@ -19,175 +61,142 @@
        function execute( $par ) {
                global $wgUser, $wgAuth, $wgOut, $wgRequest;
 
-               $this->mUserName = $wgRequest->getVal( 'wpName' );
+               $this->mUsername = $wgRequest->getVal( 'wpName', 
$wgUser->getName() );
                $this->mOldpass = $wgRequest->getVal( 'wpPassword' );
                $this->mNewpass = $wgRequest->getVal( 'wpNewPassword' );
                $this->mRetype = $wgRequest->getVal( 'wpRetype' );
+               $this->mRemember = $wgRequest->getVal( 'wpRemember' );
+               $this->mReturnTo = $wgRequest->getVal( 'returnto' );
+               $this->mReturnToQuery = $wgRequest->getVal( 'returntoquery' );
                
                $this->setHeaders();
                $this->outputHeader();
 
                if( !$wgAuth->allowPasswordChange() ) {
-                       $this->error( wfMsg( 'resetpass_forbidden' ) );
-                       return;
+                       $wgOut->showErrorPage( 'errorpagetitle', 
'resetpass_forbidden' );
+                       return false;
                }
 
                if( !$wgRequest->wasPosted() && !$wgUser->isLoggedIn() ) {
-                       $this->error( wfMsg( 'resetpass-no-info' ) );
-                       return;
+                       $wgOut->showErrorPage( 'errorpagetitle', 
'resetpass-no-info' );
+                       return false;
                }
 
-               if( $wgRequest->wasPosted() && $wgUser->matchEditToken( 
$wgRequest->getVal('token') ) ) {
-                       try {
-                               $this->attemptReset( $this->mNewpass, 
$this->mRetype );
-                               $wgOut->addWikiMsg( 'resetpass_success' );
-                               if( !$wgUser->isLoggedIn() ) {
-                                       $data = array(
-                                               'wpName'     => 
$this->mUserName,
-                                               'wpPassword' => $this->mNewpass,
-                                               'returnto'   => 
$wgRequest->getVal( 'returnto' ),
-                                       );
-                                       if( $wgRequest->getCheck( 'wpRemember' 
) ) {
-                                               $data['wpRemember'] = 1;
-                                       }
-                                       $login = new LoginForm( new 
FauxRequest( $data, true ) );
-                                       $login->login();
+               if( $wgRequest->wasPosted() 
+                   && $wgUser->matchEditToken( 
$wgRequest->getVal('wpEditToken') )
+                       && $this->attemptReset() )
+               {
+                       # Log the user in if they're not already (ie we're 
+                       # coming from the e-mail-password-reset route
+                       if( !$wgUser->isLoggedIn() ) {
+                               $data = array(
+                                       'wpName'     => $this->mUsername,
+                                       'wpPassword' => $this->mNewpass,
+                                       'returnto'   => $this->mReturnTo,
+                               );
+                               if( $this->mRemember ) {
+                                       $data['wpRemember'] = 1;
                                }
-                               $titleObj = Title::newFromText( 
$wgRequest->getVal( 'returnto' ) );
-                               if ( !$titleObj instanceof Title ) {
-                                       $titleObj = Title::newMainPage();
-                               }
-                               $wgOut->redirect( $titleObj->getFullURL() );
-                       } catch( PasswordError $e ) {
-                               $this->error( $e->getMessage() );
+                               $login = new Login( new FauxRequest( $data, 
true ) );
+                               $login->attemptLogin();
+                       
+                               # Redirect out to the appropriate target.
+                               SpecialUserlogin::successfulLogin( 
+                                       'resetpass_success', 
+                                       $this->mReturnTo, 
+                                       $this->mReturnToQuery,
+                                       $login->mLoginResult
+                               );
+                       } else {
+                               # Redirect out to the appropriate target.
+                               SpecialUserlogin::successfulLogin( 
+                                       'resetpass_success', 
+                                       $this->mReturnTo, 
+                                       $this->mReturnToQuery
+                               );
                        }
+               } else {
+                       $this->showForm();
                }
-               $this->showForm();
        }
 
-       function error( $msg ) {
-               global $wgOut;
-               $wgOut->addHTML( Xml::element('p', array( 'class' => 'error' ), 
$msg ) );
-       }
-
        function showForm() {
-               global $wgOut, $wgUser, $wgRequest;
+               global $wgOut, $wgUser;
 
                $wgOut->disallowUserJs();
-
-               $self = SpecialPage::getTitleFor( 'Resetpass' );
-               if ( !$this->mUserName ) {
-                       $this->mUserName = $wgUser->getName();
-               }
-               $rememberMe = '';
-               if ( !$wgUser->isLoggedIn() ) {
-                       $rememberMe = '<tr>' .
-                               '<td></td>' .
-                               '<td class="mw-input">' .
-                                       Xml::checkLabel( wfMsg( 
'remembermypassword' ),
-                                               'wpRemember', 'wpRemember',
-                                               $wgRequest->getCheck( 
'wpRemember' ) ) .
-                               '</td>' .
-                       '</tr>';
-                       $submitMsg = 'resetpass_submit';
-                       $oldpassMsg = 'resetpass-temp-password';
+               
+               if( $wgUser->isLoggedIn() ){
+                       unset( $this->mFormFields['Remember'] );
                } else {
-                       $oldpassMsg = 'oldpassword';
-                       $submitMsg = 'resetpass-submit-loggedin';
+                       # Request is coming from Special:UserLogin after it
+                       # authenticated someone with a temporary password.
+                       $this->mFormFields['Password']['label-message'] = 
'resetpass-temp-password';
+                       $this->mSubmitMsg = 'resetpass_submit';
                }
+               $this->mFormFields['Name']['default'] = $this->mUsername;
+               
+               $header = $this->mHeaderMsg
+                       ? Xml::element( 'div', array( 'class' => 
"{$this->mHeaderMsgType}box" ), wfMsg( $this->mHeaderMsg ) )
+                       : '';
+                               
+               $form = new HTMLForm( $this->mFormFields, '' );
+               $form->suppressReset();
+               $form->setSubmitText( wfMsg( $this->mSubmitMsg ) );
+               $form->setTitle( $this->getTitle() );
+               $form->loadData();
+               
+               $formContents = '' 
+                       . $form->getBody()
+                       . $form->getButtons()
+                       . $form->getHiddenFields()
+                       . Html::hidden( 'wpName', $this->mUsername )
+                       . Html::hidden( 'returnto', $this->mReturnTo )
+                       ;
+               $formOutput = $form->wrapForm( $formContents );
+               
                $wgOut->addHTML(
-                       Xml::fieldset( wfMsg( 'resetpass_header' ) ) .
-                       Xml::openElement( 'form',
-                               array(
-                                       'method' => 'post',
-                                       'action' => $self->getLocalUrl(),
-                                       'id' => 'mw-resetpass-form' ) ) . "\n" .
-                       Xml::hidden( 'token', $wgUser->editToken() ) . "\n" .
-                       Xml::hidden( 'wpName', $this->mUserName ) . "\n" .
-                       Xml::hidden( 'returnto', $wgRequest->getVal( 'returnto' 
) ) . "\n" .
-                       wfMsgExt( 'resetpass_text', array( 'parse' ) ) . "\n" .
-                       Xml::openElement( 'table', array( 'id' => 
'mw-resetpass-table' ) ) . "\n" .
-                       $this->pretty( array(
-                               array( 'wpName', 'username', 'text', 
$this->mUserName ),
-                               array( 'wpPassword', $oldpassMsg, 'password', 
$this->mOldpass ),
-                               array( 'wpNewPassword', 'newpassword', 
'password', null ),
-                               array( 'wpRetype', 'retypenew', 'password', 
null ),
-                       ) ) . "\n" .
-                       $rememberMe .
-                       "<tr>\n" .
-                               "<td></td>\n" .
-                               '<td class="mw-input">' .
-                                       Xml::submitButton( wfMsg( $submitMsg ) 
) .
-                               "</td>\n" .
-                       "</tr>\n" .
-                       Xml::closeElement( 'table' ) .
-                       Xml::closeElement( 'form' ) .
-                       Xml::closeElement( 'fieldset' ) . "\n"
+                       $header
+                       . Html::rawElement( 'fieldset', array( 'class' => 
'visualClear' ), ''
+                               . Html::element( 'legend', array(), wfMsg( 
'resetpass_header' ) )
+                               . $formOutput
+                       )
                );
        }
 
-       function pretty( $fields ) {
-               $out = '';
-               foreach ( $fields as $list ) {
-                       list( $name, $label, $type, $value ) = $list;
-                       if( $type == 'text' ) {
-                               $field = htmlspecialchars( $value );
-                       } else {
-                               $attribs = array( 'id' => $name );
-                               if ( $name == 'wpNewPassword' || $name == 
'wpRetype' ) {
-                                       $attribs = array_merge( $attribs,
-                                               
User::passwordChangeInputAttribs() );
-                               }
-                               if ( $name == 'wpPassword' ) {
-                                       $attribs[] = 'autofocus';
-                               }
-                               $field = Html::input( $name, $value, $type, 
$attribs );
-                       }
-                       $out .= "<tr>\n";
-                       $out .= "\t<td class='mw-label'>";
-                       if ( $type != 'text' )
-                               $out .= Xml::label( wfMsg( $label ), $name );
-                       else 
-                               $out .=  wfMsgHtml( $label );
-                       $out .= "</td>\n";
-                       $out .= "\t<td class='mw-input'>";
-                       $out .= $field;
-                       $out .= "</td>\n";
-                       $out .= "</tr>";
-               }
-               return $out;
-       }
-
        /**
-        * @throws PasswordError when cannot set the new password because 
requirements not met.
+        * Try to reset the user's password 
         */
-       protected function attemptReset( $newpass, $retype ) {
-               $user = User::newFromName( $this->mUserName );
+       protected function attemptReset() {
+               $user = User::newFromName( $this->mUsername );
                if( !$user || $user->isAnon() ) {
-                       throw new PasswordError( 'no such user' );
+                       $this->mHeaderMsg = 'no such user';
+                       return false;
                }
                
-               if( $newpass !== $retype ) {
-                       wfRunHooks( 'PrefsPasswordAudit', array( $user, 
$newpass, 'badretype' ) );
-                       throw new PasswordError( wfMsg( 'badretype' ) );
+               if( $this->mNewpass !== $this->mRetype ) {
+                       wfRunHooks( 'PrefsPasswordAudit', array( $user, 
$this->mNewpass, 'badretype' ) );
+                       $this->mHeaderMsg = 'badretype';
+                       return false;
                }
 
                if( !$user->checkTemporaryPassword($this->mOldpass) && 
!$user->checkPassword($this->mOldpass) ) {
-                       wfRunHooks( 'PrefsPasswordAudit', array( $user, 
$newpass, 'wrongpassword' ) );
-                       throw new PasswordError( wfMsg( 
'resetpass-wrong-oldpass' ) );
+                       wfRunHooks( 'PrefsPasswordAudit', array( $user, 
$this->mNewpass, 'wrongpassword' ) );
+                       $this->mHeaderMsg = 'resetpass-wrong-oldpass';
+                       return false;
                }
                
                try {
                        $user->setPassword( $this->mNewpass );
-                       wfRunHooks( 'PrefsPasswordAudit', array( $user, 
$newpass, 'success' ) );
+                       wfRunHooks( 'PrefsPasswordAudit', array( $user, 
$this->mNewpass, 'success' ) );
                        $this->mNewpass = $this->mOldpass = $this->mRetypePass 
= '';
                } catch( PasswordError $e ) {
-                       wfRunHooks( 'PrefsPasswordAudit', array( $user, 
$newpass, 'error' ) );
-                       throw new PasswordError( $e->getMessage() );
-                       return;
+                       wfRunHooks( 'PrefsPasswordAudit', array( $user, 
$this->mNewpass, 'error' ) );
+                       $this->mHeaderMsg = $e->getMessage();
+                       return false;
                }
                
                $user->setCookies();
                $user->saveSettings();
+               return true;
        }
 }

Modified: branches/happy-melon/phase3/includes/specials/SpecialUserlogin.php
===================================================================
--- branches/happy-melon/phase3/includes/specials/SpecialUserlogin.php  
2009-09-13 07:15:54 UTC (rev 56255)
+++ branches/happy-melon/phase3/includes/specials/SpecialUserlogin.php  
2009-09-13 12:51:07 UTC (rev 56256)
@@ -51,8 +51,6 @@
 
        function execute( $par ) {
                global $wgRequest;
-               $this->loadQuery();
-               $this->mLogin = new Login();
 
                # Redirect out for account creation, for B/C
                $type = ( $par == 'signup' ) ? $par : $wgRequest->getText( 
'type' );
@@ -61,11 +59,14 @@
                        $sp->execute( $par );
                        return;
                }
+               
+               $this->loadQuery();
+               $this->mLogin = new Login();
 
-               if ( !is_null( $this->mCookieCheck ) ) {
+               if ( $wgRequest->getCheck( 'wpCookieCheck' ) ) {
                        $this->onCookieRedirectCheck();
                        return;
-               } else if( $this->mPosted ) {
+               } else if( $wgRequest->wasPosted() ) {
                        if ( $this->mMailmypassword ) {
                                return $this->showMailPage();
                        } else {
@@ -90,24 +91,21 @@
 
                $this->mReturnTo = $wgRequest->getVal( 'returnto' );
                $this->mReturnToQuery = $wgRequest->getVal( 'returntoquery' );
-               $this->mCookieCheck = $wgRequest->getVal( 'wpCookieCheck' );
 
                $this->mMailmypassword = $wgRequest->getCheck( 
'wpMailmypassword' )
                                         && $wgEnableEmail;
                $this->mRemember = $wgRequest->getCheck( 'wpRemember' );
                $this->mSkipCookieCheck = $wgRequest->getCheck( 
'wpSkipCookieCheck' );
-               $this->mPosted = $wgRequest->wasPosted();
 
+               if( !$wgAuth->validDomain( $this->mDomain ) ) {
+                       $this->mDomain = 'invaliddomain';
+               }
+               $wgAuth->setDomain( $this->mDomain );
+       
                if ( $wgRedirectOnLogin ) {
                        $this->mReturnTo = $wgRedirectOnLogin;
                        $this->mReturnToQuery = '';
                }
-
-               if( !$wgAuth->validDomain( $this->mDomain ) ) {
-                       $this->mDomain = 'invaliddomain';
-               }
-               $wgAuth->setDomain( $this->mDomain );
-
                # When switching accounts, it sucks to get automatically logged 
out
                $returnToTitle = Title::newFromText( $this->mReturnTo );
                if( is_object( $returnToTitle ) && $returnToTitle->isSpecial( 
'Userlogout' ) ) {
@@ -270,7 +268,6 @@
                                wfMsgExt( 'loginend', array( 'parseinline' ) )
                        )
                );
-
        }       
 
        /**
@@ -284,7 +281,7 @@
         */
        protected function hasSessionCookie() {
                global $wgDisableCookieCheck, $wgRequest;
-               return $wgDisableCookieCheck ? true : 
$wgRequest->checkSessionCookie();
+               return $wgDisableCookieCheck || 
$wgRequest->checkSessionCookie();
        }
 
        /**
@@ -306,10 +303,14 @@
         * @param $type String action being performed
         */
        protected function onCookieRedirectCheck() {
-               if ( !$this->hasSessionCookie() ) {
+               if ( $this->hasSessionCookie() ) {
+                       return self::successfulLogin( 
+                               'loginsuccess', 
+                               $this->mReturnTo, 
+                               $this->mReturnToQuery
+                       );
+               } else {
                        return $this->mainLoginForm( wfMsgExt( 
'nocookieslogin', array( 'parseinline' ) ) );
-               } else {
-                       return self::successfulLogin( 'loginsuccess', 
$this->mReturnTo, $this->mReturnToQuery );
                }
        }
 
@@ -365,50 +366,55 @@
 
        /**
         * Display a "login successful" page.
-        * @param $msgname String message key to display
+        * @param $message String message key of main message to display
         * @param $html String HTML to optionally add
         * @param $returnto Title to returnto
         * @param $returntoQuery String query string for returnto link
         */
-       public static function displaySuccessfulLogin( $msgname, 
$injected_html='', $returnto=false, $returntoQuery=false ) {
+       public static function displaySuccessfulLogin( $message, $html='', 
$returnTo=false, $returnToQuery=false ) {
                global $wgOut, $wgUser;
-
+               
                $wgOut->setPageTitle( wfMsg( 'loginsuccesstitle' ) );
                $wgOut->setRobotPolicy( 'noindex,nofollow' );
                $wgOut->setArticleRelated( false );
-               $wgOut->addWikiMsg( $msgname, $wgUser->getName() );
-               $wgOut->addHTML( $injected_html );
+               $wgOut->addWikiMsg( $message, $wgUser->getName() );
+               $wgOut->addHTML( $html );
 
-               if ( $returnto ) {
-                       $wgOut->returnToMain( null, $returnto, 
$this->mReturnToQuery );
+               if ( $returnTo ) {
+                       $wgOut->returnToMain( null, $returnTo, $returnToQuery );
                } else {
                        $wgOut->returnToMain( null );
                }
        }
 
        /**
-        * Run any hooks registered for logins, then HTTP redirect to
+        * Display any messages generated by hooks, or HTTP redirect to
         * $this->mReturnTo (or Main Page if that's undefined).  Formerly we 
had a
-        * nice message here, but that's really not as useful as just being 
sent to
+        * nice message here, but that's not as useful as just being sent to
         * wherever you logged in from.  It should be clear that the action was
         * successful, given the lack of error messages plus the appearance of 
your
         * name in the upper right.
+        * 
+        * Remember that this function can be accessed from a variety of 
+        * places, such as Special:ResetPass, or Special:CreateAccount.
+        * @param $message String message key of a message to display if
+        *   we don't redirect
+        * @param $returnTo String title of page to redirect to
+        * @param $returnToQuery String query string to add to the redirect.
+        * @param $html String empty string to go straight 
+        *   to the redirect, or valid HTML to add underneath the text.
         */
-       public static function successfulLogin( $message, $returnTo='', 
$returnToQuery='' ) {
+       public static function successfulLogin( $message, $returnTo='', 
$returnToQuery='', $html='' ) {
                global $wgUser, $wgOut;
 
-               # Run any hooks; display injected HTML if any, else redirect
-               $injected_html = '';
-               wfRunHooks('UserLoginComplete', array(&$wgUser, 
&$injected_html));
-
-               if( $injected_html !== '' ) {
-                       SpecialUserLogin::displaySuccessfulLogin( $message, 
$injected_html );
-               } else {
+               if( $html === '' ) {
                        $titleObj = Title::newFromText( $returnTo );
                        if ( !$titleObj instanceof Title ) {
                                $titleObj = Title::newMainPage();
                        }
                        $wgOut->redirect( $titleObj->getFullURL( $returnToQuery 
) );
+               } else {
+                       SpecialUserLogin::displaySuccessfulLogin( $message, 
$html, $returnTo, $returnToQuery );
                }
        }
        
@@ -424,7 +430,11 @@
                                        global $wgLang, $wgRequest;
                                        $code = $wgRequest->getVal( 'uselang', 
$wgUser->getOption( 'language' ) );
                                        $wgLang = Language::factory( $code );
-                                       return self::successfulLogin( 
'loginsuccess', $this->mReturnTo, $this->mReturnToQuery );
+                                       return self::successfulLogin( 
+                                               'loginsuccess', 
+                                               $this->mReturnTo, 
+                                               $this->mReturnToQuery,
+                                               $this->mLogin->mLoginResult );
                                } else {
                                        # Do a redirect check to ensure that 
the cookies are 
                                        # being retained by the user's browser.
@@ -453,7 +463,12 @@
                                $this->mainLoginForm( wfMsg( 
'wrongpasswordempty' ) );
                                break;
                        case Login::RESET_PASS:
-                               $this->resetLoginForm( wfMsg( 
'resetpass_announce' ) );
+                               # 'Shell out' to Special:ResetPass to get the 
user to 
+                               # set a new permanent password from a temporary 
one.
+                               $reset = new SpecialResetpass();
+                               $reset->mHeaderMsg = 'resetpass_announce';
+                               $reset->mHeaderMsgType = 'success';
+                               $reset->execute( null );
                                break;
                        case Login::CREATE_BLOCKED:
                                $this->userBlockedMessage();
@@ -467,28 +482,15 @@
        }
 
        /**
-        * 'Shell out' to Special:ResetPass to get the user to 
-        * set a new permanent password from a temporary one.
-        * @param $error String message
-        */
-       function resetLoginForm( $error ) {
-               global $wgOut;
-               $wgOut->addHTML( Xml::element('p', array( 'class' => 'error' ), 
$error ) );
-               $reset = new SpecialResetpass();
-               $reset->execute( null );
-       }
-
-       /**
         * Attempt to send the user a password-reset mail, and display
         * the results (good, bad or ugly).
-        * @return unknown_type
         */
        protected function showMailPage(){
                global $wgOut;
                $result = $this->mLogin->mailPassword();
 
                switch( $result ){
-                       case Login::MAIL_READ_ONLY : 
+                       case Login::READ_ONLY : 
                                $wgOut->readOnlyPage();
                                return;
                        case Login::MAIL_PASSCHANGE_FORBIDDEN:

Modified: branches/happy-melon/phase3/languages/messages/MessagesEn.php
===================================================================
--- branches/happy-melon/phase3/languages/messages/MessagesEn.php       
2009-09-13 07:15:54 UTC (rev 56255)
+++ branches/happy-melon/phase3/languages/messages/MessagesEn.php       
2009-09-13 12:51:07 UTC (rev 56256)
@@ -1090,6 +1090,7 @@
 and you no longer wish to change it, you may ignore this message and
 continue using your old password.',
 'noemail'                    => 'There is no e-mail address recorded for user 
"$1".',
+'noemailcreate'              => 'You need to provide a valid email address',
 'passwordsent'               => 'A new password has been sent to the e-mail 
address registered for "$1".
 Please log in again after you receive it.',
 'blocked-mailpassword'       => 'Your IP address is blocked from editing, and 
so is not allowed to use the password recovery function to prevent abuse.',



_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to