MediaWiki  1.29.1
BlockTest.php
Go to the documentation of this file.
1 <?php
2 
8 
10  private $block;
11  private $madeAt;
12 
13  /* variable used to save up the blockID we insert in this test suite */
14  private $blockId;
15 
16  function addDBData() {
17  $user = User::newFromName( 'UTBlockee' );
18  if ( $user->getId() == 0 ) {
19  $user->addToDatabase();
20  TestUser::setPasswordForUser( $user, 'UTBlockeePassword' );
21 
22  $user->saveSettings();
23  }
24 
25  // Delete the last round's block if it's still there
26  $oldBlock = Block::newFromTarget( 'UTBlockee' );
27  if ( $oldBlock ) {
28  // An old block will prevent our new one from saving.
29  $oldBlock->delete();
30  }
31 
32  $blockOptions = [
33  'address' => 'UTBlockee',
34  'user' => $user->getId(),
35  'reason' => 'Parce que',
36  'expiry' => time() + 100500,
37  ];
38  $this->block = new Block( $blockOptions );
39  $this->madeAt = wfTimestamp( TS_MW );
40 
41  $this->block->insert();
42  // save up ID for use in assertion. Since ID is an autoincrement,
43  // its value might change depending on the order the tests are run.
44  // ApiBlockTest insert its own blocks!
45  $newBlockId = $this->block->getId();
46  if ( $newBlockId ) {
47  $this->blockId = $newBlockId;
48  } else {
49  throw new MWException( "Failed to insert block for BlockTest; old leftover block remaining?" );
50  }
51 
52  $this->addXffBlocks();
53  }
54 
58  function dumpBlocks() {
59  $v = $this->db->select( 'ipblocks', '*' );
60  print "Got " . $v->numRows() . " rows. Full dump follow:\n";
61  foreach ( $v as $row ) {
62  print_r( $row );
63  }
64  }
65 
70  $this->assertTrue(
71  $this->block->equals( Block::newFromTarget( 'UTBlockee' ) ),
72  "newFromTarget() returns the same block as the one that was made"
73  );
74  }
75 
80  $this->assertTrue(
81  $this->block->equals( Block::newFromID( $this->blockId ) ),
82  "newFromID() returns the same block as the one that was made"
83  );
84  }
85 
90  // delta to stop one-off errors when things happen to go over a second mark.
91  $delta = abs( $this->madeAt - $this->block->mTimestamp );
92  $this->assertLessThan(
93  2,
94  $delta,
95  "If no timestamp is specified, the block is recorded as time()"
96  );
97  }
98 
107  public function testBug29116NewFromTargetWithEmptyIp( $vagueTarget ) {
108  $block = Block::newFromTarget( 'UTBlockee', $vagueTarget );
109  $this->assertTrue(
110  $this->block->equals( $block ),
111  "newFromTarget() returns the same block as the one that was made when "
112  . "given empty vagueTarget param " . var_export( $vagueTarget, true )
113  );
114  }
115 
116  public static function provideBug29116Data() {
117  return [
118  [ null ],
119  [ '' ],
120  [ false ]
121  ];
122  }
123 
128  $username = 'BlockedUserToCreateAccountWith';
130  $u->addToDatabase();
131  $userId = $u->getId();
132  $this->assertNotEquals( 0, $userId, 'sanity' );
133  TestUser::setPasswordForUser( $u, 'NotRandomPass' );
134  unset( $u );
135 
136  // Sanity check
137  $this->assertNull(
139  "$username should not be blocked"
140  );
141 
142  // Reload user
144  $this->assertFalse(
145  $u->isBlockedFromCreateAccount(),
146  "Our sandbox user should be able to create account before being blocked"
147  );
148 
149  // Foreign perspective (blockee not on current wiki)...
150  $blockOptions = [
151  'address' => $username,
152  'user' => $userId,
153  'reason' => 'crosswiki block...',
154  'timestamp' => wfTimestampNow(),
155  'expiry' => $this->db->getInfinity(),
156  'createAccount' => true,
157  'enableAutoblock' => true,
158  'hideName' => true,
159  'blockEmail' => true,
160  'byText' => 'MetaWikiUser',
161  ];
162  $block = new Block( $blockOptions );
163  $block->insert();
164 
165  // Reload block from DB
166  $userBlock = Block::newFromTarget( $username );
167  $this->assertTrue(
168  (bool)$block->prevents( 'createaccount' ),
169  "Block object in DB should prevents 'createaccount'"
170  );
171 
172  $this->assertInstanceOf(
173  'Block',
174  $userBlock,
175  "'$username' block block object should be existent"
176  );
177 
178  // Reload user
180  $this->assertTrue(
181  (bool)$u->isBlockedFromCreateAccount(),
182  "Our sandbox user '$username' should NOT be able to create account"
183  );
184  }
185 
189  public function testCrappyCrossWikiBlocks() {
190  // Delete the last round's block if it's still there
191  $oldBlock = Block::newFromTarget( 'UserOnForeignWiki' );
192  if ( $oldBlock ) {
193  // An old block will prevent our new one from saving.
194  $oldBlock->delete();
195  }
196 
197  // Local perspective (blockee on current wiki)...
198  $user = User::newFromName( 'UserOnForeignWiki' );
199  $user->addToDatabase();
200  $userId = $user->getId();
201  $this->assertNotEquals( 0, $userId, 'sanity' );
202 
203  // Foreign perspective (blockee not on current wiki)...
204  $blockOptions = [
205  'address' => 'UserOnForeignWiki',
206  'user' => $user->getId(),
207  'reason' => 'crosswiki block...',
208  'timestamp' => wfTimestampNow(),
209  'expiry' => $this->db->getInfinity(),
210  'createAccount' => true,
211  'enableAutoblock' => true,
212  'hideName' => true,
213  'blockEmail' => true,
214  'byText' => 'MetaWikiUser',
215  ];
216  $block = new Block( $blockOptions );
217 
218  $res = $block->insert( $this->db );
219  $this->assertTrue( (bool)$res['id'], 'Block succeeded' );
220 
221  $user = null; // clear
222 
223  $block = Block::newFromID( $res['id'] );
224  $this->assertEquals(
225  'UserOnForeignWiki',
226  $block->getTarget()->getName(),
227  'Correct blockee name'
228  );
229  $this->assertEquals( $userId, $block->getTarget()->getId(), 'Correct blockee id' );
230  $this->assertEquals( 'MetaWikiUser', $block->getBlocker(), 'Correct blocker name' );
231  $this->assertEquals( 'MetaWikiUser', $block->getByName(), 'Correct blocker name' );
232  $this->assertEquals( 0, $block->getBy(), 'Correct blocker id' );
233  }
234 
235  protected function addXffBlocks() {
236  static $inited = false;
237 
238  if ( $inited ) {
239  return;
240  }
241 
242  $inited = true;
243 
244  $blockList = [
245  [ 'target' => '70.2.0.0/16',
246  'type' => Block::TYPE_RANGE,
247  'desc' => 'Range Hardblock',
248  'ACDisable' => false,
249  'isHardblock' => true,
250  'isAutoBlocking' => false,
251  ],
252  [ 'target' => '2001:4860:4001::/48',
253  'type' => Block::TYPE_RANGE,
254  'desc' => 'Range6 Hardblock',
255  'ACDisable' => false,
256  'isHardblock' => true,
257  'isAutoBlocking' => false,
258  ],
259  [ 'target' => '60.2.0.0/16',
260  'type' => Block::TYPE_RANGE,
261  'desc' => 'Range Softblock with AC Disabled',
262  'ACDisable' => true,
263  'isHardblock' => false,
264  'isAutoBlocking' => false,
265  ],
266  [ 'target' => '50.2.0.0/16',
267  'type' => Block::TYPE_RANGE,
268  'desc' => 'Range Softblock',
269  'ACDisable' => false,
270  'isHardblock' => false,
271  'isAutoBlocking' => false,
272  ],
273  [ 'target' => '50.1.1.1',
274  'type' => Block::TYPE_IP,
275  'desc' => 'Exact Softblock',
276  'ACDisable' => false,
277  'isHardblock' => false,
278  'isAutoBlocking' => false,
279  ],
280  ];
281 
282  foreach ( $blockList as $insBlock ) {
283  $target = $insBlock['target'];
284 
285  if ( $insBlock['type'] === Block::TYPE_IP ) {
286  $target = User::newFromName( IP::sanitizeIP( $target ), false )->getName();
287  } elseif ( $insBlock['type'] === Block::TYPE_RANGE ) {
288  $target = IP::sanitizeRange( $target );
289  }
290 
291  $block = new Block();
292  $block->setTarget( $target );
293  $block->setBlocker( 'testblocker@global' );
294  $block->mReason = $insBlock['desc'];
295  $block->mExpiry = 'infinity';
296  $block->prevents( 'createaccount', $insBlock['ACDisable'] );
297  $block->isHardblock( $insBlock['isHardblock'] );
298  $block->isAutoblocking( $insBlock['isAutoBlocking'] );
299  $block->insert();
300  }
301  }
302 
303  public static function providerXff() {
304  return [
305  [ 'xff' => '1.2.3.4, 70.2.1.1, 60.2.1.1, 2.3.4.5',
306  'count' => 2,
307  'result' => 'Range Hardblock'
308  ],
309  [ 'xff' => '1.2.3.4, 50.2.1.1, 60.2.1.1, 2.3.4.5',
310  'count' => 2,
311  'result' => 'Range Softblock with AC Disabled'
312  ],
313  [ 'xff' => '1.2.3.4, 70.2.1.1, 50.1.1.1, 2.3.4.5',
314  'count' => 2,
315  'result' => 'Exact Softblock'
316  ],
317  [ 'xff' => '1.2.3.4, 70.2.1.1, 50.2.1.1, 50.1.1.1, 2.3.4.5',
318  'count' => 3,
319  'result' => 'Exact Softblock'
320  ],
321  [ 'xff' => '1.2.3.4, 70.2.1.1, 50.2.1.1, 2.3.4.5',
322  'count' => 2,
323  'result' => 'Range Hardblock'
324  ],
325  [ 'xff' => '1.2.3.4, 70.2.1.1, 60.2.1.1, 2.3.4.5',
326  'count' => 2,
327  'result' => 'Range Hardblock'
328  ],
329  [ 'xff' => '50.2.1.1, 60.2.1.1, 2.3.4.5',
330  'count' => 2,
331  'result' => 'Range Softblock with AC Disabled'
332  ],
333  [ 'xff' => '1.2.3.4, 50.1.1.1, 60.2.1.1, 2.3.4.5',
334  'count' => 2,
335  'result' => 'Exact Softblock'
336  ],
337  [ 'xff' => '1.2.3.4, <$A_BUNCH-OF{INVALID}TEXT>, 60.2.1.1, 2.3.4.5',
338  'count' => 1,
339  'result' => 'Range Softblock with AC Disabled'
340  ],
341  [ 'xff' => '1.2.3.4, 50.2.1.1, 2001:4860:4001:802::1003, 2.3.4.5',
342  'count' => 2,
343  'result' => 'Range6 Hardblock'
344  ],
345  ];
346  }
347 
353  public function testBlocksOnXff( $xff, $exCount, $exResult ) {
354  $list = array_map( 'trim', explode( ',', $xff ) );
355  $xffblocks = Block::getBlocksForIPList( $list, true );
356  $this->assertEquals( $exCount, count( $xffblocks ), 'Number of blocks for ' . $xff );
357  $block = Block::chooseBlock( $xffblocks, $list );
358  $this->assertEquals( $exResult, $block->mReason, 'Correct block type for XFF header ' . $xff );
359  }
360 
361  public function testDeprecatedConstructor() {
362  $this->hideDeprecated( 'Block::__construct with multiple arguments' );
363  $username = 'UnthinkablySecretRandomUsername';
364  $reason = 'being irrational';
365 
366  # Set up the target
368  if ( $u->getId() == 0 ) {
369  $u->addToDatabase();
370  TestUser::setPasswordForUser( $u, 'TotallyObvious' );
371  }
372  unset( $u );
373 
374  # Make sure the user isn't blocked
375  $this->assertNull(
377  "$username should not be blocked"
378  );
379 
380  # Perform the block
381  $block = new Block(
382  /* address */ $username,
383  /* user */ 0,
384  /* by */ 0,
385  /* reason */ $reason,
386  /* timestamp */ 0,
387  /* auto */ false,
388  /* expiry */ 0
389  );
390  $block->insert();
391 
392  # Check target
393  $this->assertEquals(
394  $block->getTarget()->getName(),
395  $username,
396  "Target should be set properly"
397  );
398 
399  # Check supplied parameter
400  $this->assertEquals(
401  $block->mReason,
402  $reason,
403  "Reason should be non-default"
404  );
405 
406  # Check default parameter
407  $this->assertFalse(
408  (bool)$block->prevents( 'createaccount' ),
409  "Account creation should not be blocked by default"
410  );
411  }
412 
413  public function testSystemBlocks() {
414  $blockOptions = [
415  'address' => 'UTBlockee',
416  'reason' => 'test system block',
417  'timestamp' => wfTimestampNow(),
418  'expiry' => $this->db->getInfinity(),
419  'byText' => 'MetaWikiUser',
420  'systemBlock' => 'test',
421  'enableAutoblock' => true,
422  ];
423  $block = new Block( $blockOptions );
424 
425  $this->assertSame( 'test', $block->getSystemBlockType() );
426 
427  try {
428  $block->insert();
429  $this->fail( 'Expected exception not thrown' );
430  } catch ( MWException $ex ) {
431  $this->assertSame( 'Cannot insert a system block into the database', $ex->getMessage() );
432  }
433 
434  try {
435  $block->doAutoblock( '192.0.2.2' );
436  $this->fail( 'Expected exception not thrown' );
437  } catch ( MWException $ex ) {
438  $this->assertSame( 'Cannot autoblock from a system block', $ex->getMessage() );
439  }
440  }
441 }
Block\prevents
prevents( $action, $x=null)
Get/set whether the Block prevents a given action.
Definition: Block.php:1013
Block\isHardblock
isHardblock( $x=null)
Get/set whether the Block is a hardblock (affects logged-in users on a given IP/range)
Definition: Block.php:983
Block\getSystemBlockType
getSystemBlockType()
Get the system block type, if any.
Definition: Block.php:964
false
processing should stop and the error should be shown to the user * false
Definition: hooks.txt:189
Block\newFromID
static newFromID( $id)
Load a blocked user from their block id.
Definition: Block.php:184
Block\TYPE_IP
const TYPE_IP
Definition: Block.php:84
captcha-old.count
count
Definition: captcha-old.py:225
Block\TYPE_RANGE
const TYPE_RANGE
Definition: Block.php:85
Block\getBy
getBy()
Get the user id of the blocking sysop.
Definition: Block.php:933
Block\chooseBlock
static chooseBlock(array $blocks, array $ipChain)
From a list of multiple blocks, find the most exact and strongest Block.
Definition: Block.php:1234
wfTimestamp
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Definition: GlobalFunctions.php:1994
BlockTest\providerXff
static providerXff()
Definition: BlockTest.php:303
$user
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a account $user
Definition: hooks.txt:246
BlockTest\addDBData
addDBData()
Stub.
Definition: BlockTest.php:16
Block\newFromTarget
static newFromTarget( $specificTarget, $vagueTarget=null, $fromMaster=false)
Given a target and the target's type, get an existing Block object if possible.
Definition: Block.php:1113
User\newFromName
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
Definition: User.php:556
$res
$res
Definition: database.txt:21
BlockTest\addXffBlocks
addXffBlocks()
Definition: BlockTest.php:235
block
div flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException' returning false will NOT prevent logging a wrapping ErrorException instead of letting the login form give the generic error message that the account does not exist For when the account has been renamed or deleted or an array to pass a message key and parameters block
Definition: hooks.txt:2122
Block\insert
insert( $dbw=null)
Insert a block into the block table.
Definition: Block.php:473
php
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
BlockTest\testINewFromIDReturnsCorrectBlock
testINewFromIDReturnsCorrectBlock()
Block::newFromID.
Definition: BlockTest.php:79
BlockTest\testDeprecatedConstructor
testDeprecatedConstructor()
Definition: BlockTest.php:361
BlockTest\$blockId
$blockId
Definition: BlockTest.php:14
MWException
MediaWiki exception.
Definition: MWException.php:26
BlockTest
Database Blocking.
Definition: BlockTest.php:7
BlockTest\$madeAt
$madeAt
Definition: BlockTest.php:11
Block\doAutoblock
doAutoblock( $autoblockIP)
Autoblocks the given IP, referring to this Block.
Definition: Block.php:754
BlockTest\testBlockedUserCanNotCreateAccount
testBlockedUserCanNotCreateAccount()
Block::prevents.
Definition: BlockTest.php:127
MediaWikiTestCase\hideDeprecated
hideDeprecated( $function)
Don't throw a warning if $function is deprecated and called later.
Definition: MediaWikiTestCase.php:1413
wfTimestampNow
wfTimestampNow()
Convenience function; returns MediaWiki timestamp for the present time.
Definition: GlobalFunctions.php:2023
Block\isAutoblocking
isAutoblocking( $x=null)
Definition: Block.php:996
BlockTest\$block
Block $block
Definition: BlockTest.php:10
BlockTest\testCrappyCrossWikiBlocks
testCrappyCrossWikiBlocks()
Block::insert.
Definition: BlockTest.php:189
Block\getBlocksForIPList
static getBlocksForIPList(array $ipChain, $isAnon, $fromMaster=false)
Get all blocks that match any IP from an array of IP addresses.
Definition: Block.php:1153
TestUser\setPasswordForUser
static setPasswordForUser(User $user, $password)
Set the password on a testing user.
Definition: TestUser.php:127
Block\getBlocker
getBlocker()
Get the user who implemented this block.
Definition: Block.php:1439
Block\setBlocker
setBlocker( $user)
Set the user who implemented (or will implement) this block.
Definition: Block.php:1447
MediaWikiLangTestCase
Base class that store and restore the Language objects.
Definition: MediaWikiLangTestCase.php:6
Block\getTarget
getTarget()
Get the target for this particular Block.
Definition: Block.php:1414
BlockTest\dumpBlocks
dumpBlocks()
debug function : dump the ipblocks table
Definition: BlockTest.php:58
BlockTest\testINewFromTargetReturnsCorrectBlock
testINewFromTargetReturnsCorrectBlock()
Block::newFromTarget.
Definition: BlockTest.php:69
IP\sanitizeIP
static sanitizeIP( $ip)
Convert an IP into a verbose, uppercase, normalized form.
Definition: IP.php:140
BlockTest\testBug26425BlockTimestampDefaultsToTime
testBug26425BlockTimestampDefaultsToTime()
per T28425
Definition: BlockTest.php:89
as
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
Block
Definition: Block.php:27
BlockTest\testSystemBlocks
testSystemBlocks()
Definition: BlockTest.php:413
Block\getByName
getByName()
Get the username of the blocking sysop.
Definition: Block.php:945
BlockTest\testBlocksOnXff
testBlocksOnXff( $xff, $exCount, $exResult)
providerXff Block::getBlocksForIPList Block::chooseBlock
Definition: BlockTest.php:353
$username
this hook is for auditing only or null if authentication failed before getting that far $username
Definition: hooks.txt:783
IP\sanitizeRange
static sanitizeRange( $range)
Gets rid of unneeded numbers in quad-dotted/octet IP strings For example, 127.111....
Definition: IP.php:713
Block\setTarget
setTarget( $target)
Set the target for this block, and update $this->type accordingly.
Definition: Block.php:1431
BlockTest\testBug29116NewFromTargetWithEmptyIp
testBug29116NewFromTargetWithEmptyIp( $vagueTarget)
CheckUser since being changed to use Block::newFromTarget started failing because the new function di...
Definition: BlockTest.php:107
BlockTest\provideBug29116Data
static provideBug29116Data()
Definition: BlockTest.php:116