Merge "Type hint against LinkTarget in WatchedItemStore"
[lhc/web/wiklou.git] / tests / phpunit / includes / Permissions / PermissionManagerTest.php
1 <?php
2
3 namespace MediaWiki\Tests\Permissions;
4
5 use Action;
6 use ContentHandler;
7 use FauxRequest;
8 use MediaWiki\Block\DatabaseBlock;
9 use MediaWiki\Block\Restriction\NamespaceRestriction;
10 use MediaWiki\Block\Restriction\PageRestriction;
11 use MediaWiki\Block\SystemBlock;
12 use MediaWiki\Linker\LinkTarget;
13 use MediaWiki\MediaWikiServices;
14 use MediaWiki\Permissions\PermissionManager;
15 use MediaWiki\Revision\MutableRevisionRecord;
16 use MediaWiki\Revision\RevisionLookup;
17 use Wikimedia\ScopedCallback;
18 use MediaWiki\Session\SessionId;
19 use MediaWiki\Session\TestUtils;
20 use MediaWikiLangTestCase;
21 use RequestContext;
22 use stdClass;
23 use Title;
24 use User;
25 use Wikimedia\TestingAccessWrapper;
26
27 /**
28 * @group Database
29 *
30 * @covers \MediaWiki\Permissions\PermissionManager
31 */
32 class PermissionManagerTest extends MediaWikiLangTestCase {
33
34 /**
35 * @var string
36 */
37 protected $userName, $altUserName;
38
39 /**
40 * @var Title
41 */
42 protected $title;
43
44 /**
45 * @var User
46 */
47 protected $user, $anonUser, $userUser, $altUser;
48
49 /** Constant for self::testIsBlockedFrom */
50 const USER_TALK_PAGE = '<user talk page>';
51
52 protected function setUp() {
53 parent::setUp();
54
55 $localZone = 'UTC';
56 $localOffset = date( 'Z' ) / 60;
57
58 $this->setMwGlobals( [
59 'wgLocaltimezone' => $localZone,
60 'wgLocalTZoffset' => $localOffset,
61 'wgNamespaceProtection' => [
62 NS_MEDIAWIKI => 'editinterface',
63 ],
64 'wgRevokePermissions' => [
65 'formertesters' => [
66 'runtest' => true
67 ]
68 ],
69 'wgAvailableRights' => [
70 'test',
71 'runtest',
72 'writetest',
73 'nukeworld',
74 'modifytest',
75 'editmyoptions'
76 ]
77 ] );
78
79 $this->setGroupPermissions( 'unittesters', 'test', true );
80 $this->setGroupPermissions( 'unittesters', 'runtest', true );
81 $this->setGroupPermissions( 'unittesters', 'writetest', false );
82 $this->setGroupPermissions( 'unittesters', 'nukeworld', false );
83
84 $this->setGroupPermissions( 'testwriters', 'test', true );
85 $this->setGroupPermissions( 'testwriters', 'writetest', true );
86 $this->setGroupPermissions( 'testwriters', 'modifytest', true );
87
88 $this->setGroupPermissions( '*', 'editmyoptions', true );
89
90 // Without this testUserBlock will use a non-English context on non-English MediaWiki
91 // installations (because of how Title::checkUserBlock is implemented) and fail.
92 RequestContext::resetMain();
93
94 $this->userName = 'Useruser';
95 $this->altUserName = 'Altuseruser';
96 date_default_timezone_set( $localZone );
97
98 $this->title = Title::makeTitle( NS_MAIN, "Main Page" );
99 if ( !isset( $this->userUser ) || !( $this->userUser instanceof User ) ) {
100 $this->userUser = User::newFromName( $this->userName );
101
102 if ( !$this->userUser->getId() ) {
103 $this->userUser = User::createNew( $this->userName, [
104 "email" => "test@example.com",
105 "real_name" => "Test User" ] );
106 $this->userUser->load();
107 }
108
109 $this->altUser = User::newFromName( $this->altUserName );
110 if ( !$this->altUser->getId() ) {
111 $this->altUser = User::createNew( $this->altUserName, [
112 "email" => "alttest@example.com",
113 "real_name" => "Test User Alt" ] );
114 $this->altUser->load();
115 }
116
117 $this->anonUser = User::newFromId( 0 );
118
119 $this->user = $this->userUser;
120 }
121
122 $this->resetServices();
123 }
124
125 public function tearDown() {
126 parent::tearDown();
127 $this->restoreMwServices();
128 }
129
130 protected function setTitle( $ns, $title = "Main_Page" ) {
131 $this->title = Title::makeTitle( $ns, $title );
132 }
133
134 protected function setUser( $userName = null ) {
135 if ( $userName === 'anon' ) {
136 $this->user = $this->anonUser;
137 } elseif ( $userName === null || $userName === $this->userName ) {
138 $this->user = $this->userUser;
139 } else {
140 $this->user = $this->altUser;
141 }
142 $this->resetServices();
143 }
144
145 /**
146 * @todo This test method should be split up into separate test methods and
147 * data providers
148 *
149 * This test is failing per T201776.
150 *
151 * @group Broken
152 * @covers \MediaWiki\Permissions\PermissionManager::checkQuickPermissions
153 */
154 public function testQuickPermissions() {
155 $prefix = MediaWikiServices::getInstance()->getContentLanguage()->
156 getFormattedNsText( NS_PROJECT );
157
158 $this->setUser( 'anon' );
159 $this->setTitle( NS_TALK );
160 $this->overrideUserPermissions( $this->user, "createtalk" );
161 $res = MediaWikiServices::getInstance()->getPermissionManager()
162 ->getPermissionErrors( 'create', $this->user, $this->title );
163 $this->assertEquals( [], $res );
164
165 $this->setTitle( NS_TALK );
166 $this->overrideUserPermissions( $this->user, "createpage" );
167 $res = MediaWikiServices::getInstance()->getPermissionManager()
168 ->getPermissionErrors( 'create', $this->user, $this->title );
169 $this->assertEquals( [ [ "nocreatetext" ] ], $res );
170
171 $this->setTitle( NS_TALK );
172 $this->overrideUserPermissions( $this->user, "" );
173 $res = MediaWikiServices::getInstance()->getPermissionManager()
174 ->getPermissionErrors( 'create', $this->user, $this->title );
175 $this->assertEquals( [ [ 'nocreatetext' ] ], $res );
176
177 $this->setTitle( NS_MAIN );
178 $this->overrideUserPermissions( $this->user, "createpage" );
179 $res = MediaWikiServices::getInstance()->getPermissionManager()
180 ->getPermissionErrors( 'create', $this->user, $this->title );
181 $this->assertEquals( [], $res );
182
183 $this->setTitle( NS_MAIN );
184 $this->overrideUserPermissions( $this->user, "createtalk" );
185 $res = MediaWikiServices::getInstance()->getPermissionManager()
186 ->getPermissionErrors( 'create', $this->user, $this->title );
187 $this->assertEquals( [ [ 'nocreatetext' ] ], $res );
188
189 $this->setUser( $this->userName );
190 $this->setTitle( NS_TALK );
191 $this->overrideUserPermissions( $this->user, "createtalk" );
192 $res = MediaWikiServices::getInstance()->getPermissionManager()
193 ->getPermissionErrors( 'create', $this->user, $this->title );
194 $this->assertEquals( [], $res );
195
196 $this->setTitle( NS_TALK );
197 $this->overrideUserPermissions( $this->user, "createpage" );
198 $res = MediaWikiServices::getInstance()->getPermissionManager()
199 ->getPermissionErrors( 'create', $this->user, $this->title );
200 $this->assertEquals( [ [ 'nocreate-loggedin' ] ], $res );
201
202 $this->setTitle( NS_TALK );
203 $this->overrideUserPermissions( $this->user, "" );
204 $res = MediaWikiServices::getInstance()->getPermissionManager()
205 ->getPermissionErrors( 'create', $this->user, $this->title );
206 $this->assertEquals( [ [ 'nocreate-loggedin' ] ], $res );
207
208 $this->setTitle( NS_MAIN );
209 $this->overrideUserPermissions( $this->user, "createpage" );
210 $res = MediaWikiServices::getInstance()->getPermissionManager()
211 ->getPermissionErrors( 'create', $this->user, $this->title );
212 $this->assertEquals( [], $res );
213
214 $this->setTitle( NS_MAIN );
215 $this->overrideUserPermissions( $this->user, "createtalk" );
216 $res = MediaWikiServices::getInstance()->getPermissionManager()
217 ->getPermissionErrors( 'create', $this->user, $this->title );
218 $this->assertEquals( [ [ 'nocreate-loggedin' ] ], $res );
219
220 $this->setTitle( NS_MAIN );
221 $this->overrideUserPermissions( $this->user, "" );
222 $res = MediaWikiServices::getInstance()->getPermissionManager()
223 ->getPermissionErrors( 'create', $this->user, $this->title );
224 $this->assertEquals( [ [ 'nocreate-loggedin' ] ], $res );
225
226 $this->setUser( 'anon' );
227 $this->setTitle( NS_USER, $this->userName . '' );
228 $this->overrideUserPermissions( $this->user, "" );
229 $res = MediaWikiServices::getInstance()->getPermissionManager()
230 ->getPermissionErrors( 'move', $this->user, $this->title );
231 $this->assertEquals( [ [ 'cant-move-user-page' ], [ 'movenologintext' ] ], $res );
232
233 $this->setTitle( NS_USER, $this->userName . '/subpage' );
234 $this->overrideUserPermissions( $this->user, "" );
235 $res = MediaWikiServices::getInstance()->getPermissionManager()
236 ->getPermissionErrors( 'move', $this->user, $this->title );
237 $this->assertEquals( [ [ 'movenologintext' ] ], $res );
238
239 $this->setTitle( NS_USER, $this->userName . '' );
240 $this->overrideUserPermissions( $this->user, "move-rootuserpages" );
241 $res = MediaWikiServices::getInstance()->getPermissionManager()
242 ->getPermissionErrors( 'move', $this->user, $this->title );
243 $this->assertEquals( [ [ 'movenologintext' ] ], $res );
244
245 $this->setTitle( NS_USER, $this->userName . '/subpage' );
246 $this->overrideUserPermissions( $this->user, "move-rootuserpages" );
247 $res = MediaWikiServices::getInstance()->getPermissionManager()
248 ->getPermissionErrors( 'move', $this->user, $this->title );
249 $this->assertEquals( [ [ 'movenologintext' ] ], $res );
250
251 $this->setTitle( NS_USER, $this->userName . '' );
252 $this->overrideUserPermissions( $this->user, "" );
253 $res = MediaWikiServices::getInstance()->getPermissionManager()
254 ->getPermissionErrors( 'move', $this->user, $this->title );
255 $this->assertEquals( [ [ 'cant-move-user-page' ], [ 'movenologintext' ] ], $res );
256
257 $this->setTitle( NS_USER, $this->userName . '/subpage' );
258 $this->overrideUserPermissions( $this->user, "" );
259 $res = MediaWikiServices::getInstance()->getPermissionManager()
260 ->getPermissionErrors( 'move', $this->user, $this->title );
261 $this->assertEquals( [ [ 'movenologintext' ] ], $res );
262
263 $this->setTitle( NS_USER, $this->userName . '' );
264 $this->overrideUserPermissions( $this->user, "move-rootuserpages" );
265 $res = MediaWikiServices::getInstance()->getPermissionManager()
266 ->getPermissionErrors( 'move', $this->user, $this->title );
267 $this->assertEquals( [ [ 'movenologintext' ] ], $res );
268
269 $this->setTitle( NS_USER, $this->userName . '/subpage' );
270 $this->overrideUserPermissions( $this->user, "move-rootuserpages" );
271 $res = MediaWikiServices::getInstance()->getPermissionManager()
272 ->getPermissionErrors( 'move', $this->user, $this->title );
273 $this->assertEquals( [ [ 'movenologintext' ] ], $res );
274
275 $this->setUser( $this->userName );
276 $this->setTitle( NS_FILE, "img.png" );
277 $this->overrideUserPermissions( $this->user, "" );
278 $res = MediaWikiServices::getInstance()->getPermissionManager()
279 ->getPermissionErrors( 'move', $this->user, $this->title );
280 $this->assertEquals( [ [ 'movenotallowedfile' ], [ 'movenotallowed' ] ], $res );
281
282 $this->setTitle( NS_FILE, "img.png" );
283 $this->overrideUserPermissions( $this->user, "movefile" );
284 $res = MediaWikiServices::getInstance()->getPermissionManager()
285 ->getPermissionErrors( 'move', $this->user, $this->title );
286 $this->assertEquals( [ [ 'movenotallowed' ] ], $res );
287
288 $this->setUser( 'anon' );
289 $this->setTitle( NS_FILE, "img.png" );
290 $this->overrideUserPermissions( $this->user, "" );
291 $res = MediaWikiServices::getInstance()->getPermissionManager()
292 ->getPermissionErrors( 'move', $this->user, $this->title );
293 $this->assertEquals( [ [ 'movenotallowedfile' ], [ 'movenologintext' ] ], $res );
294
295 $this->setTitle( NS_FILE, "img.png" );
296 $this->overrideUserPermissions( $this->user, "movefile" );
297 $res = MediaWikiServices::getInstance()->getPermissionManager()
298 ->getPermissionErrors( 'move', $this->user, $this->title );
299 $this->assertEquals( [ [ 'movenologintext' ] ], $res );
300
301 $this->setUser( $this->userName );
302 // $this->setUserPerm( "move" );
303 $this->runGroupPermissions( 'move', 'move', [ [ 'movenotallowedfile' ] ] );
304
305 // $this->setUserPerm( "" );
306 $this->runGroupPermissions(
307 '',
308 'move',
309 [ [ 'movenotallowedfile' ], [ 'movenotallowed' ] ]
310 );
311
312 $this->setUser( 'anon' );
313 //$this->setUserPerm( "move" );
314 $this->runGroupPermissions( 'move', 'move', [ [ 'movenotallowedfile' ] ] );
315
316 // $this->setUserPerm( "" );
317 $this->runGroupPermissions(
318 '',
319 'move',
320 [ [ 'movenotallowedfile' ], [ 'movenotallowed' ] ],
321 [ [ 'movenotallowedfile' ], [ 'movenologintext' ] ]
322 );
323
324 if ( $this->isWikitextNS( NS_MAIN ) ) {
325 // NOTE: some content models don't allow moving
326 // @todo find a Wikitext namespace for testing
327
328 $this->setTitle( NS_MAIN );
329 $this->setUser( 'anon' );
330 // $this->setUserPerm( "move" );
331 $this->runGroupPermissions( 'move', 'move', [] );
332
333 // $this->setUserPerm( "" );
334 $this->runGroupPermissions( '', 'move', [ [ 'movenotallowed' ] ],
335 [ [ 'movenologintext' ] ] );
336
337 $this->setUser( $this->userName );
338 // $this->setUserPerm( "" );
339 $this->runGroupPermissions( '', 'move', [ [ 'movenotallowed' ] ] );
340
341 //$this->setUserPerm( "move" );
342 $this->runGroupPermissions( 'move', 'move', [] );
343
344 $this->setUser( 'anon' );
345 $this->overrideUserPermissions( $this->user, 'move' );
346 $res = MediaWikiServices::getInstance()->getPermissionManager()
347 ->getPermissionErrors( 'move-target', $this->user, $this->title );
348 $this->assertEquals( [], $res );
349
350 $this->overrideUserPermissions( $this->user, '' );
351 $res = MediaWikiServices::getInstance()->getPermissionManager()
352 ->getPermissionErrors( 'move-target', $this->user, $this->title );
353 $this->assertEquals( [ [ 'movenotallowed' ] ], $res );
354 }
355
356 $this->setTitle( NS_USER );
357 $this->setUser( $this->userName );
358 $this->overrideUserPermissions( $this->user, [ "move", "move-rootuserpages" ] );
359 $res = MediaWikiServices::getInstance()->getPermissionManager()
360 ->getPermissionErrors( 'move-target', $this->user, $this->title );
361 $this->assertEquals( [], $res );
362
363 $this->overrideUserPermissions( $this->user, "move" );
364 $res = MediaWikiServices::getInstance()->getPermissionManager()
365 ->getPermissionErrors( 'move-target', $this->user, $this->title );
366 $this->assertEquals( [ [ 'cant-move-to-user-page' ] ], $res );
367
368 $this->setUser( 'anon' );
369 $this->overrideUserPermissions( $this->user, [ "move", "move-rootuserpages" ] );
370 $res = MediaWikiServices::getInstance()->getPermissionManager()
371 ->getPermissionErrors( 'move-target', $this->user, $this->title );
372 $this->assertEquals( [], $res );
373
374 $this->setTitle( NS_USER, "User/subpage" );
375 $this->overrideUserPermissions( $this->user, [ "move", "move-rootuserpages" ] );
376 $res = MediaWikiServices::getInstance()->getPermissionManager()
377 ->getPermissionErrors( 'move-target', $this->user, $this->title );
378 $this->assertEquals( [], $res );
379
380 $this->overrideUserPermissions( $this->user, "move" );
381 $res = MediaWikiServices::getInstance()->getPermissionManager()
382 ->getPermissionErrors( 'move-target', $this->user, $this->title );
383 $this->assertEquals( [], $res );
384
385 $this->setUser( 'anon' );
386 $check = [
387 'edit' => [
388 [ [ 'badaccess-groups', "*, [[$prefix:Users|Users]]", 2 ] ],
389 [ [ 'badaccess-group0' ] ],
390 [],
391 true
392 ],
393 'protect' => [
394 [ [
395 'badaccess-groups',
396 "[[$prefix:Administrators|Administrators]]", 1 ],
397 [ 'protect-cantedit'
398 ] ],
399 [ [ 'badaccess-group0' ], [ 'protect-cantedit' ] ],
400 [ [ 'protect-cantedit' ] ],
401 false
402 ],
403 '' => [ [], [], [], true ]
404 ];
405
406 foreach ( [ "edit", "protect", "" ] as $action ) {
407 $this->overrideUserPermissions( $this->user );
408 $this->assertEquals( $check[$action][0],
409 MediaWikiServices::getInstance()->getPermissionManager()
410 ->getPermissionErrors( $action, $this->user, $this->title, true ) );
411 $this->assertEquals( $check[$action][0],
412 MediaWikiServices::getInstance()->getPermissionManager()
413 ->getPermissionErrors( $action, $this->user, $this->title, 'full' ) );
414 $this->assertEquals( $check[$action][0],
415 MediaWikiServices::getInstance()->getPermissionManager()
416 ->getPermissionErrors( $action, $this->user, $this->title, 'secure' ) );
417
418 global $wgGroupPermissions;
419 $old = $wgGroupPermissions;
420 $wgGroupPermissions = [];
421 $this->resetServices();
422
423 $this->assertEquals( $check[$action][1],
424 MediaWikiServices::getInstance()->getPermissionManager()
425 ->getPermissionErrors( $action, $this->user, $this->title, true ) );
426 $this->assertEquals( $check[$action][1],
427 MediaWikiServices::getInstance()->getPermissionManager()
428 ->getPermissionErrors( $action, $this->user, $this->title, 'full' ) );
429 $this->assertEquals( $check[$action][1],
430 MediaWikiServices::getInstance()->getPermissionManager()
431 ->getPermissionErrors( $action, $this->user, $this->title, 'secure' ) );
432 $wgGroupPermissions = $old;
433 $this->resetServices();
434
435 $this->overrideUserPermissions( $this->user, $action );
436 $this->assertEquals( $check[$action][2],
437 MediaWikiServices::getInstance()->getPermissionManager()
438 ->getPermissionErrors( $action, $this->user, $this->title, true ) );
439 $this->assertEquals( $check[$action][2],
440 MediaWikiServices::getInstance()->getPermissionManager()
441 ->getPermissionErrors( $action, $this->user, $this->title, 'full' ) );
442 $this->assertEquals( $check[$action][2],
443 MediaWikiServices::getInstance()->getPermissionManager()
444 ->getPermissionErrors( $action, $this->user, $this->title, 'secure' ) );
445
446 $this->overrideUserPermissions( $this->user, $action );
447 $this->assertEquals( $check[$action][3],
448 MediaWikiServices::getInstance()->getPermissionManager()
449 ->userCan( $action, $this->user, $this->title, true ) );
450 $this->assertEquals( $check[$action][3],
451 MediaWikiServices::getInstance()->getPermissionManager()
452 ->userCan( $action, $this->user, $this->title,
453 PermissionManager::RIGOR_QUICK ) );
454 # count( User::getGroupsWithPermissions( $action ) ) < 1
455 }
456 }
457
458 protected function runGroupPermissions( $perm, $action, $result, $result2 = null ) {
459 global $wgGroupPermissions;
460
461 if ( $result2 === null ) {
462 $result2 = $result;
463 }
464
465 $wgGroupPermissions['autoconfirmed']['move'] = false;
466 $wgGroupPermissions['user']['move'] = false;
467 $this->resetServices();
468 $this->overrideUserPermissions( $this->user, $perm );
469 $res = MediaWikiServices::getInstance()->getPermissionManager()
470 ->getPermissionErrors( $action, $this->user, $this->title );
471 $this->assertEquals( $result, $res );
472
473 $wgGroupPermissions['autoconfirmed']['move'] = true;
474 $wgGroupPermissions['user']['move'] = false;
475 $this->resetServices();
476 $this->overrideUserPermissions( $this->user, $perm );
477 $res = MediaWikiServices::getInstance()->getPermissionManager()
478 ->getPermissionErrors( $action, $this->user, $this->title );
479 $this->assertEquals( $result2, $res );
480
481 $wgGroupPermissions['autoconfirmed']['move'] = true;
482 $wgGroupPermissions['user']['move'] = true;
483 $this->resetServices();
484 $this->overrideUserPermissions( $this->user, $perm );
485 $res = MediaWikiServices::getInstance()->getPermissionManager()
486 ->getPermissionErrors( $action, $this->user, $this->title );
487 $this->assertEquals( $result2, $res );
488
489 $wgGroupPermissions['autoconfirmed']['move'] = false;
490 $wgGroupPermissions['user']['move'] = true;
491 $this->resetServices();
492 $this->overrideUserPermissions( $this->user, $perm );
493 $res = MediaWikiServices::getInstance()->getPermissionManager()
494 ->getPermissionErrors( $action, $this->user, $this->title );
495 $this->assertEquals( $result2, $res );
496 }
497
498 /**
499 * @todo This test method should be split up into separate test methods and
500 * data providers
501 * @covers MediaWiki\Permissions\PermissionManager::checkSpecialsAndNSPermissions
502 */
503 public function testSpecialsAndNSPermissions() {
504 global $wgNamespaceProtection;
505 $this->setUser( $this->userName );
506
507 $this->setTitle( NS_SPECIAL );
508
509 $this->assertEquals( [ [ 'badaccess-group0' ], [ 'ns-specialprotected' ] ],
510 MediaWikiServices::getInstance()->getPermissionManager()
511 ->getPermissionErrors( 'bogus', $this->user, $this->title ) );
512
513 $this->setTitle( NS_MAIN );
514 $this->overrideUserPermissions( $this->user, 'bogus' );
515 $this->assertEquals( [],
516 MediaWikiServices::getInstance()->getPermissionManager()
517 ->getPermissionErrors( 'bogus', $this->user, $this->title ) );
518
519 $this->setTitle( NS_MAIN );
520 $this->overrideUserPermissions( $this->user, '' );
521 $this->assertEquals( [ [ 'badaccess-group0' ] ],
522 MediaWikiServices::getInstance()->getPermissionManager()
523 ->getPermissionErrors( 'bogus', $this->user, $this->title ) );
524
525 $wgNamespaceProtection[NS_USER] = [ 'bogus' ];
526
527 $this->setTitle( NS_USER );
528 $this->overrideUserPermissions( $this->user, '' );
529 $this->assertEquals( [ [ 'badaccess-group0' ],
530 [ 'namespaceprotected', 'User', 'bogus' ] ],
531 MediaWikiServices::getInstance()->getPermissionManager()
532 ->getPermissionErrors( 'bogus', $this->user, $this->title ) );
533
534 $this->setTitle( NS_MEDIAWIKI );
535 $this->overrideUserPermissions( $this->user, 'bogus' );
536 $this->assertEquals( [ [ 'protectedinterface', 'bogus' ] ],
537 MediaWikiServices::getInstance()->getPermissionManager()
538 ->getPermissionErrors( 'bogus', $this->user, $this->title ) );
539
540 $this->setTitle( NS_MEDIAWIKI );
541 $this->overrideUserPermissions( $this->user, 'bogus' );
542 $this->assertEquals( [ [ 'protectedinterface', 'bogus' ] ],
543 MediaWikiServices::getInstance()->getPermissionManager()
544 ->getPermissionErrors( 'bogus', $this->user, $this->title ) );
545
546 $wgNamespaceProtection = null;
547
548 $this->overrideUserPermissions( $this->user, 'bogus' );
549 $this->assertEquals( [],
550 MediaWikiServices::getInstance()->getPermissionManager()
551 ->getPermissionErrors( 'bogus', $this->user, $this->title ) );
552 $this->assertEquals( true,
553 MediaWikiServices::getInstance()->getPermissionManager()
554 ->userCan( 'bogus', $this->user, $this->title ) );
555
556 $this->overrideUserPermissions( $this->user, '' );
557 $this->assertEquals( [ [ 'badaccess-group0' ] ],
558 MediaWikiServices::getInstance()->getPermissionManager()
559 ->getPermissionErrors( 'bogus', $this->user, $this->title ) );
560 $this->assertEquals( false,
561 MediaWikiServices::getInstance()->getPermissionManager()
562 ->userCan( 'bogus', $this->user, $this->title ) );
563 }
564
565 /**
566 * @todo This test method should be split up into separate test methods and
567 * data providers
568 * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
569 */
570 public function testJsConfigEditPermissions() {
571 $this->setUser( $this->userName );
572
573 $this->setTitle( NS_USER, $this->userName . '/test.js' );
574 $this->runConfigEditPermissions(
575 [ [ 'badaccess-group0' ], [ 'mycustomjsprotected', 'bogus' ] ],
576
577 [ [ 'badaccess-group0' ], [ 'mycustomjsprotected', 'bogus' ] ],
578 [ [ 'badaccess-group0' ], [ 'mycustomjsprotected', 'bogus' ] ],
579 [ [ 'badaccess-group0' ] ],
580
581 [ [ 'badaccess-group0' ], [ 'mycustomjsprotected', 'bogus' ] ],
582 [ [ 'badaccess-group0' ], [ 'mycustomjsprotected', 'bogus' ] ],
583 [ [ 'badaccess-group0' ] ],
584 [ [ 'badaccess-groups' ] ]
585 );
586 }
587
588 /**
589 * @todo This test method should be split up into separate test methods and
590 * data providers
591 * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
592 */
593 public function testJsonConfigEditPermissions() {
594 $prefix = MediaWikiServices::getInstance()->getContentLanguage()->
595 getFormattedNsText( NS_PROJECT );
596 $this->setUser( $this->userName );
597
598 $this->setTitle( NS_USER, $this->userName . '/test.json' );
599 $this->runConfigEditPermissions(
600 [ [ 'badaccess-group0' ], [ 'mycustomjsonprotected', 'bogus' ] ],
601
602 [ [ 'badaccess-group0' ], [ 'mycustomjsonprotected', 'bogus' ] ],
603 [ [ 'badaccess-group0' ] ],
604 [ [ 'badaccess-group0' ], [ 'mycustomjsonprotected', 'bogus' ] ],
605
606 [ [ 'badaccess-group0' ], [ 'mycustomjsonprotected', 'bogus' ] ],
607 [ [ 'badaccess-group0' ] ],
608 [ [ 'badaccess-group0' ], [ 'mycustomjsonprotected', 'bogus' ] ],
609 [ [ 'badaccess-groups' ] ]
610 );
611 }
612
613 /**
614 * @todo This test method should be split up into separate test methods and
615 * data providers
616 * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
617 */
618 public function testCssConfigEditPermissions() {
619 $this->setUser( $this->userName );
620
621 $this->setTitle( NS_USER, $this->userName . '/test.css' );
622 $this->runConfigEditPermissions(
623 [ [ 'badaccess-group0' ], [ 'mycustomcssprotected', 'bogus' ] ],
624
625 [ [ 'badaccess-group0' ] ],
626 [ [ 'badaccess-group0' ], [ 'mycustomcssprotected', 'bogus' ] ],
627 [ [ 'badaccess-group0' ], [ 'mycustomcssprotected', 'bogus' ] ],
628
629 [ [ 'badaccess-group0' ] ],
630 [ [ 'badaccess-group0' ], [ 'mycustomcssprotected', 'bogus' ] ],
631 [ [ 'badaccess-group0' ], [ 'mycustomcssprotected', 'bogus' ] ],
632 [ [ 'badaccess-groups' ] ]
633 );
634 }
635
636 /**
637 * @todo This test method should be split up into separate test methods and
638 * data providers
639 * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
640 */
641 public function testOtherJsConfigEditPermissions() {
642 $this->setUser( $this->userName );
643
644 $this->setTitle( NS_USER, $this->altUserName . '/test.js' );
645 $this->runConfigEditPermissions(
646 [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
647
648 [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
649 [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
650 [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
651
652 [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
653 [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
654 [ [ 'badaccess-group0' ] ],
655 [ [ 'badaccess-groups' ] ]
656 );
657 }
658
659 /**
660 * @todo This test method should be split up into separate test methods and
661 * data providers
662 * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
663 */
664 public function testOtherJsonConfigEditPermissions() {
665 $this->setUser( $this->userName );
666
667 $this->setTitle( NS_USER, $this->altUserName . '/test.json' );
668 $this->runConfigEditPermissions(
669 [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
670
671 [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
672 [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
673 [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
674
675 [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
676 [ [ 'badaccess-group0' ] ],
677 [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
678 [ [ 'badaccess-groups' ] ]
679 );
680 }
681
682 /**
683 * @todo This test method should be split up into separate test methods and
684 * data providers
685 * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
686 */
687 public function testOtherCssConfigEditPermissions() {
688 $this->setUser( $this->userName );
689
690 $this->setTitle( NS_USER, $this->altUserName . '/test.css' );
691 $this->runConfigEditPermissions(
692 [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
693
694 [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
695 [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
696 [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
697
698 [ [ 'badaccess-group0' ] ],
699 [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
700 [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
701 [ [ 'badaccess-groups' ] ]
702 );
703 }
704
705 public function testJsConfigRedirectEditPermissions() {
706 $revision = null;
707 $user = $this->getTestUser()->getUser();
708 $otherUser = $this->getTestUser( 'sysop' )->getUser();
709 $localJsTitle = Title::newFromText( 'User:' . $user->getName() . '/foo.js' );
710 $otherLocalJsTitle = Title::newFromText( 'User:' . $user->getName() . '/foo2.js' );
711 $nonlocalJsTitle = Title::newFromText( 'User:' . $otherUser->getName() . '/foo.js' );
712
713 $services = MediaWikiServices::getInstance();
714 $revisionLookup = $this->getMockBuilder( RevisionLookup::class )
715 ->setMethods( [ 'getRevisionByTitle' ] )
716 ->getMockForAbstractClass();
717 $revisionLookup->method( 'getRevisionByTitle' )
718 ->willReturnCallback( function ( LinkTarget $page ) use (
719 $services, &$revision, $localJsTitle
720 ) {
721 if ( $localJsTitle->equals( Title::newFromLinkTarget( $page ) ) ) {
722 return $revision;
723 } else {
724 return $services->getRevisionLookup()->getRevisionByTitle( $page );
725 }
726 } );
727 $permissionManager = new PermissionManager(
728 $services->getSpecialPageFactory(),
729 $revisionLookup,
730 [],
731 [],
732 false,
733 false,
734 [],
735 [],
736 [],
737 MediaWikiServices::getInstance()->getNamespaceInfo()
738 );
739 $this->setService( 'PermissionManager', $permissionManager );
740
741 $permissionManager->overrideUserRightsForTesting( $user, [ 'edit', 'editmyuserjs' ] );
742
743 $revision = $this->getJavascriptRevision( $localJsTitle, $user, '/* script */' );
744 $errors = $permissionManager->getPermissionErrors( 'edit', $user, $localJsTitle );
745 $this->assertSame( [], $errors );
746
747 $revision = $this->getJavascriptRedirectRevision( $localJsTitle, $otherLocalJsTitle, $user );
748 $errors = $permissionManager->getPermissionErrors( 'edit', $user, $localJsTitle );
749 $this->assertSame( [], $errors );
750
751 $revision = $this->getJavascriptRedirectRevision( $localJsTitle, $nonlocalJsTitle, $user );
752 $errors = $permissionManager->getPermissionErrors( 'edit', $user, $localJsTitle );
753 $this->assertSame( [ [ 'mycustomjsredirectprotected', 'edit' ] ], $errors );
754
755 $permissionManager->overrideUserRightsForTesting( $user,
756 [ 'edit', 'editmyuserjs', 'editmyuserjsredirect' ] );
757
758 $revision = $this->getJavascriptRedirectRevision( $localJsTitle, $nonlocalJsTitle, $user );
759 $errors = $permissionManager->getPermissionErrors( 'edit', $user, $localJsTitle );
760 $this->assertSame( [], $errors );
761 }
762
763 /**
764 * @todo This test method should be split up into separate test methods and
765 * data providers
766 * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
767 */
768 public function testOtherNonConfigEditPermissions() {
769 $this->setUser( $this->userName );
770
771 $this->setTitle( NS_USER, $this->altUserName . '/tempo' );
772 $this->runConfigEditPermissions(
773 [ [ 'badaccess-group0' ] ],
774
775 [ [ 'badaccess-group0' ] ],
776 [ [ 'badaccess-group0' ] ],
777 [ [ 'badaccess-group0' ] ],
778
779 [ [ 'badaccess-group0' ] ],
780 [ [ 'badaccess-group0' ] ],
781 [ [ 'badaccess-group0' ] ],
782 [ [ 'badaccess-groups' ] ]
783 );
784 }
785
786 /**
787 * @todo This should use data providers like the other methods here.
788 * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
789 */
790 public function testPatrolActionConfigEditPermissions() {
791 $this->setUser( 'anon' );
792 $this->setTitle( NS_USER, 'ToPatrolOrNotToPatrol' );
793 $this->runConfigEditPermissions(
794 [ [ 'badaccess-group0' ] ],
795
796 [ [ 'badaccess-group0' ] ],
797 [ [ 'badaccess-group0' ] ],
798 [ [ 'badaccess-group0' ] ],
799
800 [ [ 'badaccess-group0' ] ],
801 [ [ 'badaccess-group0' ] ],
802 [ [ 'badaccess-group0' ] ],
803 [ [ 'badaccess-groups' ] ]
804 );
805 }
806
807 protected function runConfigEditPermissions(
808 $resultNone,
809 $resultMyCss,
810 $resultMyJson,
811 $resultMyJs,
812 $resultUserCss,
813 $resultUserJson,
814 $resultUserJs,
815 $resultPatrol
816 ) {
817 $this->overrideUserPermissions( $this->user );
818 $result = MediaWikiServices::getInstance()->getPermissionManager()
819 ->getPermissionErrors( 'bogus', $this->user, $this->title );
820 $this->assertEquals( $resultNone, $result );
821
822 $this->overrideUserPermissions( $this->user, 'editmyusercss' );
823 $result = MediaWikiServices::getInstance()->getPermissionManager()
824 ->getPermissionErrors( 'bogus', $this->user, $this->title );
825 $this->assertEquals( $resultMyCss, $result );
826
827 $this->overrideUserPermissions( $this->user, 'editmyuserjson' );
828 $result = MediaWikiServices::getInstance()->getPermissionManager()
829 ->getPermissionErrors( 'bogus', $this->user, $this->title );
830 $this->assertEquals( $resultMyJson, $result );
831
832 $this->overrideUserPermissions( $this->user, 'editmyuserjs' );
833 $result = MediaWikiServices::getInstance()->getPermissionManager()
834 ->getPermissionErrors( 'bogus', $this->user, $this->title );
835 $this->assertEquals( $resultMyJs, $result );
836
837 $this->overrideUserPermissions( $this->user, 'editusercss' );
838 $result = MediaWikiServices::getInstance()->getPermissionManager()
839 ->getPermissionErrors( 'bogus', $this->user, $this->title );
840 $this->assertEquals( $resultUserCss, $result );
841
842 $this->overrideUserPermissions( $this->user, 'edituserjson' );
843 $result = MediaWikiServices::getInstance()->getPermissionManager()
844 ->getPermissionErrors( 'bogus', $this->user, $this->title );
845 $this->assertEquals( $resultUserJson, $result );
846
847 $this->overrideUserPermissions( $this->user, 'edituserjs' );
848 $result = MediaWikiServices::getInstance()->getPermissionManager()
849 ->getPermissionErrors( 'bogus', $this->user, $this->title );
850 $this->assertEquals( $resultUserJs, $result );
851
852 $this->overrideUserPermissions( $this->user );
853 $result = MediaWikiServices::getInstance()->getPermissionManager()
854 ->getPermissionErrors( 'patrol', $this->user, $this->title );
855 $this->assertEquals( reset( $resultPatrol[0] ), reset( $result[0] ) );
856
857 $this->overrideUserPermissions( $this->user, [ 'edituserjs', 'edituserjson', 'editusercss' ] );
858 $result = MediaWikiServices::getInstance()->getPermissionManager()
859 ->getPermissionErrors( 'bogus', $this->user, $this->title );
860 $this->assertEquals( [ [ 'badaccess-group0' ] ], $result );
861 }
862
863 /**
864 * @todo This test method should be split up into separate test methods and
865 * data providers
866 *
867 * This test is failing per T201776.
868 *
869 * @group Broken
870 * @covers \MediaWiki\Permissions\PermissionManager::checkPageRestrictions
871 */
872 public function testPageRestrictions() {
873 $prefix = MediaWikiServices::getInstance()->getContentLanguage()->
874 getFormattedNsText( NS_PROJECT );
875
876 $this->setTitle( NS_MAIN );
877 $this->title->mRestrictionsLoaded = true;
878 $this->overrideUserPermissions( $this->user, "edit" );
879 $this->title->mRestrictions = [ "bogus" => [ 'bogus', "sysop", "protect", "" ] ];
880
881 $this->assertEquals( [],
882 MediaWikiServices::getInstance()->getPermissionManager()
883 ->getPermissionErrors( 'edit', $this->user, $this->title ) );
884
885 $this->assertEquals( true,
886 MediaWikiServices::getInstance()->getPermissionManager()
887 ->userCan( 'edit', $this->user, $this->title, PermissionManager::RIGOR_QUICK ) );
888
889 $this->title->mRestrictions = [ "edit" => [ 'bogus', "sysop", "protect", "" ],
890 "bogus" => [ 'bogus', "sysop", "protect", "" ] ];
891
892 $this->assertEquals( [ [ 'badaccess-group0' ],
893 [ 'protectedpagetext', 'bogus', 'bogus' ],
894 [ 'protectedpagetext', 'editprotected', 'bogus' ],
895 [ 'protectedpagetext', 'protect', 'bogus' ] ],
896 MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors(
897 'bogus', $this->user, $this->title ) );
898 $this->assertEquals( [ [ 'protectedpagetext', 'bogus', 'edit' ],
899 [ 'protectedpagetext', 'editprotected', 'edit' ],
900 [ 'protectedpagetext', 'protect', 'edit' ] ],
901 MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors(
902 'edit', $this->user, $this->title ) );
903 $this->overrideUserPermissions( $this->user );
904 $this->assertEquals( [ [ 'badaccess-group0' ],
905 [ 'protectedpagetext', 'bogus', 'bogus' ],
906 [ 'protectedpagetext', 'editprotected', 'bogus' ],
907 [ 'protectedpagetext', 'protect', 'bogus' ] ],
908 MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors(
909 'bogus', $this->user, $this->title ) );
910 $this->assertEquals( [ [ 'badaccess-groups', "*, [[$prefix:Users|Users]]", 2 ],
911 [ 'protectedpagetext', 'bogus', 'edit' ],
912 [ 'protectedpagetext', 'editprotected', 'edit' ],
913 [ 'protectedpagetext', 'protect', 'edit' ] ],
914 MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors(
915 'edit', $this->user, $this->title ) );
916 $this->overrideUserPermissions( $this->user, [ "edit", "editprotected" ] );
917 $this->assertEquals( [ [ 'badaccess-group0' ],
918 [ 'protectedpagetext', 'bogus', 'bogus' ],
919 [ 'protectedpagetext', 'protect', 'bogus' ] ],
920 MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors(
921 'bogus', $this->user, $this->title ) );
922 $this->assertEquals( [
923 [ 'protectedpagetext', 'bogus', 'edit' ],
924 [ 'protectedpagetext', 'protect', 'edit' ] ],
925 MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors(
926 'edit', $this->user, $this->title ) );
927
928 $this->title->mCascadeRestriction = true;
929 $this->overrideUserPermissions( $this->user, "edit" );
930
931 $this->assertEquals( false,
932 MediaWikiServices::getInstance()->getPermissionManager()
933 ->userCan( 'bogus', $this->user, $this->title, PermissionManager::RIGOR_QUICK ) );
934
935 $this->assertEquals( false,
936 MediaWikiServices::getInstance()->getPermissionManager()->userCan(
937 'edit', $this->user, $this->title, PermissionManager::RIGOR_QUICK ) );
938
939 $this->assertEquals( [ [ 'badaccess-group0' ],
940 [ 'protectedpagetext', 'bogus', 'bogus' ],
941 [ 'protectedpagetext', 'editprotected', 'bogus' ],
942 [ 'protectedpagetext', 'protect', 'bogus' ] ],
943 MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors(
944 'bogus', $this->user, $this->title ) );
945 $this->assertEquals( [ [ 'protectedpagetext', 'bogus', 'edit' ],
946 [ 'protectedpagetext', 'editprotected', 'edit' ],
947 [ 'protectedpagetext', 'protect', 'edit' ] ],
948 MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors(
949 'edit', $this->user, $this->title ) );
950
951 $this->overrideUserPermissions( $this->user, [ "edit", "editprotected" ] );
952 $this->assertEquals( false,
953 MediaWikiServices::getInstance()->getPermissionManager()->userCan(
954 'bogus', $this->user, $this->title, PermissionManager::RIGOR_QUICK ) );
955
956 $this->assertEquals( false,
957 MediaWikiServices::getInstance()->getPermissionManager()->userCan(
958 'edit', $this->user, $this->title, PermissionManager::RIGOR_QUICK ) );
959
960 $this->assertEquals( [ [ 'badaccess-group0' ],
961 [ 'protectedpagetext', 'bogus', 'bogus' ],
962 [ 'protectedpagetext', 'protect', 'bogus' ],
963 [ 'protectedpagetext', 'protect', 'bogus' ] ],
964 MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors(
965 'bogus', $this->user, $this->title ) );
966 $this->assertEquals( [ [ 'protectedpagetext', 'bogus', 'edit' ],
967 [ 'protectedpagetext', 'protect', 'edit' ],
968 [ 'protectedpagetext', 'protect', 'edit' ] ],
969 MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors(
970 'edit', $this->user, $this->title ) );
971 }
972
973 /**
974 * @covers \MediaWiki\Permissions\PermissionManager::checkCascadingSourcesRestrictions
975 */
976 public function testCascadingSourcesRestrictions() {
977 $this->setTitle( NS_MAIN, "test page" );
978 $this->overrideUserPermissions( $this->user, [ "edit", "bogus" ] );
979
980 $this->title->mCascadeSources = [
981 Title::makeTitle( NS_MAIN, "Bogus" ),
982 Title::makeTitle( NS_MAIN, "UnBogus" )
983 ];
984 $this->title->mCascadingRestrictions = [
985 "bogus" => [ 'bogus', "sysop", "protect", "" ]
986 ];
987
988 $this->assertEquals( false,
989 MediaWikiServices::getInstance()->getPermissionManager()->userCan(
990 'bogus', $this->user, $this->title ) );
991 $this->assertEquals( [
992 [ "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n", 'bogus' ],
993 [ "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n", 'bogus' ],
994 [ "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n", 'bogus' ] ],
995 MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors(
996 'bogus', $this->user, $this->title ) );
997
998 $this->assertEquals( true,
999 MediaWikiServices::getInstance()->getPermissionManager()->userCan(
1000 'edit', $this->user, $this->title ) );
1001 $this->assertEquals( [],
1002 MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors(
1003 'edit', $this->user, $this->title ) );
1004 }
1005
1006 /**
1007 * @todo This test method should be split up into separate test methods and
1008 * data providers
1009 * @covers \MediaWiki\Permissions\PermissionManager::checkActionPermissions
1010 */
1011 public function testActionPermissions() {
1012 $this->overrideUserPermissions( $this->user, [ "createpage" ] );
1013 $this->setTitle( NS_MAIN, "test page" );
1014 $this->title->mTitleProtection['permission'] = '';
1015 $this->title->mTitleProtection['user'] = $this->user->getId();
1016 $this->title->mTitleProtection['expiry'] = 'infinity';
1017 $this->title->mTitleProtection['reason'] = 'test';
1018 $this->title->mCascadeRestriction = false;
1019
1020 $this->assertEquals( [ [ 'titleprotected', 'Useruser', 'test' ] ],
1021 MediaWikiServices::getInstance()->getPermissionManager()
1022 ->getPermissionErrors( 'create', $this->user, $this->title ) );
1023 $this->assertEquals( false,
1024 MediaWikiServices::getInstance()->getPermissionManager()->userCan(
1025 'create', $this->user, $this->title ) );
1026
1027 $this->title->mTitleProtection['permission'] = 'editprotected';
1028 $this->overrideUserPermissions( $this->user, [ 'createpage', 'protect' ] );
1029 $this->assertEquals( [ [ 'titleprotected', 'Useruser', 'test' ] ],
1030 MediaWikiServices::getInstance()->getPermissionManager()
1031 ->getPermissionErrors( 'create', $this->user, $this->title ) );
1032 $this->assertEquals( false,
1033 MediaWikiServices::getInstance()->getPermissionManager()->userCan(
1034 'create', $this->user, $this->title ) );
1035
1036 $this->overrideUserPermissions( $this->user, [ 'createpage', 'editprotected' ] );
1037 $this->assertEquals( [],
1038 MediaWikiServices::getInstance()->getPermissionManager()
1039 ->getPermissionErrors( 'create', $this->user, $this->title ) );
1040 $this->assertEquals( true,
1041 MediaWikiServices::getInstance()->getPermissionManager()->userCan(
1042 'create', $this->user, $this->title ) );
1043
1044 $this->overrideUserPermissions( $this->user, [ 'createpage' ] );
1045 $this->assertEquals( [ [ 'titleprotected', 'Useruser', 'test' ] ],
1046 MediaWikiServices::getInstance()->getPermissionManager()
1047 ->getPermissionErrors( 'create', $this->user, $this->title ) );
1048 $this->assertEquals( false,
1049 MediaWikiServices::getInstance()->getPermissionManager()->userCan(
1050 'create', $this->user, $this->title ) );
1051
1052 $this->setTitle( NS_MEDIA, "test page" );
1053 $this->overrideUserPermissions( $this->user, [ "move" ] );
1054 $this->assertEquals( false,
1055 MediaWikiServices::getInstance()->getPermissionManager()->userCan(
1056 'move', $this->user, $this->title ) );
1057 $this->assertEquals( [ [ 'immobile-source-namespace', 'Media' ] ],
1058 MediaWikiServices::getInstance()->getPermissionManager()
1059 ->getPermissionErrors( 'move', $this->user, $this->title ) );
1060
1061 $this->setTitle( NS_HELP, "test page" );
1062 $this->assertEquals( [],
1063 MediaWikiServices::getInstance()->getPermissionManager()
1064 ->getPermissionErrors( 'move', $this->user, $this->title ) );
1065 $this->assertEquals( true,
1066 MediaWikiServices::getInstance()->getPermissionManager()->userCan(
1067 'move', $this->user, $this->title ) );
1068
1069 $this->title->mInterwiki = "no";
1070 $this->assertEquals( [ [ 'immobile-source-page' ] ],
1071 MediaWikiServices::getInstance()->getPermissionManager()
1072 ->getPermissionErrors( 'move', $this->user, $this->title ) );
1073 $this->assertEquals( false,
1074 MediaWikiServices::getInstance()->getPermissionManager()->userCan(
1075 'move', $this->user, $this->title ) );
1076
1077 $this->setTitle( NS_MEDIA, "test page" );
1078 $this->assertEquals( false,
1079 MediaWikiServices::getInstance()->getPermissionManager()->userCan(
1080 'move-target', $this->user, $this->title ) );
1081 $this->assertEquals( [ [ 'immobile-target-namespace', 'Media' ] ],
1082 MediaWikiServices::getInstance()->getPermissionManager()
1083 ->getPermissionErrors( 'move-target', $this->user, $this->title ) );
1084
1085 $this->setTitle( NS_HELP, "test page" );
1086 $this->assertEquals( [],
1087 MediaWikiServices::getInstance()->getPermissionManager()
1088 ->getPermissionErrors( 'move-target', $this->user, $this->title ) );
1089 $this->assertEquals( true,
1090 MediaWikiServices::getInstance()->getPermissionManager()->userCan(
1091 'move-target', $this->user, $this->title ) );
1092
1093 $this->title->mInterwiki = "no";
1094 $this->assertEquals( [ [ 'immobile-target-page' ] ],
1095 MediaWikiServices::getInstance()->getPermissionManager()
1096 ->getPermissionErrors( 'move-target', $this->user, $this->title ) );
1097 $this->assertEquals( false,
1098 MediaWikiServices::getInstance()->getPermissionManager()->userCan(
1099 'move-target', $this->user, $this->title ) );
1100 }
1101
1102 /**
1103 * @covers \MediaWiki\Permissions\PermissionManager::checkUserBlock
1104 */
1105 public function testUserBlock() {
1106 $this->setMwGlobals( [
1107 'wgEmailConfirmToEdit' => true,
1108 'wgEmailAuthentication' => true,
1109 'wgBlockDisablesLogin' => false,
1110 ] );
1111
1112 $this->overrideUserPermissions( $this->user, [
1113 'createpage',
1114 'edit',
1115 'move',
1116 'rollback',
1117 'patrol',
1118 'upload',
1119 'purge'
1120 ] );
1121 $this->setTitle( NS_HELP, "test page" );
1122
1123 # $wgEmailConfirmToEdit only applies to 'edit' action
1124 $this->assertEquals( [],
1125 MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors(
1126 'move-target', $this->user, $this->title ) );
1127 $this->assertContains( [ 'confirmedittext' ],
1128 MediaWikiServices::getInstance()->getPermissionManager()
1129 ->getPermissionErrors( 'edit', $this->user, $this->title ) );
1130
1131 $this->setMwGlobals( 'wgEmailConfirmToEdit', false );
1132 $this->resetServices();
1133 $this->overrideUserPermissions( $this->user, [
1134 'createpage',
1135 'edit',
1136 'move',
1137 'rollback',
1138 'patrol',
1139 'upload',
1140 'purge'
1141 ] );
1142
1143 $this->assertNotContains( [ 'confirmedittext' ],
1144 MediaWikiServices::getInstance()->getPermissionManager()
1145 ->getPermissionErrors( 'edit', $this->user, $this->title ) );
1146
1147 # $wgEmailConfirmToEdit && !$user->isEmailConfirmed() && $action != 'createaccount'
1148 $this->assertEquals( [],
1149 MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors(
1150 'move-target', $this->user, $this->title ) );
1151
1152 global $wgLang;
1153 $prev = time();
1154 $now = time() + 120;
1155 $this->user->mBlockedby = $this->user->getId();
1156 $this->user->mBlock = new DatabaseBlock( [
1157 'address' => '127.0.8.1',
1158 'by' => $this->user->getId(),
1159 'reason' => 'no reason given',
1160 'timestamp' => $prev + 3600,
1161 'auto' => true,
1162 'expiry' => 0
1163 ] );
1164 $this->user->mBlock->mTimestamp = 0;
1165 $this->assertEquals( [ [ 'autoblockedtext',
1166 "[[User:Useruser|\u{202A}Useruser\u{202C}]]", 'no reason given', '127.0.0.1',
1167 "\u{202A}Useruser\u{202C}", null, 'infinite', '127.0.8.1',
1168 $wgLang->timeanddate( wfTimestamp( TS_MW, $prev ), true ) ] ],
1169 MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors(
1170 'move-target', $this->user, $this->title ) );
1171
1172 $this->assertEquals( false, MediaWikiServices::getInstance()->getPermissionManager()
1173 ->userCan( 'move-target', $this->user, $this->title ) );
1174 // quickUserCan should ignore user blocks
1175 $this->assertEquals( true, MediaWikiServices::getInstance()->getPermissionManager()
1176 ->userCan( 'move-target', $this->user, $this->title,
1177 PermissionManager::RIGOR_QUICK ) );
1178
1179 global $wgLocalTZoffset;
1180 $wgLocalTZoffset = -60;
1181 $this->user->mBlockedby = $this->user->getName();
1182 $this->user->mBlock = new DatabaseBlock( [
1183 'address' => '127.0.8.1',
1184 'by' => $this->user->getId(),
1185 'reason' => 'no reason given',
1186 'timestamp' => $now,
1187 'auto' => false,
1188 'expiry' => 10,
1189 ] );
1190 $this->assertEquals( [ [ 'blockedtext',
1191 "[[User:Useruser|\u{202A}Useruser\u{202C}]]", 'no reason given', '127.0.0.1',
1192 "\u{202A}Useruser\u{202C}", null, '23:00, 31 December 1969', '127.0.8.1',
1193 $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ],
1194 MediaWikiServices::getInstance()->getPermissionManager()
1195 ->getPermissionErrors( 'move-target', $this->user, $this->title ) );
1196 # $action != 'read' && $action != 'createaccount' && $user->isBlockedFrom( $this )
1197 # $user->blockedFor() == ''
1198 # $user->mBlock->mExpiry == 'infinity'
1199
1200 $this->user->mBlockedby = $this->user->getName();
1201 $this->user->mBlock = new SystemBlock( [
1202 'address' => '127.0.8.1',
1203 'by' => $this->user->getId(),
1204 'reason' => 'no reason given',
1205 'timestamp' => $now,
1206 'auto' => false,
1207 'systemBlock' => 'test',
1208 ] );
1209
1210 $errors = [ [ 'systemblockedtext',
1211 "[[User:Useruser|\u{202A}Useruser\u{202C}]]", 'no reason given', '127.0.0.1',
1212 "\u{202A}Useruser\u{202C}", 'test', 'infinite', '127.0.8.1',
1213 $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ];
1214
1215 $this->assertEquals( $errors,
1216 MediaWikiServices::getInstance()->getPermissionManager()
1217 ->getPermissionErrors( 'edit', $this->user, $this->title ) );
1218 $this->assertEquals( $errors,
1219 MediaWikiServices::getInstance()->getPermissionManager()
1220 ->getPermissionErrors( 'move-target', $this->user, $this->title ) );
1221 $this->assertEquals( $errors,
1222 MediaWikiServices::getInstance()->getPermissionManager()
1223 ->getPermissionErrors( 'rollback', $this->user, $this->title ) );
1224 $this->assertEquals( $errors,
1225 MediaWikiServices::getInstance()->getPermissionManager()
1226 ->getPermissionErrors( 'patrol', $this->user, $this->title ) );
1227 $this->assertEquals( $errors,
1228 MediaWikiServices::getInstance()->getPermissionManager()
1229 ->getPermissionErrors( 'upload', $this->user, $this->title ) );
1230 $this->assertEquals( [],
1231 MediaWikiServices::getInstance()->getPermissionManager()
1232 ->getPermissionErrors( 'purge', $this->user, $this->title ) );
1233
1234 // partial block message test
1235 $this->user->mBlockedby = $this->user->getName();
1236 $this->user->mBlock = new DatabaseBlock( [
1237 'address' => '127.0.8.1',
1238 'by' => $this->user->getId(),
1239 'reason' => 'no reason given',
1240 'timestamp' => $now,
1241 'sitewide' => false,
1242 'expiry' => 10,
1243 ] );
1244
1245 $this->assertEquals( [],
1246 MediaWikiServices::getInstance()->getPermissionManager()
1247 ->getPermissionErrors( 'edit', $this->user, $this->title ) );
1248 $this->assertEquals( [],
1249 MediaWikiServices::getInstance()->getPermissionManager()
1250 ->getPermissionErrors( 'move-target', $this->user, $this->title ) );
1251 $this->assertEquals( [],
1252 MediaWikiServices::getInstance()->getPermissionManager()
1253 ->getPermissionErrors( 'rollback', $this->user, $this->title ) );
1254 $this->assertEquals( [],
1255 MediaWikiServices::getInstance()->getPermissionManager()
1256 ->getPermissionErrors( 'patrol', $this->user, $this->title ) );
1257 $this->assertEquals( [],
1258 MediaWikiServices::getInstance()->getPermissionManager()
1259 ->getPermissionErrors( 'upload', $this->user, $this->title ) );
1260 $this->assertEquals( [],
1261 MediaWikiServices::getInstance()->getPermissionManager()
1262 ->getPermissionErrors( 'purge', $this->user, $this->title ) );
1263
1264 $this->user->mBlock->setRestrictions( [
1265 ( new PageRestriction( 0, $this->title->getArticleID() ) )->setTitle( $this->title ),
1266 ] );
1267
1268 $errors = [ [ 'blockedtext-partial',
1269 "[[User:Useruser|\u{202A}Useruser\u{202C}]]", 'no reason given', '127.0.0.1',
1270 "\u{202A}Useruser\u{202C}", null, '23:00, 31 December 1969', '127.0.8.1',
1271 $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ];
1272
1273 $this->assertEquals( $errors,
1274 MediaWikiServices::getInstance()->getPermissionManager()
1275 ->getPermissionErrors( 'edit', $this->user, $this->title ) );
1276 $this->assertEquals( $errors,
1277 MediaWikiServices::getInstance()->getPermissionManager()
1278 ->getPermissionErrors( 'move-target', $this->user, $this->title ) );
1279 $this->assertEquals( $errors,
1280 MediaWikiServices::getInstance()->getPermissionManager()
1281 ->getPermissionErrors( 'rollback', $this->user, $this->title ) );
1282 $this->assertEquals( $errors,
1283 MediaWikiServices::getInstance()->getPermissionManager()
1284 ->getPermissionErrors( 'patrol', $this->user, $this->title ) );
1285 $this->assertEquals( [],
1286 MediaWikiServices::getInstance()->getPermissionManager()
1287 ->getPermissionErrors( 'upload', $this->user, $this->title ) );
1288 $this->assertEquals( [],
1289 MediaWikiServices::getInstance()->getPermissionManager()
1290 ->getPermissionErrors( 'purge', $this->user, $this->title ) );
1291
1292 // Test no block.
1293 $this->user->mBlockedby = null;
1294 $this->user->mBlock = null;
1295
1296 $this->assertEquals( [],
1297 MediaWikiServices::getInstance()->getPermissionManager()
1298 ->getPermissionErrors( 'edit', $this->user, $this->title ) );
1299 }
1300
1301 /**
1302 * @covers \MediaWiki\Permissions\PermissionManager::checkUserBlock
1303 *
1304 * Tests to determine that the passed in permission does not get mixed up with
1305 * an action of the same name.
1306 */
1307 public function testUserBlockAction() {
1308 global $wgLang;
1309
1310 $tester = $this->getMockBuilder( Action::class )
1311 ->disableOriginalConstructor()
1312 ->getMock();
1313 $tester->method( 'getName' )
1314 ->willReturn( 'tester' );
1315 $tester->method( 'getRestriction' )
1316 ->willReturn( 'test' );
1317 $tester->method( 'requiresUnblock' )
1318 ->willReturn( false );
1319
1320 $this->setMwGlobals( [
1321 'wgActions' => [
1322 'tester' => $tester,
1323 ],
1324 'wgGroupPermissions' => [
1325 '*' => [
1326 'tester' => true,
1327 ],
1328 ],
1329 ] );
1330
1331 $now = time();
1332 $this->user->mBlockedby = $this->user->getName();
1333 $this->user->mBlock = new DatabaseBlock( [
1334 'address' => '127.0.8.1',
1335 'by' => $this->user->getId(),
1336 'reason' => 'no reason given',
1337 'timestamp' => $now,
1338 'auto' => false,
1339 'expiry' => 'infinity',
1340 ] );
1341
1342 $errors = [ [ 'blockedtext',
1343 "[[User:Useruser|\u{202A}Useruser\u{202C}]]", 'no reason given', '127.0.0.1',
1344 "\u{202A}Useruser\u{202C}", null, 'infinite', '127.0.8.1',
1345 $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ];
1346
1347 $this->assertEquals( $errors,
1348 MediaWikiServices::getInstance()->getPermissionManager()
1349 ->getPermissionErrors( 'tester', $this->user, $this->title ) );
1350 }
1351
1352 /**
1353 * @covers \MediaWiki\Permissions\PermissionManager::isBlockedFrom
1354 */
1355 public function testBlockInstanceCache() {
1356 // First, check the user isn't blocked
1357 $user = $this->getMutableTestUser()->getUser();
1358 $ut = Title::makeTitle( NS_USER_TALK, $user->getName() );
1359 $this->assertNull( $user->getBlock( false ), 'sanity check' );
1360 //$this->assertSame( '', $user->blockedBy(), 'sanity check' );
1361 //$this->assertSame( '', $user->blockedFor(), 'sanity check' );
1362 //$this->assertFalse( (bool)$user->isHidden(), 'sanity check' );
1363 $this->assertFalse( MediaWikiServices::getInstance()->getPermissionManager()
1364 ->isBlockedFrom( $user, $ut ), 'sanity check' );
1365
1366 // Block the user
1367 $blocker = $this->getTestSysop()->getUser();
1368 $block = new DatabaseBlock( [
1369 'hideName' => true,
1370 'allowUsertalk' => false,
1371 'reason' => 'Because',
1372 ] );
1373 $block->setTarget( $user );
1374 $block->setBlocker( $blocker );
1375 $res = $block->insert();
1376 $this->assertTrue( (bool)$res['id'], 'sanity check: Failed to insert block' );
1377
1378 // Clear cache and confirm it loaded the block properly
1379 $user->clearInstanceCache();
1380 $this->assertInstanceOf( DatabaseBlock::class, $user->getBlock( false ) );
1381 //$this->assertSame( $blocker->getName(), $user->blockedBy() );
1382 //$this->assertSame( 'Because', $user->blockedFor() );
1383 //$this->assertTrue( (bool)$user->isHidden() );
1384 $this->assertTrue( MediaWikiServices::getInstance()->getPermissionManager()
1385 ->isBlockedFrom( $user, $ut ) );
1386
1387 // Unblock
1388 $block->delete();
1389
1390 // Clear cache and confirm it loaded the not-blocked properly
1391 $user->clearInstanceCache();
1392 $this->assertNull( $user->getBlock( false ) );
1393 //$this->assertSame( '', $user->blockedBy() );
1394 //$this->assertSame( '', $user->blockedFor() );
1395 //$this->assertFalse( (bool)$user->isHidden() );
1396 $this->assertFalse( MediaWikiServices::getInstance()->getPermissionManager()
1397 ->isBlockedFrom( $user, $ut ) );
1398 }
1399
1400 /**
1401 * @covers \MediaWiki\Permissions\PermissionManager::isBlockedFrom
1402 * @dataProvider provideIsBlockedFrom
1403 * @param string|null $title Title to test.
1404 * @param bool $expect Expected result from User::isBlockedFrom()
1405 * @param array $options Additional test options:
1406 * - 'blockAllowsUTEdit': (bool, default true) Value for $wgBlockAllowsUTEdit
1407 * - 'allowUsertalk': (bool, default false) Passed to DatabaseBlock::__construct()
1408 * - 'pageRestrictions': (array|null) If non-empty, page restriction titles for the block.
1409 */
1410 public function testIsBlockedFrom( $title, $expect, array $options = [] ) {
1411 $this->setMwGlobals( [
1412 'wgBlockAllowsUTEdit' => $options['blockAllowsUTEdit'] ?? true,
1413 ] );
1414
1415 $user = $this->getTestUser()->getUser();
1416
1417 if ( $title === self::USER_TALK_PAGE ) {
1418 $title = $user->getTalkPage();
1419 } else {
1420 $title = Title::newFromText( $title );
1421 }
1422
1423 $restrictions = [];
1424 foreach ( $options['pageRestrictions'] ?? [] as $pagestr ) {
1425 $page = $this->getExistingTestPage(
1426 $pagestr === self::USER_TALK_PAGE ? $user->getTalkPage() : $pagestr
1427 );
1428 $restrictions[] = new PageRestriction( 0, $page->getId() );
1429 }
1430 foreach ( $options['namespaceRestrictions'] ?? [] as $ns ) {
1431 $restrictions[] = new NamespaceRestriction( 0, $ns );
1432 }
1433
1434 $block = new DatabaseBlock( [
1435 'expiry' => wfTimestamp( TS_MW, wfTimestamp() + ( 40 * 60 * 60 ) ),
1436 'allowUsertalk' => $options['allowUsertalk'] ?? false,
1437 'sitewide' => !$restrictions,
1438 ] );
1439 $block->setTarget( $user );
1440 $block->setBlocker( $this->getTestSysop()->getUser() );
1441 if ( $restrictions ) {
1442 $block->setRestrictions( $restrictions );
1443 }
1444 $block->insert();
1445
1446 try {
1447 $this->assertSame( $expect, MediaWikiServices::getInstance()->getPermissionManager()
1448 ->isBlockedFrom( $user, $title ) );
1449 } finally {
1450 $block->delete();
1451 }
1452 }
1453
1454 public static function provideIsBlockedFrom() {
1455 return [
1456 'Sitewide block, basic operation' => [ 'Test page', true ],
1457 'Sitewide block, not allowing user talk' => [
1458 self::USER_TALK_PAGE, true, [
1459 'allowUsertalk' => false,
1460 ]
1461 ],
1462 'Sitewide block, allowing user talk' => [
1463 self::USER_TALK_PAGE, false, [
1464 'allowUsertalk' => true,
1465 ]
1466 ],
1467 'Sitewide block, allowing user talk but $wgBlockAllowsUTEdit is false' => [
1468 self::USER_TALK_PAGE, true, [
1469 'allowUsertalk' => true,
1470 'blockAllowsUTEdit' => false,
1471 ]
1472 ],
1473 'Partial block, blocking the page' => [
1474 'Test page', true, [
1475 'pageRestrictions' => [ 'Test page' ],
1476 ]
1477 ],
1478 'Partial block, not blocking the page' => [
1479 'Test page 2', false, [
1480 'pageRestrictions' => [ 'Test page' ],
1481 ]
1482 ],
1483 'Partial block, not allowing user talk but user talk page is not blocked' => [
1484 self::USER_TALK_PAGE, false, [
1485 'allowUsertalk' => false,
1486 'pageRestrictions' => [ 'Test page' ],
1487 ]
1488 ],
1489 'Partial block, allowing user talk but user talk page is blocked' => [
1490 self::USER_TALK_PAGE, true, [
1491 'allowUsertalk' => true,
1492 'pageRestrictions' => [ self::USER_TALK_PAGE ],
1493 ]
1494 ],
1495 'Partial block, user talk page is not blocked but $wgBlockAllowsUTEdit is false' => [
1496 self::USER_TALK_PAGE, false, [
1497 'allowUsertalk' => false,
1498 'pageRestrictions' => [ 'Test page' ],
1499 'blockAllowsUTEdit' => false,
1500 ]
1501 ],
1502 'Partial block, user talk page is blocked and $wgBlockAllowsUTEdit is false' => [
1503 self::USER_TALK_PAGE, true, [
1504 'allowUsertalk' => true,
1505 'pageRestrictions' => [ self::USER_TALK_PAGE ],
1506 'blockAllowsUTEdit' => false,
1507 ]
1508 ],
1509 'Partial user talk namespace block, not allowing user talk' => [
1510 self::USER_TALK_PAGE, true, [
1511 'allowUsertalk' => false,
1512 'namespaceRestrictions' => [ NS_USER_TALK ],
1513 ]
1514 ],
1515 'Partial user talk namespace block, allowing user talk' => [
1516 self::USER_TALK_PAGE, false, [
1517 'allowUsertalk' => true,
1518 'namespaceRestrictions' => [ NS_USER_TALK ],
1519 ]
1520 ],
1521 'Partial user talk namespace block, where $wgBlockAllowsUTEdit is false' => [
1522 self::USER_TALK_PAGE, true, [
1523 'allowUsertalk' => true,
1524 'namespaceRestrictions' => [ NS_USER_TALK ],
1525 'blockAllowsUTEdit' => false,
1526 ]
1527 ],
1528 ];
1529 }
1530
1531 /**
1532 * @covers \MediaWiki\Permissions\PermissionManager::getUserPermissions
1533 */
1534 public function testGetUserPermissions() {
1535 $user = $this->getTestUser( [ 'unittesters' ] )->getUser();
1536 $rights = MediaWikiServices::getInstance()->getPermissionManager()
1537 ->getUserPermissions( $user );
1538 $this->assertContains( 'runtest', $rights );
1539 $this->assertNotContains( 'writetest', $rights );
1540 $this->assertNotContains( 'modifytest', $rights );
1541 $this->assertNotContains( 'nukeworld', $rights );
1542 }
1543
1544 /**
1545 * @covers \MediaWiki\Permissions\PermissionManager::getUserPermissions
1546 */
1547 public function testGetUserPermissionsHooks() {
1548 $user = $this->getTestUser( [ 'unittesters', 'testwriters' ] )->getUser();
1549 $userWrapper = TestingAccessWrapper::newFromObject( $user );
1550
1551 $rights = MediaWikiServices::getInstance()->getPermissionManager()
1552 ->getUserPermissions( $user );
1553 $this->assertContains( 'test', $rights, 'sanity check' );
1554 $this->assertContains( 'runtest', $rights, 'sanity check' );
1555 $this->assertContains( 'writetest', $rights, 'sanity check' );
1556 $this->assertNotContains( 'nukeworld', $rights, 'sanity check' );
1557
1558 // Add a hook manipluating the rights
1559 $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'UserGetRights' => [ function ( $user, &$rights ) {
1560 $rights[] = 'nukeworld';
1561 $rights = array_diff( $rights, [ 'writetest' ] );
1562 } ] ] );
1563
1564 $this->resetServices();
1565 $rights = MediaWikiServices::getInstance()->getPermissionManager()
1566 ->getUserPermissions( $user );
1567 $this->assertContains( 'test', $rights );
1568 $this->assertContains( 'runtest', $rights );
1569 $this->assertNotContains( 'writetest', $rights );
1570 $this->assertContains( 'nukeworld', $rights );
1571
1572 // Add a Session that limits rights
1573 $mock = $this->getMockBuilder( stdClass::class )
1574 ->setMethods( [ 'getAllowedUserRights', 'deregisterSession', 'getSessionId' ] )
1575 ->getMock();
1576 $mock->method( 'getAllowedUserRights' )->willReturn( [ 'test', 'writetest' ] );
1577 $mock->method( 'getSessionId' )->willReturn(
1578 new SessionId( str_repeat( 'X', 32 ) )
1579 );
1580 $session = TestUtils::getDummySession( $mock );
1581 $mockRequest = $this->getMockBuilder( FauxRequest::class )
1582 ->setMethods( [ 'getSession' ] )
1583 ->getMock();
1584 $mockRequest->method( 'getSession' )->willReturn( $session );
1585 $userWrapper->mRequest = $mockRequest;
1586
1587 $this->resetServices();
1588 $rights = MediaWikiServices::getInstance()->getPermissionManager()
1589 ->getUserPermissions( $user );
1590 $this->assertContains( 'test', $rights );
1591 $this->assertNotContains( 'runtest', $rights );
1592 $this->assertNotContains( 'writetest', $rights );
1593 $this->assertNotContains( 'nukeworld', $rights );
1594 }
1595
1596 /**
1597 * @covers \MediaWiki\Permissions\PermissionManager::getGroupPermissions
1598 */
1599 public function testGroupPermissions() {
1600 $rights = MediaWikiServices::getInstance()->getPermissionManager()
1601 ->getGroupPermissions( [ 'unittesters' ] );
1602 $this->assertContains( 'runtest', $rights );
1603 $this->assertNotContains( 'writetest', $rights );
1604 $this->assertNotContains( 'modifytest', $rights );
1605 $this->assertNotContains( 'nukeworld', $rights );
1606
1607 $rights = MediaWikiServices::getInstance()->getPermissionManager()
1608 ->getGroupPermissions( [ 'unittesters', 'testwriters' ] );
1609 $this->assertContains( 'runtest', $rights );
1610 $this->assertContains( 'writetest', $rights );
1611 $this->assertContains( 'modifytest', $rights );
1612 $this->assertNotContains( 'nukeworld', $rights );
1613 }
1614
1615 /**
1616 * @covers \MediaWiki\Permissions\PermissionManager::getGroupPermissions
1617 */
1618 public function testRevokePermissions() {
1619 $rights = MediaWikiServices::getInstance()->getPermissionManager()
1620 ->getGroupPermissions( [ 'unittesters', 'formertesters' ] );
1621 $this->assertNotContains( 'runtest', $rights );
1622 $this->assertNotContains( 'writetest', $rights );
1623 $this->assertNotContains( 'modifytest', $rights );
1624 $this->assertNotContains( 'nukeworld', $rights );
1625 }
1626
1627 /**
1628 * @dataProvider provideGetGroupsWithPermission
1629 * @covers \MediaWiki\Permissions\PermissionManager::getGroupsWithPermission
1630 */
1631 public function testGetGroupsWithPermission( $expected, $right ) {
1632 $result = MediaWikiServices::getInstance()->getPermissionManager()
1633 ->getGroupsWithPermission( $right );
1634 sort( $result );
1635 sort( $expected );
1636
1637 $this->assertEquals( $expected, $result, "Groups with permission $right" );
1638 }
1639
1640 public static function provideGetGroupsWithPermission() {
1641 return [
1642 [
1643 [ 'unittesters', 'testwriters' ],
1644 'test'
1645 ],
1646 [
1647 [ 'unittesters' ],
1648 'runtest'
1649 ],
1650 [
1651 [ 'testwriters' ],
1652 'writetest'
1653 ],
1654 [
1655 [ 'testwriters' ],
1656 'modifytest'
1657 ],
1658 ];
1659 }
1660
1661 /**
1662 * @covers \MediaWiki\Permissions\PermissionManager::userHasRight
1663 */
1664 public function testUserHasRight() {
1665 $result = MediaWikiServices::getInstance()->getPermissionManager()->userHasRight(
1666 $this->getTestUser( 'unittesters' )->getUser(),
1667 'test'
1668 );
1669 $this->assertTrue( $result );
1670
1671 $result = MediaWikiServices::getInstance()->getPermissionManager()->userHasRight(
1672 $this->getTestUser( 'formertesters' )->getUser(),
1673 'runtest'
1674 );
1675 $this->assertFalse( $result );
1676
1677 $result = MediaWikiServices::getInstance()->getPermissionManager()->userHasRight(
1678 $this->getTestUser( 'formertesters' )->getUser(),
1679 ''
1680 );
1681 $this->assertTrue( $result );
1682 }
1683
1684 /**
1685 * @covers \MediaWiki\Permissions\PermissionManager::groupHasPermission
1686 */
1687 public function testGroupHasPermission() {
1688 $result = MediaWikiServices::getInstance()->getPermissionManager()->groupHasPermission(
1689 'unittesters',
1690 'test'
1691 );
1692 $this->assertTrue( $result );
1693
1694 $result = MediaWikiServices::getInstance()->getPermissionManager()->groupHasPermission(
1695 'formertesters',
1696 'runtest'
1697 );
1698 $this->assertFalse( $result );
1699 }
1700
1701 /**
1702 * @covers \MediaWiki\Permissions\PermissionManager::isEveryoneAllowed
1703 */
1704 public function testIsEveryoneAllowed() {
1705 $result = MediaWikiServices::getInstance()->getPermissionManager()
1706 ->isEveryoneAllowed( 'editmyoptions' );
1707 $this->assertTrue( $result );
1708
1709 $result = MediaWikiServices::getInstance()->getPermissionManager()
1710 ->isEveryoneAllowed( 'test' );
1711 $this->assertFalse( $result );
1712 }
1713
1714 /**
1715 * @covers \MediaWiki\Permissions\PermissionManager::addTemporaryUserRights
1716 */
1717 public function testAddTemporaryUserRights() {
1718 $permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
1719 $this->overrideUserPermissions( $this->user, [ 'read', 'edit' ] );
1720 // sanity checks
1721 $this->assertEquals( [ 'read', 'edit' ], $permissionManager->getUserPermissions( $this->user ) );
1722 $this->assertFalse( $permissionManager->userHasRight( $this->user, 'move' ) );
1723
1724 $scope = $permissionManager->addTemporaryUserRights( $this->user, [ 'move', 'delete' ] );
1725 $this->assertEquals( [ 'read', 'edit', 'move', 'delete' ],
1726 $permissionManager->getUserPermissions( $this->user ) );
1727 $this->assertTrue( $permissionManager->userHasRight( $this->user, 'move' ) );
1728
1729 $scope2 = $permissionManager->addTemporaryUserRights( $this->user, [ 'delete', 'upload' ] );
1730 $this->assertEquals( [ 'read', 'edit', 'move', 'delete', 'upload' ],
1731 $permissionManager->getUserPermissions( $this->user ) );
1732
1733 ScopedCallback::consume( $scope );
1734 $this->assertEquals( [ 'read', 'edit', 'delete', 'upload' ],
1735 $permissionManager->getUserPermissions( $this->user ) );
1736 ScopedCallback::consume( $scope2 );
1737 $this->assertEquals( [ 'read', 'edit' ],
1738 $permissionManager->getUserPermissions( $this->user ) );
1739 $this->assertFalse( $permissionManager->userHasRight( $this->user, 'move' ) );
1740
1741 ( function () use ( $permissionManager ) {
1742 $scope = $permissionManager->addTemporaryUserRights( $this->user, 'move' );
1743 $this->assertTrue( $permissionManager->userHasRight( $this->user, 'move' ) );
1744 } )();
1745 $this->assertFalse( $permissionManager->userHasRight( $this->user, 'move' ) );
1746 }
1747
1748 /**
1749 * Create a RevisionRecord with a single Javascript main slot.
1750 * @param Title $title
1751 * @param User $user
1752 * @param string $text
1753 * @return MutableRevisionRecord
1754 */
1755 private function getJavascriptRevision( Title $title, User $user, $text ) {
1756 $content = ContentHandler::makeContent( $text, $title, CONTENT_MODEL_JAVASCRIPT );
1757 $revision = new MutableRevisionRecord( $title );
1758 $revision->setContent( 'main', $content );
1759 return $revision;
1760 }
1761
1762 /**
1763 * Create a RevisionRecord with a single Javascript redirect main slot.
1764 * @param Title $title
1765 * @param Title $redirectTargetTitle
1766 * @param User $user
1767 * @return MutableRevisionRecord
1768 */
1769 private function getJavascriptRedirectRevision(
1770 Title $title, Title $redirectTargetTitle, User $user
1771 ) {
1772 $content = ContentHandler::getForModelID( CONTENT_MODEL_JAVASCRIPT )
1773 ->makeRedirectContent( $redirectTargetTitle );
1774 $revision = new MutableRevisionRecord( $title );
1775 $revision->setContent( 'main', $content );
1776 return $revision;
1777 }
1778
1779 }