API: Added bkip parameter to list=blocks. This more than fixes bug 14405.
authorRoan Kattouw <catrope@users.mediawiki.org>
Thu, 19 Jun 2008 13:43:14 +0000 (13:43 +0000)
committerRoan Kattouw <catrope@users.mediawiki.org>
Thu, 19 Jun 2008 13:43:14 +0000 (13:43 +0000)
About the database query: I know it filesorts the result set, but that shouldn't cause any trouble as the result set is always small. To be more specific: it cannot be larger than 17 rows. This is because bkip=foo only grabs (range) blocks that contain foo *in its entirety*. Therefore, in the worst case foo is a single IP and the result set will consist of a single block, a /31 range block, a /30, etc. to /16 (blocks that cross /16 , which adds up to 17 blocks (note that there's only one /N range that a /N+K range is part of).

RELEASE-NOTES
includes/api/ApiQueryBlocks.php

index 46a787a..97f8acb 100644 (file)
@@ -460,6 +460,7 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
 * Added 'hidden' flag to list=allcategories and prop=categoryinfo output
 * Added nocreate parameter to action=edit
 * (bug 14402) Added maxage and smaxage parameters to api.php
+* Added bkip parameter to list=blocks
 
 === Languages updated in 1.13 ===
 
index e5335d5..f634565 100644 (file)
@@ -49,6 +49,9 @@ class ApiQueryBlocks extends ApiQueryBase {
                global $wgUser;
 
                $params = $this->extractRequestParams();
+               if(isset($params['users']) && isset($params['ip']))
+                       $this->dieUsage('bkusers and bkip cannot be used together', 'usersandip');
+
                $prop = array_flip($params['prop']);
                $fld_id = isset($prop['id']);
                $fld_user = isset($prop['user']);
@@ -96,6 +99,26 @@ class ApiQueryBlocks extends ApiQueryBase {
                                $this->prepareUsername($u);
                        $this->addWhere(array('ipb_address' => $this->usernames));
                }
+               if(isset($params['ip']))
+               {
+                       list($ip, $range) = IP::parseCIDR($params['ip']);
+                       if($ip && $range)
+                       {
+                               # We got a CIDR range
+                               if($range < 16)
+                                       $this->dieUsage('CIDR ranges broader than /16 are not accepted', 'cidrtoobroad');
+                               $lower = wfBaseConvert($ip, 10, 16, 8, false);
+                               $upper = wfBaseConvert($ip + pow(2, 32 - $range) - 1, 10, 16, 8, false);
+                       }
+                       else
+                               $lower = $upper = IP::toHex($params['ip']);
+                       $prefix = substr($lower, 0, 4);
+                       $this->addWhere(array(
+                               "ipb_range_start LIKE '$prefix%'",
+                               "ipb_range_start <= '$lower'",
+                               "ipb_range_end >= '$upper'"
+                       ));
+               }
                if(!$wgUser->isAllowed('suppress'))
                        $this->addWhere(array('ipb_deleted' => 0));
 
@@ -159,19 +182,16 @@ class ApiQueryBlocks extends ApiQueryBase {
                $result->addValue('query', $this->getModuleName(), $data);
        }
        
-       protected function prepareUsername($user) {
-               if( $user ) {
-                       $name = User::isIP( $user )
-                               ? $user
-                               : User::getCanonicalName( $user, 'valid' );
-                       if( $name === false ) {
-                               $this->dieUsage( "User name {$user} is not valid", 'param_user' );
-                       } else {
-                               $this->usernames[] = $name;
-                       }
-               } else {
-                       $this->dieUsage( 'User parameter may not be empty', 'param_user' );
-               }
+       protected function prepareUsername($user)
+       {
+               if(!$user)
+                       $this->dieUsage('User parameter may not be empty', 'param_user');
+               $name = User::isIP($user)
+                       ? $user
+                       : User::getCanonicalName($user, 'valid');
+               if($name === false)
+                       $this->dieUsage("User name {$user} is not valid", 'param_user');
+               $this->usernames[] = $name;
        }
 
        protected function convertHexIP($ip)
@@ -209,6 +229,7 @@ class ApiQueryBlocks extends ApiQueryBase {
                        'users' => array(
                                ApiBase :: PARAM_ISMULTI => true
                        ),
+                       'ip' => null,
                        'limit' => array(
                                ApiBase :: PARAM_DFLT => 10,
                                ApiBase :: PARAM_TYPE => 'limit',
@@ -240,6 +261,8 @@ class ApiQueryBlocks extends ApiQueryBase {
                        'dir' => 'The direction in which to enumerate',
                        'ids' => 'Pipe-separated list of block IDs to list (optional)',
                        'users' => 'Pipe-separated list of users to search for (optional)',
+                       'ip' => array(  'Get all blocks applying to this IP or CIDR range, including range blocks.',
+                                       'Cannot be used together with bkusers. CIDR ranges broader than /16 are not accepted.'),
                        'limit' => 'The maximum amount of blocks to list',
                        'prop' => 'Which properties to get',
                );