MediaWiki  1.32.0
BlockTest.php
Go to the documentation of this file.
1 <?php
2 
8 
12  private function getUserForBlocking() {
13  $testUser = $this->getMutableTestUser();
14  $user = $testUser->getUser();
15  $user->addToDatabase();
16  TestUser::setPasswordForUser( $user, 'UTBlockeePassword' );
17  $user->saveSettings();
18  return $user;
19  }
20 
27  private function addBlockForUser( User $user ) {
28  // Delete the last round's block if it's still there
29  $oldBlock = Block::newFromTarget( $user->getName() );
30  if ( $oldBlock ) {
31  // An old block will prevent our new one from saving.
32  $oldBlock->delete();
33  }
34 
35  $blockOptions = [
36  'address' => $user->getName(),
37  'user' => $user->getId(),
38  'by' => $this->getTestSysop()->getUser()->getId(),
39  'reason' => 'Parce que',
40  'expiry' => time() + 100500,
41  ];
42  $block = new Block( $blockOptions );
43 
44  $block->insert();
45  // save up ID for use in assertion. Since ID is an autoincrement,
46  // its value might change depending on the order the tests are run.
47  // ApiBlockTest insert its own blocks!
48  if ( !$block->getId() ) {
49  throw new MWException( "Failed to insert block for BlockTest; old leftover block remaining?" );
50  }
51 
52  $this->addXffBlocks();
53 
54  return $block;
55  }
56 
61  $user = $this->getUserForBlocking();
62  $block = $this->addBlockForUser( $user );
63 
64  $this->assertTrue(
65  $block->equals( Block::newFromTarget( $user->getName() ) ),
66  "newFromTarget() returns the same block as the one that was made"
67  );
68  }
69 
74  $user = $this->getUserForBlocking();
75  $block = $this->addBlockForUser( $user );
76 
77  $this->assertTrue(
78  $block->equals( Block::newFromID( $block->getId() ) ),
79  "newFromID() returns the same block as the one that was made"
80  );
81  }
82 
88  $user = $this->getUserForBlocking();
89  $block = $this->addBlockForUser( $user );
90  $madeAt = wfTimestamp( TS_MW );
91 
92  // delta to stop one-off errors when things happen to go over a second mark.
93  $delta = abs( $madeAt - $block->mTimestamp );
94  $this->assertLessThan(
95  2,
96  $delta,
97  "If no timestamp is specified, the block is recorded as time()"
98  );
99  }
100 
109  public function testT31116NewFromTargetWithEmptyIp( $vagueTarget ) {
110  $user = $this->getUserForBlocking();
111  $initialBlock = $this->addBlockForUser( $user );
112  $block = Block::newFromTarget( $user->getName(), $vagueTarget );
113 
114  $this->assertTrue(
115  $initialBlock->equals( $block ),
116  "newFromTarget() returns the same block as the one that was made when "
117  . "given empty vagueTarget param " . var_export( $vagueTarget, true )
118  );
119  }
120 
121  public static function provideT31116Data() {
122  return [
123  [ null ],
124  [ '' ],
125  [ false ]
126  ];
127  }
128 
133  $username = 'BlockedUserToCreateAccountWith';
135  $u->addToDatabase();
136  $userId = $u->getId();
137  $this->assertNotEquals( 0, $userId, 'sanity' );
138  TestUser::setPasswordForUser( $u, 'NotRandomPass' );
139  unset( $u );
140 
141  // Sanity check
142  $this->assertNull(
144  "$username should not be blocked"
145  );
146 
147  // Reload user
149  $this->assertFalse(
150  $u->isBlockedFromCreateAccount(),
151  "Our sandbox user should be able to create account before being blocked"
152  );
153 
154  // Foreign perspective (blockee not on current wiki)...
155  $blockOptions = [
156  'address' => $username,
157  'user' => $userId,
158  'reason' => 'crosswiki block...',
159  'timestamp' => wfTimestampNow(),
160  'expiry' => $this->db->getInfinity(),
161  'createAccount' => true,
162  'enableAutoblock' => true,
163  'hideName' => true,
164  'blockEmail' => true,
165  'byText' => 'm>MetaWikiUser',
166  ];
167  $block = new Block( $blockOptions );
168  $block->insert();
169 
170  // Reload block from DB
171  $userBlock = Block::newFromTarget( $username );
172  $this->assertTrue(
173  (bool)$block->prevents( 'createaccount' ),
174  "Block object in DB should prevents 'createaccount'"
175  );
176 
177  $this->assertInstanceOf(
178  Block::class,
179  $userBlock,
180  "'$username' block block object should be existent"
181  );
182 
183  // Reload user
185  $this->assertTrue(
186  (bool)$u->isBlockedFromCreateAccount(),
187  "Our sandbox user '$username' should NOT be able to create account"
188  );
189  }
190 
194  public function testCrappyCrossWikiBlocks() {
195  // Delete the last round's block if it's still there
196  $oldBlock = Block::newFromTarget( 'UserOnForeignWiki' );
197  if ( $oldBlock ) {
198  // An old block will prevent our new one from saving.
199  $oldBlock->delete();
200  }
201 
202  // Local perspective (blockee on current wiki)...
203  $user = User::newFromName( 'UserOnForeignWiki' );
204  $user->addToDatabase();
205  $userId = $user->getId();
206  $this->assertNotEquals( 0, $userId, 'sanity' );
207 
208  // Foreign perspective (blockee not on current wiki)...
209  $blockOptions = [
210  'address' => 'UserOnForeignWiki',
211  'user' => $user->getId(),
212  'reason' => 'crosswiki block...',
213  'timestamp' => wfTimestampNow(),
214  'expiry' => $this->db->getInfinity(),
215  'createAccount' => true,
216  'enableAutoblock' => true,
217  'hideName' => true,
218  'blockEmail' => true,
219  'byText' => 'Meta>MetaWikiUser',
220  ];
221  $block = new Block( $blockOptions );
222 
223  $res = $block->insert( $this->db );
224  $this->assertTrue( (bool)$res['id'], 'Block succeeded' );
225 
226  $user = null; // clear
227 
228  $block = Block::newFromID( $res['id'] );
229  $this->assertEquals(
230  'UserOnForeignWiki',
231  $block->getTarget()->getName(),
232  'Correct blockee name'
233  );
234  $this->assertEquals( $userId, $block->getTarget()->getId(), 'Correct blockee id' );
235  $this->assertEquals( 'Meta>MetaWikiUser', $block->getBlocker()->getName(),
236  'Correct blocker name' );
237  $this->assertEquals( 'Meta>MetaWikiUser', $block->getByName(), 'Correct blocker name' );
238  $this->assertEquals( 0, $block->getBy(), 'Correct blocker id' );
239  }
240 
241  protected function addXffBlocks() {
242  static $inited = false;
243 
244  if ( $inited ) {
245  return;
246  }
247 
248  $inited = true;
249 
250  $blockList = [
251  [ 'target' => '70.2.0.0/16',
252  'type' => Block::TYPE_RANGE,
253  'desc' => 'Range Hardblock',
254  'ACDisable' => false,
255  'isHardblock' => true,
256  'isAutoBlocking' => false,
257  ],
258  [ 'target' => '2001:4860:4001::/48',
259  'type' => Block::TYPE_RANGE,
260  'desc' => 'Range6 Hardblock',
261  'ACDisable' => false,
262  'isHardblock' => true,
263  'isAutoBlocking' => false,
264  ],
265  [ 'target' => '60.2.0.0/16',
266  'type' => Block::TYPE_RANGE,
267  'desc' => 'Range Softblock with AC Disabled',
268  'ACDisable' => true,
269  'isHardblock' => false,
270  'isAutoBlocking' => false,
271  ],
272  [ 'target' => '50.2.0.0/16',
273  'type' => Block::TYPE_RANGE,
274  'desc' => 'Range Softblock',
275  'ACDisable' => false,
276  'isHardblock' => false,
277  'isAutoBlocking' => false,
278  ],
279  [ 'target' => '50.1.1.1',
280  'type' => Block::TYPE_IP,
281  'desc' => 'Exact Softblock',
282  'ACDisable' => false,
283  'isHardblock' => false,
284  'isAutoBlocking' => false,
285  ],
286  ];
287 
288  $blocker = $this->getTestUser()->getUser();
289  foreach ( $blockList as $insBlock ) {
290  $target = $insBlock['target'];
291 
292  if ( $insBlock['type'] === Block::TYPE_IP ) {
293  $target = User::newFromName( IP::sanitizeIP( $target ), false )->getName();
294  } elseif ( $insBlock['type'] === Block::TYPE_RANGE ) {
295  $target = IP::sanitizeRange( $target );
296  }
297 
298  $block = new Block();
299  $block->setTarget( $target );
300  $block->setBlocker( $blocker );
301  $block->mReason = $insBlock['desc'];
302  $block->mExpiry = 'infinity';
303  $block->prevents( 'createaccount', $insBlock['ACDisable'] );
304  $block->isHardblock( $insBlock['isHardblock'] );
305  $block->isAutoblocking( $insBlock['isAutoBlocking'] );
306  $block->insert();
307  }
308  }
309 
310  public static function providerXff() {
311  return [
312  [ 'xff' => '1.2.3.4, 70.2.1.1, 60.2.1.1, 2.3.4.5',
313  'count' => 2,
314  'result' => 'Range Hardblock'
315  ],
316  [ 'xff' => '1.2.3.4, 50.2.1.1, 60.2.1.1, 2.3.4.5',
317  'count' => 2,
318  'result' => 'Range Softblock with AC Disabled'
319  ],
320  [ 'xff' => '1.2.3.4, 70.2.1.1, 50.1.1.1, 2.3.4.5',
321  'count' => 2,
322  'result' => 'Exact Softblock'
323  ],
324  [ 'xff' => '1.2.3.4, 70.2.1.1, 50.2.1.1, 50.1.1.1, 2.3.4.5',
325  'count' => 3,
326  'result' => 'Exact Softblock'
327  ],
328  [ 'xff' => '1.2.3.4, 70.2.1.1, 50.2.1.1, 2.3.4.5',
329  'count' => 2,
330  'result' => 'Range Hardblock'
331  ],
332  [ 'xff' => '1.2.3.4, 70.2.1.1, 60.2.1.1, 2.3.4.5',
333  'count' => 2,
334  'result' => 'Range Hardblock'
335  ],
336  [ 'xff' => '50.2.1.1, 60.2.1.1, 2.3.4.5',
337  'count' => 2,
338  'result' => 'Range Softblock with AC Disabled'
339  ],
340  [ 'xff' => '1.2.3.4, 50.1.1.1, 60.2.1.1, 2.3.4.5',
341  'count' => 2,
342  'result' => 'Exact Softblock'
343  ],
344  [ 'xff' => '1.2.3.4, <$A_BUNCH-OF{INVALID}TEXT>, 60.2.1.1, 2.3.4.5',
345  'count' => 1,
346  'result' => 'Range Softblock with AC Disabled'
347  ],
348  [ 'xff' => '1.2.3.4, 50.2.1.1, 2001:4860:4001:802::1003, 2.3.4.5',
349  'count' => 2,
350  'result' => 'Range6 Hardblock'
351  ],
352  ];
353  }
354 
360  public function testBlocksOnXff( $xff, $exCount, $exResult ) {
361  $user = $this->getUserForBlocking();
362  $this->addBlockForUser( $user );
363 
364  $list = array_map( 'trim', explode( ',', $xff ) );
365  $xffblocks = Block::getBlocksForIPList( $list, true );
366  $this->assertEquals( $exCount, count( $xffblocks ), 'Number of blocks for ' . $xff );
367  $block = Block::chooseBlock( $xffblocks, $list );
368  $this->assertEquals( $exResult, $block->mReason, 'Correct block type for XFF header ' . $xff );
369  }
370 
374  public function testDeprecatedConstructor() {
375  $this->hideDeprecated( 'Block::__construct with multiple arguments' );
376  $username = 'UnthinkablySecretRandomUsername';
377  $reason = 'being irrational';
378 
379  # Set up the target
381  if ( $u->getId() == 0 ) {
382  $u->addToDatabase();
383  TestUser::setPasswordForUser( $u, 'TotallyObvious' );
384  }
385  unset( $u );
386 
387  # Make sure the user isn't blocked
388  $this->assertNull(
390  "$username should not be blocked"
391  );
392 
393  # Perform the block
394  $block = new Block(
395  /* address */ $username,
396  /* user */ 0,
397  /* by */ $this->getTestSysop()->getUser()->getId(),
398  /* reason */ $reason,
399  /* timestamp */ 0,
400  /* auto */ false,
401  /* expiry */ 0
402  );
403  $block->insert();
404 
405  # Check target
406  $this->assertEquals(
407  $block->getTarget()->getName(),
408  $username,
409  "Target should be set properly"
410  );
411 
412  # Check supplied parameter
413  $this->assertEquals(
414  $block->mReason,
415  $reason,
416  "Reason should be non-default"
417  );
418 
419  # Check default parameter
420  $this->assertFalse(
421  (bool)$block->prevents( 'createaccount' ),
422  "Account creation should not be blocked by default"
423  );
424  }
425 
431  public function testSystemBlocks() {
432  $user = $this->getUserForBlocking();
433  $this->addBlockForUser( $user );
434 
435  $blockOptions = [
436  'address' => $user->getName(),
437  'reason' => 'test system block',
438  'timestamp' => wfTimestampNow(),
439  'expiry' => $this->db->getInfinity(),
440  'byText' => 'MediaWiki default',
441  'systemBlock' => 'test',
442  'enableAutoblock' => true,
443  ];
444  $block = new Block( $blockOptions );
445 
446  $this->assertSame( 'test', $block->getSystemBlockType() );
447 
448  try {
449  $block->insert();
450  $this->fail( 'Expected exception not thrown' );
451  } catch ( MWException $ex ) {
452  $this->assertSame( 'Cannot insert a system block into the database', $ex->getMessage() );
453  }
454 
455  try {
456  $block->doAutoblock( '192.0.2.2' );
457  $this->fail( 'Expected exception not thrown' );
458  } catch ( MWException $ex ) {
459  $this->assertSame( 'Cannot autoblock from a system block', $ex->getMessage() );
460  }
461  }
462 
463 }
$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:244
false
processing should stop and the error should be shown to the user * false
Definition: hooks.txt:187
MediaWikiTestCase\getTestUser
static getTestUser( $groups=[])
Convenience method for getting an immutable test user.
Definition: MediaWikiTestCase.php:179
BlockTest\getUserForBlocking
getUserForBlocking()
Definition: BlockTest.php:12
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:249
Block\TYPE_RANGE
const TYPE_RANGE
Definition: Block.php:85
Block\chooseBlock
static chooseBlock(array $blocks, array $ipChain)
From a list of multiple blocks, find the most exact and strongest Block.
Definition: Block.php:1294
wfTimestamp
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Definition: GlobalFunctions.php:1954
BlockTest\providerXff
static providerXff()
Definition: BlockTest.php:310
BlockTest\testT28425BlockTimestampDefaultsToTime
testT28425BlockTimestampDefaultsToTime()
per T28425 Block::__construct
Definition: BlockTest.php:87
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:1174
User\newFromName
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
Definition: User.php:592
$res
$res
Definition: database.txt:21
BlockTest\addXffBlocks
addXffBlocks()
Definition: BlockTest.php:241
BlockTest\provideT31116Data
static provideT31116Data()
Definition: BlockTest.php:121
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:73
BlockTest\testDeprecatedConstructor
testDeprecatedConstructor()
Block::__construct.
Definition: BlockTest.php:374
MWException
MediaWiki exception.
Definition: MWException.php:26
BlockTest\testT31116NewFromTargetWithEmptyIp
testT31116NewFromTargetWithEmptyIp( $vagueTarget)
CheckUser since being changed to use Block::newFromTarget started failing because the new function di...
Definition: BlockTest.php:109
BlockTest
Database Blocking.
Definition: BlockTest.php:7
BlockTest\testBlockedUserCanNotCreateAccount
testBlockedUserCanNotCreateAccount()
Block::prevents.
Definition: BlockTest.php:132
MediaWikiTestCase\hideDeprecated
hideDeprecated( $function)
Don't throw a warning if $function is deprecated and called later.
Definition: MediaWikiTestCase.php:1940
wfTimestampNow
wfTimestampNow()
Convenience function; returns MediaWiki timestamp for the present time.
Definition: GlobalFunctions.php:1983
BlockTest\testCrappyCrossWikiBlocks
testCrappyCrossWikiBlocks()
Block::insert.
Definition: BlockTest.php:194
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:1213
TestUser\setPasswordForUser
static setPasswordForUser(User $user, $password)
Set the password on a testing user.
Definition: TestUser.php:129
MediaWikiTestCase\getMutableTestUser
static getMutableTestUser( $groups=[])
Convenience method for getting a mutable test user.
Definition: MediaWikiTestCase.php:191
MediaWikiTestCase\getTestSysop
static getTestSysop()
Convenience method for getting an immutable admin test user.
Definition: MediaWikiTestCase.php:203
MediaWikiLangTestCase
Base class that store and restore the Language objects.
Definition: MediaWikiLangTestCase.php:8
BlockTest\addBlockForUser
addBlockForUser(User $user)
Definition: BlockTest.php:27
BlockTest\testINewFromTargetReturnsCorrectBlock
testINewFromTargetReturnsCorrectBlock()
Block::newFromTarget.
Definition: BlockTest.php:60
IP\sanitizeIP
static sanitizeIP( $ip)
Convert an IP into a verbose, uppercase, normalized form.
Definition: IP.php:152
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()
@covers Block::getSystemBlockType @covers Block::insert @covers Block::doAutoblock
Definition: BlockTest.php:431
class
you have access to all of the normal MediaWiki so you can get a DB use the etc For full docs on the Maintenance class
Definition: maintenance.txt:52
BlockTest\testBlocksOnXff
testBlocksOnXff( $xff, $exCount, $exResult)
providerXff Block::getBlocksForIPList Block::chooseBlock
Definition: BlockTest.php:360
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:47
$username
this hook is for auditing only or null if authentication failed before getting that far $username
Definition: hooks.txt:813
IP\sanitizeRange
static sanitizeRange( $range)
Gets rid of unneeded numbers in quad-dotted/octet IP strings For example, 127.111....
Definition: IP.php:725