From 69ea44000374f2fc4dcac0799031f62154e12881 Mon Sep 17 00:00:00 2001 From: parent5446 Date: Tue, 7 Aug 2012 10:46:31 -0400 Subject: [PATCH] Changed LoginForm::addNewaccountInternal() to return Status. Rather than calling mainLoginForm() and returning false, the addNewaccountInternal() function now returns a Status on failure. mainLoginForm() is then called in addNewAccount() and addNewAccountMailPassword() instead. This allows for processing of the account creation form without submitting anything to $wgOut. Change-Id: I402c6bebcfe276233cc1f9e16efbe55a034b2181 --- includes/AutoLoader.php | 1 + includes/Message.php | 42 ++++++++ includes/specials/SpecialUserlogin.php | 136 ++++++++++--------------- 3 files changed, 96 insertions(+), 83 deletions(-) diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php index f71857dbcc..bd996a2f2b 100644 --- a/includes/AutoLoader.php +++ b/includes/AutoLoader.php @@ -196,6 +196,7 @@ $wgAutoloadLocalClasses = array( 'ProtectionForm' => 'includes/ProtectionForm.php', 'QueryPage' => 'includes/QueryPage.php', 'QuickTemplate' => 'includes/SkinTemplate.php', + 'RawMessage' => 'includes/Message.php', 'RCCacheEntry' => 'includes/ChangesList.php', 'RdfMetaData' => 'includes/Metadata.php', 'ReadOnlyError' => 'includes/Exception.php', diff --git a/includes/Message.php b/includes/Message.php index abc7dc4b31..976f144e70 100644 --- a/includes/Message.php +++ b/includes/Message.php @@ -674,3 +674,45 @@ class Message { } } + +/** + * Variant of the Message class. + * + * Rather than treating the message key as a lookup + * value (which is passed to the MessageCache and + * translated as necessary), a RawMessage key is + * treated as the actual message. + * + * All other functionality (parsing, escaping, etc.) + * is preserved. + * + * @since 1.21 + */ +class RawMessage extends Message { + /** + * Call the parent constructor, then store the key as + * the message. + * + * @param $key Message to use + * @param $params Parameters for the message + * @see Message::__construct + */ + public function __construct( $key, $params = array() ) { + parent::__construct( $key, $params ); + // The key is the message. + $this->message = $key; + } + + /** + * Fetch the message (in this case, the key). + * + * @return string + */ + public function fetchMessage() { + // Just in case the message is unset somewhere. + if( !isset( $this->message ) ) { + $this->message = $this->key; + } + return $this->message; + } +} diff --git a/includes/specials/SpecialUserlogin.php b/includes/specials/SpecialUserlogin.php index a09d5bddf1..d571c8b99b 100644 --- a/includes/specials/SpecialUserlogin.php +++ b/includes/specials/SpecialUserlogin.php @@ -197,12 +197,15 @@ class LoginForm extends SpecialPage { return; } - $u = $this->addNewaccountInternal(); - - if ( $u == null ) { - return; + $status = $this->addNewaccountInternal(); + if( !$status->isGood() ) { + $error = $this->getOutput()->parse( $status->getWikiText() ); + $this->mainLoginForm( $error ); + return false; } + $u = $status->getValue(); + // Wipe the initial password and mail a temporary one $u->setPassword( null ); $u->saveSettings(); @@ -230,11 +233,15 @@ class LoginForm extends SpecialPage { global $wgUser, $wgEmailAuthentication, $wgLoginLanguageSelector; # Create the account and abort if there's a problem doing so - $u = $this->addNewAccountInternal(); - if( $u == null ) { + $status = $this->addNewAccountInternal(); + if( !$status->isGood() ) { + $error = $this->getOutput()->parse( $status->getWikiText() ); + $this->mainLoginForm( $error ); return false; } + $u = $status->getValue(); + # 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 if( $wgLoginLanguageSelector && $this->mLanguage ) { @@ -285,18 +292,18 @@ class LoginForm extends SpecialPage { } /** + * Make a new user account using the loaded data. * @private * @throws PermissionsError|ReadOnlyError - * @return bool|User + * @return Status */ - function addNewAccountInternal() { + public function addNewAccountInternal() { global $wgAuth, $wgMemc, $wgAccountCreationThrottle, $wgMinimalPasswordLength, $wgEmailConfirmToEdit; // If the user passes an invalid domain, something is fishy if( !$wgAuth->validDomain( $this->mDomain ) ) { - $this->mainLoginForm( $this->msg( 'wrongpassword' )->text() ); - return false; + return Status::newFatal( 'wrongpassword' ); } // If we are not allowing users to login locally, we should be checking @@ -305,10 +312,12 @@ class LoginForm extends SpecialPage { // create a local account and login as any domain user). We only need // to check this for domains that aren't local. if( 'local' != $this->mDomain && $this->mDomain != '' ) { - if( !$wgAuth->canCreateAccounts() && ( !$wgAuth->userExists( $this->mUsername ) - || !$wgAuth->authenticate( $this->mUsername, $this->mPassword ) ) ) { - $this->mainLoginForm( $this->msg( 'wrongpassword' )->text() ); - return false; + if( + !$wgAuth->canCreateAccounts() && + ( !$wgAuth->userExists( $this->mUsername || + !$wgAuth->authenticate( $this->mUsername, $this->mPassword ) ) ) + ) { + return Status::newFatal( 'wrongpassword' ); } } @@ -319,28 +328,28 @@ class LoginForm extends SpecialPage { # Request forgery checks. if ( !self::getCreateaccountToken() ) { self::setCreateaccountToken(); - $this->mainLoginForm( $this->msg( 'nocookiesfornew' )->parse() ); - return false; + return Status::newFatal( 'sessionfailure' ); } # The user didn't pass a createaccount token if ( !$this->mToken ) { - $this->mainLoginForm( $this->msg( 'sessionfailure' )->text() ); - return false; + return Status::newFatal( 'sessionfailure' ); } # Validate the createaccount token if ( $this->mToken !== self::getCreateaccountToken() ) { - $this->mainLoginForm( $this->msg( 'sessionfailure' )->text() ); - return false; + return Status::newFatal( 'sessionfailure' ); } # Check permissions $currentUser = $this->getUser(); + $creationBlock = $currentUser->isBlockedFromCreateAccount(); if ( !$currentUser->isAllowed( 'createaccount' ) ) { throw new PermissionsError( 'createaccount' ); - } elseif ( $currentUser->isBlockedFromCreateAccount() ) { - $this->userBlockedMessage( $currentUser->isBlockedFromCreateAccount() ); + } elseif ( $creationBlock instanceof Block ) { + // Throws an ErrorPageError. + $this->userBlockedMessage( $creationBlock ); + // This should never be reached. return false; } @@ -352,41 +361,28 @@ class LoginForm extends SpecialPage { $ip = $this->getRequest()->getIP(); if ( $currentUser->isDnsBlacklisted( $ip, true /* check $wgProxyWhitelist */ ) ) { - $this->mainLoginForm( $this->msg( 'sorbs_create_account_reason' )->text() . ' ' . $this->msg( 'parentheses', $ip )->escaped() ); - return false; + return Status::newFatal( 'sorbs_create_account_reason' ); } # Now create a dummy user ($u) and check if it is valid $name = trim( $this->mUsername ); $u = User::newFromName( $name, 'creatable' ); if ( !is_object( $u ) ) { - $this->mainLoginForm( $this->msg( 'noname' )->text() ); - return false; - } - - if ( 0 != $u->idForName() ) { - $this->mainLoginForm( $this->msg( 'userexists' )->text() ); - return false; - } - - if ( 0 != strcmp( $this->mPassword, $this->mRetype ) ) { - $this->mainLoginForm( $this->msg( 'badretype' )->text() ); - return false; + return Status::newFatal( 'noname' ); + } elseif ( 0 != $u->idForName() ) { + return Status::newFatal( 'userexists' ); + } elseif ( 0 != strcmp( $this->mPassword, $this->mRetype ) ) { + return Status::newFatal( 'badretype' ); } # check for minimal password length $valid = $u->getPasswordValidity( $this->mPassword ); if ( $valid !== true ) { if ( !$this->mCreateaccountMail ) { - if ( is_array( $valid ) ) { - $message = array_shift( $valid ); - $params = $valid; - } else { - $message = $valid; - $params = array( $wgMinimalPasswordLength ); + if ( !is_array( $valid ) ) { + $valid = array( $valid, $wgMinimalPasswordLength ); } - $this->mainLoginForm( $this->msg( $message, $params )->text() ); - return false; + return call_user_func_array( 'Status::newFatal', $valid ); } else { # do not force a password for account creation by email # set invalid password, it will be replaced later by a random generated password @@ -397,13 +393,11 @@ class LoginForm extends SpecialPage { # if you need a confirmed email address to edit, then obviously you # need an email address. if ( $wgEmailConfirmToEdit && empty( $this->mEmail ) ) { - $this->mainLoginForm( $this->msg( 'noemailtitle' )->text() ); - return false; + return Status::newFatal( 'noemailtitle' ); } if( !empty( $this->mEmail ) && !Sanitizer::validateEmail( $this->mEmail ) ) { - $this->mainLoginForm( $this->msg( 'invalidemailaddress' )->text() ); - return false; + return Status::newFatal( 'invalidemailaddress' ); } # Set some additional data so the AbortNewAccount hook can be used for @@ -415,8 +409,7 @@ class LoginForm extends SpecialPage { if( !wfRunHooks( 'AbortNewAccount', array( $u, &$abortError ) ) ) { // Hook point to add extra creation throttles and blocks wfDebug( "LoginForm::addNewAccountInternal: a hook blocked creation\n" ); - $this->mainLoginForm( $abortError ); - return false; + return Status::newFatal( new RawMessage( $abortError ) ); } // Hook point to check for exempt from account creation throttle @@ -430,26 +423,18 @@ class LoginForm extends SpecialPage { $wgMemc->set( $key, 0, 86400 ); } if ( $value >= $wgAccountCreationThrottle ) { - $this->throttleHit( $wgAccountCreationThrottle ); - return false; + return Status::newFatal( 'acct_creation_throttle_hit', $wgAccountCreationThrottle ); } $wgMemc->incr( $key ); } } if( !$wgAuth->addUser( $u, $this->mPassword, $this->mEmail, $this->mRealName ) ) { - $this->mainLoginForm( $this->msg( 'externaldberror' )->text() ); - return false; + return Status::newFatal( 'externaldberror' ); } self::clearCreateaccountToken(); - - $status = $this->initUser( $u, false ); - if ( !$status->isOK() ) { - $this->mainLoginForm( $status->getHTML() ); - return false; - } - return $status->value; + return $this->initUser( $u, false ); } /** @@ -965,23 +950,15 @@ class LoginForm extends SpecialPage { # haven't bothered to log out before trying to create an account to # evade it, but we'll leave that to their guilty conscience to figure # out. - - $out = $this->getOutput(); - $out->setPageTitle( $this->msg( 'cantcreateaccounttitle' ) ); - - $block_reason = $block->mReason; - if ( strval( $block_reason ) === '' ) { - $block_reason = $this->msg( 'blockednoreason' )->text(); - } - - $out->addWikiMsg( + throw new ErrorPageError( + 'cantcreateaccounttitle', 'cantcreateaccount-text', - $block->getTarget(), - $block_reason, - $block->getByName() + array( + $block->getTarget(), + $block->mReason ? $block->mReason : $this->msg( 'blockednoreason' )->text(), + $block->getByName() + ) ); - - $this->executeReturnTo( 'error' ); } /** @@ -1316,13 +1293,6 @@ class LoginForm extends SpecialPage { } } - /** - * @private - */ - function throttleHit( $limit ) { - $this->mainLoginForm( $this->msg( 'acct_creation_throttle_hit' )->numParams( $limit )->parse() ); - } - /** * Produce a bar of links which allow the user to select another language * during login/registration but retain "returnto" -- 2.20.1