MediaWiki  REL1_22
BlockTest.php
Go to the documentation of this file.
00001 <?php
00002 
00007 class BlockTest extends MediaWikiLangTestCase {
00008 
00009     private $block, $madeAt;
00010 
00011     /* variable used to save up the blockID we insert in this test suite */
00012     private $blockId;
00013 
00014     protected function setUp() {
00015         parent::setUp();
00016         $this->setMwGlobals( array(
00017             'wgLanguageCode' => 'en',
00018             'wgContLang' => Language::factory( 'en' )
00019         ) );
00020     }
00021 
00022     function addDBData() {
00023 
00024         $user = User::newFromName( 'UTBlockee' );
00025         if ( $user->getID() == 0 ) {
00026             $user->addToDatabase();
00027             $user->setPassword( 'UTBlockeePassword' );
00028 
00029             $user->saveSettings();
00030         }
00031 
00032         // Delete the last round's block if it's still there
00033         $oldBlock = Block::newFromTarget( 'UTBlockee' );
00034         if ( $oldBlock ) {
00035             // An old block will prevent our new one from saving.
00036             $oldBlock->delete();
00037         }
00038 
00039         $this->block = new Block( 'UTBlockee', $user->getID(), 0,
00040             'Parce que', 0, false, time() + 100500
00041         );
00042         $this->madeAt = wfTimestamp( TS_MW );
00043 
00044         $this->block->insert();
00045         // save up ID for use in assertion. Since ID is an autoincrement,
00046         // its value might change depending on the order the tests are run.
00047         // ApiBlockTest insert its own blocks!
00048         $newBlockId = $this->block->getId();
00049         if ( $newBlockId ) {
00050             $this->blockId = $newBlockId;
00051         } else {
00052             throw new MWException( "Failed to insert block for BlockTest; old leftover block remaining?" );
00053         }
00054 
00055         $this->addXffBlocks();
00056     }
00057 
00061     function dumpBlocks() {
00062         $v = $this->db->select( 'ipblocks', '*' );
00063         print "Got " . $v->numRows() . " rows. Full dump follow:\n";
00064         foreach ( $v as $row ) {
00065             print_r( $row );
00066         }
00067     }
00068 
00069     public function testInitializerFunctionsReturnCorrectBlock() {
00070         // $this->dumpBlocks();
00071 
00072         $this->assertTrue( $this->block->equals( Block::newFromTarget( 'UTBlockee' ) ), "newFromTarget() returns the same block as the one that was made" );
00073 
00074         $this->assertTrue( $this->block->equals( Block::newFromID( $this->blockId ) ), "newFromID() returns the same block as the one that was made" );
00075     }
00076 
00080     public function testBug26425BlockTimestampDefaultsToTime() {
00081         // delta to stop one-off errors when things happen to go over a second mark.
00082         $delta = abs( $this->madeAt - $this->block->mTimestamp );
00083         $this->assertLessThan( 2, $delta, "If no timestamp is specified, the block is recorded as time()" );
00084     }
00085 
00094     public function testBug29116LoadWithEmptyIp( $vagueTarget ) {
00095         $this->hideDeprecated( 'Block::load' );
00096 
00097         $uid = User::idFromName( 'UTBlockee' );
00098         $this->assertTrue( ( $uid > 0 ), 'Must be able to look up the target user during tests' );
00099 
00100         $block = new Block();
00101         $ok = $block->load( $vagueTarget, $uid );
00102         $this->assertTrue( $ok, "Block->load() with empty IP and user ID '$uid' should return a block" );
00103 
00104         $this->assertTrue( $this->block->equals( $block ), "Block->load() returns the same block as the one that was made when given empty ip param " . var_export( $vagueTarget, true ) );
00105     }
00106 
00114     public function testBug29116NewFromTargetWithEmptyIp( $vagueTarget ) {
00115         $block = Block::newFromTarget( 'UTBlockee', $vagueTarget );
00116         $this->assertTrue( $this->block->equals( $block ), "newFromTarget() returns the same block as the one that was made when given empty vagueTarget param " . var_export( $vagueTarget, true ) );
00117     }
00118 
00119     public static function provideBug29116Data() {
00120         return array(
00121             array( null ),
00122             array( '' ),
00123             array( false )
00124         );
00125     }
00126 
00127     public function testBlockedUserCanNotCreateAccount() {
00128         $username = 'BlockedUserToCreateAccountWith';
00129         $u = User::newFromName( $username );
00130         $u->setPassword( 'NotRandomPass' );
00131         $u->addToDatabase();
00132         unset( $u );
00133 
00134         // Sanity check
00135         $this->assertNull(
00136             Block::newFromTarget( $username ),
00137             "$username should not be blocked"
00138         );
00139 
00140         // Reload user
00141         $u = User::newFromName( $username );
00142         $this->assertFalse(
00143             $u->isBlockedFromCreateAccount(),
00144             "Our sandbox user should be able to create account before being blocked"
00145         );
00146 
00147         // Foreign perspective (blockee not on current wiki)...
00148         $block = new Block(
00149             /* $address */ $username,
00150             /* $user */ 14146,
00151             /* $by */ 0,
00152             /* $reason */ 'crosswiki block...',
00153             /* $timestamp */ wfTimestampNow(),
00154             /* $auto */ false,
00155             /* $expiry */ $this->db->getInfinity(),
00156             /* anonOnly */ false,
00157             /* $createAccount */ true,
00158             /* $enableAutoblock */ true,
00159             /* $hideName (ipb_deleted) */ true,
00160             /* $blockEmail */ true,
00161             /* $allowUsertalk */ false,
00162             /* $byName */ 'MetaWikiUser'
00163         );
00164         $block->insert();
00165 
00166         // Reload block from DB
00167         $userBlock = Block::newFromTarget( $username );
00168         $this->assertTrue(
00169             (bool)$block->prevents( 'createaccount' ),
00170             "Block object in DB should prevents 'createaccount'"
00171         );
00172 
00173         $this->assertInstanceOf(
00174             'Block',
00175             $userBlock,
00176             "'$username' block block object should be existent"
00177         );
00178 
00179         // Reload user
00180         $u = User::newFromName( $username );
00181         $this->assertTrue(
00182             (bool)$u->isBlockedFromCreateAccount(),
00183             "Our sandbox user '$username' should NOT be able to create account"
00184         );
00185     }
00186 
00187     public function testCrappyCrossWikiBlocks() {
00188         // Delete the last round's block if it's still there
00189         $oldBlock = Block::newFromTarget( 'UserOnForeignWiki' );
00190         if ( $oldBlock ) {
00191             // An old block will prevent our new one from saving.
00192             $oldBlock->delete();
00193         }
00194 
00195         // Foreign perspective (blockee not on current wiki)...
00196         $block = new Block(
00197             /* $address */ 'UserOnForeignWiki',
00198             /* $user */ 14146,
00199             /* $by */ 0,
00200             /* $reason */ 'crosswiki block...',
00201             /* $timestamp */ wfTimestampNow(),
00202             /* $auto */ false,
00203             /* $expiry */ $this->db->getInfinity(),
00204             /* anonOnly */ false,
00205             /* $createAccount */ true,
00206             /* $enableAutoblock */ true,
00207             /* $hideName (ipb_deleted) */ true,
00208             /* $blockEmail */ true,
00209             /* $allowUsertalk */ false,
00210             /* $byName */ 'MetaWikiUser'
00211         );
00212 
00213         $res = $block->insert( $this->db );
00214         $this->assertTrue( (bool)$res['id'], 'Block succeeded' );
00215 
00216         // Local perspective (blockee on current wiki)...
00217         $user = User::newFromName( 'UserOnForeignWiki' );
00218         $user->addToDatabase();
00219         // Set user ID to match the test value
00220         $this->db->update( 'user', array( 'user_id' => 14146 ), array( 'user_id' => $user->getId() ) );
00221         $user = null; // clear
00222 
00223         $block = Block::newFromID( $res['id'] );
00224         $this->assertEquals( 'UserOnForeignWiki', $block->getTarget()->getName(), 'Correct blockee name' );
00225         $this->assertEquals( '14146', $block->getTarget()->getId(), 'Correct blockee id' );
00226         $this->assertEquals( 'MetaWikiUser', $block->getBlocker(), 'Correct blocker name' );
00227         $this->assertEquals( 'MetaWikiUser', $block->getByName(), 'Correct blocker name' );
00228         $this->assertEquals( 0, $block->getBy(), 'Correct blocker id' );
00229     }
00230 
00231     protected function addXffBlocks() {
00232         static $inited = false;
00233 
00234         if ( $inited ) {
00235             return;
00236         }
00237 
00238         $inited = true;
00239 
00240         $blockList = array(
00241             array( 'target' => '70.2.0.0/16',
00242                 'type' => Block::TYPE_RANGE,
00243                 'desc' => 'Range Hardblock',
00244                 'ACDisable' => false,
00245                 'isHardblock' => true,
00246                 'isAutoBlocking' => false,
00247             ),
00248             array( 'target' => '2001:4860:4001::/48',
00249                 'type' => Block::TYPE_RANGE,
00250                 'desc' => 'Range6 Hardblock',
00251                 'ACDisable' => false,
00252                 'isHardblock' => true,
00253                 'isAutoBlocking' => false,
00254             ),
00255             array( 'target' => '60.2.0.0/16',
00256                 'type' => Block::TYPE_RANGE,
00257                 'desc' => 'Range Softblock with AC Disabled',
00258                 'ACDisable' => true,
00259                 'isHardblock' => false,
00260                 'isAutoBlocking' => false,
00261             ),
00262             array( 'target' => '50.2.0.0/16',
00263                 'type' => Block::TYPE_RANGE,
00264                 'desc' => 'Range Softblock',
00265                 'ACDisable' => false,
00266                 'isHardblock' => false,
00267                 'isAutoBlocking' => false,
00268             ),
00269             array( 'target' => '50.1.1.1',
00270                 'type' => Block::TYPE_IP,
00271                 'desc' => 'Exact Softblock',
00272                 'ACDisable' => false,
00273                 'isHardblock' => false,
00274                 'isAutoBlocking' => false,
00275             ),
00276         );
00277 
00278         foreach ( $blockList as $insBlock ) {
00279             $target = $insBlock['target'];
00280 
00281             if ( $insBlock['type'] === Block::TYPE_IP ) {
00282                 $target = User::newFromName( IP::sanitizeIP( $target ), false )->getName();
00283             } elseif ( $insBlock['type'] === Block::TYPE_RANGE ) {
00284                 $target = IP::sanitizeRange( $target );
00285             }
00286 
00287             $block = new Block();
00288             $block->setTarget( $target );
00289             $block->setBlocker( 'testblocker@global' );
00290             $block->mReason = $insBlock['desc'];
00291             $block->mExpiry = 'infinity';
00292             $block->prevents( 'createaccount', $insBlock['ACDisable'] );
00293             $block->isHardblock( $insBlock['isHardblock'] );
00294             $block->isAutoblocking( $insBlock['isAutoBlocking'] );
00295             $block->insert();
00296         }
00297     }
00298 
00299     public static function providerXff() {
00300         return array(
00301             array( 'xff' => '1.2.3.4, 70.2.1.1, 60.2.1.1, 2.3.4.5',
00302                 'count' => 2,
00303                 'result' => 'Range Hardblock'
00304             ),
00305             array( 'xff' => '1.2.3.4, 50.2.1.1, 60.2.1.1, 2.3.4.5',
00306                 'count' => 2,
00307                 'result' => 'Range Softblock with AC Disabled'
00308             ),
00309             array( 'xff' => '1.2.3.4, 70.2.1.1, 50.1.1.1, 2.3.4.5',
00310                 'count' => 2,
00311                 'result' => 'Exact Softblock'
00312             ),
00313             array( 'xff' => '1.2.3.4, 70.2.1.1, 50.2.1.1, 50.1.1.1, 2.3.4.5',
00314                 'count' => 3,
00315                 'result' => 'Exact Softblock'
00316             ),
00317             array( 'xff' => '1.2.3.4, 70.2.1.1, 50.2.1.1, 2.3.4.5',
00318                 'count' => 2,
00319                 'result' => 'Range Hardblock'
00320             ),
00321             array( 'xff' => '1.2.3.4, 70.2.1.1, 60.2.1.1, 2.3.4.5',
00322                 'count' => 2,
00323                 'result' => 'Range Hardblock'
00324             ),
00325             array( 'xff' => '50.2.1.1, 60.2.1.1, 2.3.4.5',
00326                 'count' => 2,
00327                 'result' => 'Range Softblock with AC Disabled'
00328             ),
00329             array( 'xff' => '1.2.3.4, 50.1.1.1, 60.2.1.1, 2.3.4.5',
00330                 'count' => 2,
00331                 'result' => 'Exact Softblock'
00332             ),
00333             array( 'xff' => '1.2.3.4, <$A_BUNCH-OF{INVALID}TEXT>, 60.2.1.1, 2.3.4.5',
00334                 'count' => 1,
00335                 'result' => 'Range Softblock with AC Disabled'
00336             ),
00337             array( 'xff' => '1.2.3.4, 50.2.1.1, 2001:4860:4001:802::1003, 2.3.4.5',
00338                 'count' => 2,
00339                 'result' => 'Range6 Hardblock'
00340             ),
00341         );
00342     }
00343 
00347     public function testBlocksOnXff( $xff, $exCount, $exResult ) {
00348         $list = array_map( 'trim', explode( ',', $xff ) );
00349         $xffblocks = Block::getBlocksForIPList( $list, true );
00350         $this->assertEquals( $exCount, count( $xffblocks ), 'Number of blocks for ' . $xff );
00351         $block = Block::chooseBlock( $xffblocks, $list );
00352         $this->assertEquals( $exResult, $block->mReason, 'Correct block type for XFF header ' . $xff );
00353     }
00354 }