Two blocking features: IP range blocks, and expiry times configurable block-by-block.
authorTim Starling <tstarling@users.mediawiki.org>
Sat, 14 Feb 2004 12:37:25 +0000 (12:37 +0000)
committerTim Starling <tstarling@users.mediawiki.org>
Sat, 14 Feb 2004 12:37:25 +0000 (12:37 +0000)
Possible issue: uses strtotime(), which is very handy but in English

14 files changed:
docs/memcached.doc
includes/Block.php
includes/BlockCache.php [new file with mode: 0644]
includes/DefaultSettings.php
includes/Setup.php
includes/SpecialBlockip.php
includes/SpecialIpblocklist.php
includes/User.php
languages/Language.php
maintenance/InitialiseMessages.inc
maintenance/archives/patch-ipb_expiry.sql [new file with mode: 0644]
maintenance/tables.sql
update.php
wiki.phtml

index e2e016d..6752e9c 100644 (file)
@@ -122,4 +122,11 @@ Watchlist:
        stores: HTML string
        cleared by: nothing, expiry time $wgWLCacheTimeout (1 hour)
        note: emergency optimisation only
+
+IP blocks:
+       key: $wgDBname:ipblocks
+       ex: wikidb:ipblocks
+       stores: array of arrays, for the BlockCache class
+       cleared by: BlockCache:clear()
+       
 ... more to come ...
index 3da568e..13cb657 100644 (file)
@@ -8,12 +8,15 @@
 #
 # To use delete(), you only need to fill $mAddress
 
+# Globals used: $wgIPBlockCache, $wgAutoblockExpiry
+
 class Block
 {
-       var $mAddress, $mUser, $mBy, $mReason, $mTimestamp, $mAuto, $mId;
+       /* public*/ var $mAddress, $mUser, $mBy, $mReason, $mTimestamp, $mAuto, $mId, $mExpiry;
+       /* private */ var $mNetworkBits, $mIntegerAddr;
        
        function Block( $address = "", $user = "", $by = 0, $reason = "", 
-               $timestamp = "" , $auto = 0) 
+               $timestamp = "" , $auto = 0, $expiry = "" 
        {
                $this->mAddress = $address;
                $this->mUser = $user;
@@ -21,21 +24,27 @@ class Block
                $this->mReason = $reason;
                $this->mTimestamp = $timestamp;
                $this->mAuto = $auto;
-       }
+               $this->mExpiry = $expiry;
 
-       /*static*/ function newFromDB( $address, $user = 0, $killExpired = true ) {
+               $this->initialiseRange();
+       }
+       
+       /*static*/ function newFromDB( $address, $user = 0, $killExpired = true ) 
+       {
                $ban = new Block();
                $ban->load( $address, $user, $killExpired );
                return $ban;
        }
-               
-       function clear() {
+       
+       function clear() 
+       {
                $mAddress = $mReason = $mTimestamp = "";
                $mUser = $mBy = 0;
        }
 
        # Get a ban from the DB, with either the given address or the given username
-       function load( $address, $user = 0, $killExpired = true ) {
+       function load( $address, $user = 0, $killExpired = true ) 
+       {
                $fname = "Block::load";
                $ret = false;
                $killed = false;
@@ -83,7 +92,8 @@ class Block
                return $ret;
        }
        
-       function initFromRow( $row ) {
+       function initFromRow( $row ) 
+       {
                $this->mAddress = $row->ipb_address;
                $this->mReason = $row->ipb_reason;
                $this->mTimestamp = $row->ipb_timestamp;
@@ -91,10 +101,30 @@ class Block
                $this->mBy = $row->ipb_by;
                $this->mAuto = $row->ipb_auto;
                $this->mId = $row->ipb_id;
+               $this->mExpiry = $row->ipb_expiry;
+
+               $this->initialiseRange();
        }       
 
+       function initialiseRange()
+       {
+               if ( $this->mUser == 0 ) {
+                       $rangeParts = explode( "/", $this->mAddress );
+                       if ( count( $rangeParts ) == 2 ) {
+                               $this->mNetworkBits = $rangeParts[1];
+                       } else {
+                               $this->mNetworkBits = 32;
+                       }
+                       $this->mIntegerAddr = ip2long( $rangeParts[0] );
+               } else {
+                       $this->mNetworkBits = false;
+                       $this->mIntegerAddr = false;
+               }
+       }
+       
        # Callback with a Block object for every block
-       /*static*/ function enumBlocks( $callback, $tag, $killExpired = true ) {
+       /*static*/ function enumBlocks( $callback, $tag, $killExpired = true ) 
+       {
                $sql = "SELECT * FROM ipblocks ORDER BY ipb_timestamp DESC";
                $res = wfQuery( $sql, DB_READ, "Block::enumBans" );
                $block = new Block();
@@ -112,7 +142,8 @@ class Block
                wfFreeResult( $res );
        }
 
-       function delete() {
+       function delete() 
+       {
                $fname = "Block::delete";
                if ( $this->mAddress == "" ) {
                        $sql = "DELETE FROM ipblocks WHERE ipb_id={$this->mId}";
@@ -121,17 +152,23 @@ class Block
                                wfStrencode( $this->mAddress ) . "'";
                }
                wfQuery( $sql, DB_WRITE, "Block::delete" );
+
+               $this->clearCache();
        }
 
-       function insert() {
+       function insert() 
+       {
                $sql = "INSERT INTO ipblocks 
-                 (ipb_address, ipb_user, ipb_by, ipb_reason, ipb_timestamp, ipb_auto ) 
+                 (ipb_address, ipb_user, ipb_by, ipb_reason, ipb_timestamp, ipb_auto, ipb_expiry ) 
                  VALUES ('" . wfStrencode( $this->mAddress ) . "', {$this->mUser}, {$this->mBy}, '" . 
-                 wfStrencode( $this->mReason ) . "','{$this->mTimestamp}', {$this->mAuto})";
+                 wfStrencode( $this->mReason ) . "','{$this->mTimestamp}', {$this->mAuto}, '{$this->mExpiry}')";
                wfQuery( $sql, DB_WRITE, "Block::insert" );
+
+               $this->clearCache();
        }
 
-       function deleteIfExpired() {
+       function deleteIfExpired() 
+       {
                if ( $this->isExpired() ) {
                        $this->delete();
                        return true;
@@ -140,31 +177,64 @@ class Block
                }
        }
 
-       function isExpired() {
-               global $wgIPBlockExpiration, $wgUserBlockExpiration;
-               
-               $period = $this->mUser ? $wgUserBlockExpiration : $wgIPBlockExpiration;
-               
-               # Period==0 means no expiry
-               if ( !$period ) { 
-                       return false;
-               }
-               $expiry = wfTimestamp2Unix( $this->mTimestamp ) + $period;
-               $now = wfTimestamp2Unix( wfTimestampNow() );
-               if ( $now > $expiry ) {
-                       return true;
-               } else {
-                       return false;
-               }
+       function isExpired() 
+       {       
+               return wfTimestampNow() > $this->mExpiry;
        }
 
-       function isValid() {
+       function isValid() 
+       {
                return $this->mAddress != "";
        }
        
        function updateTimestamp() {
-               wfQuery( "UPDATE ipblocks SET ipb_timestamp='" . wfTimestampNow() . 
-                       "' WHERE ipb_address='" . wfStrencode( $this->mAddress ) . "'", DB_WRITE, "Block::updateTimestamp" );
+               
+               $this->mTimestamp = wfTimestampNow();
+               $this->mExpiry = Block::getAutoblockExpiry( $this->mTimestamp );
+
+               wfQuery( "UPDATE ipblocks SET " .
+                       "ipb_timestamp='" . $this->mTimestamp . "', " .
+                       "ipb_expiry='" . $this->mExpiry . "' " .
+                       "WHERE ipb_address='" . wfStrencode( $this->mAddress ) . "'", DB_WRITE, "Block::updateTimestamp" );
+               
+               $this->clearCache();
+       }
+
+       /* private */ function clearCache()
+       {
+               global $wgBlockCache;
+               if ( is_object( $wgBlockCache ) ) {
+                       $wgBlockCache->clear();
+               }
+       }
+       
+       function getIntegerAddr()
+       {
+               return $this->mIntegerAddr;
+       }
+       
+       function getNetworkBits()
+       {
+               return $this->mNetworkBits;
+       }
+
+       /* static */ function getAutoblockExpiry( $timestamp )
+       {
+               global $wgAutoblockExpiry;
+               return wfUnix2Timestamp( wfTimestamp2Unix( $timestamp ) + $wgAutoblockExpiry );
+       }
+
+       /* static */ function normaliseRange( $range )
+       {
+               $parts = explode( "/", $range );
+               if ( count( $parts ) == 2 ) {
+                       $shift = 32 - $parts[1];
+                       $ipint = ip2long( $parts[0] );
+                       $ipint = $ipint >> $shift << $shift;
+                       $newip = long2ip( $ipint );
+                       $range = "$newip/{$parts[1]}";
+               }
+               return $range;
        }
 
 }
diff --git a/includes/BlockCache.php b/includes/BlockCache.php
new file mode 100644 (file)
index 0000000..48921a4
--- /dev/null
@@ -0,0 +1,115 @@
+<?
+
+# Object for fast lookup of IP blocks
+# Represents a memcached value, and in some sense, the entire ipblocks table
+
+class BlockCache
+{
+       var $mData = false, $mMemcKey;
+
+       function BlockCache( $deferLoad = false, $dbName = "" )
+       {
+               global $wgDBname;
+
+               if ( $dbName == "" ) {
+                       $dbName = $wgDBname;
+               }
+
+               $this->mMemcKey = "$dbName:ipblocks";
+
+               if ( !$deferLoad ) {
+                       $this->load();
+               }
+       }
+
+       function load()
+       {
+               global $wgUseMemCached, $wgMemc;
+
+               if ( $this->mData === false) {
+                       $this->mData = array();
+
+                       $saveMemc = false;
+                       # Try memcached
+                       if ( $wgUseMemCached ) {
+                               $this->mData = $wgMemc->get( $this->mMemcKey );
+                               if ( !$this->mData ) {
+                                       $saveMemc = true;
+                               }
+                       }
+
+                       if ( $this->mData === false || is_null( $this->mData ) ) {
+                               # Load from DB
+                               $this->mData = array();
+                               Block::enumBlocks( "wfBlockCacheInsert", "" ); # Calls $this->insert()
+                       }
+                       
+                       if ( $saveMemc ) {
+                               $wgMemc->set( $this->mMemcKey, $this->mData, 0 );
+                       }
+               }
+       }
+
+       function insert( &$block )
+       {
+               if ( $block->mUser == 0 ) {
+                       $nb = $block->getNetworkBits();
+                       $ipint = $block->getIntegerAddr();
+                       $index = $ipint >> ( 32 - $nb );
+
+                       if ( !array_key_exists( $nb, $this->mData ) ) {
+                               $this->mData[$nb] = array();
+                       }
+               
+                       $this->mData[$nb][$index] = 1;
+               }
+       }
+               
+       function get( $ip )
+       {
+               $this->load();
+               $ipint = ip2long( $ip );
+               $blocked = false;
+
+               foreach ( $this->mData as $networkBits => $blockInts ) {
+                       if ( array_key_exists( $ipint >> ( 32 - $networkBits ), $blockInts ) ) {
+                               $blocked = true;
+                               break;
+                       }
+               }
+               if ( $blocked ) {
+                       # Clear low order bits
+                       if ( $networkBits != 32 ) {
+                               $ip .= "/$networkBits";
+                               $ip = Block::normaliseRange( $ip );
+                       }
+                       $block = new Block();
+                       $block->load( $ip );
+               } else {
+                       $block = false;
+               }
+
+               return $block;
+       }
+
+       function clear()
+       {
+               global $wgUseMemCached, $wgMemc;
+
+               $this->mData = false;
+               if ( $wgUseMemCached ) {
+                       $wgMemc->delete( $this->mMemcKey );
+               }
+       }
+
+       function clearLocal()
+       {
+               $this->mData = false;
+       }
+}
+
+function wfBlockCacheInsert( $block, $tag )
+{
+       global $wgBlockCache;
+       $wgBlockCache->insert( $block );
+}
index 45b862a..c24eec9 100644 (file)
@@ -113,17 +113,10 @@ $wgWhitelistEdit = false;
 $wgWhitelistRead = false;
 $wgWhitelistAccount = array ( "user" => 1, "sysop" => 1, "developer" => 1 );
 $wgSysopUserBans        = false; # Allow sysops to ban logged-in users
-$wgIPBlockExpiration    = 86400; # IP blocks expire after this many seconds, 0=infinite
-$wgUserBlockExpiration  = 0; # As above, but for logged-in users
-
-# User agent/range blocking
-# Blocks all users using a particular user agent, possibly restricted to a 
-# set of IP ranges. Note: you can't block all user agents by leaving 
-# $wgBadUserAgents blank. That would block nothing.
-$wgBadRanges                   = false; # e.g. array(array("1.2.3.0", "1.2.3.255"))
-$wgBadUserAgents               = false; # e.g. array("OfflineExplorer/1.0")
-$wgRangeBlockUser              = 0;     # The block is attributed to this user ID
-$wgRangeBlockReason            = "";    # This reason is given (should be in wfMsg, obviously)
+$wgSysopRangeBans              = false; # Allow sysops to ban IP ranges
+$wgDefaultBlockExpiry  = "24 hours"; # default expiry time
+                                # strtotime format, or "infinite" for an infinite block
+$wgAutoblockExpiry             = 86400; # Number of seconds before autoblock entries expire
 
 # Client-side caching:
 $wgCachePages       = true; # Allow client-side caching of pages
index 2149dce..b85f107 100644 (file)
@@ -48,6 +48,7 @@ include_once( "Block.php" );
 include_once( "SearchEngine.php" );
 include_once( "DifferenceEngine.php" );
 include_once( "MessageCache.php" );
+include_once( "BlockCache.php" );
 
 wfProfileOut( "$fname-includes" );
 wfProfileIn( "$fname-memcached" );
@@ -56,6 +57,21 @@ global $wgArticle, $wgDeferredUpdateList, $wgLinkCache;
 global $wgMemc, $wgMagicWords, $wgMwRedir, $wgDebugLogFile;
 global $wgMessageCache, $wgUseMemCached, $wgUseDatabaseMessages;
 global $wgMsgCacheExpiry, $wgDBname, $wgCommandLineMode;
+global $wgBlockCache;
+
+# Useful debug output
+if ( function_exists( "getallheaders" ) ) {
+       wfDebug( "\nStart request\n" );
+       wfDebug( "$REQUEST_METHOD $REQUEST_URI\n" );
+       $headers = getallheaders();
+       foreach ($headers as $name => $value) {
+               wfDebug( "$name: $value\n" );
+       }
+       wfDebug( "\n" );
+} else {
+       wfDebug( "$REQUEST_METHOD $REQUEST_URI\n" );
+}
+
 
 class MemCachedClientforWiki extends memcached {
        function _debugprint( $text ) {
@@ -134,6 +150,7 @@ if( !$wgCommandLineMode && isset( $_COOKIE[ini_get("session.name")] )  ) {
        User::SetupSession();
 }
 
+$wgBlockCache = new BlockCache( true );
 $wgUser = User::loadFromSession();
 $wgDeferredUpdateList = array();
 $wgLinkCache = new LinkCache();
index 023ca54..4b29d03 100644 (file)
@@ -8,7 +8,7 @@ function wfSpecialBlockip()
                $wgOut->sysopRequired();
                return;
        }
-       $fields = array( "wpBlockAddress", "wpBlockReason" );
+       $fields = array( "wpBlockAddress", "wpBlockReason", "wpBlockExpiry" );
        wfCleanFormFields( $fields );
        $ipb = new IPBlockForm();
 
@@ -21,16 +21,24 @@ class IPBlockForm {
 
        function showForm( $err )
        {
-               global $wgOut, $wgUser, $wgLang;
-               global $ip, $wpBlockAddress, $wpBlockReason;
+               global $wgOut, $wgUser, $wgLang, $wgDefaultBlockExpiry;
+               global $ip, $wpBlockAddress, $wpBlockExpiry, $wpBlockReason;
 
                $wgOut->setPagetitle( wfMsg( "blockip" ) );
                $wgOut->addWikiText( wfMsg( "blockiptext" ) );
 
-               if ( ! $wpBlockAddress ) { $wpBlockAddress = $ip; }
-               $ipa = wfMsg( "ipaddress" );
-               $reason = wfMsg( "ipbreason" );
-               $ipbs = wfMsg( "ipbsubmit" );
+               if ( ! $wpBlockAddress ) { 
+                       $wpBlockAddress = $ip; 
+               }
+
+               if ( is_null( $wpBlockExpiry ) || $wpBlockExpiry === "" ) {
+                       $wpBlockExpiry = $wgDefaultBlockExpiry;
+               }
+
+               $mIpaddress = wfMsg( "ipaddress" );
+               $mIpbexpiry = wfMsg( "ipbexpiry" );
+               $mIpbreason = wfMsg( "ipbreason" );
+               $mIpbsubmit = wfMsg( "ipbsubmit" );
                $action = wfLocalUrlE( $wgLang->specialPage( "Blockip" ),
                  "action=submit" );
 
@@ -38,19 +46,28 @@ class IPBlockForm {
                        $wgOut->setSubtitle( wfMsg( "formerror" ) );
                        $wgOut->addHTML( "<p><font color='red' size='+1'>{$err}</font>\n" );
                }
+
+               $scBlockAddress = htmlspecialchars( $wpBlockAddress );
+               $scBlockExpiry = htmlspecialchars( $wpBlockExpiry );
+               $scBlockReason = htmlspecialchars( $wpBlockReason );
+               
                $wgOut->addHTML( "<p>
 <form id=\"blockip\" method=\"post\" action=\"{$action}\">
 <table border=0><tr>
-<td align=\"right\">{$ipa}:</td>
+<td align=\"right\">{$mIpaddress}:</td>
+<td align=\"left\">
+<input tabindex=1 type=text size=20 name=\"wpBlockAddress\" value=\"{$scBlockAddress}\">
+</td></tr><tr>
+<td align=\"right\">{$mIpbexpiry}:</td>
 <td align=\"left\">
-<input tabindex=1 type=text size=20 name=\"wpBlockAddress\" value=\"{$wpBlockAddress}\">
+<input tabindex=2 type=text size=20 name=\"wpBlockExpiry\" value=\"{$scBlockExpiry}\">
 </td></tr><tr>
-<td align=\"right\">{$reason}:</td>
+<td align=\"right\">{$mIpbreason}:</td>
 <td align=\"left\">
-<input tabindex=2 type=text size=40 name=\"wpBlockReason\" value=\"{$wpBlockReason}\">
+<input tabindex=3 type=text size=40 name=\"wpBlockReason\" value=\"{$scBlockReason}\">
 </td></tr><tr>
 <td>&nbsp;</td><td align=\"left\">
-<input tabindex=3 type=submit name=\"wpBlock\" value=\"{$ipbs}\">
+<input tabindex=4 type=submit name=\"wpBlock\" value=\"{$mIpbsubmit}\">
 </td></tr></table>
 </form>\n" );
 
@@ -59,25 +76,54 @@ class IPBlockForm {
        function doSubmit()
        {
                global $wgOut, $wgUser, $wgLang;
-               global $ip, $wpBlockAddress, $wpBlockReason, $wgSysopUserBans;
+               global $ip, $wpBlockAddress, $wpBlockReason, $wpBlockExpiry;
+               global $wgSysopUserBans, $wgSysopRangeBans;
                
                $userId = 0;
                $wpBlockAddress = trim( $wpBlockAddress );
-
-               if ( ! preg_match( "/^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/",
-                 $wpBlockAddress ) ) 
-               {
-                       if ( $wgSysopUserBans ) {       
-                               $userId = User::idFromName( $wpBlockAddress );
-                               if ( $userId == 0 ) {
-                                       $this->showForm( wfMsg( "badipaddress" ) );
+               $rxIP = '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';
+
+               # Check for invalid specifications
+               if ( ! preg_match( "/^$rxIP$/", $wpBlockAddress ) ) {
+                       if ( preg_match( "/^($rxIP)\\/(\\d{1,2})$/", $wpBlockAddress, $matches ) ) {
+                               if ( $wgSysopRangeBans ) {
+                                       if ( $matches[2] > 31 || $matches[2] < 1 ) {
+                                               $this->showForm( wfMsg( "ip_range_invalid" ) );
+                                       }
+                                       $wpBlockAddress = Block::normaliseRange( $wpBlockAddress );
+                               } else {
+                                       # Range block illegal
+                                       $this->showForm( wfMsg( "range_block_disabled" ) );
                                        return;
                                }
                        } else {
-                               $this->showForm( wfMsg( "badipaddress" ) );
-                               return;
-                       }               
+                               # Username block
+                               if ( $wgSysopUserBans ) {       
+                                       $userId = User::idFromName( $wpBlockAddress );
+                                       if ( $userId == 0 ) {
+                                               $this->showForm( wfMsg( "nosuchuser", htmlspecialchars( $wpBlockAddress ) ) );
+                                               return;
+                                       }
+                               } else {
+                                       $this->showForm( wfMsg( "badipaddress" ) );
+                                       return;
+                               }
+                       }
+               }
+
+               if ( $wpBlockExpiry == "infinite" || $wpBlockExpiry == "indefinite" ) {
+                       $expiry = 0;
+               } else {
+                       # Convert GNU-style date, returns -1 on error
+                       $expiry = strtotime( $wpBlockExpiry );
                }
+
+               if ( $expiry < 0 ) {
+                       $this->showForm( wfMsg( "ipb_expiry_invalid" ) );
+                       return;
+               }
+               $expiry = wfUnix2Timestamp( $expiry );
+
                if ( "" == $wpBlockReason ) {
                        $this->showForm( wfMsg( "noblockreason" ) );
                        return;
@@ -85,13 +131,14 @@ class IPBlockForm {
                
                # Create block
                # Note: for a user block, ipb_address is only for display purposes
+
                $ban = new Block( $wpBlockAddress, $userId, $wgUser->getID(), 
-                       wfStrencode( $wpBlockReason ), wfTimestampNow(), 0 );
+                       wfStrencode( $wpBlockReason ), wfTimestampNow(), 0, $expiry );
                $ban->insert();
 
                # Make log entry
                $log = new LogPage( wfMsg( "blocklogpage" ), wfMsg( "blocklogtext" ) );
-               $action = wfMsg( "blocklogentry", $wpBlockAddress );
+               $action = wfMsg( "blocklogentry", $wpBlockAddress, $wpBlockExpiry );
                $log->addEntry( $action, $wpBlockReason );
 
                # Report to the user
index 9368bd4..30bef11 100644 (file)
@@ -117,9 +117,15 @@ function wfAddRow( $block, $tag ) {
 
        $name = User::whoIs( $block->mBy );
        $ulink = $sk->makeKnownLink( $wgLang->getNsText( Namespace::getUser() ). ":{$name}", $name );
-       $d = $wgLang->timeanddate( $block->mTimestamp, true );
-
-       $line = wfMsg( "blocklistline", $d, $ulink, $addr );
+       $formattedTime = $wgLang->timeanddate( $block->mTimestamp, true );
+       
+       if ( $block->mExpiry === "" ) {
+               $formattedExpiry = "indefinite";
+       } else {
+               $formattedExpiry = $wgLang->timeanddate( $block->mExpiry, true );
+       }
+       
+       $line = wfMsg( "blocklistline", $formattedTime, $ulink, $addr, $formattedExpiry );
        
        $wgOut->addHTML( "<li>{$line}" );
        
index 4851b99..9bf1d4c 100644 (file)
@@ -94,45 +94,29 @@ class User {
 
        /* private */ function getBlockedStatus()
        {
-               global $wgBadRanges, $wgBadUserAgents, $wgRangeBlockUser, $wgRangeBlockReason, $wgIP;
+               global $wgIP, $wgBlockCache;
 
                if ( -1 != $this->mBlockedby ) { return; }
+       
+               $this->mBlockedby = 0;
                
-               # Range/user-agent blocking
-               
-               $fBlock = false; # Mmmm, Hungarian
-               if ( ( !is_array( $wgBadUserAgents ) ||
-                                       array_key_exists( getenv( "HTTP_USER_AGENT" ), $wgBadUserAgents ) ) &&
-                               is_array( $wgBadRanges ) )
-               {
-                       $iIp = ip2long( $wgIP );
-                       foreach ( $wgBadRanges as $range ) {
-                               $start = ip2long( $range[0] );
-                               $end = ip2long( $range[1] );
-                               if ( $iIp >= $start && $iIp <= $end ) {
-                                       $fBlock = true;
-                                       break;
-                               }
+               # User blocking
+               if ( $this->mId ) {     
+                       $block = new Block();
+                       if ( $block->load( $wgIP , $this->mId ) ) {
+                               $this->mBlockedby = $block->mBy;
+                               $this->mBlockreason = $block->mReason;
                        }
                }
 
-               if ( $fBlock ) {
-                       $this->mBlockedby = $wgRangeBlockUser;
-                       $this->mBlockreason = $wgRangeBlockReason;
-                       return;
-               }
-
-               # User/IP blocking
-
-               $block = new Block();
-               if ( !$block->load( $wgIP , $this->mId ) ) {
-                       wfDebug( $wgIP ." is not blocked\n" );
-                       $this->mBlockedby = 0;
-                       return;
+               # IP/range blocking
+               if ( !$this->mBlockedby ) {
+                       $block = $wgBlockCache->get( $wgIP );
+                       if ( $block !== false ) {
+                               $this->mBlockedby = $block->mBy;
+                               $this->mBlockreason = $block->mReason;
+                       }
                }
-
-               $this->mBlockedby = $block->mBy;
-               $this->mBlockreason = $block->mReason;
        }
 
        function isBlocked()
@@ -626,6 +610,7 @@ class User {
                $ipblock->mReason = wfMsg( "autoblocker", $this->getName(), $userblock->mReason );
                $ipblock->mTimestamp = wfTimestampNow();
                $ipblock->mAuto = 1;
+               $ipblock->mExpiry = Block::getAutoblockExpiry( $ipblock->mTimestamp );
 
                # Insert it
                $ipblock->insert();
index 1f779af..bf99247 100644 (file)
@@ -643,11 +643,6 @@ The reason given is this:<br>''$2''<p>You may contact $1 or one of the other
 Note that you may not use the \"email this user\" feature unless you have a valid email address registered in your [[Special:Preferences|user preferences]].
 
 Your IP address is $3. Please include this address in any queries you make.
-
-==Note to AOL users==
-Due to continuing acts of vandalism by one particular AOL user, Wikipedia often blocks AOL proxies. Unfortunately, a single proxy server may be used by a large number of AOL users, and hence innocent AOL users are often inadvertently blocked. We apologise for any inconvenience caused.
-
-If this happens to you, please email an administrator, using an AOL email address. Be sure to include the IP address given above.
 ",
 "whitelistedittitle" => "Login required to edit",
 "whitelistedittext" => "You have to [[Special:Userlogin|login]] to edit articles.",
@@ -1208,9 +1203,10 @@ accordance with [[$wgMetaNamespace:Policy|policy]].
 Fill in a specific reason below (for example, citing particular
 pages that were vandalized).",
 "ipaddress"            => "IP Address/username",
+"ipbexpiry"            => "Expiry",
 "ipbreason"            => "Reason",
 "ipbsubmit"            => "Block this user",
-"badipaddress" => "No user exists by that name",
+"badipaddress" => "Invalid IP address",
 "noblockreason" => "You must supply a reason for the block.",
 "blockipsuccesssub" => "Block succeeded",
 "blockipsuccesstext" => "\"$1\" has been blocked.
@@ -1221,17 +1217,20 @@ to a previously blocked IP address or username.",
 "ipusubmit"            => "Unblock this address",
 "ipusuccess"   => "\"$1\" unblocked",
 "ipblocklist"  => "List of blocked IP addresses and usernames",
-"blocklistline"        => "$1, $2 blocked $3",
+"blocklistline"        => "$1, $2 blocked $3 (expires $4)",
 "blocklink"            => "block",
 "unblocklink"  => "unblock",
 "contribslink" => "contribs",
 "autoblocker"  => "Autoblocked because you share an IP address with \"$1\". Reason \"$2\".",
 "blocklogpage" => "Block_log",
-"blocklogentry"        => 'blocked "$1"',
+"blocklogentry"        => 'blocked "$1" with an expiry time of $2',
 "blocklogtext" => "This is a log of user blocking and unblocking actions. Automatically 
 blocked IP addresses are not be listed. See the [[Special:Ipblocklist|IP block list]] for
 the list of currently operational bans and blocks.",
 "unblocklogentry"      => 'unblocked "$1"',
+"range_block_disabled" => "The sysop ability to create range blocks is disabled.",
+"ipb_expiry_invalid"   => "Expiry time invalid.",
+"ip_range_invalid"     => "Invalid IP range.\n",
 
 # Developer tools
 #
index 5eeb0d2..315ab64 100755 (executable)
@@ -74,8 +74,7 @@ function initialiseMessages( $overwrite = false) {
 
                $doInsert = true;
                if ( $overwrite ) {
-                       $sql = "DELETE FROM cur WHERE cur_namespace=$ns AND cur_title='$title'";
-                       wfQuery( $sql, DB_WRITE, $fname );
+                       wfQuery( "DELETE FROM cur WHERE cur_namespace=$ns AND cur_title='$title'", DB_WRITE, $fname );
                } else {        
                        if (array_key_exists($title, $exists)) {
                                $doInsert = false;
@@ -112,7 +111,11 @@ function initialiseMessages( $overwrite = false) {
        }
        print "Done\n";
        print "Writing...";
-       wfQuery( $sql, DB_WRITE, $fname );
+
+       if ( !$first ) {
+               wfQuery( $sql, DB_WRITE, $fname );
+       }
+
        print "Done\n";
 
        $navText .= "</table>";
diff --git a/maintenance/archives/patch-ipb_expiry.sql b/maintenance/archives/patch-ipb_expiry.sql
new file mode 100644 (file)
index 0000000..d41c877
--- /dev/null
@@ -0,0 +1,8 @@
+-- Adds the ipb_expiry field to ipblocks
+
+ALTER TABLE ipblocks ADD ipb_expiry char(14) binary NOT NULL default '';
+
+-- All IP blocks have one day expiry
+UPDATE ipblocks SET ipb_expiry = date_format(date_add(ipb_timestamp,INTERVAL 1 DAY),"%Y%m%d%H%i%s") WHERE ipb_user = 0;
+
+-- Null string is fine for user blocks, since this indicates infinity
index 8a9d79a..71f5525 100644 (file)
@@ -126,6 +126,7 @@ CREATE TABLE ipblocks (
   ipb_reason tinyblob NOT NULL default '',
   ipb_timestamp char(14) binary NOT NULL default '',
   ipb_auto tinyint(1) NOT NULL default '0',
+  ipb_expiry char(14) binary NOT NULL default '',
   UNIQUE KEY ipb_id (ipb_id)
 ) TYPE=MyISAM PACK_KEYS=1;
 
index 5dac771..58f8e3c 100644 (file)
@@ -154,13 +154,29 @@ function update_passwords() {
 
 function do_ipblocks_update() {
        global $wgDatabase;
-       if ( $wgDatabase->fieldExists( "ipblocks", "ipb_id" ) ) {
-               echo "...ipblocks table is up to date.\n";
-       } else {
+
+       $do1 = $do2 = false;
+
+       if ( !$wgDatabase->fieldExists( "ipblocks", "ipb_id" ) ) {
+               $do1 = true;
+       }
+       if ( !$wgDatabase->fieldExists( "ipblocks", "ipb_expiry" ) ) {
+               $do2 = true;
+       }
+
+       if ( $do1 || $do2 ) {
                echo "Updating ipblocks table... ";
-               dbsource( "maintenance/archives/patch-ipblocks.sql", $wgDatabase );
+               if ( $do1 ) {
+                       dbsource( "maintenance/archives/patch-ipblocks.sql", $wgDatabase );
+               }
+               if ( $do2 ) {
+                       dbsource( "maintenance/archives/patch-ipb_expiry.sql", $wgDatabase );
+               }
                echo "ok\n";
+       } else {
+               echo "...ipblocks is up to date.\n";
        }
+       
 }
 
 
index 35fdcd9..4093459 100644 (file)
@@ -16,19 +16,6 @@ include_once( "Setup.php" );
 wfProfileIn( "main-misc-setup" );
 OutputPage::setEncodings(); # Not really used yet
 
-# Useful debug output
-if ( function_exists( "getallheaders" ) ) {
-       wfDebug( "\nStart request\n" );
-       wfDebug( "$REQUEST_METHOD $REQUEST_URI\n" );
-       $headers = getallheaders();
-       foreach ($headers as $name => $value) {
-               wfDebug( "$name: $value\n" );
-       }
-       wfDebug( "\n" );
-} else {
-       wfDebug( "$REQUEST_METHOD $REQUEST_URI\n" );
-}
-
 # Query string fields
 #
 global $action, $title, $search, $go, $target, $printable;