From 8671e7cda835dbb832bcfb86b0e994e5ce0df88f Mon Sep 17 00:00:00 2001 From: Andrew Garrett Date: Wed, 8 Nov 2006 09:54:06 +0000 Subject: [PATCH] * (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. --- RELEASE-NOTES | 5 +- includes/Block.php | 84 +++++++++++++++++++ includes/User.php | 40 +-------- languages/messages/MessagesEn.php | 2 +- .../archives/patch-rc_user_text-index.sql | 7 ++ maintenance/tables.sql | 3 +- maintenance/updaters.inc | 14 +++- 7 files changed, 112 insertions(+), 43 deletions(-) create mode 100644 maintenance/archives/patch-rc_user_text-index.sql diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 8d62530801..7dcd45b440 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -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 == diff --git a/includes/Block.php b/includes/Block.php index 8a0f27ca46..8558a61171 100644 --- a/includes/Block.php +++ b/includes/Block.php @@ -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'; diff --git a/includes/User.php b/includes/User.php index c6763359f6..64084dd5b0 100644 --- a/includes/User.php +++ b/includes/User.php @@ -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() ); } diff --git a/languages/messages/MessagesEn.php b/languages/messages/MessagesEn.php index 4a3d8d3ba7..7f2a404f63 100644 --- a/languages/messages/MessagesEn.php +++ b/languages/messages/MessagesEn.php @@ -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 index 0000000000..f6acc99213 --- /dev/null +++ b/maintenance/archives/patch-rc_user_text-index.sql @@ -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 diff --git a/maintenance/tables.sql b/maintenance/tables.sql index 9f9cb698ed..e68c9b072c 100644 --- a/maintenance/tables.sql +++ b/maintenance/tables.sql @@ -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; diff --git a/maintenance/updaters.inc b/maintenance/updaters.inc index 6552c7b259..d7c41aced6 100644 --- a/maintenance/updaters.inc +++ b/maintenance/updaters.inc @@ -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" ); } } -- 2.20.1