Alex Monk has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/60229


Change subject: Detect user rights conflicts from user_touched
......................................................................

Detect user rights conflicts from user_touched

User_touched gets updated by other things changing, but this is
unlikely to happen in the middle of a user rights change, so I don't
think it's worth storing extra data to detect only rights changes.

Bug: 38989
Change-Id: I75996605885c1b5300da8ad7b03c48560450a0c4
---
M includes/User.php
M includes/UserRightsProxy.php
M includes/specials/SpecialUserrights.php
M languages/messages/MessagesEn.php
M languages/messages/MessagesQqq.php
M maintenance/language/messages.inc
6 files changed, 38 insertions(+), 24 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/29/60229/1

diff --git a/includes/User.php b/includes/User.php
index ed97deb..1e5fb04 100644
--- a/includes/User.php
+++ b/includes/User.php
@@ -1933,7 +1933,7 @@
         * user_touched field when we update things.
         * @return String Timestamp in TS_MW format
         */
-       private static function newTouchedTimestamp() {
+       public static function newTouchedTimestamp() {
                global $wgClockSkewFudge;
                return wfTimestamp( TS_MW, time() + $wgClockSkewFudge );
        }
diff --git a/includes/UserRightsProxy.php b/includes/UserRightsProxy.php
index cd5dff8..cda014c 100644
--- a/includes/UserRightsProxy.php
+++ b/includes/UserRightsProxy.php
@@ -36,12 +36,13 @@
         * @param string $name user name
         * @param $id Integer: user ID
         */
-       private function __construct( $db, $database, $name, $id ) {
+       private function __construct( $db, $database, $name, $id, $touched ) {
                $this->db = $db;
                $this->database = $database;
                $this->name = $name;
                $this->id = intval( $id );
                $this->newOptions = array();
+               $this->touched = $touched;
        }
 
        /**
@@ -116,13 +117,15 @@
                $db = self::getDB( $database, $ignoreInvalidDB );
                if( $db ) {
                        $row = $db->selectRow( 'user',
-                               array( 'user_id', 'user_name' ),
+                               array( 'user_id', 'user_name', 'user_touched' ),
                                array( $field => $value ),
                                __METHOD__ );
                        if( $row !== false ) {
                                return new UserRightsProxy( $db, $database,
                                        $row->user_name,
-                                       intval( $row->user_id ) );
+                                       intval( $row->user_id ),
+                                       $row->user_touched
+                               );
                        }
                }
                return null;
@@ -258,4 +261,8 @@
                $key = wfForeignMemcKey( $this->database, false, 'user', 'id', 
$this->id );
                $wgMemc->delete( $key );
        }
+
+       function getTouched() {
+               return $this->touched;
+       }
 }
diff --git a/includes/specials/SpecialUserrights.php 
b/includes/specials/SpecialUserrights.php
index 7501371..d1ca166 100644
--- a/includes/specials/SpecialUserrights.php
+++ b/includes/specials/SpecialUserrights.php
@@ -127,19 +127,29 @@
                        $this->switchForm();
                }
 
-               if( $request->wasPosted() ) {
+               if ( $request->wasPosted() ) {
                        // save settings
-                       if( $request->getCheck( 'saveusergroups' ) ) {
-                               $reason = $request->getVal( 'user-reason' );
-                               $tok = $request->getVal( 'wpEditToken' );
-                               if( $user->matchEditToken( $tok, $this->mTarget 
) ) {
-                                       $this->saveUserGroups(
-                                               $this->mTarget,
-                                               $reason
-                                       );
+                       if ( $request->getCheck( 'saveusergroups' ) ) {
+                               if ( $user->matchEditToken( $request->getVal( 
'wpEditToken' ), $this->mTarget ) ) {
+                                       $status = $this->fetchUser( 
$this->mTarget );
+                                       if ( !$status->isOK() ) {
+                                               
$this->getOutput()->addWikiText( $status->getWikiText() );
+                                               return;
+                                       } else {
+                                               $targetUser = $status->value;
+                                       }
+                                       if ( $targetUser->getTouched() > 
$request->getVal( 'formLoadTimestamp' ) ) {
+                                               $out->addWikiMsg( 
'userrights-conflict' );
+                                       } else {
+                                               $this->saveUserGroups(
+                                                       $this->mTarget,
+                                                       $request->getVal( 
'user-reason' ),
+                                                       $targetUser
+                                               );
 
-                                       $out->redirect( $this->getSuccessURL() 
);
-                                       return;
+                                               $out->redirect( 
$this->getSuccessURL() );
+                                               return;
+                                       }
                                }
                        }
                }
@@ -160,17 +170,10 @@
         *
         * @param string $username username to apply changes to.
         * @param string $reason reason for group change
+        * @param User|UserRightsProxy $user Target user object.
         * @return null
         */
-       function saveUserGroups( $username, $reason = '' ) {
-               $status = $this->fetchUser( $username );
-               if( !$status->isOK() ) {
-                       $this->getOutput()->addWikiText( $status->getWikiText() 
);
-                       return;
-               } else {
-                       $user = $status->value;
-               }
-
+       function saveUserGroups( $username, $reason = '', $user ) {
                $allgroups = $this->getAllGroups();
                $addgroup = array();
                $removegroup = array();
@@ -472,6 +475,7 @@
                        Xml::openElement( 'form', array( 'method' => 'post', 
'action' => $this->getTitle()->getLocalURL(), 'name' => 'editGroup', 'id' => 
'mw-userrights-form2' ) ) .
                        Html::hidden( 'user', $this->mTarget ) .
                        Html::hidden( 'wpEditToken', 
$this->getUser()->getEditToken( $this->mTarget ) ) .
+                       Html::hidden( 'formLoadTimestamp', 
User::newTouchedTimestamp() ) . // Conflict detection
                        Xml::openElement( 'fieldset' ) .
                        Xml::element( 'legend', array(), $this->msg( 
'userrights-editusergroup', $user->getName() )->text() ) .
                        $this->msg( 'editinguser' )->params( wfEscapeWikiText( 
$user->getName() ) )->rawParams( $userToolLinks )->parse() .
diff --git a/languages/messages/MessagesEn.php 
b/languages/messages/MessagesEn.php
index 90fdd10..0ae0137 100644
--- a/languages/messages/MessagesEn.php
+++ b/languages/messages/MessagesEn.php
@@ -1970,6 +1970,7 @@
 'userrights-changeable-col'      => 'Groups you can change',
 'userrights-unchangeable-col'    => 'Groups you cannot change',
 'userrights-irreversible-marker' => '$1*', # only translate this message to 
other languages if you have to change it
+'userrights-conflict'            => 'Possible user rights conflict! Please 
apply your changes again.',
 
 # Groups
 'group'               => 'Group:',
diff --git a/languages/messages/MessagesQqq.php 
b/languages/messages/MessagesQqq.php
index f2ae692..86edda8 100644
--- a/languages/messages/MessagesQqq.php
+++ b/languages/messages/MessagesQqq.php
@@ -2635,6 +2635,7 @@
 Parameters:
 * $1 - optional, for PLURAL use, the number of items in the column following 
the message. Avoid PLURAL, if your language allows that.',
 'userrights-irreversible-marker' => '{{optional}}',
+'userrights-conflict'            => 'Shown on Special:UserRights when the 
target\'s user_touched is greater than the time that the form was generated.',
 
 # Groups
 'group' => '{{Identical|Group}}',
diff --git a/maintenance/language/messages.inc 
b/maintenance/language/messages.inc
index 39083f9..3286fac 100644
--- a/maintenance/language/messages.inc
+++ b/maintenance/language/messages.inc
@@ -1104,6 +1104,7 @@
                'userrights-changeable-col',
                'userrights-unchangeable-col',
                'userrights-irreversible-marker',
+               'userrights-conflict',
        ),
        'group' => array(
                'group',

-- 
To view, visit https://gerrit.wikimedia.org/r/60229
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I75996605885c1b5300da8ad7b03c48560450a0c4
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Alex Monk <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to