jenkins-bot has submitted this change and it was merged.

Change subject: Handle AuthManager introduction to core
......................................................................


Handle AuthManager introduction to core

This makes "accept" redirect to CreateAccount with a mostly-locked
form for creating the user and sending them their temporary password.
When that happens, the request queue is updated as normal.

Also fixed some rollback exceptions that happen on form rejection.

Bug: T110451
Change-Id: Ib803ee30f2ad7bd48eed7f7fcfdc97d219b76ef7
---
M ConfirmAccount.php
M ConfirmAccount.setup.php
M business/AccountConfirmSubmission.php
M business/AccountRequestSubmission.php
A business/ConfirmAccountPreAuthenticationProvider.php
M frontend/ConfirmAccountUI.hooks.php
M frontend/ConfirmAccountUI.setup.php
M frontend/specialpages/actions/ConfirmAccount_body.php
M i18n/confirmaccount/en.json
M i18n/confirmaccount/qqq.json
10 files changed, 296 insertions(+), 132 deletions(-)

Approvals:
  Aaron Schulz: Looks good to me, approved
  Gergő Tisza: Looks good to me, but someone else must approve
  jenkins-bot: Verified



diff --git a/ConfirmAccount.php b/ConfirmAccount.php
index 9731637..5594ee7 100644
--- a/ConfirmAccount.php
+++ b/ConfirmAccount.php
@@ -58,8 +58,11 @@
 # UI-related hook handlers
 ConfirmAccountUISetup::defineHookHandlers( $wgHooks );
 
-# Check for account name collisions
-$wgHooks['AbortNewAccount'][] = 
'ConfirmAccountUIHooks::checkIfAccountNameIsPending';
+# Check for account name collisions and handle queue updates
+$wgAuthManagerAutoConfig['preauth'][ConfirmAccountPreAuthenticationProvider::class]
 = [
+       'class' => ConfirmAccountPreAuthenticationProvider::class,
+       'sort'  => 0
+];
 
 # Schema changes
 $wgHooks['LoadExtensionSchemaUpdates'][] = 
'ConfirmAccountUpdaterHooks::addSchemaUpdates';
diff --git a/ConfirmAccount.setup.php b/ConfirmAccount.setup.php
index 845b1c8..4014cb7 100644
--- a/ConfirmAccount.setup.php
+++ b/ConfirmAccount.setup.php
@@ -53,6 +53,8 @@
                # Business logic
                $classes['AccountRequestSubmission'] = 
"$businessDir/AccountRequestSubmission.php";
                $classes['AccountConfirmSubmission'] = 
"$businessDir/AccountConfirmSubmission.php";
+               $classes['ConfirmAccountPreAuthenticationProvider'] =
+                       
"$businessDir/ConfirmAccountPreAuthenticationProvider.php";
 
                # Schema changes
                $classes['ConfirmAccountUpdaterHooks'] = 
"$schemaDir/ConfirmAccountUpdater.hooks.php";
diff --git a/business/AccountConfirmSubmission.php 
b/business/AccountConfirmSubmission.php
index 4e4de45..ecdf6ed 100644
--- a/business/AccountConfirmSubmission.php
+++ b/business/AccountConfirmSubmission.php
@@ -17,6 +17,9 @@
        protected $action;
        protected $reason;
 
+       /** @var bool Enable dummy "complete" action */
+       protected $allowComplete;
+
        public function __construct( User $admin, UserAccountRequest $accReq, 
array $params ) {
                $this->admin = $admin;
                $this->accountReq = $accReq;
@@ -26,19 +29,28 @@
                $this->areas = $params['areas'];
                $this->action = $params['action'];
                $this->reason = $params['reason'];
+               $this->allowComplete = !empty( $params['allowComplete'] );
        }
 
        /**
         * Attempt to validate and submit this data to the DB
         * @param $context IContextSource
-        * @return array( true or error key string, html error msg or null )
+        * @return array( true or error key string, html error msg or null, 
redirect URL )
         */
        public function submit( IContextSource $context ) {
                # Make sure that basic permissions are checked
                if ( !$this->admin->getID() || !$this->admin->isAllowed( 
'confirmaccount' ) ) {
-                       return [ 'accountconf_permission_denied', 
$context->msg( 'badaccess-group0' )->escaped() ];
+                       return [
+                               'accountconf_permission_denied',
+                               $context->msg( 'badaccess-group0' )->escaped(),
+                               null
+                       ];
                } elseif ( wfReadOnly() ) {
-                       return [ 'accountconf_readonly', $context->msg( 
'badaccess-group0' )->escaped() ];
+                       return [
+                               'accountconf_readonly',
+                               $context->msg( 'badaccess-group0' )->escaped(),
+                               null
+                       ];
                }
                if ( $this->action === 'spam' ) {
                        return $this->spamRequest( $context );
@@ -48,8 +60,14 @@
                        return $this->holdRequest( $context );
                } elseif ( $this->action === 'accept' ) {
                        return $this->acceptRequest( $context );
+               } elseif ( $this->action === 'complete' && $this->allowComplete 
) {
+                       return $this->completeRequest( $context );
                } else {
-                       return [ 'accountconf_bad_action', $context->msg( 
'confirmaccount-badaction' )->escaped() ];
+                       return [
+                               'accountconf_bad_action',
+                               $context->msg( 'confirmaccount-badaction' 
)->escaped(),
+                               null
+                       ];
                }
        }
 
@@ -64,7 +82,7 @@
                }
 
                $dbw->endAtomic( __METHOD__ );
-               return [ true, null ];
+               return [ true, null, null ];
        }
 
        protected function rejectRequest( IContextSource $context ) {
@@ -89,18 +107,21 @@
                                $emailBody
                        );
                        if ( !$result->isOk() ) {
-                               $dbw->rollback( __METHOD__ );
-                               return [ 'accountconf_mailerror',
+                               wfGetLBFactory()->rollbackMasterChanges( 
__METHOD__ );
+                               return [
+                                       'accountconf_mailerror',
                                        $context->msg( 'mailerror' )->rawParams(
                                                $context->getOutput()->parse( 
$result->getWikiText() )
-                                       )->text() ];
+                                       )->text(),
+                                       null
+                               ];
                        }
                        # Clear cache for notice of how many account requests 
there are
                        ConfirmAccount::clearAccountRequestCountCache();
                }
 
                $dbw->endAtomic( __METHOD__ );
-               return [ true, null ];
+               return [ true, null, null ];
        }
 
        protected function holdRequest( IContextSource $context ) {
@@ -111,7 +132,9 @@
                # Pointless without a summary...
                if ( $this->reason == '' ) {
                        return [
-                               'accountconf_needreason', $context->msg( 
'confirmaccount-needreason' )->escaped()
+                               'accountconf_needreason',
+                               $context->msg( 'confirmaccount-needreason' 
)->escaped(),
+                               null
                        ];
                }
 
@@ -121,8 +144,12 @@
                # If not already held or deleted, mark as held
                $ok = $this->accountReq->markHeld( $this->admin, 
wfTimestampNow(), $this->reason );
                if ( !$ok ) { // already held or deleted?
-                       $dbw->rollback( __METHOD__ );
-                       return [ 'accountconf_canthold', $context->msg( 
'confirmaccount-canthold' )->escaped() ];
+                       wfGetLBFactory()->rollbackMasterChanges( __METHOD__ );
+                       return [
+                               'accountconf_canthold',
+                               $context->msg( 'confirmaccount-canthold' 
)->escaped(),
+                               null
+                       ];
                }
 
                # Send out a request hold email...
@@ -133,61 +160,55 @@
                        )->inContentLanguage()->text()
                );
                if ( !$result->isOk() ) {
-                       $dbw->rollback( __METHOD__ );
-                       return [ 'accountconf_mailerror',
+                       wfGetLBFactory()->rollbackMasterChanges( __METHOD__ );
+                       return [
+                               'accountconf_mailerror',
                                $context->msg( 'mailerror' )->rawParams(
                                        $context->getOutput()->parse( 
$result->getWikiText() )
-                               )->text() ];
+                               )->text(),
+                               null
+                       ];
                }
 
                # Clear cache for notice of how many account requests there are
                ConfirmAccount::clearAccountRequestCountCache();
 
                $dbw->endAtomic( __METHOD__ );
-               return [ true, null ];
+               return [ true, null, null ];
        }
 
        protected function acceptRequest( IContextSource $context ) {
-               global $wgAuth, $wgConfirmAccountSaveInfo;
+               global $wgAccountRequestTypes;
+
+               $id = $this->accountReq->getId();
+               $type = $wgAccountRequestTypes[$this->accountReq->getType()][0];
+               $redirTitle = SpecialPageFactory::getTitleForAlias( 
'CreateAccount' );
+               $returnTitle = SpecialPageFactory::getTitleForAlias( 
"ConfirmAccounts/{$type}" );
+               $params = [
+                       'AccountRequestId' => $id,
+                       'wpName' => $this->userName,
+                       'returnto' => $returnTitle->getPrefixedDBkey(),
+                       'reason' => $this->reason
+               ];
+
+               return [ true, null, $redirTitle->getFullURL( $params ) ];
+       }
+
+       protected function completeRequest( IContextSource $context ) {
+               global $wgConfirmAccountSaveInfo;
                global $wgConfirmAccountRequestFormItems, 
$wgConfirmAccountFSRepos;
 
                $formConfig = $wgConfirmAccountRequestFormItems; // convience
                $accReq = $this->accountReq; // convenience
 
                # Now create user and check if the name is valid
-               $user = User::newFromName( $this->userName, 'creatable' );
+               $user = User::newFromName( $this->userName, false );
                if ( !$user ) {
-                       return [ 'accountconf_invalid_name', $context->msg( 
'noname' )->escaped() ];
-               }
-
-               # Check if account name is already in use
-               if ( 0 != $user->idForName() || 
AuthManager::singleton()->userExists( $user->getName() ) ) {
-                       return [ 'accountconf_user_exists', $context->msg( 
'userexists' )->escaped() ];
+                       return [ 'accountconf_invalid_name', $context->msg( 
'noname' )->escaped(), null ];
                }
 
                $dbw = wfGetDB( DB_MASTER );
                $dbw->startAtomic( __METHOD__ );
-
-               # Make a random password
-               $pass = User::randomPassword();
-
-               # Insert the new user into the DB...
-               $tokenExpires = $accReq->getEmailTokenExpires();
-               $authenticated = $accReq->getEmailAuthTimestamp();
-               $params = [
-                       # Set the user's real name
-                       'real_name' => $accReq->getRealName(),
-                       # Set the temporary password
-                       'newpassword' => User::crypt( $pass ),
-                       # VERY important to set email now. Otherwise the user
-                       # will have to request a new password at the login 
screen...
-                       'email' => $accReq->getEmail(),
-                       # Import email address confirmation status
-                       'email_authenticated' => $dbw->timestampOrNull( 
$authenticated ),
-                       'email_token_expires' => $dbw->timestamp( $tokenExpires 
),
-                       'email_token' => $accReq->getEmailToken()
-               ];
-               $user = User::createNew( $user->getName(), $params );
 
                # Grant any necessary rights (exclude blank or dummy groups)
                $group = self::getGroupFromType( $this->type );
@@ -210,9 +231,12 @@
                                $triplet = [ $oldPath, 'public', $pathRel ];
                                $status = $repoNew->storeBatch( [ $triplet ] ); 
// copy!
                                if ( !$status->isOK() ) {
-                                       $dbw->rollback( __METHOD__ );
-                                       return [ 'accountconf_copyfailed',
-                                               $context->getOutput()->parse( 
$status->getWikiText() ) ];
+                                       
wfGetLBFactory()->rollbackMasterChanges( __METHOD__ );
+                                       return [
+                                               'accountconf_copyfailed',
+                                               $context->getOutput()->parse( 
$status->getWikiText() ),
+                                               null
+                                       ];
                                }
                        }
                        $acd_id = $dbw->nextSequenceValue( 
'account_credentials_acd_id_seq' );
@@ -222,7 +246,8 @@
                                        'acd_user_id' => $user->getID(),
                                        'acd_real_name' => 
$accReq->getRealName(),
                                        'acd_email' => $accReq->getEmail(),
-                                       'acd_email_authenticated' => 
$dbw->timestampOrNull( $authenticated ),
+                                       'acd_email_authenticated' =>
+                                               $dbw->timestampOrNull( 
$accReq->getEmailAuthTimestamp() ),
                                        'acd_bio' => $accReq->getBio(),
                                        'acd_notes' => $accReq->getNotes(),
                                        'acd_urls' => $accReq->getUrls(),
@@ -240,15 +265,6 @@
                                ],
                                __METHOD__
                        );
-                       if ( is_null( $acd_id ) ) {
-                               $acd_id = $dbw->insertId(); // set $acd_id to 
ID inserted
-                       }
-               }
-
-               # Add to global user login system (if there is one)
-               if ( !$wgAuth->addUser( $user, $pass, $accReq->getEmail(), 
$accReq->getRealName() ) ) {
-                       $dbw->rollback( __METHOD__ );
-                       return [ 'accountconf_externaldberror', $context->msg( 
'externaldberror' )->escaped() ];
                }
 
                # OK, now remove the request from the queue
@@ -261,57 +277,18 @@
 
                $that = $this;
                DeferredUpdates::addCallableUpdate(
-                       function () use ( $that, $user, $context, $group, 
$pass, $accReq ) {
-                               $that->doPostCommitNewUserUpdates( $user, 
$context, $group, $pass, $accReq );
+                       function () use ( $that, $user, $context, $group, 
$accReq ) {
+                               $that->doPostCommitNewUserUpdates( $user, 
$context, $group, $accReq );
                        }
                );
 
-               return [ true, null ];
+               return [ true, null, null ];
        }
 
        public function doPostCommitNewUserUpdates(
-               User $user, IContextSource $context, $group, $pass, 
UserAccountRequest $accReq
+               User $user, IContextSource $context, $group, UserAccountRequest 
$accReq
        ) {
                global $wgConfirmAccountRequestFormItems, 
$wgConfirmAccountFSRepos;
-
-               # Prepare a temporary password email...
-               if ( $this->reason != '' ) {
-                       $msg = "confirmaccount-email-body2-pos {$this->type}";
-                       $msgObj = $context->msg( $msg, $user->getName(), $pass, 
$this->reason );
-                       # If the user is in a group and there is a welcome for 
that group, use it
-                       if ( $group && !$msgObj->isDisabled() ) {
-                               $ebody = $msgObj->inContentLanguage()->text();
-                               # Use standard if none found...
-                       } else {
-                               $ebody = $context->msg( 
'confirmaccount-email-body2',
-                                       $user->getName(), $pass, $this->reason 
)->inContentLanguage()->text();
-                       }
-               } else {
-                       $msg = "confirmaccount-email-body-pos{$this->type}";
-                       # If the user is in a group and there is a welcome for 
that group, use it
-                       if ( $group && !$context->msg( $msg )->isDisabled() ) {
-                               $ebody = $context->msg( $msg,
-                                       $user->getName(), $pass, $this->reason 
)->inContentLanguage()->text();
-                               # Use standard if none found...
-                       } else {
-                               $ebody = $context->msg( 
'confirmaccount-email-body',
-                                       $user->getName(), $pass, $this->reason 
)->inContentLanguage()->text();
-                       }
-               }
-
-               # Actually send out the email
-               $user->sendMail(
-                       $context->msg( 'confirmaccount-email-subj' 
)->inContentLanguage()->text(),
-                       $ebody
-               );
-
-               # Update user count
-               $ssUpdate = new SiteStatsUpdate( 0, 0, 0, 0, 1 );
-               $ssUpdate->doUpdate();
-
-               # Safe to hook/log now...
-               Hooks::run( 'AddNewAccount', [ $user, false /* not by email */ 
] );
-               $user->addNewUserLogEntry();
 
                # Clear cache for notice of how many account requests there are
                ConfirmAccount::clearAccountRequestCountCache();
diff --git a/business/AccountRequestSubmission.php 
b/business/AccountRequestSubmission.php
index 5b0b5c8..75a6d72 100644
--- a/business/AccountRequestSubmission.php
+++ b/business/AccountRequestSubmission.php
@@ -159,7 +159,7 @@
                $dbw->startAtomic( __METHOD__ ); // ready to acquire locks
                # Check pending accounts for name use
                if ( !UserAccountRequest::acquireUsername( $u->getName() ) ) {
-                       $dbw->rollback( __METHOD__ );
+                       $dbw->endAtomic( __METHOD__ );
                        return [
                                'accountreq_username_pending',
                                $context->msg( 'requestaccount-inuse' 
)->escaped()
@@ -167,7 +167,7 @@
                }
                # Check if someone else has an account request with the same 
email
                if ( !UserAccountRequest::acquireEmail( $u->getEmail() ) ) {
-                       $dbw->rollback( __METHOD__ );
+                       $dbw->endAtomic( __METHOD__ );
                        return [
                                'acct_request_email_exists',
                                $context->msg( 'requestaccount-emaildup' 
)->escaped()
@@ -182,7 +182,7 @@
                        # File must have size.
                        if ( trim( $this->attachmentSrcName ) == '' || empty( 
$this->attachmentSize ) ) {
                                $this->attachmentPrevName = '';
-                               $dbw->rollback( __METHOD__ );
+                               $dbw->endAtomic( __METHOD__ );
                                return [ 'acct_request_empty_file', 
$context->msg( 'emptyfile' )->escaped() ];
                        }
                        # Look at the contents of the file; if we can recognize 
the
@@ -190,7 +190,7 @@
                        # probably not accept it.
                        if ( !in_array( $finalExt, $wgAccountRequestExts ) ) {
                                $this->attachmentPrevName = '';
-                               $dbw->rollback( __METHOD__ );
+                               $dbw->endAtomic( __METHOD__ );
                                return [
                                        'acct_request_bad_file_ext',
                                        $context->msg( 'requestaccount-exts' 
)->escaped()
@@ -199,7 +199,7 @@
                        $veri = ConfirmAccount::verifyAttachment( 
$this->attachmentTempPath, $finalExt );
                        if ( !$veri->isGood() ) {
                                $this->attachmentPrevName = '';
-                               $dbw->rollback( __METHOD__ );
+                               $dbw->endAtomic( __METHOD__ );
                                return [
                                        'acct_request_corrupt_file',
                                        $context->msg( 'verification-error' 
)->escaped()
@@ -212,7 +212,7 @@
                        $triplet = [ $this->attachmentTempPath, 'public', 
$pathRel ];
                        $status = $repo->storeBatch( [ $triplet ], 
FileRepo::OVERWRITE_SAME ); // save!
                        if ( !$status->isOk() ) {
-                               $dbw->rollback( __METHOD__ );
+                               wfGetLBFactory()->rollbackMasterChanges( 
__METHOD__ );
                                return [ 'acct_request_file_store_error',
                                        $context->msg( 'filecopyerror', 
$this->attachmentTempPath, $pathRel )->escaped() ];
                        }
@@ -246,7 +246,7 @@
                # Send confirmation, required!
                $result = ConfirmAccount::sendConfirmationMail( $u, $this->ip, 
$token, $expires );
                if ( !$result->isOK() ) {
-                       $dbw->rollback( __METHOD__ ); // nevermind
+                       wfGetLBFactory()->rollbackMasterChanges( __METHOD__ ); 
// nevermind
                        if ( isset( $repo ) && isset( $pathRel ) ) { // remove 
attachment
                                $repo->cleanupBatch( [ [ 'public', $pathRel ] ] 
);
                        }
diff --git a/business/ConfirmAccountPreAuthenticationProvider.php 
b/business/ConfirmAccountPreAuthenticationProvider.php
new file mode 100644
index 0000000..f557a63
--- /dev/null
+++ b/business/ConfirmAccountPreAuthenticationProvider.php
@@ -0,0 +1,120 @@
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Auth
+ */
+
+use \MediaWiki\Auth\AbstractPreAuthenticationProvider;
+use \MediaWiki\Auth\AuthenticationRequest;
+use \MediaWiki\Auth\AuthenticationResponse;
+use \MediaWiki\MediaWikiServices;
+
+class ConfirmAccountPreAuthenticationProvider extends 
AbstractPreAuthenticationProvider {
+       const SESSION_INFO_KEY = 'ConfirmAccountRequestInfo';
+
+       /**
+        * @param \User $user
+        * @param \User $creator
+        * @param array $reqs
+        * @return bool
+        * @throws MWException
+        */
+       public function testForAccountCreation( $user, $creator, array $reqs ) {
+               if ( UserAccountRequest::acquireUsername( $user->getName() ) ) {
+                       return StatusValue::newGood(); // no pending request 
for an account with this name
+               }
+
+               /** @var \MediaWiki\Auth\UserDataAuthenticationRequest 
$usrDataAuthReq */
+               $usrDataAuthReq = AuthenticationRequest::getRequestByClass(
+                       $reqs, 
\MediaWiki\Auth\UserDataAuthenticationRequest::class );
+               /** @var \MediaWiki\Auth\TemporaryPasswordAuthenticationRequest 
$tmpPassAuthReq */
+               $tmpPassAuthReq = AuthenticationRequest::getRequestByClass(
+                       $reqs, 
\MediaWiki\Auth\TemporaryPasswordAuthenticationRequest::class );
+
+               $request = RequestContext::getMain()->getRequest();
+               $accReqId = $request->getInt( 'AccountRequestId' );
+               # Allow creations for account requests as long as the 
parameters match up.
+               # Always keep names reserved on API requests as there is no API 
support for now.
+               if ( !$accReqId || !$creator->isAllowed( 'confirmaccount' ) || 
defined( 'MW_API' ) ) {
+                       return StatusValue::newFatal( 'requestaccount-inuse' );
+               }
+
+               $accountReq = UserAccountRequest::newFromId( $accReqId );
+               if ( !$accountReq ) {
+                       return StatusValue::newFatal( 'confirmaccount-badid' );
+               }
+
+               # Make sure certain field were left unchanged from the account 
request
+               if (
+                       !$tmpPassAuthReq ||
+                       $usrDataAuthReq->email !== $accountReq->getEmail() ||
+                       $usrDataAuthReq->realname !== 
$accountReq->getRealName() ||
+                       !$tmpPassAuthReq->mailpassword
+               ) {
+                       return StatusValue::newFatal( 
'confirmaccount-mismatched-general' );
+               }
+
+               $this->manager->setAuthenticationSessionData(
+                       self::SESSION_INFO_KEY,
+                       [
+                               'accountRequestId' => $accountReq->getId(),
+                               'confirmationParams' => [
+                                       'userName' => $user->getName(),
+                                       'action' => 'complete',
+                                       'reason' => $request->getVal( 
'wpReason', '' ),
+                                       // @TODO: make overridable in GUI
+                                       'bio' => $request->getText( 'wpNewBio', 
$accountReq->getBio() ),
+                                       'type' => $request->getInt( 'wpType', 
$accountReq->getType() ),
+                                       // @TODO: make overridable
+                                       'areas' => $accountReq->getAreas(),
+                                       'allowComplete' => true // action not 
enabled via GUI
+                               ]
+                       ]
+               );
+
+               return StatusValue::newGood();
+       }
+
+       public function postAccountCreation( $user, $creator, 
AuthenticationResponse $response ) {
+               if ( $response->status === AuthenticationResponse::FAIL ) {
+                       return; // nothing happened
+               }
+
+               $data = $this->manager->getAuthenticationSessionData( 
self::SESSION_INFO_KEY );
+               if ( !$data ) {
+                       return; // wasn't for a pending account request
+               }
+
+               $submission = new AccountConfirmSubmission(
+                       $creator,
+                       UserAccountRequest::newFromId( 
$data['accountRequestId'], 'dbmaster' ),
+                       $data['confirmationParams']
+               );
+
+               # Update the queue to reflect approval of this user
+               list( $status, $msg ) = $submission->submit( 
RequestContext::getMain() );
+               if ( $status !== true ) {
+                       // ErrorPageError does not trigger rollback
+                       $lbFactory = 
MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
+                       $lbFactory->rollbackMasterChanges( __METHOD__ );
+                       throw new ErrorPageError( 'createacct-error', new 
RawMessage( $msg ) );
+               }
+
+               return;
+       }
+}
diff --git a/frontend/ConfirmAccountUI.hooks.php 
b/frontend/ConfirmAccountUI.hooks.php
index 045c601..5d1651c 100644
--- a/frontend/ConfirmAccountUI.hooks.php
+++ b/frontend/ConfirmAccountUI.hooks.php
@@ -38,23 +38,9 @@
        }
 
        /**
-        * @param $user User
-        * @param $abortError
-        * @return bool
-        */
-       public static function checkIfAccountNameIsPending( User $user, 
&$abortError ) {
-               # If an account is made with name X, and one is pending with 
name X
-               # we will have problems if the pending one is later confirmed
-               if ( !UserAccountRequest::acquireUsername( $user->getName() ) ) 
{
-                       $abortError = wfMessage( 'requestaccount-inuse' 
)->escaped();
-                       return false;
-               }
-               return true;
-       }
-
-       /**
         * Add "x email-confirmed open account requests" notice
-        * @param $notice
+        * @param OutputPage $out
+        * @param Skin $skin
         * @return bool
         */
        public static function confirmAccountsNotice( OutputPage &$out, Skin 
&$skin ) {
@@ -101,4 +87,70 @@
 
                return true;
        }
+
+       /**
+        * @param array $requests
+        * @param array $fieldInfo
+        * @param array $formDescriptor
+        * @param string $action
+        * @return bool
+        * @throws ErrorPageError
+        */
+       public static function onAuthChangeFormFields(
+               $requests, $fieldInfo, array &$formDescriptor, $action
+       ) {
+               if ( $action !== \MediaWiki\Auth\AuthManager::ACTION_CREATE ) {
+                       return true;
+               }
+
+               $request = RequestContext::getMain()->getRequest();
+               $accReqId = $request->getInt( 'AccountRequestId' );
+               $isAllowed = RequestContext::getMain()->getUser()->isAllowed( 
'confirmaccount' );
+               if ( $accReqId && $isAllowed ) {
+                       $accReq = UserAccountRequest::newFromId( $accReqId );
+                       if ( !$accReq ) {
+                               throw new ErrorPageError( 'createacct-error', 
'confirmaccount-badid' );
+                       }
+               } else {
+                       return true;
+               }
+
+               $formDescriptor['username']['default'] = $accReq->getName();
+
+               $formDescriptor['mailpassword']['default'] = 1;
+               $formDescriptor['mailpassword']['checked'] = true;
+               $formDescriptor['mailpassword']['readonly'] = true;
+               $formDescriptor['mailpassword']['validation-callback'] = 
function ( $v ) use ( $accReq ) {
+                       return ( $v === true )
+                               ? true
+                               : wfMessage( 'confirmaccount-mismatched' );
+               };
+
+               unset( $formDescriptor['password'] );
+               unset( $formDescriptor['retype'] );
+
+               $formDescriptor['email']['default'] = $accReq->getEmail();
+               $formDescriptor['email']['readonly'] = true;
+               $formDescriptor['email']['validation-callback'] = function ( $v 
) use ( $accReq ) {
+                       return ( $v === $accReq->getEmail() )
+                               ? true
+                               : wfMessage( 'confirmaccount-mismatched' );
+               };
+
+               $formDescriptor['realname']['default'] = $accReq->getRealName();
+               $formDescriptor['realname']['readonly'] = true;
+               $formDescriptor['realname']['validation-callback'] = function ( 
$v ) use ( $accReq ) {
+                       return ( $v === $accReq->getRealName() )
+                               ? true
+                               : wfMessage( 'confirmaccount-mismatched' );
+               };
+
+               $formDescriptor['accountrequestid'] = [
+                       'name' => 'AccountRequestId',
+                       'type' => 'hidden',
+                       'default' => $accReqId
+               ];
+
+               return true;
+       }
 }
diff --git a/frontend/ConfirmAccountUI.setup.php 
b/frontend/ConfirmAccountUI.setup.php
index 9a1d54a..5924fca 100644
--- a/frontend/ConfirmAccountUI.setup.php
+++ b/frontend/ConfirmAccountUI.setup.php
@@ -5,7 +5,7 @@
 class ConfirmAccountUISetup {
        /**
         * Register ConfirmAccount hooks.
-        * @param $hooks Array $wgHooks (assoc array of hooks and handlers)
+        * @param $hooks array $wgHooks (assoc array of hooks and handlers)
         * @return void
         */
        public static function defineHookHandlers( array &$hooks ) {
@@ -18,11 +18,13 @@
                $hooks['BeforePageDisplay'][] = 
'ConfirmAccountUIHooks::confirmAccountsNotice';
                # Register admin pages for AdminLinks extension.
                $hooks['AdminLinks'][] = 
'ConfirmAccountUIHooks::confirmAccountAdminLinks';
+               # Pre-fill/lock the form if its for an approval
+               $hooks['AuthChangeFormFields'][] = 
'ConfirmAccountUIHooks::onAuthChangeFormFields';
        }
 
        /**
         * Register ConfirmAccount special pages as needed.
-        * @param $pages Array $wgSpecialPages (list of special pages)
+        * @param $pages array $wgSpecialPages (list of special pages)
         * @return void
         */
        public static function defineSpecialPages( array &$pages ) {
@@ -33,7 +35,7 @@
 
        /**
         * Append ConfirmAccount resource module definitions
-        * @param $modules Array $wgResourceModules
+        * @param $modules array $wgResourceModules
         * @return void
         */
        public static function defineResourceModules( array &$modules ) {
diff --git a/frontend/specialpages/actions/ConfirmAccount_body.php 
b/frontend/specialpages/actions/ConfirmAccount_body.php
index 62ee274..e1c14f1 100644
--- a/frontend/specialpages/actions/ConfirmAccount_body.php
+++ b/frontend/specialpages/actions/ConfirmAccount_body.php
@@ -576,7 +576,7 @@
                );
 
                # Actually submit!
-               list( $status, $msg ) = $submission->submit( 
$this->getContext() );
+               list( $status, $msg, $url ) = $submission->submit( 
$this->getContext() );
 
                # Check for error messages
                if ( $status !== true ) {
@@ -585,7 +585,11 @@
                }
 
                # Done!
-               $this->showSuccess( $this->submitType, $this->reqUsername, 
(array)$msg );
+               if ( $url ) {
+                       $this->getOutput()->redirect( $url );
+               } else {
+                       $this->showSuccess( $this->submitType, 
$this->reqUsername, (array)$msg );
+               }
        }
 
        /**
diff --git a/i18n/confirmaccount/en.json b/i18n/confirmaccount/en.json
index b45586c..c799a60 100644
--- a/i18n/confirmaccount/en.json
+++ b/i18n/confirmaccount/en.json
@@ -61,7 +61,7 @@
        "confirmaccount-deny": "Reject (delist)",
        "confirmaccount-hold": "Hold",
        "confirmaccount-spam": "Spam (do not send email)",
-       "confirmaccount-reason": "Comment (will be included in email):",
+       "confirmaccount-reason": "Comment (included in rejection and holding 
emails):",
        "confirmaccount-ip": "IP address:",
        "confirmaccount-xff": "X-Forwarded-For:",
        "confirmaccount-agent": "User-Agent:",
@@ -70,6 +70,8 @@
        "confirmaccount-needreason": "You must provide a reason in the comment 
box below.",
        "confirmaccount-canthold": "This request is already either on hold or 
deleted.",
        "confirmaccount-badaction": "A valid action (accept, reject, hold) must 
be specified in order to proceed.",
+       "confirmaccount-mismatched": "This field must match that of the 
original account request.",
+       "confirmaccount-mismatched-general": "An override was requested on a 
field of the original account request that is not allowed or the \"mail 
password\" option was not set.",
        "confirmaccount-acc": "Account request confirmed;\n\tcreated new user 
account [[User:$1|$1]].",
        "confirmaccount-rej": "Account request rejected.",
        "confirmaccount-viewing": "(currently {{GENDER:$1|being}} viewed by 
[[User:$1|$1]])",
diff --git a/i18n/confirmaccount/qqq.json b/i18n/confirmaccount/qqq.json
index f30bfbe..5890bb1 100644
--- a/i18n/confirmaccount/qqq.json
+++ b/i18n/confirmaccount/qqq.json
@@ -81,6 +81,8 @@
        "confirmaccount-submit": "Used as label for Submit button which is used 
to confirm the validity of the account request.\n{{Identical|Confirm}}",
        "confirmaccount-needreason": "Used as error message.",
        "confirmaccount-canthold": "Used as error message.",
+       "confirmaccount-mismatched": "Used as error message.",
+       "confirmaccount-mismatched-general": "Used as error message.",
        "confirmaccount-badaction": "Used as error message.\n\nThis message 
should be consistent with the following radio button labels:\n* 
{{msg-mw|Confirmaccount-create}} - \"accept\"\n* {{msg-mw|Confirmaccount-deny}} 
- \"reject\"\n* {{msg-mw|Confirmaccount-hold}} - \"hold\"",
        "confirmaccount-acc": "This message means \"The account request has 
been confirmed successfully\".\n\nThe page title for this message is 
{{msg-mw|Actioncomplete}}.\n\nParameters:\n* $1 - username\n\nSee also:\n* 
{{msg-mw|Confirmaccount-rej}}",
        "confirmaccount-rej": "This message means \"The account request has 
been rejected successfully\".\n\nThe page title for this message is 
{{msg-mw|Actioncomplete}}.\n\nSee also:\n* {{msg-mw|Confirmaccount-acc}}",

-- 
To view, visit https://gerrit.wikimedia.org/r/305830
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ib803ee30f2ad7bd48eed7f7fcfdc97d219b76ef7
Gerrit-PatchSet: 6
Gerrit-Project: mediawiki/extensions/ConfirmAccount
Gerrit-Branch: master
Gerrit-Owner: Aaron Schulz <[email protected]>
Gerrit-Reviewer: Aaron Schulz <[email protected]>
Gerrit-Reviewer: Anomie <[email protected]>
Gerrit-Reviewer: GergÅ‘ Tisza <[email protected]>
Gerrit-Reviewer: Paladox <[email protected]>
Gerrit-Reviewer: Siebrand <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

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

Reply via email to