Merge "resourceloader: Add explicit tests for isValidModuleName()"
[lhc/web/wiklou.git] / includes / block / BlockManager.php
index 3ef35d7..8d2fe0c 100644 (file)
 
 namespace MediaWiki\Block;
 
-use Block;
 use IP;
+use MediaWiki\User\UserIdentity;
 use User;
 use WebRequest;
 use Wikimedia\IPSet;
-use MediaWiki\User\UserIdentity;
 
 /**
  * A service class for checking blocks.
@@ -111,7 +110,7 @@ class BlockManager {
         * @param bool $fromReplica Whether to check the replica DB first.
         *  To improve performance, non-critical checks are done against replica DBs.
         *  Check when actually saving should be done against master.
-        * @return Block|null The most relevant block, or null if there is no block.
+        * @return AbstractBlock|null The most relevant block, or null if there is no block.
         */
        public function getUserBlock( User $user, $fromReplica ) {
                $isAnon = $user->getId() === 0;
@@ -120,7 +119,7 @@ class BlockManager {
                // we should not look for XFF or cookie blocks.
                $request = $user->getRequest();
 
-               # We only need to worry about passing the IP address to the Block generator if the
+               # We only need to worry about passing the IP address to the block generator if the
                # user is not immune to autoblocks/hardblocks, and they are the current user so we
                # know which IP address they're actually coming from
                $ip = null;
@@ -135,26 +134,29 @@ class BlockManager {
                }
 
                // User/IP blocking
-               // TODO: remove dependency on Block
-               $block = Block::newFromTarget( $user, $ip, !$fromReplica );
+               // TODO: remove dependency on DatabaseBlock
+               $block = DatabaseBlock::newFromTarget( $user, $ip, !$fromReplica );
 
                // Cookie blocking
-               if ( !$block instanceof Block ) {
+               if ( !$block instanceof AbstractBlock ) {
                        $block = $this->getBlockFromCookieValue( $user, $request );
                }
 
                // Proxy blocking
-               if ( !$block instanceof Block && $ip !== null && !in_array( $ip, $this->proxyWhitelist ) ) {
+               if ( !$block instanceof AbstractBlock
+                       && $ip !== null
+                       && !in_array( $ip, $this->proxyWhitelist )
+               ) {
                        // Local list
                        if ( $this->isLocallyBlockedProxy( $ip ) ) {
-                               $block = new Block( [
+                               $block = new SystemBlock( [
                                        'byText' => wfMessage( 'proxyblocker' )->text(),
                                        'reason' => wfMessage( 'proxyblockreason' )->plain(),
                                        'address' => $ip,
                                        'systemBlock' => 'proxy',
                                ] );
                        } elseif ( $isAnon && $this->isDnsBlacklisted( $ip ) ) {
-                               $block = new Block( [
+                               $block = new SystemBlock( [
                                        'byText' => wfMessage( 'sorbs' )->text(),
                                        'reason' => wfMessage( 'sorbsreason' )->plain(),
                                        'address' => $ip,
@@ -164,7 +166,7 @@ class BlockManager {
                }
 
                // (T25343) Apply IP blocks to the contents of XFF headers, if enabled
-               if ( !$block instanceof Block
+               if ( !$block instanceof AbstractBlock
                        && $this->applyIpBlocksToXff
                        && $ip !== null
                        && !in_array( $ip, $this->proxyWhitelist )
@@ -172,23 +174,23 @@ class BlockManager {
                        $xff = $request->getHeader( 'X-Forwarded-For' );
                        $xff = array_map( 'trim', explode( ',', $xff ) );
                        $xff = array_diff( $xff, [ $ip ] );
-                       // TODO: remove dependency on Block
-                       $xffblocks = Block::getBlocksForIPList( $xff, $isAnon, !$fromReplica );
-                       // TODO: remove dependency on Block
-                       $block = Block::chooseBlock( $xffblocks, $xff );
-                       if ( $block instanceof Block ) {
+                       // TODO: remove dependency on DatabaseBlock
+                       $xffblocks = DatabaseBlock::getBlocksForIPList( $xff, $isAnon, !$fromReplica );
+                       // TODO: remove dependency on DatabaseBlock
+                       $block = DatabaseBlock::chooseBlock( $xffblocks, $xff );
+                       if ( $block instanceof AbstractBlock ) {
                                # Mangle the reason to alert the user that the block
                                # originated from matching the X-Forwarded-For header.
                                $block->setReason( wfMessage( 'xffblockreason', $block->getReason() )->plain() );
                        }
                }
 
-               if ( !$block instanceof Block
+               if ( !$block instanceof AbstractBlock
                        && $ip !== null
                        && $isAnon
                        && IP::isInRanges( $ip, $this->softBlockRanges )
                ) {
-                       $block = new Block( [
+                       $block = new SystemBlock( [
                                'address' => $ip,
                                'byText' => 'MediaWiki default',
                                'reason' => wfMessage( 'softblockrangesreason', $ip )->plain(),
@@ -201,11 +203,11 @@ class BlockManager {
        }
 
        /**
-        * Try to load a Block from an ID given in a cookie value.
+        * Try to load a block from an ID given in a cookie value.
         *
         * @param UserIdentity $user
         * @param WebRequest $request
-        * @return Block|bool The Block object, or false if none could be loaded.
+        * @return DatabaseBlock|bool The block object, or false if none could be loaded.
         */
        private function getBlockFromCookieValue(
                UserIdentity $user,
@@ -218,21 +220,21 @@ class BlockManager {
                if ( strlen( $blockCookieVal ) < 1 || !is_numeric( substr( $blockCookieVal, 0, 1 ) ) ) {
                        return false;
                }
-               // Load the Block from the ID in the cookie.
-               // TODO: remove dependency on Block
-               $blockCookieId = Block::getIdFromCookieValue( $blockCookieVal );
+               // Load the block from the ID in the cookie.
+               // TODO: remove dependency on DatabaseBlock
+               $blockCookieId = DatabaseBlock::getIdFromCookieValue( $blockCookieVal );
                if ( $blockCookieId !== null ) {
                        // An ID was found in the cookie.
-                       // TODO: remove dependency on Block
-                       $tmpBlock = Block::newFromID( $blockCookieId );
-                       if ( $tmpBlock instanceof Block ) {
+                       // TODO: remove dependency on DatabaseBlock
+                       $tmpBlock = DatabaseBlock::newFromID( $blockCookieId );
+                       if ( $tmpBlock instanceof DatabaseBlock ) {
                                switch ( $tmpBlock->getType() ) {
-                                       case Block::TYPE_USER:
+                                       case DatabaseBlock::TYPE_USER:
                                                $blockIsValid = !$tmpBlock->isExpired() && $tmpBlock->isAutoblocking();
                                                $useBlockCookie = ( $this->cookieSetOnAutoblock === true );
                                                break;
-                                       case Block::TYPE_IP:
-                                       case Block::TYPE_RANGE:
+                                       case DatabaseBlock::TYPE_IP:
+                                       case DatabaseBlock::TYPE_RANGE:
                                                // If block is type IP or IP range, load only if user is not logged in (T152462)
                                                $blockIsValid = !$tmpBlock->isExpired() && $user->getId() === 0;
                                                $useBlockCookie = ( $this->cookieSetOnIpBlock === true );
@@ -248,12 +250,12 @@ class BlockManager {
                                }
 
                                // If the block is not valid, remove the cookie.
-                               // TODO: remove dependency on Block
-                               Block::clearCookie( $response );
+                               // TODO: remove dependency on DatabaseBlock
+                               DatabaseBlock::clearCookie( $response );
                        } else {
                                // If the block doesn't exist, remove the cookie.
-                               // TODO: remove dependency on Block
-                               Block::clearCookie( $response );
+                               // TODO: remove dependency on DatabaseBlock
+                               DatabaseBlock::clearCookie( $response );
                        }
                }
                return false;
@@ -342,29 +344,42 @@ class BlockManager {
                                if ( is_array( $base ) ) {
                                        if ( count( $base ) >= 2 ) {
                                                // Access key is 1, base URL is 0
-                                               $host = "{$base[1]}.$ipReversed.{$base[0]}";
+                                               $hostname = "{$base[1]}.$ipReversed.{$base[0]}";
                                        } else {
-                                               $host = "$ipReversed.{$base[0]}";
+                                               $hostname = "$ipReversed.{$base[0]}";
                                        }
                                        $basename = $base[0];
                                } else {
-                                       $host = "$ipReversed.$base";
+                                       $hostname = "$ipReversed.$base";
                                }
 
                                // Send query
-                               $ipList = gethostbynamel( $host );
+                               $ipList = $this->checkHost( $hostname );
 
                                if ( $ipList ) {
-                                       wfDebugLog( 'dnsblacklist', "Hostname $host is {$ipList[0]}, it's a proxy says $basename!" );
+                                       wfDebugLog(
+                                               'dnsblacklist',
+                                               "Hostname $hostname is {$ipList[0]}, it's a proxy says $basename!"
+                                       );
                                        $found = true;
                                        break;
                                }
 
-                               wfDebugLog( 'dnsblacklist', "Requested $host, not found in $basename." );
+                               wfDebugLog( 'dnsblacklist', "Requested $hostname, not found in $basename." );
                        }
                }
 
                return $found;
        }
 
+       /**
+        * Wrapper for mocking in tests.
+        *
+        * @param string $hostname DNSBL query
+        * @return string[]|bool IPv4 array, or false if the IP is not blacklisted
+        */
+       protected function checkHost( $hostname ) {
+               return gethostbynamel( $hostname );
+       }
+
 }