Merge "Remove commit() hack from User::addToDatabase()"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Tue, 23 Aug 2016 04:29:20 +0000 (04:29 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 23 Aug 2016 04:29:20 +0000 (04:29 +0000)
1  2 
includes/user/User.php

diff --combined includes/user/User.php
@@@ -3147,22 -3147,6 +3147,22 @@@ class User implements IDBAccessObject 
                        Hooks::run( 'UserGetRights', [ $this, &$this->mRights ] );
                        // Force reindexation of rights when a hook has unset one of them
                        $this->mRights = array_values( array_unique( $this->mRights ) );
 +
 +                      // If block disables login, we should also remove any
 +                      // extra rights blocked users might have, in case the
 +                      // blocked user has a pre-existing session (T129738).
 +                      // This is checked here for cases where people only call
 +                      // $user->isAllowed(). It is also checked in Title::checkUserBlock()
 +                      // to give a better error message in the common case.
 +                      $config = RequestContext::getMain()->getConfig();
 +                      if (
 +                              $this->isLoggedIn() &&
 +                              $config->get( 'BlockDisablesLogin' ) &&
 +                              $this->isBlocked()
 +                      ) {
 +                              $anon = new User;
 +                              $this->mRights = array_intersect( $this->mRights, $anon->getRights() );
 +                      }
                }
                return $this->mRights;
        }
                $noPass = PasswordFactory::newInvalidPassword()->toString();
  
                $dbw = wfGetDB( DB_MASTER );
-               $inWrite = $dbw->writesOrCallbacksPending();
                $seqVal = $dbw->nextSequenceValue( 'user_user_id_seq' );
                $dbw->insert( 'user',
                        [
                        [ 'IGNORE' ]
                );
                if ( !$dbw->affectedRows() ) {
-                       // The queries below cannot happen in the same REPEATABLE-READ snapshot.
-                       // Handle this by COMMIT, if possible, or by LOCK IN SHARE MODE otherwise.
-                       if ( $inWrite ) {
-                               // Can't commit due to pending writes that may need atomicity.
-                               // This may cause some lock contention unlike the case below.
-                               $options = [ 'LOCK IN SHARE MODE' ];
-                               $flags = self::READ_LOCKING;
-                       } else {
-                               // Often, this case happens early in views before any writes when
-                               // using CentralAuth. It's should be OK to commit and break the snapshot.
-                               $dbw->commit( __METHOD__, 'flush' );
-                               $options = [];
-                               $flags = self::READ_LATEST;
-                       }
-                       $this->mId = $dbw->selectField( 'user', 'user_id',
-                               [ 'user_name' => $this->mName ], __METHOD__, $options );
+                       // Use locking reads to bypass any REPEATABLE-READ snapshot.
+                       $this->mId = $dbw->selectField(
+                               'user',
+                               'user_id',
+                               [ 'user_name' => $this->mName ],
+                               __METHOD__,
+                               [ 'LOCK IN SHARE MODE' ]
+                       );
                        $loaded = false;
                        if ( $this->mId ) {
-                               if ( $this->loadFromDatabase( $flags ) ) {
+                               if ( $this->loadFromDatabase( self::READ_LOCKING ) ) {
                                        $loaded = true;
                                }
                        }