diff options
author | jenkins-bot <jenkins-bot@gerrit.wikimedia.org> | 2015-04-21 15:43:54 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@wikimedia.org> | 2015-04-21 15:43:54 +0000 |
commit | 786a37c5778e2fc69b48010236199621449ebba0 (patch) | |
tree | 856f6490cd63668aada503a98739bca19cc35e9e /includes/User.php | |
parent | 3e4fdee72341534673a227744a20ef26c972a71d (diff) | |
parent | 8c5406a437aab8751801a24dd2fe8e4473466b32 (diff) | |
download | mediawikicore-786a37c5778e2fc69b48010236199621449ebba0.tar.gz mediawikicore-786a37c5778e2fc69b48010236199621449ebba0.zip |
Merge "Added CAS logic to User::addAutopromoteOnceGroups"
Diffstat (limited to 'includes/User.php')
-rw-r--r-- | includes/User.php | 107 |
1 files changed, 83 insertions, 24 deletions
diff --git a/includes/User.php b/includes/User.php index b122a9fd96d7..c3d4a65c6d94 100644 --- a/includes/User.php +++ b/includes/User.php @@ -1431,38 +1431,86 @@ class User implements IDBAccessObject { public function addAutopromoteOnceGroups( $event ) { global $wgAutopromoteOnceLogInRC, $wgAuth; - $toPromote = array(); - if ( !wfReadOnly() && $this->getId() ) { - $toPromote = Autopromote::getAutopromoteOnceGroups( $this, $event ); - if ( count( $toPromote ) ) { - $oldGroups = $this->getGroups(); // previous groups - - foreach ( $toPromote as $group ) { - $this->addGroup( $group ); - } - // update groups in external authentication database - $wgAuth->updateExternalDBGroups( $this, $toPromote ); + if ( wfReadOnly() || !$this->getId() ) { + return array(); + } - $newGroups = array_merge( $oldGroups, $toPromote ); // all groups + $toPromote = Autopromote::getAutopromoteOnceGroups( $this, $event ); + if ( !count( $toPromote ) ) { + return array(); + } - $logEntry = new ManualLogEntry( 'rights', 'autopromote' ); - $logEntry->setPerformer( $this ); - $logEntry->setTarget( $this->getUserPage() ); - $logEntry->setParameters( array( - '4::oldgroups' => $oldGroups, - '5::newgroups' => $newGroups, - ) ); - $logid = $logEntry->insert(); - if ( $wgAutopromoteOnceLogInRC ) { - $logEntry->publish( $logid ); - } - } + if ( !$this->checkAndSetTouched() ) { + return array(); // raced out (bug T48834) + } + + $oldGroups = $this->getGroups(); // previous groups + foreach ( $toPromote as $group ) { + $this->addGroup( $group ); + } + + // update groups in external authentication database + $wgAuth->updateExternalDBGroups( $this, $toPromote ); + + $newGroups = array_merge( $oldGroups, $toPromote ); // all groups + + $logEntry = new ManualLogEntry( 'rights', 'autopromote' ); + $logEntry->setPerformer( $this ); + $logEntry->setTarget( $this->getUserPage() ); + $logEntry->setParameters( array( + '4::oldgroups' => $oldGroups, + '5::newgroups' => $newGroups, + ) ); + $logid = $logEntry->insert(); + if ( $wgAutopromoteOnceLogInRC ) { + $logEntry->publish( $logid ); } return $toPromote; } /** + * Bump user_touched if it didn't change since this object was loaded + * + * On success, the mTouched field is updated. + * The user serialization cache is always cleared. + * + * @return bool Whether user_touched was actually updated + * @since 1.26 + */ + protected function checkAndSetTouched() { + $this->load(); + + if ( !$this->mId ) { + return false; // anon + } + + // Get a new user_touched that is higher than the old one + $oldTouched = $this->mTouched; + $newTouched = $this->newTouchedTimestamp(); + + $dbw = wfGetDB( DB_MASTER ); + $dbw->update( 'user', + array( 'user_touched' => $dbw->timestamp( $newTouched ) ), + array( + 'user_id' => $this->mId, + 'user_touched' => $dbw->timestamp( $oldTouched ) // CAS check + ), + __METHOD__ + ); + $success = ( $dbw->affectedRows() > 0 ); + + if ( $success ) { + $this->mTouched = $newTouched; + } + + // Clears on failure too since that is desired if the cache is stale + $this->clearSharedCache(); + + return $success; + } + + /** * Clear various cached data stored in this object. The cache of the user table * data (i.e. self::$mCacheVars) is not cleared unless $reloadFrom is given. * @@ -2342,6 +2390,17 @@ class User implements IDBAccessObject { } /** + * Get the user_touched timestamp field (time of last DB updates) + * @return string TS_MW Timestamp + * @since 1.26 + */ + protected function getDBTouched() { + $this->load(); + + return $this->mTouched; + } + + /** * @return Password * @since 1.24 */ |