From b6f5529236c9ed319624b9130a5432d16dcf8a32 Mon Sep 17 00:00:00 2001 From: Brad Jorsch Date: Fri, 30 Oct 2015 11:19:12 -0400 Subject: [PATCH] Disallow User::setPassword() on users not in database Change I2c736ad mostly removed the password handling from the User object, but left in a little password handling to preserve the existing ability to call $user->setPassword() before the user was actually added to the database. That ability is now removed. Bug: T47716 Change-Id: Id3d40742f2e2b197ad6facd149cc6350006bf289 --- includes/User.php | 45 ++++++++++++++------------------ maintenance/createAndPromote.php | 12 ++++----- 2 files changed, 25 insertions(+), 32 deletions(-) diff --git a/includes/User.php b/includes/User.php index a6b897dd92..eb3ab9d2a2 100644 --- a/includes/User.php +++ b/includes/User.php @@ -185,8 +185,6 @@ class User implements IDBAccessObject { public $mName; /** @var string */ public $mRealName; - /** @var Password|null */ - private $mPassword = null; /** @var string */ public $mEmail; @@ -2400,32 +2398,32 @@ class User implements IDBAccessObject { /** * Actually set the password and such + * @since 1.27 cannot set a password for a user not in the database * @param string|null $str New password to set or null to set an invalid * password hash meaning that the user will not be able to log in * through the web interface. */ private function setPasswordInternal( $str ) { $id = self::idFromName( $this->getName() ); - if ( $id ) { - $passwordFactory = new PasswordFactory(); - $passwordFactory->init( RequestContext::getMain()->getConfig() ); - $dbw = wfGetDB( DB_MASTER ); - $dbw->update( - 'user', - array( - 'user_password' => $passwordFactory->newFromPlaintext( $str )->toString(), - 'user_newpassword' => PasswordFactory::newInvalidPassword()->toString(), - 'user_newpass_time' => $dbw->timestampOrNull( null ), - ), - array( - 'user_id' => $id, - ), - __METHOD__ - ); - $this->mPassword = null; - } else { - $this->mPassword = $str; + if ( $id == 0 ) { + throw new LogicException( 'Cannot set a password for a user that is not in the database.' ); } + + $passwordFactory = new PasswordFactory(); + $passwordFactory->init( RequestContext::getMain()->getConfig() ); + $dbw = wfGetDB( DB_MASTER ); + $dbw->update( + 'user', + array( + 'user_password' => $passwordFactory->newFromPlaintext( $str )->toString(), + 'user_newpassword' => PasswordFactory::newInvalidPassword()->toString(), + 'user_newpass_time' => $dbw->timestampOrNull( null ), + ), + array( + 'user_id' => $id, + ), + __METHOD__ + ); } /** @@ -3882,11 +3880,6 @@ class User implements IDBAccessObject { } $this->mId = $dbw->insertId(); - // Set the password now that it's in the DB, if applicable - if ( $this->mPassword !== null ) { - $this->setPasswordInternal( $this->mPassword ); - } - // Clear instance cache other than user table data, which is already accurate $this->clearInstanceCache(); diff --git a/maintenance/createAndPromote.php b/maintenance/createAndPromote.php index 861b364b68..c1a2022138 100644 --- a/maintenance/createAndPromote.php +++ b/maintenance/createAndPromote.php @@ -106,6 +106,12 @@ class CreateAndPromote extends Maintenance { } } + if ( !$exists ) { + # Insert the account into the database + $user->addToDatabase(); + $user->saveSettings(); + } + if ( $password ) { # Try to set the password try { @@ -119,12 +125,6 @@ class CreateAndPromote extends Maintenance { } } - if ( !$exists ) { - # Insert the account into the database - $user->addToDatabase(); - $user->saveSettings(); - } - # Promote user array_map( array( $user, 'addGroup' ), $promotions ); -- 2.20.1