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