Merge "Cleanup LinkerTest leakage between provider entries"
[lhc/web/wiklou.git] / tests / phpunit / includes / TitlePermissionTest.php
1 <?php
2
3 use MediaWiki\Block\DatabaseBlock;
4 use MediaWiki\Block\Restriction\PageRestriction;
5 use MediaWiki\Block\SystemBlock;
6 use MediaWiki\MediaWikiServices;
7
8 /**
9 * @group Database
10 *
11 * @covers \MediaWiki\Permissions\PermissionManager::getPermissionErrors
12 * @covers \MediaWiki\Permissions\PermissionManager::getPermissionErrorsInternal
13 */
14 class TitlePermissionTest extends MediaWikiLangTestCase {
15
16 /**
17 * @var string
18 */
19 protected $userName, $altUserName;
20
21 /**
22 * @var Title
23 */
24 protected $title;
25
26 /**
27 * @var User
28 */
29 protected $user, $anonUser, $userUser, $altUser;
30
31 protected function setUp() {
32 parent::setUp();
33
34 $localZone = 'UTC';
35 $localOffset = date( 'Z' ) / 60;
36
37 $this->setMwGlobals( [
38 'wgLocaltimezone' => $localZone,
39 'wgLocalTZoffset' => $localOffset,
40 'wgNamespaceProtection' => [
41 NS_MEDIAWIKI => 'editinterface',
42 ],
43 ] );
44 // Without this testUserBlock will use a non-English context on non-English MediaWiki
45 // installations (because of how Title::checkUserBlock is implemented) and fail.
46 RequestContext::resetMain();
47
48 $this->userName = 'Useruser';
49 $this->altUserName = 'Altuseruser';
50 date_default_timezone_set( $localZone );
51
52 $this->title = Title::makeTitle( NS_MAIN, "Main Page" );
53 if ( !isset( $this->userUser ) || !( $this->userUser instanceof User ) ) {
54 $this->userUser = User::newFromName( $this->userName );
55
56 if ( !$this->userUser->getId() ) {
57 $this->userUser = User::createNew( $this->userName, [
58 "email" => "test@example.com",
59 "real_name" => "Test User" ] );
60 $this->userUser->load();
61 }
62
63 $this->altUser = User::newFromName( $this->altUserName );
64 if ( !$this->altUser->getId() ) {
65 $this->altUser = User::createNew( $this->altUserName, [
66 "email" => "alttest@example.com",
67 "real_name" => "Test User Alt" ] );
68 $this->altUser->load();
69 }
70
71 $this->anonUser = User::newFromId( 0 );
72
73 $this->user = $this->userUser;
74 }
75 $this->overrideMwServices();
76 }
77
78 protected function setUserPerm( $perm ) {
79 // Setting member variables is evil!!!
80
81 if ( is_array( $perm ) ) {
82 $this->user->mRights = $perm;
83 } else {
84 $this->user->mRights = [ $perm ];
85 }
86 }
87
88 protected function setTitle( $ns, $title = "Main_Page" ) {
89 $this->title = Title::makeTitle( $ns, $title );
90 }
91
92 protected function setUser( $userName = null ) {
93 if ( $userName === 'anon' ) {
94 $this->user = $this->anonUser;
95 } elseif ( $userName === null || $userName === $this->userName ) {
96 $this->user = $this->userUser;
97 } else {
98 $this->user = $this->altUser;
99 }
100 }
101
102 /**
103 * @todo This test method should be split up into separate test methods and
104 * data providers
105 *
106 * This test is failing per T201776.
107 *
108 * @group Broken
109 * @covers \MediaWiki\Permissions\PermissionManager::checkQuickPermissions
110 */
111 public function testQuickPermissions() {
112 $prefix = MediaWikiServices::getInstance()->getContentLanguage()->
113 getFormattedNsText( NS_PROJECT );
114
115 $this->setUser( 'anon' );
116 $this->setTitle( NS_TALK );
117 $this->setUserPerm( "createtalk" );
118 $res = $this->title->getUserPermissionsErrors( 'create', $this->user );
119 $this->assertEquals( [], $res );
120
121 $this->setTitle( NS_TALK );
122 $this->setUserPerm( "createpage" );
123 $res = $this->title->getUserPermissionsErrors( 'create', $this->user );
124 $this->assertEquals( [ [ "nocreatetext" ] ], $res );
125
126 $this->setTitle( NS_TALK );
127 $this->setUserPerm( "" );
128 $res = $this->title->getUserPermissionsErrors( 'create', $this->user );
129 $this->assertEquals( [ [ 'nocreatetext' ] ], $res );
130
131 $this->setTitle( NS_MAIN );
132 $this->setUserPerm( "createpage" );
133 $res = $this->title->getUserPermissionsErrors( 'create', $this->user );
134 $this->assertEquals( [], $res );
135
136 $this->setTitle( NS_MAIN );
137 $this->setUserPerm( "createtalk" );
138 $res = $this->title->getUserPermissionsErrors( 'create', $this->user );
139 $this->assertEquals( [ [ 'nocreatetext' ] ], $res );
140
141 $this->setUser( $this->userName );
142 $this->setTitle( NS_TALK );
143 $this->setUserPerm( "createtalk" );
144 $res = $this->title->getUserPermissionsErrors( 'create', $this->user );
145 $this->assertEquals( [], $res );
146
147 $this->setTitle( NS_TALK );
148 $this->setUserPerm( "createpage" );
149 $res = $this->title->getUserPermissionsErrors( 'create', $this->user );
150 $this->assertEquals( [ [ 'nocreate-loggedin' ] ], $res );
151
152 $this->setTitle( NS_TALK );
153 $this->setUserPerm( "" );
154 $res = $this->title->getUserPermissionsErrors( 'create', $this->user );
155 $this->assertEquals( [ [ 'nocreate-loggedin' ] ], $res );
156
157 $this->setTitle( NS_MAIN );
158 $this->setUserPerm( "createpage" );
159 $res = $this->title->getUserPermissionsErrors( 'create', $this->user );
160 $this->assertEquals( [], $res );
161
162 $this->setTitle( NS_MAIN );
163 $this->setUserPerm( "createtalk" );
164 $res = $this->title->getUserPermissionsErrors( 'create', $this->user );
165 $this->assertEquals( [ [ 'nocreate-loggedin' ] ], $res );
166
167 $this->setTitle( NS_MAIN );
168 $this->setUserPerm( "" );
169 $res = $this->title->getUserPermissionsErrors( 'create', $this->user );
170 $this->assertEquals( [ [ 'nocreate-loggedin' ] ], $res );
171
172 $this->setUser( 'anon' );
173 $this->setTitle( NS_USER, $this->userName . '' );
174 $this->setUserPerm( "" );
175 $res = $this->title->getUserPermissionsErrors( 'move', $this->user );
176 $this->assertEquals( [ [ 'cant-move-user-page' ], [ 'movenologintext' ] ], $res );
177
178 $this->setTitle( NS_USER, $this->userName . '/subpage' );
179 $this->setUserPerm( "" );
180 $res = $this->title->getUserPermissionsErrors( 'move', $this->user );
181 $this->assertEquals( [ [ 'movenologintext' ] ], $res );
182
183 $this->setTitle( NS_USER, $this->userName . '' );
184 $this->setUserPerm( "move-rootuserpages" );
185 $res = $this->title->getUserPermissionsErrors( 'move', $this->user );
186 $this->assertEquals( [ [ 'movenologintext' ] ], $res );
187
188 $this->setTitle( NS_USER, $this->userName . '/subpage' );
189 $this->setUserPerm( "move-rootuserpages" );
190 $res = $this->title->getUserPermissionsErrors( 'move', $this->user );
191 $this->assertEquals( [ [ 'movenologintext' ] ], $res );
192
193 $this->setTitle( NS_USER, $this->userName . '' );
194 $this->setUserPerm( "" );
195 $res = $this->title->getUserPermissionsErrors( 'move', $this->user );
196 $this->assertEquals( [ [ 'cant-move-user-page' ], [ 'movenologintext' ] ], $res );
197
198 $this->setTitle( NS_USER, $this->userName . '/subpage' );
199 $this->setUserPerm( "" );
200 $res = $this->title->getUserPermissionsErrors( 'move', $this->user );
201 $this->assertEquals( [ [ 'movenologintext' ] ], $res );
202
203 $this->setTitle( NS_USER, $this->userName . '' );
204 $this->setUserPerm( "move-rootuserpages" );
205 $res = $this->title->getUserPermissionsErrors( 'move', $this->user );
206 $this->assertEquals( [ [ 'movenologintext' ] ], $res );
207
208 $this->setTitle( NS_USER, $this->userName . '/subpage' );
209 $this->setUserPerm( "move-rootuserpages" );
210 $res = $this->title->getUserPermissionsErrors( 'move', $this->user );
211 $this->assertEquals( [ [ 'movenologintext' ] ], $res );
212
213 $this->setUser( $this->userName );
214 $this->setTitle( NS_FILE, "img.png" );
215 $this->setUserPerm( "" );
216 $res = $this->title->getUserPermissionsErrors( 'move', $this->user );
217 $this->assertEquals( [ [ 'movenotallowedfile' ], [ 'movenotallowed' ] ], $res );
218
219 $this->setTitle( NS_FILE, "img.png" );
220 $this->setUserPerm( "movefile" );
221 $res = $this->title->getUserPermissionsErrors( 'move', $this->user );
222 $this->assertEquals( [ [ 'movenotallowed' ] ], $res );
223
224 $this->setUser( 'anon' );
225 $this->setTitle( NS_FILE, "img.png" );
226 $this->setUserPerm( "" );
227 $res = $this->title->getUserPermissionsErrors( 'move', $this->user );
228 $this->assertEquals( [ [ 'movenotallowedfile' ], [ 'movenologintext' ] ], $res );
229
230 $this->setTitle( NS_FILE, "img.png" );
231 $this->setUserPerm( "movefile" );
232 $res = $this->title->getUserPermissionsErrors( 'move', $this->user );
233 $this->assertEquals( [ [ 'movenologintext' ] ], $res );
234
235 $this->setUser( $this->userName );
236 $this->setUserPerm( "move" );
237 $this->runGroupPermissions( 'move', [ [ 'movenotallowedfile' ] ] );
238
239 $this->setUserPerm( "" );
240 $this->runGroupPermissions(
241 'move',
242 [ [ 'movenotallowedfile' ], [ 'movenotallowed' ] ]
243 );
244
245 $this->setUser( 'anon' );
246 $this->setUserPerm( "move" );
247 $this->runGroupPermissions( 'move', [ [ 'movenotallowedfile' ] ] );
248
249 $this->setUserPerm( "" );
250 $this->runGroupPermissions(
251 'move',
252 [ [ 'movenotallowedfile' ], [ 'movenotallowed' ] ],
253 [ [ 'movenotallowedfile' ], [ 'movenologintext' ] ]
254 );
255
256 if ( $this->isWikitextNS( NS_MAIN ) ) {
257 // NOTE: some content models don't allow moving
258 // @todo find a Wikitext namespace for testing
259
260 $this->setTitle( NS_MAIN );
261 $this->setUser( 'anon' );
262 $this->setUserPerm( "move" );
263 $this->runGroupPermissions( 'move', [] );
264
265 $this->setUserPerm( "" );
266 $this->runGroupPermissions( 'move', [ [ 'movenotallowed' ] ],
267 [ [ 'movenologintext' ] ] );
268
269 $this->setUser( $this->userName );
270 $this->setUserPerm( "" );
271 $this->runGroupPermissions( 'move', [ [ 'movenotallowed' ] ] );
272
273 $this->setUserPerm( "move" );
274 $this->runGroupPermissions( 'move', [] );
275
276 $this->setUser( 'anon' );
277 $this->setUserPerm( 'move' );
278 $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
279 $this->assertEquals( [], $res );
280
281 $this->setUserPerm( '' );
282 $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
283 $this->assertEquals( [ [ 'movenotallowed' ] ], $res );
284 }
285
286 $this->setTitle( NS_USER );
287 $this->setUser( $this->userName );
288 $this->setUserPerm( [ "move", "move-rootuserpages" ] );
289 $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
290 $this->assertEquals( [], $res );
291
292 $this->setUserPerm( "move" );
293 $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
294 $this->assertEquals( [ [ 'cant-move-to-user-page' ] ], $res );
295
296 $this->setUser( 'anon' );
297 $this->setUserPerm( [ "move", "move-rootuserpages" ] );
298 $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
299 $this->assertEquals( [], $res );
300
301 $this->setTitle( NS_USER, "User/subpage" );
302 $this->setUserPerm( [ "move", "move-rootuserpages" ] );
303 $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
304 $this->assertEquals( [], $res );
305
306 $this->setUserPerm( "move" );
307 $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
308 $this->assertEquals( [], $res );
309
310 $this->setUser( 'anon' );
311 $check = [
312 'edit' => [
313 [ [ 'badaccess-groups', "*, [[$prefix:Users|Users]]", 2 ] ],
314 [ [ 'badaccess-group0' ] ],
315 [],
316 true
317 ],
318 'protect' => [
319 [ [
320 'badaccess-groups',
321 "[[$prefix:Administrators|Administrators]]", 1 ],
322 [ 'protect-cantedit'
323 ] ],
324 [ [ 'badaccess-group0' ], [ 'protect-cantedit' ] ],
325 [ [ 'protect-cantedit' ] ],
326 false
327 ],
328 '' => [ [], [], [], true ]
329 ];
330
331 foreach ( [ "edit", "protect", "" ] as $action ) {
332 $this->setUserPerm( null );
333 $this->assertEquals( $check[$action][0],
334 $this->title->getUserPermissionsErrors( $action, $this->user, true ) );
335 $this->assertEquals( $check[$action][0],
336 $this->title->getUserPermissionsErrors( $action, $this->user, 'full' ) );
337 $this->assertEquals( $check[$action][0],
338 $this->title->getUserPermissionsErrors( $action, $this->user, 'secure' ) );
339
340 global $wgGroupPermissions;
341 $old = $wgGroupPermissions;
342 $wgGroupPermissions = [];
343
344 $this->assertEquals( $check[$action][1],
345 $this->title->getUserPermissionsErrors( $action, $this->user, true ) );
346 $this->assertEquals( $check[$action][1],
347 $this->title->getUserPermissionsErrors( $action, $this->user, 'full' ) );
348 $this->assertEquals( $check[$action][1],
349 $this->title->getUserPermissionsErrors( $action, $this->user, 'secure' ) );
350 $wgGroupPermissions = $old;
351
352 $this->setUserPerm( $action );
353 $this->assertEquals( $check[$action][2],
354 $this->title->getUserPermissionsErrors( $action, $this->user, true ) );
355 $this->assertEquals( $check[$action][2],
356 $this->title->getUserPermissionsErrors( $action, $this->user, 'full' ) );
357 $this->assertEquals( $check[$action][2],
358 $this->title->getUserPermissionsErrors( $action, $this->user, 'secure' ) );
359
360 $this->setUserPerm( $action );
361 $this->assertEquals( $check[$action][3],
362 $this->title->userCan( $action, $this->user, true ) );
363 $this->assertEquals( $check[$action][3],
364 $this->title->quickUserCan( $action, $this->user ) );
365 # count( User::getGroupsWithPermissions( $action ) ) < 1
366 }
367 }
368
369 protected function runGroupPermissions( $action, $result, $result2 = null ) {
370 global $wgGroupPermissions;
371
372 if ( $result2 === null ) {
373 $result2 = $result;
374 }
375
376 $wgGroupPermissions['autoconfirmed']['move'] = false;
377 $wgGroupPermissions['user']['move'] = false;
378 $res = $this->title->getUserPermissionsErrors( $action, $this->user );
379 $this->assertEquals( $result, $res );
380
381 $wgGroupPermissions['autoconfirmed']['move'] = true;
382 $wgGroupPermissions['user']['move'] = false;
383 $res = $this->title->getUserPermissionsErrors( $action, $this->user );
384 $this->assertEquals( $result2, $res );
385
386 $wgGroupPermissions['autoconfirmed']['move'] = true;
387 $wgGroupPermissions['user']['move'] = true;
388 $res = $this->title->getUserPermissionsErrors( $action, $this->user );
389 $this->assertEquals( $result2, $res );
390
391 $wgGroupPermissions['autoconfirmed']['move'] = false;
392 $wgGroupPermissions['user']['move'] = true;
393 $res = $this->title->getUserPermissionsErrors( $action, $this->user );
394 $this->assertEquals( $result2, $res );
395 }
396
397 /**
398 * @todo This test method should be split up into separate test methods and
399 * data providers
400 * @covers \MediaWiki\Permissions\PermissionManager::checkSpecialsAndNSPermissions
401 */
402 public function testSpecialsAndNSPermissions() {
403 global $wgNamespaceProtection;
404 $this->setUser( $this->userName );
405
406 $this->setTitle( NS_SPECIAL );
407
408 $this->assertEquals( [ [ 'badaccess-group0' ], [ 'ns-specialprotected' ] ],
409 $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
410
411 $this->setTitle( NS_MAIN );
412 $this->setUserPerm( 'bogus' );
413 $this->assertEquals( [],
414 $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
415
416 $this->setTitle( NS_MAIN );
417 $this->setUserPerm( '' );
418 $this->assertEquals( [ [ 'badaccess-group0' ] ],
419 $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
420
421 $wgNamespaceProtection[NS_USER] = [ 'bogus' ];
422
423 $this->setTitle( NS_USER );
424 $this->setUserPerm( '' );
425 $this->assertEquals( [ [ 'badaccess-group0' ],
426 [ 'namespaceprotected', 'User', 'bogus' ] ],
427 $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
428
429 $this->setTitle( NS_MEDIAWIKI );
430 $this->setUserPerm( 'bogus' );
431 $this->assertEquals( [ [ 'protectedinterface', 'bogus' ] ],
432 $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
433
434 $this->setTitle( NS_MEDIAWIKI );
435 $this->setUserPerm( 'bogus' );
436 $this->assertEquals( [ [ 'protectedinterface', 'bogus' ] ],
437 $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
438
439 $wgNamespaceProtection = null;
440
441 $this->setUserPerm( 'bogus' );
442 $this->assertEquals( [],
443 $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
444 $this->assertEquals( true,
445 $this->title->userCan( 'bogus', $this->user ) );
446
447 $this->setUserPerm( '' );
448 $this->assertEquals( [ [ 'badaccess-group0' ] ],
449 $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
450 $this->assertEquals( false,
451 $this->title->userCan( 'bogus', $this->user ) );
452 }
453
454 /**
455 * @todo This test method should be split up into separate test methods and
456 * data providers
457 * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
458 */
459 public function testJsConfigEditPermissions() {
460 $this->setUser( $this->userName );
461
462 $this->setTitle( NS_USER, $this->userName . '/test.js' );
463 $this->runConfigEditPermissions(
464 [ [ 'badaccess-group0' ], [ 'mycustomjsprotected', 'bogus' ] ],
465
466 [ [ 'badaccess-group0' ], [ 'mycustomjsprotected', 'bogus' ] ],
467 [ [ 'badaccess-group0' ], [ 'mycustomjsprotected', 'bogus' ] ],
468 [ [ 'badaccess-group0' ] ],
469
470 [ [ 'badaccess-group0' ], [ 'mycustomjsprotected', 'bogus' ] ],
471 [ [ 'badaccess-group0' ], [ 'mycustomjsprotected', 'bogus' ] ],
472 [ [ 'badaccess-group0' ] ],
473 [ [ 'badaccess-groups' ] ]
474 );
475 }
476
477 /**
478 * @todo This test method should be split up into separate test methods and
479 * data providers
480 * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
481 */
482 public function testJsonConfigEditPermissions() {
483 $prefix = MediaWikiServices::getInstance()->getContentLanguage()->
484 getFormattedNsText( NS_PROJECT );
485 $this->setUser( $this->userName );
486
487 $this->setTitle( NS_USER, $this->userName . '/test.json' );
488 $this->runConfigEditPermissions(
489 [ [ 'badaccess-group0' ], [ 'mycustomjsonprotected', 'bogus' ] ],
490
491 [ [ 'badaccess-group0' ], [ 'mycustomjsonprotected', 'bogus' ] ],
492 [ [ 'badaccess-group0' ] ],
493 [ [ 'badaccess-group0' ], [ 'mycustomjsonprotected', 'bogus' ] ],
494
495 [ [ 'badaccess-group0' ], [ 'mycustomjsonprotected', 'bogus' ] ],
496 [ [ 'badaccess-group0' ] ],
497 [ [ 'badaccess-group0' ], [ 'mycustomjsonprotected', 'bogus' ] ],
498 [ [ 'badaccess-groups' ] ]
499 );
500 }
501
502 /**
503 * @todo This test method should be split up into separate test methods and
504 * data providers
505 * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
506 */
507 public function testCssConfigEditPermissions() {
508 $this->setUser( $this->userName );
509
510 $this->setTitle( NS_USER, $this->userName . '/test.css' );
511 $this->runConfigEditPermissions(
512 [ [ 'badaccess-group0' ], [ 'mycustomcssprotected', 'bogus' ] ],
513
514 [ [ 'badaccess-group0' ] ],
515 [ [ 'badaccess-group0' ], [ 'mycustomcssprotected', 'bogus' ] ],
516 [ [ 'badaccess-group0' ], [ 'mycustomcssprotected', 'bogus' ] ],
517
518 [ [ 'badaccess-group0' ] ],
519 [ [ 'badaccess-group0' ], [ 'mycustomcssprotected', 'bogus' ] ],
520 [ [ 'badaccess-group0' ], [ 'mycustomcssprotected', 'bogus' ] ],
521 [ [ 'badaccess-groups' ] ]
522 );
523 }
524
525 /**
526 * @todo This test method should be split up into separate test methods and
527 * data providers
528 * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
529 */
530 public function testOtherJsConfigEditPermissions() {
531 $this->setUser( $this->userName );
532
533 $this->setTitle( NS_USER, $this->altUserName . '/test.js' );
534 $this->runConfigEditPermissions(
535 [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
536
537 [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
538 [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
539 [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
540
541 [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
542 [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
543 [ [ 'badaccess-group0' ] ],
544 [ [ 'badaccess-groups' ] ]
545 );
546 }
547
548 /**
549 * @todo This test method should be split up into separate test methods and
550 * data providers
551 * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
552 */
553 public function testOtherJsonConfigEditPermissions() {
554 $this->setUser( $this->userName );
555
556 $this->setTitle( NS_USER, $this->altUserName . '/test.json' );
557 $this->runConfigEditPermissions(
558 [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
559
560 [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
561 [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
562 [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
563
564 [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
565 [ [ 'badaccess-group0' ] ],
566 [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
567 [ [ 'badaccess-groups' ] ]
568 );
569 }
570
571 /**
572 * @todo This test method should be split up into separate test methods and
573 * data providers
574 * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
575 */
576 public function testOtherCssConfigEditPermissions() {
577 $this->setUser( $this->userName );
578
579 $this->setTitle( NS_USER, $this->altUserName . '/test.css' );
580 $this->runConfigEditPermissions(
581 [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
582
583 [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
584 [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
585 [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
586
587 [ [ 'badaccess-group0' ] ],
588 [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
589 [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
590 [ [ 'badaccess-groups' ] ]
591 );
592 }
593
594 /**
595 * @todo This test method should be split up into separate test methods and
596 * data providers
597 * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
598 */
599 public function testOtherNonConfigEditPermissions() {
600 $this->setUser( $this->userName );
601
602 $this->setTitle( NS_USER, $this->altUserName . '/tempo' );
603 $this->runConfigEditPermissions(
604 [ [ 'badaccess-group0' ] ],
605
606 [ [ 'badaccess-group0' ] ],
607 [ [ 'badaccess-group0' ] ],
608 [ [ 'badaccess-group0' ] ],
609
610 [ [ 'badaccess-group0' ] ],
611 [ [ 'badaccess-group0' ] ],
612 [ [ 'badaccess-group0' ] ],
613 [ [ 'badaccess-groups' ] ]
614 );
615 }
616
617 /**
618 * @todo This should use data providers like the other methods here.
619 * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
620 */
621 public function testPatrolActionConfigEditPermissions() {
622 $this->setUser( 'anon' );
623 $this->setTitle( NS_USER, 'ToPatrolOrNotToPatrol' );
624 $this->runConfigEditPermissions(
625 [ [ 'badaccess-group0' ] ],
626
627 [ [ 'badaccess-group0' ] ],
628 [ [ 'badaccess-group0' ] ],
629 [ [ 'badaccess-group0' ] ],
630
631 [ [ 'badaccess-group0' ] ],
632 [ [ 'badaccess-group0' ] ],
633 [ [ 'badaccess-group0' ] ],
634 [ [ 'badaccess-groups' ] ]
635 );
636 }
637
638 protected function runConfigEditPermissions(
639 $resultNone,
640 $resultMyCss,
641 $resultMyJson,
642 $resultMyJs,
643 $resultUserCss,
644 $resultUserJson,
645 $resultUserJs,
646 $resultPatrol
647 ) {
648 $this->setUserPerm( '' );
649 $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user );
650 $this->assertEquals( $resultNone, $result );
651
652 $this->setUserPerm( 'editmyusercss' );
653 $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user );
654 $this->assertEquals( $resultMyCss, $result );
655
656 $this->setUserPerm( 'editmyuserjson' );
657 $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user );
658 $this->assertEquals( $resultMyJson, $result );
659
660 $this->setUserPerm( 'editmyuserjs' );
661 $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user );
662 $this->assertEquals( $resultMyJs, $result );
663
664 $this->setUserPerm( 'editusercss' );
665 $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user );
666 $this->assertEquals( $resultUserCss, $result );
667
668 $this->setUserPerm( 'edituserjson' );
669 $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user );
670 $this->assertEquals( $resultUserJson, $result );
671
672 $this->setUserPerm( 'edituserjs' );
673 $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user );
674 $this->assertEquals( $resultUserJs, $result );
675
676 $this->setUserPerm( '' );
677 $result = $this->title->getUserPermissionsErrors( 'patrol', $this->user );
678 $this->assertEquals( reset( $resultPatrol[0] ), reset( $result[0] ) );
679
680 $this->setUserPerm( [ 'edituserjs', 'edituserjson', 'editusercss' ] );
681 $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user );
682 $this->assertEquals( [ [ 'badaccess-group0' ] ], $result );
683 }
684
685 /**
686 * @todo This test method should be split up into separate test methods and
687 * data providers
688 *
689 * This test is failing per T201776.
690 *
691 * @group Broken
692 * @covers \MediaWiki\Permissions\PermissionManager::checkPageRestrictions
693 */
694 public function testPageRestrictions() {
695 $prefix = MediaWikiServices::getInstance()->getContentLanguage()->
696 getFormattedNsText( NS_PROJECT );
697
698 $this->setTitle( NS_MAIN );
699 $this->title->mRestrictionsLoaded = true;
700 $this->setUserPerm( "edit" );
701 $this->title->mRestrictions = [ "bogus" => [ 'bogus', "sysop", "protect", "" ] ];
702
703 $this->assertEquals( [],
704 $this->title->getUserPermissionsErrors( 'edit',
705 $this->user ) );
706
707 $this->assertEquals( true,
708 $this->title->quickUserCan( 'edit', $this->user ) );
709 $this->title->mRestrictions = [ "edit" => [ 'bogus', "sysop", "protect", "" ],
710 "bogus" => [ 'bogus', "sysop", "protect", "" ] ];
711
712 $this->assertEquals( [ [ 'badaccess-group0' ],
713 [ 'protectedpagetext', 'bogus', 'bogus' ],
714 [ 'protectedpagetext', 'editprotected', 'bogus' ],
715 [ 'protectedpagetext', 'protect', 'bogus' ] ],
716 $this->title->getUserPermissionsErrors( 'bogus',
717 $this->user ) );
718 $this->assertEquals( [ [ 'protectedpagetext', 'bogus', 'edit' ],
719 [ 'protectedpagetext', 'editprotected', 'edit' ],
720 [ 'protectedpagetext', 'protect', 'edit' ] ],
721 $this->title->getUserPermissionsErrors( 'edit',
722 $this->user ) );
723 $this->setUserPerm( "" );
724 $this->assertEquals( [ [ 'badaccess-group0' ],
725 [ 'protectedpagetext', 'bogus', 'bogus' ],
726 [ 'protectedpagetext', 'editprotected', 'bogus' ],
727 [ 'protectedpagetext', 'protect', 'bogus' ] ],
728 $this->title->getUserPermissionsErrors( 'bogus',
729 $this->user ) );
730 $this->assertEquals( [ [ 'badaccess-groups', "*, [[$prefix:Users|Users]]", 2 ],
731 [ 'protectedpagetext', 'bogus', 'edit' ],
732 [ 'protectedpagetext', 'editprotected', 'edit' ],
733 [ 'protectedpagetext', 'protect', 'edit' ] ],
734 $this->title->getUserPermissionsErrors( 'edit',
735 $this->user ) );
736 $this->setUserPerm( [ "edit", "editprotected" ] );
737 $this->assertEquals( [ [ 'badaccess-group0' ],
738 [ 'protectedpagetext', 'bogus', 'bogus' ],
739 [ 'protectedpagetext', 'protect', 'bogus' ] ],
740 $this->title->getUserPermissionsErrors( 'bogus',
741 $this->user ) );
742 $this->assertEquals( [
743 [ 'protectedpagetext', 'bogus', 'edit' ],
744 [ 'protectedpagetext', 'protect', 'edit' ] ],
745 $this->title->getUserPermissionsErrors( 'edit',
746 $this->user ) );
747
748 $this->title->mCascadeRestriction = true;
749 $this->setUserPerm( "edit" );
750 $this->assertEquals( false,
751 $this->title->quickUserCan( 'bogus', $this->user ) );
752 $this->assertEquals( false,
753 $this->title->quickUserCan( 'edit', $this->user ) );
754 $this->assertEquals( [ [ 'badaccess-group0' ],
755 [ 'protectedpagetext', 'bogus', 'bogus' ],
756 [ 'protectedpagetext', 'editprotected', 'bogus' ],
757 [ 'protectedpagetext', 'protect', 'bogus' ] ],
758 $this->title->getUserPermissionsErrors( 'bogus',
759 $this->user ) );
760 $this->assertEquals( [ [ 'protectedpagetext', 'bogus', 'edit' ],
761 [ 'protectedpagetext', 'editprotected', 'edit' ],
762 [ 'protectedpagetext', 'protect', 'edit' ] ],
763 $this->title->getUserPermissionsErrors( 'edit',
764 $this->user ) );
765
766 $this->setUserPerm( [ "edit", "editprotected" ] );
767 $this->assertEquals( false,
768 $this->title->quickUserCan( 'bogus', $this->user ) );
769 $this->assertEquals( false,
770 $this->title->quickUserCan( 'edit', $this->user ) );
771 $this->assertEquals( [ [ 'badaccess-group0' ],
772 [ 'protectedpagetext', 'bogus', 'bogus' ],
773 [ 'protectedpagetext', 'protect', 'bogus' ],
774 [ 'protectedpagetext', 'protect', 'bogus' ] ],
775 $this->title->getUserPermissionsErrors( 'bogus',
776 $this->user ) );
777 $this->assertEquals( [ [ 'protectedpagetext', 'bogus', 'edit' ],
778 [ 'protectedpagetext', 'protect', 'edit' ],
779 [ 'protectedpagetext', 'protect', 'edit' ] ],
780 $this->title->getUserPermissionsErrors( 'edit',
781 $this->user ) );
782 }
783
784 /**
785 * @covers \MediaWiki\Permissions\PermissionManager::checkCascadingSourcesRestrictions
786 */
787 public function testCascadingSourcesRestrictions() {
788 $this->setTitle( NS_MAIN, "test page" );
789 $this->setUserPerm( [ "edit", "bogus" ] );
790
791 $this->title->mCascadeSources = [
792 Title::makeTitle( NS_MAIN, "Bogus" ),
793 Title::makeTitle( NS_MAIN, "UnBogus" )
794 ];
795 $this->title->mCascadingRestrictions = [
796 "bogus" => [ 'bogus', "sysop", "protect", "" ]
797 ];
798
799 $this->assertEquals( false,
800 $this->title->userCan( 'bogus', $this->user ) );
801 $this->assertEquals( [
802 [ "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n", 'bogus' ],
803 [ "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n", 'bogus' ],
804 [ "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n", 'bogus' ] ],
805 $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
806
807 $this->assertEquals( true,
808 $this->title->userCan( 'edit', $this->user ) );
809 $this->assertEquals( [],
810 $this->title->getUserPermissionsErrors( 'edit', $this->user ) );
811 }
812
813 /**
814 * @todo This test method should be split up into separate test methods and
815 * data providers
816 * @covers \MediaWiki\Permissions\PermissionManager::checkActionPermissions
817 */
818 public function testActionPermissions() {
819 $this->setUserPerm( [ "createpage" ] );
820 $this->setTitle( NS_MAIN, "test page" );
821 $this->title->mTitleProtection['permission'] = '';
822 $this->title->mTitleProtection['user'] = $this->user->getId();
823 $this->title->mTitleProtection['expiry'] = 'infinity';
824 $this->title->mTitleProtection['reason'] = 'test';
825 $this->title->mCascadeRestriction = false;
826
827 $this->assertEquals( [ [ 'titleprotected', 'Useruser', 'test' ] ],
828 $this->title->getUserPermissionsErrors( 'create', $this->user ) );
829 $this->assertEquals( false,
830 $this->title->userCan( 'create', $this->user ) );
831
832 $this->title->mTitleProtection['permission'] = 'editprotected';
833 $this->setUserPerm( [ 'createpage', 'protect' ] );
834 $this->assertEquals( [ [ 'titleprotected', 'Useruser', 'test' ] ],
835 $this->title->getUserPermissionsErrors( 'create', $this->user ) );
836 $this->assertEquals( false,
837 $this->title->userCan( 'create', $this->user ) );
838
839 $this->setUserPerm( [ 'createpage', 'editprotected' ] );
840 $this->assertEquals( [],
841 $this->title->getUserPermissionsErrors( 'create', $this->user ) );
842 $this->assertEquals( true,
843 $this->title->userCan( 'create', $this->user ) );
844
845 $this->setUserPerm( [ 'createpage' ] );
846 $this->assertEquals( [ [ 'titleprotected', 'Useruser', 'test' ] ],
847 $this->title->getUserPermissionsErrors( 'create', $this->user ) );
848 $this->assertEquals( false,
849 $this->title->userCan( 'create', $this->user ) );
850
851 $this->setTitle( NS_MEDIA, "test page" );
852 $this->setUserPerm( [ "move" ] );
853 $this->assertEquals( false,
854 $this->title->userCan( 'move', $this->user ) );
855 $this->assertEquals( [ [ 'immobile-source-namespace', 'Media' ] ],
856 $this->title->getUserPermissionsErrors( 'move', $this->user ) );
857
858 $this->setTitle( NS_HELP, "test page" );
859 $this->assertEquals( [],
860 $this->title->getUserPermissionsErrors( 'move', $this->user ) );
861 $this->assertEquals( true,
862 $this->title->userCan( 'move', $this->user ) );
863
864 $this->title->mInterwiki = "no";
865 $this->assertEquals( [ [ 'immobile-source-page' ] ],
866 $this->title->getUserPermissionsErrors( 'move', $this->user ) );
867 $this->assertEquals( false,
868 $this->title->userCan( 'move', $this->user ) );
869
870 $this->setTitle( NS_MEDIA, "test page" );
871 $this->assertEquals( false,
872 $this->title->userCan( 'move-target', $this->user ) );
873 $this->assertEquals( [ [ 'immobile-target-namespace', 'Media' ] ],
874 $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
875
876 $this->setTitle( NS_HELP, "test page" );
877 $this->assertEquals( [],
878 $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
879 $this->assertEquals( true,
880 $this->title->userCan( 'move-target', $this->user ) );
881
882 $this->title->mInterwiki = "no";
883 $this->assertEquals( [ [ 'immobile-target-page' ] ],
884 $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
885 $this->assertEquals( false,
886 $this->title->userCan( 'move-target', $this->user ) );
887 }
888
889 /**
890 * @covers \MediaWiki\Permissions\PermissionManager::checkUserBlock
891 */
892 public function testUserBlock() {
893 $this->setMwGlobals( [
894 'wgEmailConfirmToEdit' => true,
895 'wgEmailAuthentication' => true,
896 'wgBlockDisablesLogin' => false,
897 ] );
898 $this->overrideMwServices();
899
900 $this->setUserPerm( [ 'createpage', 'edit', 'move', 'rollback', 'patrol', 'upload', 'purge' ] );
901 $this->setTitle( NS_HELP, "test page" );
902
903 # $wgEmailConfirmToEdit only applies to 'edit' action
904 $this->assertEquals( [],
905 $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
906 $this->assertContains( [ 'confirmedittext' ],
907 $this->title->getUserPermissionsErrors( 'edit', $this->user ) );
908
909 $this->setMwGlobals( 'wgEmailConfirmToEdit', false );
910 $this->overrideMwServices();
911
912 $this->assertNotContains( [ 'confirmedittext' ],
913 $this->title->getUserPermissionsErrors( 'edit', $this->user ) );
914
915 # $wgEmailConfirmToEdit && !$user->isEmailConfirmed() && $action != 'createaccount'
916 $this->assertEquals( [],
917 $this->title->getUserPermissionsErrors( 'move-target',
918 $this->user ) );
919
920 global $wgLang;
921 $prev = time();
922 $now = time() + 120;
923 $this->user->mBlockedby = $this->user->getId();
924 $this->user->mBlock = new DatabaseBlock( [
925 'address' => '127.0.8.1',
926 'by' => $this->user->getId(),
927 'reason' => 'no reason given',
928 'timestamp' => $prev + 3600,
929 'auto' => true,
930 'expiry' => 0
931 ] );
932 $this->user->mBlock->setTimestamp( 0 );
933 $this->assertEquals( [ [ 'autoblockedtext',
934 '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
935 'Useruser', null, 'infinite', '127.0.8.1',
936 $wgLang->timeanddate( wfTimestamp( TS_MW, $prev ), true ) ] ],
937 $this->title->getUserPermissionsErrors( 'move-target',
938 $this->user ) );
939
940 $this->assertEquals( false, $this->title->userCan( 'move-target', $this->user ) );
941 // quickUserCan should ignore user blocks
942 $this->assertEquals( true, $this->title->quickUserCan( 'move-target', $this->user ) );
943
944 global $wgLocalTZoffset;
945 $wgLocalTZoffset = -60;
946 $this->user->mBlockedby = $this->user->getName();
947 $this->user->mBlock = new DatabaseBlock( [
948 'address' => '127.0.8.1',
949 'by' => $this->user->getId(),
950 'reason' => 'no reason given',
951 'timestamp' => $now,
952 'auto' => false,
953 'expiry' => 10,
954 ] );
955 $this->assertEquals( [ [ 'blockedtext',
956 '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
957 'Useruser', null, '23:00, 31 December 1969', '127.0.8.1',
958 $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ],
959 $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
960 # $action != 'read' && $action != 'createaccount' && $user->isBlockedFrom( $this )
961 # $user->blockedFor() == ''
962 # $user->mBlock->mExpiry == 'infinity'
963
964 $this->user->mBlockedby = $this->user->getName();
965 $this->user->mBlock = new SystemBlock( [
966 'address' => '127.0.8.1',
967 'by' => $this->user->getId(),
968 'reason' => 'no reason given',
969 'timestamp' => $now,
970 'systemBlock' => 'test',
971 ] );
972
973 $errors = [ [ 'systemblockedtext',
974 '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
975 'Useruser', 'test', 'infinite', '127.0.8.1',
976 $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ];
977
978 $this->assertEquals( $errors,
979 $this->title->getUserPermissionsErrors( 'edit', $this->user ) );
980 $this->assertEquals( $errors,
981 $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
982 $this->assertEquals( $errors,
983 $this->title->getUserPermissionsErrors( 'rollback', $this->user ) );
984 $this->assertEquals( $errors,
985 $this->title->getUserPermissionsErrors( 'patrol', $this->user ) );
986 $this->assertEquals( $errors,
987 $this->title->getUserPermissionsErrors( 'upload', $this->user ) );
988 $this->assertEquals( [],
989 $this->title->getUserPermissionsErrors( 'purge', $this->user ) );
990
991 // partial block message test
992 $this->user->mBlockedby = $this->user->getName();
993 $this->user->mBlock = new DatabaseBlock( [
994 'address' => '127.0.8.1',
995 'by' => $this->user->getId(),
996 'reason' => 'no reason given',
997 'timestamp' => $now,
998 'sitewide' => false,
999 'expiry' => 10,
1000 ] );
1001
1002 $this->assertEquals( [],
1003 $this->title->getUserPermissionsErrors( 'edit', $this->user ) );
1004 $this->assertEquals( [],
1005 $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
1006 $this->assertEquals( [],
1007 $this->title->getUserPermissionsErrors( 'rollback', $this->user ) );
1008 $this->assertEquals( [],
1009 $this->title->getUserPermissionsErrors( 'patrol', $this->user ) );
1010 $this->assertEquals( [],
1011 $this->title->getUserPermissionsErrors( 'upload', $this->user ) );
1012 $this->assertEquals( [],
1013 $this->title->getUserPermissionsErrors( 'purge', $this->user ) );
1014
1015 $this->user->mBlock->setRestrictions( [
1016 ( new PageRestriction( 0, $this->title->getArticleID() ) )->setTitle( $this->title ),
1017 ] );
1018
1019 $errors = [ [ 'blockedtext-partial',
1020 '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
1021 'Useruser', null, '23:00, 31 December 1969', '127.0.8.1',
1022 $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ];
1023
1024 $this->assertEquals( $errors,
1025 $this->title->getUserPermissionsErrors( 'edit', $this->user ) );
1026 $this->assertEquals( $errors,
1027 $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
1028 $this->assertEquals( $errors,
1029 $this->title->getUserPermissionsErrors( 'rollback', $this->user ) );
1030 $this->assertEquals( $errors,
1031 $this->title->getUserPermissionsErrors( 'patrol', $this->user ) );
1032 $this->assertEquals( [],
1033 $this->title->getUserPermissionsErrors( 'upload', $this->user ) );
1034 $this->assertEquals( [],
1035 $this->title->getUserPermissionsErrors( 'purge', $this->user ) );
1036
1037 // Test no block.
1038 $this->user->mBlockedby = null;
1039 $this->user->mBlock = null;
1040
1041 $this->assertEquals( [],
1042 $this->title->getUserPermissionsErrors( 'edit', $this->user ) );
1043 }
1044
1045 /**
1046 * @covers \MediaWiki\Permissions\PermissionManager::checkUserBlock
1047 *
1048 * Tests to determine that the passed in permission does not get mixed up with
1049 * an action of the same name.
1050 */
1051 public function testUserBlockAction() {
1052 global $wgLang;
1053
1054 $tester = $this->getMockBuilder( Action::class )
1055 ->disableOriginalConstructor()
1056 ->getMock();
1057 $tester->method( 'getName' )
1058 ->willReturn( 'tester' );
1059 $tester->method( 'getRestriction' )
1060 ->willReturn( 'test' );
1061 $tester->method( 'requiresUnblock' )
1062 ->willReturn( false );
1063
1064 $this->setMwGlobals( [
1065 'wgActions' => [
1066 'tester' => $tester,
1067 ],
1068 'wgGroupPermissions' => [
1069 '*' => [
1070 'tester' => true,
1071 ],
1072 ],
1073 ] );
1074
1075 $now = time();
1076 $this->user->mBlockedby = $this->user->getName();
1077 $this->user->mBlock = new DatabaseBlock( [
1078 'address' => '127.0.8.1',
1079 'by' => $this->user->getId(),
1080 'reason' => 'no reason given',
1081 'timestamp' => $now,
1082 'auto' => false,
1083 'expiry' => 'infinity',
1084 ] );
1085
1086 $errors = [ [ 'blockedtext',
1087 '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
1088 'Useruser', null, 'infinite', '127.0.8.1',
1089 $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ];
1090
1091 $this->assertEquals( $errors,
1092 $this->title->getUserPermissionsErrors( 'tester', $this->user ) );
1093 }
1094 }