Merge "Add "mVersion" sanity check to User::loadFromCache()"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Mon, 16 May 2016 19:12:15 +0000 (19:12 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Mon, 16 May 2016 19:12:15 +0000 (19:12 +0000)
1  2 
includes/user/User.php

diff --combined includes/user/User.php
@@@ -23,9 -23,6 +23,9 @@@
  use MediaWiki\MediaWikiServices;
  use MediaWiki\Session\SessionManager;
  use MediaWiki\Session\Token;
 +use MediaWiki\Auth\AuthManager;
 +use MediaWiki\Auth\AuthenticationResponse;
 +use MediaWiki\Auth\AuthenticationRequest;
  
  /**
   * String Some punctuation to prevent editing from broken text-mangling proxies.
@@@ -502,7 -499,10 +502,10 @@@ class User implements IDBAccessObject 
                $data = $processCache->get( $key );
                if ( !is_array( $data ) ) {
                        $data = $cache->get( $key );
-                       if ( !is_array( $data ) || $data['mVersion'] < self::VERSION ) {
+                       if ( !is_array( $data )
+                               || !isset( $data['mVersion'] )
+                               || $data['mVersion'] < self::VERSION
+                       ) {
                                // Object is expired
                                return false;
                        }
         *  - steal: Whether to reset the account's password and email if it
         *    already exists, default false
         * @return User|null
 +       * @since 1.27
         */
        public static function newSystemUser( $name, $options = [] ) {
 +              global $wgDisableAuthManager;
 +
                $options += [
                        'validate' => 'valid',
                        'create' => true,
                        return null;
                }
  
 +              $fields = self::selectFields();
 +              if ( $wgDisableAuthManager ) {
 +                      $fields = array_merge( $fields, [ 'user_password', 'user_newpassword' ] );
 +              }
 +
                $dbw = wfGetDB( DB_MASTER );
                $row = $dbw->selectRow(
                        'user',
 -                      array_merge(
 -                              self::selectFields(),
 -                              [ 'user_password', 'user_newpassword' ]
 -                      ),
 +                      $fields,
                        [ 'user_name' => $name ],
                        __METHOD__
                );
                // A user is considered to exist as a non-system user if it has a
                // password set, or a temporary password set, or an email set, or a
                // non-invalid token.
 -              $passwordFactory = new PasswordFactory();
 -              $passwordFactory->init( RequestContext::getMain()->getConfig() );
 -              try {
 -                      $password = $passwordFactory->newFromCiphertext( $row->user_password );
 -              } catch ( PasswordError $e ) {
 -                      wfDebug( 'Invalid password hash found in database.' );
 -                      $password = PasswordFactory::newInvalidPassword();
 -              }
 -              try {
 -                      $newpassword = $passwordFactory->newFromCiphertext( $row->user_newpassword );
 -              } catch ( PasswordError $e ) {
 -                      wfDebug( 'Invalid password hash found in database.' );
 -                      $newpassword = PasswordFactory::newInvalidPassword();
 -              }
 -              if ( !$password instanceof InvalidPassword || !$newpassword instanceof InvalidPassword
 -                      || $user->mEmail || $user->mToken !== self::INVALID_TOKEN
 -              ) {
 +              if ( !$user->mEmail && $user->mToken === self::INVALID_TOKEN ) {
 +                      if ( $wgDisableAuthManager ) {
 +                              $passwordFactory = new PasswordFactory();
 +                              $passwordFactory->init( RequestContext::getMain()->getConfig() );
 +                              try {
 +                                      $password = $passwordFactory->newFromCiphertext( $row->user_password );
 +                              } catch ( PasswordError $e ) {
 +                                      wfDebug( 'Invalid password hash found in database.' );
 +                                      $password = PasswordFactory::newInvalidPassword();
 +                              }
 +                              try {
 +                                      $newpassword = $passwordFactory->newFromCiphertext( $row->user_newpassword );
 +                              } catch ( PasswordError $e ) {
 +                                      wfDebug( 'Invalid password hash found in database.' );
 +                                      $newpassword = PasswordFactory::newInvalidPassword();
 +                              }
 +                              $canAuthenticate = !$password instanceof InvalidPassword ||
 +                                      !$newpassword instanceof InvalidPassword;
 +                      } else {
 +                              $canAuthenticate = AuthManager::singleton()->userCanAuthenticate( $name );
 +                      }
 +              }
 +              if ( $user->mEmail || $user->mToken !== self::INVALID_TOKEN || $canAuthenticate ) {
                        // User exists. Steal it?
                        if ( !$options['steal'] ) {
                                return null;
                        }
  
 -                      $nopass = PasswordFactory::newInvalidPassword()->toString();
 +                      if ( $wgDisableAuthManager ) {
 +                              $nopass = PasswordFactory::newInvalidPassword()->toString();
 +                              $dbw->update(
 +                                      'user',
 +                                      [
 +                                              'user_password' => $nopass,
 +                                              'user_newpassword' => $nopass,
 +                                              'user_newpass_time' => null,
 +                                      ],
 +                                      [ 'user_id' => $user->getId() ],
 +                                      __METHOD__
 +                              );
 +                      } else {
 +                              AuthManager::singleton()->revokeAccessForUser( $name );
 +                      }
  
 -                      $dbw->update(
 -                              'user',
 -                              [
 -                                      'user_password' => $nopass,
 -                                      'user_newpassword' => $nopass,
 -                                      'user_newpass_time' => null,
 -                              ],
 -                              [ 'user_id' => $user->getId() ],
 -                              __METHOD__
 -                      );
                        $user->invalidateEmail();
                        $user->mToken = self::INVALID_TOKEN;
                        $user->saveSettings();
                }
  
                // Reject various classes of invalid names
 -              global $wgAuth;
 -              $name = $wgAuth->getCanonicalName( $t->getText() );
 +              $name = AuthManager::callLegacyAuthPlugin(
 +                      'getCanonicalName', [ $t->getText() ], $t->getText()
 +              );
  
                switch ( $validate ) {
                        case false:
         * @see $wgAutopromoteOnce
         */
        public function addAutopromoteOnceGroups( $event ) {
 -              global $wgAutopromoteOnceLogInRC, $wgAuth;
 +              global $wgAutopromoteOnceLogInRC;
  
                if ( wfReadOnly() || !$this->getId() ) {
                        return [];
                }
                // update groups in external authentication database
                Hooks::run( 'UserGroupsChanged', [ $this, $toPromote, [], false, false ] );
 -              $wgAuth->updateExternalDBGroups( $this, $toPromote );
 +              AuthManager::callLegacyAuthPlugin( 'updateExternalDBGroups', [ $this, $toPromote ] );
  
                $newGroups = array_merge( $oldGroups, $toPromote ); // all groups
  
                if ( $this->mLocked !== null ) {
                        return $this->mLocked;
                }
 -              global $wgAuth;
 -              $authUser = $wgAuth->getUserInstance( $this );
 -              $this->mLocked = (bool)$authUser->isLocked();
 +              $authUser = AuthManager::callLegacyAuthPlugin( 'getUserInstance', [ &$this ], null );
 +              $this->mLocked = $authUser && $authUser->isLocked();
                Hooks::run( 'UserIsLocked', [ $this, &$this->mLocked ] );
                return $this->mLocked;
        }
                }
                $this->getBlockedStatus();
                if ( !$this->mHideName ) {
 -                      global $wgAuth;
 -                      $authUser = $wgAuth->getUserInstance( $this );
 -                      $this->mHideName = (bool)$authUser->isHidden();
 +                      $authUser = AuthManager::callLegacyAuthPlugin( 'getUserInstance', [ &$this ], null );
 +                      $this->mHideName = $authUser && $authUser->isHidden();
                        Hooks::run( 'UserIsHidden', [ $this, &$this->mHideName ] );
                }
                return $this->mHideName;
         * wipes it, so the account cannot be logged in until
         * a new password is set, for instance via e-mail.
         *
 -       * @deprecated since 1.27. AuthManager is coming.
 +       * @deprecated since 1.27, use AuthManager instead
         * @param string $str New password to set
         * @throws PasswordError On failure
         * @return bool
         */
        public function setPassword( $str ) {
 -              global $wgAuth;
 +              global $wgAuth, $wgDisableAuthManager;
 +
 +              if ( !$wgDisableAuthManager ) {
 +                      return $this->setPasswordInternal( $str );
 +              }
  
                if ( $str !== null ) {
                        if ( !$wgAuth->allowPasswordChange() ) {
  
                $this->setOption( 'watchlisttoken', false );
                $this->setPasswordInternal( $str );
 -              SessionManager::singleton()->invalidateSessionsForUser( $this );
  
                return true;
        }
        /**
         * Set the password and reset the random token unconditionally.
         *
 -       * @deprecated since 1.27. AuthManager is coming.
 +       * @deprecated since 1.27, use AuthManager instead
         * @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.
         */
        public function setInternalPassword( $str ) {
 -              global $wgAuth;
 +              global $wgAuth, $wgDisableAuthManager;
 +
 +              if ( !$wgDisableAuthManager ) {
 +                      $this->setPasswordInternal( $str );
 +              }
  
                if ( $wgAuth->allowSetLocalPassword() ) {
                        $this->setOption( 'watchlisttoken', false );
                        $this->setPasswordInternal( $str );
 -                      SessionManager::singleton()->invalidateSessionsForUser( $this );
                }
        }
  
         * @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.
 +       * @return bool Success
         */
        private function setPasswordInternal( $str ) {
 -              $id = self::idFromName( $this->getName(), self::READ_LATEST );
 -              if ( $id == 0 ) {
 -                      throw new LogicException( 'Cannot set a password for a user that is not in the database.' );
 +              global $wgDisableAuthManager;
 +
 +              if ( $wgDisableAuthManager ) {
 +                      $id = self::idFromName( $this->getName(), self::READ_LATEST );
 +                      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',
 +                              [
 +                                      'user_password' => $passwordFactory->newFromPlaintext( $str )->toString(),
 +                                      'user_newpassword' => PasswordFactory::newInvalidPassword()->toString(),
 +                                      'user_newpass_time' => $dbw->timestampOrNull( null ),
 +                              ],
 +                              [
 +                                      'user_id' => $id,
 +                              ],
 +                              __METHOD__
 +                      );
 +
 +                      // When the main password is changed, invalidate all bot passwords too
 +                      BotPassword::invalidateAllPasswordsForUser( $this->getName() );
 +              } else {
 +                      $manager = AuthManager::singleton();
 +
 +                      // If the user doesn't exist yet, fail
 +                      if ( !$manager->userExists( $this->getName() ) ) {
 +                              throw new LogicException( 'Cannot set a password for a user that is not in the database.' );
 +                      }
 +
 +                      $data = [
 +                              'username' => $this->getName(),
 +                              'password' => $str,
 +                              'retype' => $str,
 +                      ];
 +                      $reqs = $manager->getAuthenticationRequests( AuthManager::ACTION_CHANGE, $this );
 +                      $reqs = AuthenticationRequest::loadRequestsFromSubmission( $reqs, $data );
 +                      foreach ( $reqs as $req ) {
 +                              $status = $manager->allowsAuthenticationDataChange( $req );
 +                              if ( !$status->isOk() ) {
 +                                      \MediaWiki\Logger\LoggerFactory::getInstance( 'authentication' )
 +                                              ->info( __METHOD__ . ': Password change rejected: ' . $status->getWikiText() );
 +                                      return false;
 +                              }
 +                      }
 +                      foreach ( $reqs as $req ) {
 +                              $manager->changeAuthenticationData( $req );
 +                      }
 +
 +                      $this->setOption( 'watchlisttoken', false );
                }
  
 -              $passwordFactory = new PasswordFactory();
 -              $passwordFactory->init( RequestContext::getMain()->getConfig() );
 -              $dbw = wfGetDB( DB_MASTER );
 -              $dbw->update(
 -                      'user',
 -                      [
 -                              'user_password' => $passwordFactory->newFromPlaintext( $str )->toString(),
 -                              'user_newpassword' => PasswordFactory::newInvalidPassword()->toString(),
 -                              'user_newpass_time' => $dbw->timestampOrNull( null ),
 -                      ],
 -                      [
 -                              'user_id' => $id,
 -                      ],
 -                      __METHOD__
 -              );
 +              SessionManager::singleton()->invalidateSessionsForUser( $this );
  
 -              // When the main password is changed, invalidate all bot passwords too
 -              BotPassword::invalidateAllPasswordsForUser( $this->getName() );
 +              return true;
        }
  
        /**
        /**
         * Set the password for a password reminder or new account email
         *
 -       * @deprecated since 1.27, AuthManager is coming
 +       * @deprecated Removed in 1.27. Use PasswordReset instead.
         * @param string $str New password to set or null to set an invalid
         *  password hash meaning that the user will not be able to use it
         * @param bool $throttle If true, reset the throttle timestamp to the present
         */
        public function setNewpassword( $str, $throttle = true ) {
 -              $id = $this->getId();
 -              if ( $id == 0 ) {
 -                      throw new LogicException( 'Cannot set new password for a user that is not in the database.' );
 -              }
 +              global $wgDisableAuthManager;
  
 -              $dbw = wfGetDB( DB_MASTER );
 +              if ( $wgDisableAuthManager ) {
 +                      $id = $this->getId();
 +                      if ( $id == 0 ) {
 +                              throw new LogicException( 'Cannot set new password for a user that is not in the database.' );
 +                      }
  
 -              $passwordFactory = new PasswordFactory();
 -              $passwordFactory->init( RequestContext::getMain()->getConfig() );
 -              $update = [
 -                      'user_newpassword' => $passwordFactory->newFromPlaintext( $str )->toString(),
 -              ];
 +                      $dbw = wfGetDB( DB_MASTER );
  
 -              if ( $str === null ) {
 -                      $update['user_newpass_time'] = null;
 -              } elseif ( $throttle ) {
 -                      $update['user_newpass_time'] = $dbw->timestamp();
 -              }
 +                      $passwordFactory = new PasswordFactory();
 +                      $passwordFactory->init( RequestContext::getMain()->getConfig() );
 +                      $update = [
 +                              'user_newpassword' => $passwordFactory->newFromPlaintext( $str )->toString(),
 +                      ];
 +
 +                      if ( $str === null ) {
 +                              $update['user_newpass_time'] = null;
 +                      } elseif ( $throttle ) {
 +                              $update['user_newpass_time'] = $dbw->timestamp();
 +                      }
  
 -              $dbw->update( 'user', $update, [ 'user_id' => $id ], __METHOD__ );
 +                      $dbw->update( 'user', $update, [ 'user_id' => $id ], __METHOD__ );
 +              } else {
 +                      throw new BadMethodCallException( __METHOD__ . ' has been removed in 1.27' );
 +              }
        }
  
        /**
         * Has password reminder email been sent within the last
         * $wgPasswordReminderResendTime hours?
 +       * @deprecated Removed in 1.27. See above.
         * @return bool
         */
        public function isPasswordReminderThrottled() {
 -              global $wgPasswordReminderResendTime;
 +              global $wgPasswordReminderResendTime, $wgDisableAuthManager;
  
 -              if ( !$wgPasswordReminderResendTime ) {
 -                      return false;
 -              }
 +              if ( $wgDisableAuthManager ) {
 +                      if ( !$wgPasswordReminderResendTime ) {
 +                              return false;
 +                      }
  
 -              $this->load();
 +                      $this->load();
  
 -              $db = ( $this->queryFlagsUsed & self::READ_LATEST )
 -                      ? wfGetDB( DB_MASTER )
 -                      : wfGetDB( DB_SLAVE );
 -              $newpassTime = $db->selectField(
 -                      'user',
 -                      'user_newpass_time',
 -                      [ 'user_id' => $this->getId() ],
 -                      __METHOD__
 -              );
 +                      $db = ( $this->queryFlagsUsed & self::READ_LATEST )
 +                              ? wfGetDB( DB_MASTER )
 +                              : wfGetDB( DB_SLAVE );
 +                      $newpassTime = $db->selectField(
 +                              'user',
 +                              'user_newpass_time',
 +                              [ 'user_id' => $this->getId() ],
 +                              __METHOD__
 +                      );
  
 -              if ( $newpassTime === null ) {
 -                      return false;
 +                      if ( $newpassTime === null ) {
 +                              return false;
 +                      }
 +                      $expiry = wfTimestamp( TS_UNIX, $newpassTime ) + $wgPasswordReminderResendTime * 3600;
 +                      return time() < $expiry;
 +              } else {
 +                      throw new BadMethodCallException( __METHOD__ . ' has been removed in 1.27' );
                }
 -              $expiry = wfTimestamp( TS_UNIX, $newpassTime ) + $wgPasswordReminderResendTime * 3600;
 -              return time() < $expiry;
        }
  
        /**
  
        /**
         * Check to see if the given clear-text password is one of the accepted passwords
 -       * @deprecated since 1.27. AuthManager is coming.
 +       * @deprecated since 1.27, use AuthManager instead
         * @param string $password User password
         * @return bool True if the given password is correct, otherwise False
         */
        public function checkPassword( $password ) {
 -              global $wgAuth, $wgLegacyEncoding;
 +              global $wgAuth, $wgLegacyEncoding, $wgDisableAuthManager;
  
 -              $this->load();
 +              if ( $wgDisableAuthManager ) {
 +                      $this->load();
  
 -              // Some passwords will give a fatal Status, which means there is
 -              // some sort of technical or security reason for this password to
 -              // be completely invalid and should never be checked (e.g., T64685)
 -              if ( !$this->checkPasswordValidity( $password )->isOK() ) {
 -                      return false;
 -              }
 +                      // Some passwords will give a fatal Status, which means there is
 +                      // some sort of technical or security reason for this password to
 +                      // be completely invalid and should never be checked (e.g., T64685)
 +                      if ( !$this->checkPasswordValidity( $password )->isOK() ) {
 +                              return false;
 +                      }
  
 -              // Certain authentication plugins do NOT want to save
 -              // domain passwords in a mysql database, so we should
 -              // check this (in case $wgAuth->strict() is false).
 -              if ( $wgAuth->authenticate( $this->getName(), $password ) ) {
 -                      return true;
 -              } elseif ( $wgAuth->strict() ) {
 -                      // Auth plugin doesn't allow local authentication
 -                      return false;
 -              } elseif ( $wgAuth->strictUserAuth( $this->getName() ) ) {
 -                      // Auth plugin doesn't allow local authentication for this user name
 -                      return false;
 -              }
 +                      // Certain authentication plugins do NOT want to save
 +                      // domain passwords in a mysql database, so we should
 +                      // check this (in case $wgAuth->strict() is false).
 +                      if ( $wgAuth->authenticate( $this->getName(), $password ) ) {
 +                              return true;
 +                      } elseif ( $wgAuth->strict() ) {
 +                              // Auth plugin doesn't allow local authentication
 +                              return false;
 +                      } elseif ( $wgAuth->strictUserAuth( $this->getName() ) ) {
 +                              // Auth plugin doesn't allow local authentication for this user name
 +                              return false;
 +                      }
  
 -              $passwordFactory = new PasswordFactory();
 -              $passwordFactory->init( RequestContext::getMain()->getConfig() );
 -              $db = ( $this->queryFlagsUsed & self::READ_LATEST )
 -                      ? wfGetDB( DB_MASTER )
 -                      : wfGetDB( DB_SLAVE );
 +                      $passwordFactory = new PasswordFactory();
 +                      $passwordFactory->init( RequestContext::getMain()->getConfig() );
 +                      $db = ( $this->queryFlagsUsed & self::READ_LATEST )
 +                              ? wfGetDB( DB_MASTER )
 +                              : wfGetDB( DB_SLAVE );
  
 -              try {
 -                      $mPassword = $passwordFactory->newFromCiphertext( $db->selectField(
 -                              'user', 'user_password', [ 'user_id' => $this->getId() ], __METHOD__
 -                      ) );
 -              } catch ( PasswordError $e ) {
 -                      wfDebug( 'Invalid password hash found in database.' );
 -                      $mPassword = PasswordFactory::newInvalidPassword();
 -              }
 +                      try {
 +                              $mPassword = $passwordFactory->newFromCiphertext( $db->selectField(
 +                                      'user', 'user_password', [ 'user_id' => $this->getId() ], __METHOD__
 +                              ) );
 +                      } catch ( PasswordError $e ) {
 +                              wfDebug( 'Invalid password hash found in database.' );
 +                              $mPassword = PasswordFactory::newInvalidPassword();
 +                      }
  
 -              if ( !$mPassword->equals( $password ) ) {
 -                      if ( $wgLegacyEncoding ) {
 -                              // Some wikis were converted from ISO 8859-1 to UTF-8, the passwords can't be converted
 -                              // Check for this with iconv
 -                              $cp1252Password = iconv( 'UTF-8', 'WINDOWS-1252//TRANSLIT', $password );
 -                              if ( $cp1252Password === $password || !$mPassword->equals( $cp1252Password ) ) {
 +                      if ( !$mPassword->equals( $password ) ) {
 +                              if ( $wgLegacyEncoding ) {
 +                                      // Some wikis were converted from ISO 8859-1 to UTF-8, the passwords can't be converted
 +                                      // Check for this with iconv
 +                                      $cp1252Password = iconv( 'UTF-8', 'WINDOWS-1252//TRANSLIT', $password );
 +                                      if ( $cp1252Password === $password || !$mPassword->equals( $cp1252Password ) ) {
 +                                              return false;
 +                                      }
 +                              } else {
                                        return false;
                                }
 -                      } else {
 -                              return false;
                        }
 -              }
  
 -              if ( $passwordFactory->needsUpdate( $mPassword ) && !wfReadOnly() ) {
 -                      $this->setPasswordInternal( $password );
 -              }
 +                      if ( $passwordFactory->needsUpdate( $mPassword ) && !wfReadOnly() ) {
 +                              $this->setPasswordInternal( $password );
 +                      }
  
 -              return true;
 +                      return true;
 +              } else {
 +                      $manager = AuthManager::singleton();
 +                      $reqs = AuthenticationRequest::loadRequestsFromSubmission(
 +                              $manager->getAuthenticationRequests( AuthManager::ACTION_LOGIN ),
 +                              [
 +                                      'username' => $this->getName(),
 +                                      'password' => $password,
 +                              ]
 +                      );
 +                      $res = AuthManager::singleton()->beginAuthentication( $reqs, 'null:' );
 +                      switch ( $res->status ) {
 +                              case AuthenticationResponse::PASS:
 +                                      return true;
 +                              case AuthenticationResponse::FAIL:
 +                                      // Hope it's not a PreAuthenticationProvider that failed...
 +                                      \MediaWiki\Logger\LoggerFactory::getInstance( 'authentication' )
 +                                              ->info( __METHOD__ . ': Authentication failed: ' . $res->message->plain() );
 +                                      return false;
 +                              default:
 +                                      throw new BadMethodCallException(
 +                                              'AuthManager returned a response unsupported by ' . __METHOD__
 +                                      );
 +                      }
 +              }
        }
  
        /**
         * Check if the given clear-text password matches the temporary password
         * sent by e-mail for password reset operations.
         *
 -       * @deprecated since 1.27. AuthManager is coming.
 +       * @deprecated since 1.27, use AuthManager instead
         * @param string $plaintext
         * @return bool True if matches, false otherwise
         */
        public function checkTemporaryPassword( $plaintext ) {
 -              global $wgNewPasswordExpiry;
 +              global $wgNewPasswordExpiry, $wgDisableAuthManager;
  
 -              $this->load();
 +              if ( $wgDisableAuthManager ) {
 +                      $this->load();
  
 -              $passwordFactory = new PasswordFactory();
 -              $passwordFactory->init( RequestContext::getMain()->getConfig() );
 -              $db = ( $this->queryFlagsUsed & self::READ_LATEST )
 -                      ? wfGetDB( DB_MASTER )
 -                      : wfGetDB( DB_SLAVE );
 +                      $passwordFactory = new PasswordFactory();
 +                      $passwordFactory->init( RequestContext::getMain()->getConfig() );
 +                      $db = ( $this->queryFlagsUsed & self::READ_LATEST )
 +                              ? wfGetDB( DB_MASTER )
 +                              : wfGetDB( DB_SLAVE );
  
 -              $row = $db->selectRow(
 -                      'user',
 -                      [ 'user_newpassword', 'user_newpass_time' ],
 -                      [ 'user_id' => $this->getId() ],
 -                      __METHOD__
 -              );
 -              try {
 -                      $newPassword = $passwordFactory->newFromCiphertext( $row->user_newpassword );
 -              } catch ( PasswordError $e ) {
 -                      wfDebug( 'Invalid password hash found in database.' );
 -                      $newPassword = PasswordFactory::newInvalidPassword();
 -              }
 +                      $row = $db->selectRow(
 +                              'user',
 +                              [ 'user_newpassword', 'user_newpass_time' ],
 +                              [ 'user_id' => $this->getId() ],
 +                              __METHOD__
 +                      );
 +                      try {
 +                              $newPassword = $passwordFactory->newFromCiphertext( $row->user_newpassword );
 +                      } catch ( PasswordError $e ) {
 +                              wfDebug( 'Invalid password hash found in database.' );
 +                              $newPassword = PasswordFactory::newInvalidPassword();
 +                      }
  
 -              if ( $newPassword->equals( $plaintext ) ) {
 -                      if ( is_null( $row->user_newpass_time ) ) {
 -                              return true;
 +                      if ( $newPassword->equals( $plaintext ) ) {
 +                              if ( is_null( $row->user_newpass_time ) ) {
 +                                      return true;
 +                              }
 +                              $expiry = wfTimestamp( TS_UNIX, $row->user_newpass_time ) + $wgNewPasswordExpiry;
 +                              return ( time() < $expiry );
 +                      } else {
 +                              return false;
                        }
 -                      $expiry = wfTimestamp( TS_UNIX, $row->user_newpass_time ) + $wgNewPasswordExpiry;
 -                      return ( time() < $expiry );
                } else {
 -                      return false;
 +                      // Can't check the temporary password individually.
 +                      return $this->checkPassword( $plaintext );
                }
        }
  
         * Add a newuser log entry for this user.
         * Before 1.19 the return value was always true.
         *
 +       * @deprecated since 1.27, AuthManager handles logging
         * @param string|bool $action Account creation type.
         *   - String, one of the following values:
         *     - 'create' for an anonymous user creating an account for himself.
         *     - true will be converted to 'byemail'
         *     - false will be converted to 'create' if this object is the same as
         *       $wgUser and to 'create2' otherwise
 -       *
         * @param string $reason User supplied reason
 -       *
 -       * @return int|bool True if not $wgNewUserLog; otherwise ID of log item or 0 on failure
 +       * @return int|bool True if not $wgNewUserLog or not $wgDisableAuthManager;
 +       *   otherwise ID of log item or 0 on failure
         */
        public function addNewUserLogEntry( $action = false, $reason = '' ) {
 -              global $wgUser, $wgNewUserLog;
 -              if ( empty( $wgNewUserLog ) ) {
 +              global $wgUser, $wgNewUserLog, $wgDisableAuthManager;
 +              if ( !$wgDisableAuthManager || empty( $wgNewUserLog ) ) {
                        return true; // disabled
                }
  
         * Used by things like CentralAuth and perhaps other authplugins.
         * Consider calling addNewUserLogEntry() directly instead.
         *
 +       * @deprecated since 1.27, AuthManager handles logging
         * @return bool
         */
        public function addNewUserLogEntryAutoCreate() {