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