* (bug 5149) When autoblocks are enabled, retroactively apply an autoblock to the...
authorAndrew Garrett <werdna@users.mediawiki.org>
Wed, 8 Nov 2006 09:54:06 +0000 (09:54 +0000)
committerAndrew Garrett <werdna@users.mediawiki.org>
Wed, 8 Nov 2006 09:54:06 +0000 (09:54 +0000)
* Add an index on (rc_user_text,rc_timestamp) on the recentchanges table. This will make CheckUser.php and the new retroactive autoblock functionality faster.

RELEASE-NOTES
includes/Block.php
includes/User.php
languages/messages/MessagesEn.php
maintenance/archives/patch-rc_user_text-index.sql [new file with mode: 0644]
maintenance/tables.sql
maintenance/updaters.inc

index 8d62530..7dcd45b 100644 (file)
@@ -153,7 +153,10 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
   if they have selected that option in preferences.
 * (bug 5936) Show an 'm' to the left of the edit summary on diff pages for minor edits.
 * (bug 7820) Improve error reporting for uploads via URL.
-
+* (bug 5149) When autoblocks are enabled, retroactively apply an autoblock to the most 
+  recently used IP of a user when they are blocked.
+* Add an index on (rc_user_text,rc_timestamp) on the recentchanges table. This will 
+  make CheckUser.php and the new retroactive autoblock functionality faster.
 
 == Languages updated ==
 
index 8a0f27c..8558a61 100644 (file)
@@ -356,6 +356,10 @@ class Block
                return $dbw->affectedRows() > 0;
        }
 
+       /**
+       * Insert a block into the block table.
+       *@return Whether or not the insertion was successful.
+       */
        function insert()
        {
                wfDebug( "Block::insert; timestamp {$this->mTimestamp}\n" );
@@ -395,9 +399,89 @@ class Block
                );
                $affected = $dbw->affectedRows();
                $dbw->commit();
+
+               $this->doRetroactiveAutoblock();
+
                return $affected;
        }
 
+       /**
+       * Retroactively autoblocks the last IP used by the user (if it is a user)
+       * blocked by this Block.
+       *@return Whether or not a retroactive autoblock was made.
+       */
+       function doRetroactiveAutoblock() {
+               $dbr = wfGetDb( DB_SLAVE );
+               #If autoblock is enabled, autoblock the LAST IP used
+               # - stolen shamelessly from CheckUser_body.php
+
+               if ($this->mEnableAutoblock && $this->mUser) {
+                       wfDebug("Doing retroactive autoblocks for " . $this->mAddress . "\n");
+
+                       $row = $dbr->selectRow( 'recentchanges', array( 'rc_ip' ), array( 'rc_user_text' => $this->mAddress ),
+                               $fname, array( 'ORDER BY' => 'rc_timestamp DESC' ) );
+
+                       if ( !$row || !$row->rc_ip ) {
+                               #No results, don't autoblock anything
+                               wfDebug("No IP found to retroactively autoblock\n");
+                       } else {
+                               #Limit is 1, so no loop needed.
+                               $retroblockip = $row->rc_ip;
+                               return $this->doAutoblock($retroblockip);
+                       }
+               }
+       }
+
+       /**
+       * Autoblocks the given IP, referring to this Block.
+       *@param $autoblockip The IP to autoblock.
+       *@return Whether or not an autoblock was inserted.
+       */
+       function doAutoblock( $autoblockip ) {
+               # Check if this IP address is already blocked
+               $dbw =& wfGetDb( DB_MASTER );
+               $dbw->begin();
+
+               if ( !$this->mEnableAutoblock ) {
+                       return;
+               }
+
+               $ipblock = Block::newFromDB( $autoblockip );
+               if ( $ipblock ) {
+                       # If the user is already blocked. Then check if the autoblock would
+                       # exceed the user block. If it would exceed, then do nothing, else
+                       # prolong block time
+                       if ($this->mExpiry &&
+                       ($this->mExpiry < Block::getAutoblockExpiry($ipblock->mTimestamp))) {
+                               return;
+                       }
+                       # Just update the timestamp
+                       $ipblock->updateTimestamp();
+                       return;
+               } else {
+                       $ipblock = new Block;
+               }
+
+               # Make a new block object with the desired properties
+               wfDebug( "Autoblocking {$this->mAddress}@" . $autoblockip . "\n" );
+               $ipblock->mAddress = $autoblockip;
+               $ipblock->mUser = 0;
+               $ipblock->mBy = $this->mBy;
+               $ipblock->mReason = wfMsgForContent( 'autoblocker', $this->mAddress, $this->mReason );
+               $ipblock->mTimestamp = wfTimestampNow();
+               $ipblock->mAuto = 1;
+
+               # If the user is already blocked with an expiry date, we don't
+               # want to pile on top of that!
+               if($this->mExpiry) {
+                       $ipblock->mExpiry = min ( $this->mExpiry, Block::getAutoblockExpiry( $this->mTimestamp ));
+               } else {
+                       $ipblock->mExpiry = Block::getAutoblockExpiry( $this->mTimestamp );
+               }
+               # Insert it
+               return $ipblock->insert();
+       }
+
        function deleteIfExpired()
        {
                $fname = 'Block::deleteIfExpired';
index c676335..64084dd 100644 (file)
@@ -1924,45 +1924,7 @@ class User {
                        return;
                }
 
-               if ( !$userblock->mEnableAutoblock ) {
-                       return;
-               }
-
-               # Check if this IP address is already blocked
-               $ipblock = Block::newFromDB( wfGetIP() );
-               if ( $ipblock ) {
-                       # If the user is already blocked. Then check if the autoblock would
-                       # exceed the user block. If it would exceed, then do nothing, else
-                       # prolong block time
-                       if ($userblock->mExpiry &&
-                               ($userblock->mExpiry < Block::getAutoblockExpiry($ipblock->mTimestamp))) {
-                               return;
-                       }
-                       # Just update the timestamp
-                       $ipblock->updateTimestamp();
-                       return;
-               } else {
-                       $ipblock = new Block;
-               }
-
-               # Make a new block object with the desired properties
-               wfDebug( "Autoblocking {$this->mName}@" . wfGetIP() . "\n" );
-               $ipblock->mAddress = wfGetIP();
-               $ipblock->mUser = 0;
-               $ipblock->mBy = $userblock->mBy;
-               $ipblock->mReason = wfMsg( 'autoblocker', $this->getName(), $userblock->mReason );
-               $ipblock->mTimestamp = wfTimestampNow();
-               $ipblock->mAuto = 1;
-               # If the user is already blocked with an expiry date, we don't
-               # want to pile on top of that!
-               if($userblock->mExpiry) {
-                       $ipblock->mExpiry = min ( $userblock->mExpiry, Block::getAutoblockExpiry( $ipblock->mTimestamp ));
-               } else {
-                       $ipblock->mExpiry = Block::getAutoblockExpiry( $ipblock->mTimestamp );
-               }
-
-               # Insert it
-               $ipblock->insert();
+               $userblock->doAutoblock( wfGetIp() );
 
        }
 
index 4a3d8d3..7f2a404 100644 (file)
@@ -1770,7 +1770,7 @@ pages that were vandalized).",
 'ipbreason'            => 'Reason',
 'ipbanononly'   => 'Block anonymous users only',
 'ipbcreateaccount' => 'Prevent account creation',
-'ipbenableautoblock' => 'Automatically block IP addresses used by this user',
+'ipbenableautoblock' => 'Automatically block the last IP address used by this user, and any subsequent addresses they try to edit from',
 'ipbsubmit'            => 'Block this user',
 'ipbother'             => 'Other time',
 'ipboptions'           => '2 hours:2 hours,1 day:1 day,3 days:3 days,1 week:1 week,2 weeks:2 weeks,1 month:1 month,3 months:3 months,6 months:6 months,1 year:1 year,infinite:infinite',
diff --git a/maintenance/archives/patch-rc_user_text-index.sql b/maintenance/archives/patch-rc_user_text-index.sql
new file mode 100644 (file)
index 0000000..f6acc99
--- /dev/null
@@ -0,0 +1,7 @@
+-- Add an index to recentchanges on rc_user_text
+--
+-- Added 2006-11-08
+--
+
+     ALTER TABLE /*$wgDBprefix*/recentchanges
+ADD INDEX rc_user_text(rc_user_text, rc_timestamp);
\ No newline at end of file
index 9f9cb69..e68c9b0 100644 (file)
@@ -804,7 +804,8 @@ CREATE TABLE /*$wgDBprefix*/recentchanges (
   INDEX rc_cur_id (rc_cur_id),
   INDEX new_name_timestamp (rc_new,rc_namespace,rc_timestamp),
   INDEX rc_ip (rc_ip),
-  INDEX rc_ns_usertext (rc_namespace, rc_user_text)
+  INDEX rc_ns_usertext (rc_namespace, rc_user_text),
+  INDEX rc_user_text (rc_user_text, rc_timestamp)
 
 ) TYPE=InnoDB;
 
index 6552c7b..d7c41ac 100644 (file)
@@ -779,7 +779,19 @@ function do_rc_indices_update() {
                dbsource( archive( 'patch-recentchanges-utindex.sql' ) );
        } else {
                # Index seems to exist
-               echo( "...seems to be ok\n" );
+               echo( "...index on ( rc_namespace, rc_user_text ) seems to be ok\n" );
+       }
+
+       #Add (rc_user_text, rc_timestamp) index [A. Garrett], November 2006
+       # See if we can find the index we want
+       $info = $wgDatabase->indexInfo( 'recentchanges', 'rc_user_text', __METHOD__ );
+       if( !$info ) {
+               # None, so create
+               echo( "...index on ( rc_user_text, rc_timestamp ) not found; creating\n" );
+               dbsource( archive( 'patch-rc_user_text-index.sql' ) );
+       } else {
+               # Index seems to exist
+               echo( "...index on ( rc_user_text, rc_timestamp ) seems to be ok\n" );
        }
 }