3 use MediaWiki\Block\DatabaseBlock
;
4 use MediaWiki\Block\Restriction\PageRestriction
;
5 use MediaWiki\Block\SystemBlock
;
6 use MediaWiki\MediaWikiServices
;
11 * @covers \MediaWiki\Permissions\PermissionManager::getPermissionErrors
12 * @covers \MediaWiki\Permissions\PermissionManager::getPermissionErrorsInternal
14 class TitlePermissionTest
extends MediaWikiLangTestCase
{
19 protected $userName, $altUserName;
29 protected $user, $anonUser, $userUser, $altUser;
31 protected function setUp() {
35 $localOffset = date( 'Z' ) / 60;
37 $this->setMwGlobals( [
38 'wgLocaltimezone' => $localZone,
39 'wgLocalTZoffset' => $localOffset,
40 'wgNamespaceProtection' => [
41 NS_MEDIAWIKI
=> 'editinterface',
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();
48 $this->userName
= 'Useruser';
49 $this->altUserName
= 'Altuseruser';
50 date_default_timezone_set( $localZone );
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
);
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();
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();
71 $this->anonUser
= User
::newFromId( 0 );
73 $this->user
= $this->userUser
;
75 $this->resetServices();
78 protected function setTitle( $ns, $title = "Main_Page" ) {
79 $this->title
= Title
::makeTitle( $ns, $title );
82 protected function setUser( $userName = null ) {
83 if ( $userName === 'anon' ) {
84 $this->user
= $this->anonUser
;
85 } elseif ( $userName === null ||
$userName === $this->userName
) {
86 $this->user
= $this->userUser
;
88 $this->user
= $this->altUser
;
93 * @todo This test method should be split up into separate test methods and
96 * This test is failing per T201776.
99 * @covers \MediaWiki\Permissions\PermissionManager::checkQuickPermissions
101 public function testQuickPermissions() {
102 $prefix = MediaWikiServices
::getInstance()->getContentLanguage()->
103 getFormattedNsText( NS_PROJECT
);
105 $this->setUser( 'anon' );
106 $this->setTitle( NS_TALK
);
107 $this->overrideUserPermissions( $this->user
, "createtalk" );
108 $res = $this->title
->getUserPermissionsErrors( 'create', $this->user
);
109 $this->assertEquals( [], $res );
111 $this->setTitle( NS_TALK
);
112 $this->overrideUserPermissions( $this->user
, "createpage" );
113 $res = $this->title
->getUserPermissionsErrors( 'create', $this->user
);
114 $this->assertEquals( [ [ "nocreatetext" ] ], $res );
116 $this->setTitle( NS_TALK
);
117 $this->overrideUserPermissions( $this->user
, "" );
118 $res = $this->title
->getUserPermissionsErrors( 'create', $this->user
);
119 $this->assertEquals( [ [ 'nocreatetext' ] ], $res );
121 $this->setTitle( NS_MAIN
);
122 $this->overrideUserPermissions( $this->user
, "createpage" );
123 $res = $this->title
->getUserPermissionsErrors( 'create', $this->user
);
124 $this->assertEquals( [], $res );
126 $this->setTitle( NS_MAIN
);
127 $this->overrideUserPermissions( $this->user
, "createtalk" );
128 $res = $this->title
->getUserPermissionsErrors( 'create', $this->user
);
129 $this->assertEquals( [ [ 'nocreatetext' ] ], $res );
131 $this->setUser( $this->userName
);
132 $this->setTitle( NS_TALK
);
133 $this->overrideUserPermissions( $this->user
, "createtalk" );
134 $res = $this->title
->getUserPermissionsErrors( 'create', $this->user
);
135 $this->assertEquals( [], $res );
137 $this->setTitle( NS_TALK
);
138 $this->overrideUserPermissions( $this->user
, "createpage" );
139 $res = $this->title
->getUserPermissionsErrors( 'create', $this->user
);
140 $this->assertEquals( [ [ 'nocreate-loggedin' ] ], $res );
142 $this->setTitle( NS_TALK
);
143 $this->overrideUserPermissions( $this->user
);
144 $res = $this->title
->getUserPermissionsErrors( 'create', $this->user
);
145 $this->assertEquals( [ [ 'nocreate-loggedin' ] ], $res );
147 $this->setTitle( NS_MAIN
);
148 $this->overrideUserPermissions( $this->user
, "createpage" );
149 $res = $this->title
->getUserPermissionsErrors( 'create', $this->user
);
150 $this->assertEquals( [], $res );
152 $this->setTitle( NS_MAIN
);
153 $this->overrideUserPermissions( $this->user
, "createtalk" );
154 $res = $this->title
->getUserPermissionsErrors( 'create', $this->user
);
155 $this->assertEquals( [ [ 'nocreate-loggedin' ] ], $res );
157 $this->setTitle( NS_MAIN
);
158 $this->overrideUserPermissions( $this->user
);
159 $res = $this->title
->getUserPermissionsErrors( 'create', $this->user
);
160 $this->assertEquals( [ [ 'nocreate-loggedin' ] ], $res );
162 $this->setUser( 'anon' );
163 $this->setTitle( NS_USER
, $this->userName
. '' );
164 $this->overrideUserPermissions( $this->user
);
165 $res = $this->title
->getUserPermissionsErrors( 'move', $this->user
);
166 $this->assertEquals( [ [ 'cant-move-user-page' ], [ 'movenologintext' ] ], $res );
168 $this->setTitle( NS_USER
, $this->userName
. '/subpage' );
169 $this->overrideUserPermissions( $this->user
);
170 $res = $this->title
->getUserPermissionsErrors( 'move', $this->user
);
171 $this->assertEquals( [ [ 'movenologintext' ] ], $res );
173 $this->setTitle( NS_USER
, $this->userName
. '' );
174 $this->overrideUserPermissions( $this->user
, "move-rootuserpages" );
175 $res = $this->title
->getUserPermissionsErrors( 'move', $this->user
);
176 $this->assertEquals( [ [ 'movenologintext' ] ], $res );
178 $this->setTitle( NS_USER
, $this->userName
. '/subpage' );
179 $this->overrideUserPermissions( $this->user
, "move-rootuserpages" );
180 $res = $this->title
->getUserPermissionsErrors( 'move', $this->user
);
181 $this->assertEquals( [ [ 'movenologintext' ] ], $res );
183 $this->setTitle( NS_USER
, $this->userName
. '' );
184 $this->overrideUserPermissions( $this->user
, "" );
185 $res = $this->title
->getUserPermissionsErrors( 'move', $this->user
);
186 $this->assertEquals( [ [ 'cant-move-user-page' ], [ 'movenologintext' ] ], $res );
188 $this->setTitle( NS_USER
, $this->userName
. '/subpage' );
189 $this->overrideUserPermissions( $this->user
, "" );
190 $res = $this->title
->getUserPermissionsErrors( 'move', $this->user
);
191 $this->assertEquals( [ [ 'movenologintext' ] ], $res );
193 $this->setTitle( NS_USER
, $this->userName
. '' );
194 $this->overrideUserPermissions( $this->user
, "move-rootuserpages" );
195 $res = $this->title
->getUserPermissionsErrors( 'move', $this->user
);
196 $this->assertEquals( [ [ 'movenologintext' ] ], $res );
198 $this->setTitle( NS_USER
, $this->userName
. '/subpage' );
199 $this->overrideUserPermissions( $this->user
, "move-rootuserpages" );
200 $res = $this->title
->getUserPermissionsErrors( 'move', $this->user
);
201 $this->assertEquals( [ [ 'movenologintext' ] ], $res );
203 $this->setUser( $this->userName
);
204 $this->setTitle( NS_FILE
, "img.png" );
205 $this->overrideUserPermissions( $this->user
);
206 $res = $this->title
->getUserPermissionsErrors( 'move', $this->user
);
207 $this->assertEquals( [ [ 'movenotallowedfile' ], [ 'movenotallowed' ] ], $res );
209 $this->setTitle( NS_FILE
, "img.png" );
210 $this->overrideUserPermissions( $this->user
, "movefile" );
211 $res = $this->title
->getUserPermissionsErrors( 'move', $this->user
);
212 $this->assertEquals( [ [ 'movenotallowed' ] ], $res );
214 $this->setUser( 'anon' );
215 $this->setTitle( NS_FILE
, "img.png" );
216 $this->overrideUserPermissions( $this->user
);
217 $res = $this->title
->getUserPermissionsErrors( 'move', $this->user
);
218 $this->assertEquals( [ [ 'movenotallowedfile' ], [ 'movenologintext' ] ], $res );
220 $this->setTitle( NS_FILE
, "img.png" );
221 $this->overrideUserPermissions( $this->user
, "movefile" );
222 $res = $this->title
->getUserPermissionsErrors( 'move', $this->user
);
223 $this->assertEquals( [ [ 'movenologintext' ] ], $res );
225 $this->setUser( $this->userName
);
226 $this->overrideUserPermissions( $this->user
, "move" );
227 $this->runGroupPermissions( 'move', [ [ 'movenotallowedfile' ] ] );
229 $this->overrideUserPermissions( $this->user
);
230 $this->runGroupPermissions(
232 [ [ 'movenotallowedfile' ], [ 'movenotallowed' ] ]
235 $this->setUser( 'anon' );
236 $this->overrideUserPermissions( $this->user
, "move" );
237 $this->runGroupPermissions( 'move', [ [ 'movenotallowedfile' ] ] );
239 $this->overrideUserPermissions( $this->user
);
240 $this->runGroupPermissions(
242 [ [ 'movenotallowedfile' ], [ 'movenotallowed' ] ],
243 [ [ 'movenotallowedfile' ], [ 'movenologintext' ] ]
246 if ( $this->isWikitextNS( NS_MAIN
) ) {
247 // NOTE: some content models don't allow moving
248 // @todo find a Wikitext namespace for testing
250 $this->setTitle( NS_MAIN
);
251 $this->setUser( 'anon' );
252 $this->overrideUserPermissions( $this->user
, "move" );
253 $this->runGroupPermissions( 'move', [] );
255 $this->overrideUserPermissions( $this->user
, "" );
256 $this->runGroupPermissions( 'move', [ [ 'movenotallowed' ] ],
257 [ [ 'movenologintext' ] ] );
259 $this->setUser( $this->userName
);
260 $this->overrideUserPermissions( $this->user
, "" );
261 $this->runGroupPermissions( 'move', [ [ 'movenotallowed' ] ] );
263 $this->overrideUserPermissions( $this->user
, "move" );
264 $this->runGroupPermissions( 'move', [] );
266 $this->setUser( 'anon' );
267 $this->overrideUserPermissions( $this->user
, 'move' );
268 $res = $this->title
->getUserPermissionsErrors( 'move-target', $this->user
);
269 $this->assertEquals( [], $res );
271 $this->overrideUserPermissions( $this->user
);
272 $res = $this->title
->getUserPermissionsErrors( 'move-target', $this->user
);
273 $this->assertEquals( [ [ 'movenotallowed' ] ], $res );
276 $this->setTitle( NS_USER
);
277 $this->setUser( $this->userName
);
278 $this->overrideUserPermissions( $this->user
, [ "move", "move-rootuserpages" ] );
279 $res = $this->title
->getUserPermissionsErrors( 'move-target', $this->user
);
280 $this->assertEquals( [], $res );
282 $this->overrideUserPermissions( $this->user
, "move" );
283 $res = $this->title
->getUserPermissionsErrors( 'move-target', $this->user
);
284 $this->assertEquals( [ [ 'cant-move-to-user-page' ] ], $res );
286 $this->setUser( 'anon' );
287 $this->overrideUserPermissions( $this->user
, [ "move", "move-rootuserpages" ] );
288 $res = $this->title
->getUserPermissionsErrors( 'move-target', $this->user
);
289 $this->assertEquals( [], $res );
291 $this->setTitle( NS_USER
, "User/subpage" );
292 $this->overrideUserPermissions( $this->user
, [ "move", "move-rootuserpages" ] );
293 $res = $this->title
->getUserPermissionsErrors( 'move-target', $this->user
);
294 $this->assertEquals( [], $res );
296 $this->overrideUserPermissions( $this->user
, "move" );
297 $res = $this->title
->getUserPermissionsErrors( 'move-target', $this->user
);
298 $this->assertEquals( [], $res );
300 $this->setUser( 'anon' );
303 [ [ 'badaccess-groups', "*, [[$prefix:Users|Users]]", 2 ] ],
304 [ [ 'badaccess-group0' ] ],
311 "[[$prefix:Administrators|Administrators]]", 1 ],
314 [ [ 'badaccess-group0' ], [ 'protect-cantedit' ] ],
315 [ [ 'protect-cantedit' ] ],
318 '' => [ [], [], [], true ]
321 foreach ( [ "edit", "protect", "" ] as $action ) {
322 $this->overrideUserPermissions( $this->user
);
323 $this->assertEquals( $check[$action][0],
324 $this->title
->getUserPermissionsErrors( $action, $this->user
, true ) );
325 $this->assertEquals( $check[$action][0],
326 $this->title
->getUserPermissionsErrors( $action, $this->user
, 'full' ) );
327 $this->assertEquals( $check[$action][0],
328 $this->title
->getUserPermissionsErrors( $action, $this->user
, 'secure' ) );
330 global $wgGroupPermissions;
331 $old = $wgGroupPermissions;
332 $wgGroupPermissions = [];
334 $this->resetServices();
336 $this->assertEquals( $check[$action][1],
337 $this->title
->getUserPermissionsErrors( $action, $this->user
, true ) );
338 $this->assertEquals( $check[$action][1],
339 $this->title
->getUserPermissionsErrors( $action, $this->user
, 'full' ) );
340 $this->assertEquals( $check[$action][1],
341 $this->title
->getUserPermissionsErrors( $action, $this->user
, 'secure' ) );
343 $wgGroupPermissions = $old;
344 $this->resetServices();
346 $this->overrideUserPermissions( $this->user
, $action );
347 $this->assertEquals( $check[$action][2],
348 $this->title
->getUserPermissionsErrors( $action, $this->user
, true ) );
349 $this->assertEquals( $check[$action][2],
350 $this->title
->getUserPermissionsErrors( $action, $this->user
, 'full' ) );
351 $this->assertEquals( $check[$action][2],
352 $this->title
->getUserPermissionsErrors( $action, $this->user
, 'secure' ) );
354 $this->overrideUserPermissions( $this->user
, $action );
355 $this->assertEquals( $check[$action][3],
356 $this->title
->userCan( $action, $this->user
, true ) );
357 $this->assertEquals( $check[$action][3],
358 $this->title
->quickUserCan( $action, $this->user
) );
359 # count( User::getGroupsWithPermissions( $action ) ) < 1
363 protected function runGroupPermissions( $action, $result, $result2 = null ) {
364 global $wgGroupPermissions;
366 if ( $result2 === null ) {
370 // XXX: there could be a better way to handle this, but since we need to
371 // override PermissionManager service each time globals are changed
372 // and in the same time we need to keep user permissions overrides from the outside
373 // the best we can do inside this method is to save & restore faked user perms
375 $userPermsOverrides = MediaWikiServices
::getInstance()->getPermissionManager()
376 ->getUserPermissions( $this->user
);
378 $wgGroupPermissions['autoconfirmed']['move'] = false;
379 $wgGroupPermissions['user']['move'] = false;
380 $this->resetServices();
381 $this->overrideUserPermissions( $this->user
, $userPermsOverrides );
382 $res = $this->title
->getUserPermissionsErrors( $action, $this->user
);
383 $this->assertEquals( $result, $res );
385 $wgGroupPermissions['autoconfirmed']['move'] = true;
386 $wgGroupPermissions['user']['move'] = false;
387 $this->resetServices();
388 $this->overrideUserPermissions( $this->user
, $userPermsOverrides );
389 $res = $this->title
->getUserPermissionsErrors( $action, $this->user
);
390 $this->assertEquals( $result2, $res );
392 $wgGroupPermissions['autoconfirmed']['move'] = true;
393 $wgGroupPermissions['user']['move'] = true;
394 $this->resetServices();
395 $this->overrideUserPermissions( $this->user
, $userPermsOverrides );
396 $res = $this->title
->getUserPermissionsErrors( $action, $this->user
);
397 $this->assertEquals( $result2, $res );
399 $wgGroupPermissions['autoconfirmed']['move'] = false;
400 $wgGroupPermissions['user']['move'] = true;
401 $this->resetServices();
402 $this->overrideUserPermissions( $this->user
, $userPermsOverrides );
403 $res = $this->title
->getUserPermissionsErrors( $action, $this->user
);
404 $this->assertEquals( $result2, $res );
408 * @todo This test method should be split up into separate test methods and
410 * @covers \MediaWiki\Permissions\PermissionManager::checkSpecialsAndNSPermissions
412 public function testSpecialsAndNSPermissions() {
413 global $wgNamespaceProtection;
414 $this->setUser( $this->userName
);
416 $this->setTitle( NS_SPECIAL
);
418 $this->assertEquals( [ [ 'badaccess-group0' ], [ 'ns-specialprotected' ] ],
419 $this->title
->getUserPermissionsErrors( 'bogus', $this->user
) );
421 $this->setTitle( NS_MAIN
);
422 $this->overrideUserPermissions( $this->user
, 'bogus' );
423 $this->assertEquals( [],
424 $this->title
->getUserPermissionsErrors( 'bogus', $this->user
) );
426 $this->setTitle( NS_MAIN
);
427 $this->overrideUserPermissions( $this->user
);
428 $this->assertEquals( [ [ 'badaccess-group0' ] ],
429 $this->title
->getUserPermissionsErrors( 'bogus', $this->user
) );
431 $wgNamespaceProtection[NS_USER
] = [ 'bogus' ];
433 $this->setTitle( NS_USER
);
434 $this->overrideUserPermissions( $this->user
);
435 $this->assertEquals( [ [ 'badaccess-group0' ],
436 [ 'namespaceprotected', 'User', 'bogus' ] ],
437 $this->title
->getUserPermissionsErrors( 'bogus', $this->user
) );
439 $this->setTitle( NS_MEDIAWIKI
);
440 $this->overrideUserPermissions( $this->user
, 'bogus' );
441 $this->assertEquals( [ [ 'protectedinterface', 'bogus' ] ],
442 $this->title
->getUserPermissionsErrors( 'bogus', $this->user
) );
444 $this->setTitle( NS_MEDIAWIKI
);
445 $this->overrideUserPermissions( $this->user
, 'bogus' );
446 $this->assertEquals( [ [ 'protectedinterface', 'bogus' ] ],
447 $this->title
->getUserPermissionsErrors( 'bogus', $this->user
) );
449 $wgNamespaceProtection = null;
451 $this->overrideUserPermissions( $this->user
, 'bogus' );
452 $this->assertEquals( [],
453 $this->title
->getUserPermissionsErrors( 'bogus', $this->user
) );
454 $this->assertEquals( true,
455 $this->title
->userCan( 'bogus', $this->user
) );
457 $this->overrideUserPermissions( $this->user
);
458 $this->assertEquals( [ [ 'badaccess-group0' ] ],
459 $this->title
->getUserPermissionsErrors( 'bogus', $this->user
) );
460 $this->assertEquals( false,
461 $this->title
->userCan( 'bogus', $this->user
) );
465 * @todo This test method should be split up into separate test methods and
467 * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
469 public function testJsConfigEditPermissions() {
470 $this->setUser( $this->userName
);
472 $this->setTitle( NS_USER
, $this->userName
. '/test.js' );
473 $this->runConfigEditPermissions(
474 [ [ 'badaccess-group0' ], [ 'mycustomjsprotected', 'bogus' ] ],
476 [ [ 'badaccess-group0' ], [ 'mycustomjsprotected', 'bogus' ] ],
477 [ [ 'badaccess-group0' ], [ 'mycustomjsprotected', 'bogus' ] ],
478 [ [ 'badaccess-group0' ] ],
480 [ [ 'badaccess-group0' ], [ 'mycustomjsprotected', 'bogus' ] ],
481 [ [ 'badaccess-group0' ], [ 'mycustomjsprotected', 'bogus' ] ],
482 [ [ 'badaccess-group0' ] ],
483 [ [ 'badaccess-groups' ] ]
488 * @todo This test method should be split up into separate test methods and
490 * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
492 public function testJsonConfigEditPermissions() {
493 $prefix = MediaWikiServices
::getInstance()->getContentLanguage()->
494 getFormattedNsText( NS_PROJECT
);
495 $this->setUser( $this->userName
);
497 $this->setTitle( NS_USER
, $this->userName
. '/test.json' );
498 $this->runConfigEditPermissions(
499 [ [ 'badaccess-group0' ], [ 'mycustomjsonprotected', 'bogus' ] ],
501 [ [ 'badaccess-group0' ], [ 'mycustomjsonprotected', 'bogus' ] ],
502 [ [ 'badaccess-group0' ] ],
503 [ [ 'badaccess-group0' ], [ 'mycustomjsonprotected', 'bogus' ] ],
505 [ [ 'badaccess-group0' ], [ 'mycustomjsonprotected', 'bogus' ] ],
506 [ [ 'badaccess-group0' ] ],
507 [ [ 'badaccess-group0' ], [ 'mycustomjsonprotected', 'bogus' ] ],
508 [ [ 'badaccess-groups' ] ]
513 * @todo This test method should be split up into separate test methods and
515 * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
517 public function testCssConfigEditPermissions() {
518 $this->setUser( $this->userName
);
520 $this->setTitle( NS_USER
, $this->userName
. '/test.css' );
521 $this->runConfigEditPermissions(
522 [ [ 'badaccess-group0' ], [ 'mycustomcssprotected', 'bogus' ] ],
524 [ [ 'badaccess-group0' ] ],
525 [ [ 'badaccess-group0' ], [ 'mycustomcssprotected', 'bogus' ] ],
526 [ [ 'badaccess-group0' ], [ 'mycustomcssprotected', 'bogus' ] ],
528 [ [ 'badaccess-group0' ] ],
529 [ [ 'badaccess-group0' ], [ 'mycustomcssprotected', 'bogus' ] ],
530 [ [ 'badaccess-group0' ], [ 'mycustomcssprotected', 'bogus' ] ],
531 [ [ 'badaccess-groups' ] ]
536 * @todo This test method should be split up into separate test methods and
538 * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
540 public function testOtherJsConfigEditPermissions() {
541 $this->setUser( $this->userName
);
543 $this->setTitle( NS_USER
, $this->altUserName
. '/test.js' );
544 $this->runConfigEditPermissions(
545 [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
547 [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
548 [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
549 [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
551 [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
552 [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
553 [ [ 'badaccess-group0' ] ],
554 [ [ 'badaccess-groups' ] ]
559 * @todo This test method should be split up into separate test methods and
561 * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
563 public function testOtherJsonConfigEditPermissions() {
564 $this->setUser( $this->userName
);
566 $this->setTitle( NS_USER
, $this->altUserName
. '/test.json' );
567 $this->runConfigEditPermissions(
568 [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
570 [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
571 [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
572 [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
574 [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
575 [ [ 'badaccess-group0' ] ],
576 [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
577 [ [ 'badaccess-groups' ] ]
582 * @todo This test method should be split up into separate test methods and
584 * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
586 public function testOtherCssConfigEditPermissions() {
587 $this->setUser( $this->userName
);
589 $this->setTitle( NS_USER
, $this->altUserName
. '/test.css' );
590 $this->runConfigEditPermissions(
591 [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
593 [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
594 [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
595 [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
597 [ [ 'badaccess-group0' ] ],
598 [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
599 [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
600 [ [ 'badaccess-groups' ] ]
605 * @todo This test method should be split up into separate test methods and
607 * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
609 public function testOtherNonConfigEditPermissions() {
610 $this->setUser( $this->userName
);
612 $this->setTitle( NS_USER
, $this->altUserName
. '/tempo' );
613 $this->runConfigEditPermissions(
614 [ [ 'badaccess-group0' ] ],
616 [ [ 'badaccess-group0' ] ],
617 [ [ 'badaccess-group0' ] ],
618 [ [ 'badaccess-group0' ] ],
620 [ [ 'badaccess-group0' ] ],
621 [ [ 'badaccess-group0' ] ],
622 [ [ 'badaccess-group0' ] ],
623 [ [ 'badaccess-groups' ] ]
628 * @todo This should use data providers like the other methods here.
629 * @covers \MediaWiki\Permissions\PermissionManager::checkUserConfigPermissions
631 public function testPatrolActionConfigEditPermissions() {
632 $this->setUser( 'anon' );
633 $this->setTitle( NS_USER
, 'ToPatrolOrNotToPatrol' );
634 $this->runConfigEditPermissions(
635 [ [ 'badaccess-group0' ] ],
637 [ [ 'badaccess-group0' ] ],
638 [ [ 'badaccess-group0' ] ],
639 [ [ 'badaccess-group0' ] ],
641 [ [ 'badaccess-group0' ] ],
642 [ [ 'badaccess-group0' ] ],
643 [ [ 'badaccess-group0' ] ],
644 [ [ 'badaccess-groups' ] ]
648 protected function runConfigEditPermissions(
658 $this->overrideUserPermissions( $this->user
);
659 $result = $this->title
->getUserPermissionsErrors( 'bogus', $this->user
);
660 $this->assertEquals( $resultNone, $result );
662 $this->overrideUserPermissions( $this->user
, 'editmyusercss' );
663 $result = $this->title
->getUserPermissionsErrors( 'bogus', $this->user
);
664 $this->assertEquals( $resultMyCss, $result );
666 $this->overrideUserPermissions( $this->user
, 'editmyuserjson' );
667 $result = $this->title
->getUserPermissionsErrors( 'bogus', $this->user
);
668 $this->assertEquals( $resultMyJson, $result );
670 $this->overrideUserPermissions( $this->user
, 'editmyuserjs' );
671 $result = $this->title
->getUserPermissionsErrors( 'bogus', $this->user
);
672 $this->assertEquals( $resultMyJs, $result );
674 $this->overrideUserPermissions( $this->user
, 'editusercss' );
675 $result = $this->title
->getUserPermissionsErrors( 'bogus', $this->user
);
676 $this->assertEquals( $resultUserCss, $result );
678 $this->overrideUserPermissions( $this->user
, 'edituserjson' );
679 $result = $this->title
->getUserPermissionsErrors( 'bogus', $this->user
);
680 $this->assertEquals( $resultUserJson, $result );
682 $this->overrideUserPermissions( $this->user
, 'edituserjs' );
683 $result = $this->title
->getUserPermissionsErrors( 'bogus', $this->user
);
684 $this->assertEquals( $resultUserJs, $result );
686 $this->overrideUserPermissions( $this->user
);
687 $result = $this->title
->getUserPermissionsErrors( 'patrol', $this->user
);
688 $this->assertEquals( reset( $resultPatrol[0] ), reset( $result[0] ) );
690 $this->overrideUserPermissions( $this->user
, [ 'edituserjs', 'edituserjson', 'editusercss' ] );
691 $result = $this->title
->getUserPermissionsErrors( 'bogus', $this->user
);
692 $this->assertEquals( [ [ 'badaccess-group0' ] ], $result );
696 * @todo This test method should be split up into separate test methods and
699 * This test is failing per T201776.
702 * @covers \MediaWiki\Permissions\PermissionManager::checkPageRestrictions
704 public function testPageRestrictions() {
705 $prefix = MediaWikiServices
::getInstance()->getContentLanguage()->
706 getFormattedNsText( NS_PROJECT
);
708 $this->setTitle( NS_MAIN
);
709 $this->title
->mRestrictionsLoaded
= true;
710 $this->overrideUserPermissions( $this->user
, "edit" );
711 $this->title
->mRestrictions
= [ "bogus" => [ 'bogus', "sysop", "protect", "" ] ];
713 $this->assertEquals( [],
714 $this->title
->getUserPermissionsErrors( 'edit',
717 $this->assertEquals( true,
718 $this->title
->quickUserCan( 'edit', $this->user
) );
719 $this->title
->mRestrictions
= [ "edit" => [ 'bogus', "sysop", "protect", "" ],
720 "bogus" => [ 'bogus', "sysop", "protect", "" ] ];
722 $this->assertEquals( [ [ 'badaccess-group0' ],
723 [ 'protectedpagetext', 'bogus', 'bogus' ],
724 [ 'protectedpagetext', 'editprotected', 'bogus' ],
725 [ 'protectedpagetext', 'protect', 'bogus' ] ],
726 $this->title
->getUserPermissionsErrors( 'bogus',
728 $this->assertEquals( [ [ 'protectedpagetext', 'bogus', 'edit' ],
729 [ 'protectedpagetext', 'editprotected', 'edit' ],
730 [ 'protectedpagetext', 'protect', 'edit' ] ],
731 $this->title
->getUserPermissionsErrors( 'edit',
733 $this->overrideUserPermissions( $this->user
);
734 $this->assertEquals( [ [ 'badaccess-group0' ],
735 [ 'protectedpagetext', 'bogus', 'bogus' ],
736 [ 'protectedpagetext', 'editprotected', 'bogus' ],
737 [ 'protectedpagetext', 'protect', 'bogus' ] ],
738 $this->title
->getUserPermissionsErrors( 'bogus',
740 $this->assertEquals( [ [ 'badaccess-groups', "*, [[$prefix:Users|Users]]", 2 ],
741 [ 'protectedpagetext', 'bogus', 'edit' ],
742 [ 'protectedpagetext', 'editprotected', 'edit' ],
743 [ 'protectedpagetext', 'protect', 'edit' ] ],
744 $this->title
->getUserPermissionsErrors( 'edit',
746 $this->overrideUserPermissions( $this->user
, [ "edit", "editprotected" ] );
747 $this->assertEquals( [ [ 'badaccess-group0' ],
748 [ 'protectedpagetext', 'bogus', 'bogus' ],
749 [ 'protectedpagetext', 'protect', 'bogus' ] ],
750 $this->title
->getUserPermissionsErrors( 'bogus',
752 $this->assertEquals( [
753 [ 'protectedpagetext', 'bogus', 'edit' ],
754 [ 'protectedpagetext', 'protect', 'edit' ] ],
755 $this->title
->getUserPermissionsErrors( 'edit',
758 $this->title
->mCascadeRestriction
= true;
759 $this->overrideUserPermissions( $this->user
, "edit" );
760 $this->assertEquals( false,
761 $this->title
->quickUserCan( 'bogus', $this->user
) );
762 $this->assertEquals( false,
763 $this->title
->quickUserCan( 'edit', $this->user
) );
764 $this->assertEquals( [ [ 'badaccess-group0' ],
765 [ 'protectedpagetext', 'bogus', 'bogus' ],
766 [ 'protectedpagetext', 'editprotected', 'bogus' ],
767 [ 'protectedpagetext', 'protect', 'bogus' ] ],
768 $this->title
->getUserPermissionsErrors( 'bogus',
770 $this->assertEquals( [ [ 'protectedpagetext', 'bogus', 'edit' ],
771 [ 'protectedpagetext', 'editprotected', 'edit' ],
772 [ 'protectedpagetext', 'protect', 'edit' ] ],
773 $this->title
->getUserPermissionsErrors( 'edit',
776 $this->overrideUserPermissions( $this->user
, [ "edit", "editprotected" ] );
777 $this->assertEquals( false,
778 $this->title
->quickUserCan( 'bogus', $this->user
) );
779 $this->assertEquals( false,
780 $this->title
->quickUserCan( 'edit', $this->user
) );
781 $this->assertEquals( [ [ 'badaccess-group0' ],
782 [ 'protectedpagetext', 'bogus', 'bogus' ],
783 [ 'protectedpagetext', 'protect', 'bogus' ],
784 [ 'protectedpagetext', 'protect', 'bogus' ] ],
785 $this->title
->getUserPermissionsErrors( 'bogus',
787 $this->assertEquals( [ [ 'protectedpagetext', 'bogus', 'edit' ],
788 [ 'protectedpagetext', 'protect', 'edit' ],
789 [ 'protectedpagetext', 'protect', 'edit' ] ],
790 $this->title
->getUserPermissionsErrors( 'edit',
795 * @covers \MediaWiki\Permissions\PermissionManager::checkCascadingSourcesRestrictions
797 public function testCascadingSourcesRestrictions() {
798 $this->setTitle( NS_MAIN
, "test page" );
799 $this->overrideUserPermissions( $this->user
, [ "edit", "bogus" ] );
801 $this->title
->mCascadeSources
= [
802 Title
::makeTitle( NS_MAIN
, "Bogus" ),
803 Title
::makeTitle( NS_MAIN
, "UnBogus" )
805 $this->title
->mCascadingRestrictions
= [
806 "bogus" => [ 'bogus', "sysop", "protect", "" ]
809 $this->assertEquals( false,
810 $this->title
->userCan( 'bogus', $this->user
) );
811 $this->assertEquals( [
812 [ "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n", 'bogus' ],
813 [ "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n", 'bogus' ],
814 [ "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n", 'bogus' ] ],
815 $this->title
->getUserPermissionsErrors( 'bogus', $this->user
) );
817 $this->assertEquals( true,
818 $this->title
->userCan( 'edit', $this->user
) );
819 $this->assertEquals( [],
820 $this->title
->getUserPermissionsErrors( 'edit', $this->user
) );
824 * @todo This test method should be split up into separate test methods and
826 * @covers \MediaWiki\Permissions\PermissionManager::checkActionPermissions
828 public function testActionPermissions() {
829 $this->overrideUserPermissions( $this->user
, [ "createpage" ] );
830 $this->setTitle( NS_MAIN
, "test page" );
831 $this->title
->mTitleProtection
['permission'] = '';
832 $this->title
->mTitleProtection
['user'] = $this->user
->getId();
833 $this->title
->mTitleProtection
['expiry'] = 'infinity';
834 $this->title
->mTitleProtection
['reason'] = 'test';
835 $this->title
->mCascadeRestriction
= false;
837 $this->assertEquals( [ [ 'titleprotected', 'Useruser', 'test' ] ],
838 $this->title
->getUserPermissionsErrors( 'create', $this->user
) );
839 $this->assertEquals( false,
840 $this->title
->userCan( 'create', $this->user
) );
842 $this->title
->mTitleProtection
['permission'] = 'editprotected';
843 $this->overrideUserPermissions( $this->user
, [ 'createpage', 'protect' ] );
844 $this->assertEquals( [ [ 'titleprotected', 'Useruser', 'test' ] ],
845 $this->title
->getUserPermissionsErrors( 'create', $this->user
) );
846 $this->assertEquals( false,
847 $this->title
->userCan( 'create', $this->user
) );
849 $this->overrideUserPermissions( $this->user
, [ 'createpage', 'editprotected' ] );
850 $this->assertEquals( [],
851 $this->title
->getUserPermissionsErrors( 'create', $this->user
) );
852 $this->assertEquals( true,
853 $this->title
->userCan( 'create', $this->user
) );
855 $this->overrideUserPermissions( $this->user
, [ 'createpage' ] );
856 $this->assertEquals( [ [ 'titleprotected', 'Useruser', 'test' ] ],
857 $this->title
->getUserPermissionsErrors( 'create', $this->user
) );
858 $this->assertEquals( false,
859 $this->title
->userCan( 'create', $this->user
) );
861 $this->setTitle( NS_MEDIA
, "test page" );
862 $this->overrideUserPermissions( $this->user
, [ "move" ] );
863 $this->assertEquals( false,
864 $this->title
->userCan( 'move', $this->user
) );
865 $this->assertEquals( [ [ 'immobile-source-namespace', 'Media' ] ],
866 $this->title
->getUserPermissionsErrors( 'move', $this->user
) );
868 $this->setTitle( NS_HELP
, "test page" );
869 $this->assertEquals( [],
870 $this->title
->getUserPermissionsErrors( 'move', $this->user
) );
871 $this->assertEquals( true,
872 $this->title
->userCan( 'move', $this->user
) );
874 $this->title
->mInterwiki
= "no";
875 $this->assertEquals( [ [ 'immobile-source-page' ] ],
876 $this->title
->getUserPermissionsErrors( 'move', $this->user
) );
877 $this->assertEquals( false,
878 $this->title
->userCan( 'move', $this->user
) );
880 $this->setTitle( NS_MEDIA
, "test page" );
881 $this->assertEquals( false,
882 $this->title
->userCan( 'move-target', $this->user
) );
883 $this->assertEquals( [ [ 'immobile-target-namespace', 'Media' ] ],
884 $this->title
->getUserPermissionsErrors( 'move-target', $this->user
) );
886 $this->setTitle( NS_HELP
, "test page" );
887 $this->assertEquals( [],
888 $this->title
->getUserPermissionsErrors( 'move-target', $this->user
) );
889 $this->assertEquals( true,
890 $this->title
->userCan( 'move-target', $this->user
) );
892 $this->title
->mInterwiki
= "no";
893 $this->assertEquals( [ [ 'immobile-target-page' ] ],
894 $this->title
->getUserPermissionsErrors( 'move-target', $this->user
) );
895 $this->assertEquals( false,
896 $this->title
->userCan( 'move-target', $this->user
) );
900 * @covers \MediaWiki\Permissions\PermissionManager::checkUserBlock
902 public function testUserBlock() {
903 $this->setMwGlobals( [
904 'wgEmailConfirmToEdit' => true,
905 'wgEmailAuthentication' => true,
906 'wgBlockDisablesLogin' => false,
908 $this->resetServices();
910 $this->overrideUserPermissions(
912 [ 'createpage', 'edit', 'move', 'rollback', 'patrol', 'upload', 'purge' ]
914 $this->setTitle( NS_HELP
, "test page" );
916 # $wgEmailConfirmToEdit only applies to 'edit' action
917 $this->assertEquals( [],
918 $this->title
->getUserPermissionsErrors( 'move-target', $this->user
) );
919 $this->assertContains( [ 'confirmedittext' ],
920 $this->title
->getUserPermissionsErrors( 'edit', $this->user
) );
922 $this->setMwGlobals( 'wgEmailConfirmToEdit', false );
923 $this->resetServices();
924 $this->overrideUserPermissions(
926 [ 'createpage', 'edit', 'move', 'rollback', 'patrol', 'upload', 'purge' ]
929 $this->assertNotContains( [ 'confirmedittext' ],
930 $this->title
->getUserPermissionsErrors( 'edit', $this->user
) );
932 # $wgEmailConfirmToEdit && !$user->isEmailConfirmed() && $action != 'createaccount'
933 $this->assertEquals( [],
934 $this->title
->getUserPermissionsErrors( 'move-target',
940 $this->user
->mBlockedby
= $this->user
->getId();
941 $this->user
->mBlock
= new DatabaseBlock( [
942 'address' => '127.0.8.1',
943 'by' => $this->user
->getId(),
944 'reason' => 'no reason given',
945 'timestamp' => $prev +
3600,
949 $this->user
->mBlock
->setTimestamp( 0 );
950 $this->assertEquals( [ [ 'autoblockedtext',
951 "[[User:Useruser|\u{202A}Useruser\u{202C}]]", 'no reason given', '127.0.0.1',
952 "\u{202A}Useruser\u{202C}", null, 'infinite', '127.0.8.1',
953 $wgLang->timeanddate( wfTimestamp( TS_MW
, $prev ), true ) ] ],
954 $this->title
->getUserPermissionsErrors( 'move-target',
957 $this->assertEquals( false, $this->title
->userCan( 'move-target', $this->user
) );
958 // quickUserCan should ignore user blocks
959 $this->assertEquals( true, $this->title
->quickUserCan( 'move-target', $this->user
) );
961 global $wgLocalTZoffset;
962 $wgLocalTZoffset = -60;
963 $this->user
->mBlockedby
= $this->user
->getName();
964 $this->user
->mBlock
= new DatabaseBlock( [
965 'address' => '127.0.8.1',
966 'by' => $this->user
->getId(),
967 'reason' => 'no reason given',
972 $this->assertEquals( [ [ 'blockedtext',
973 "[[User:Useruser|\u{202A}Useruser\u{202C}]]", 'no reason given', '127.0.0.1',
974 "\u{202A}Useruser\u{202C}", null, '23:00, 31 December 1969', '127.0.8.1',
975 $wgLang->timeanddate( wfTimestamp( TS_MW
, $now ), true ) ] ],
976 $this->title
->getUserPermissionsErrors( 'move-target', $this->user
) );
977 # $action != 'read' && $action != 'createaccount' && $user->isBlockedFrom( $this )
978 # $user->blockedFor() == ''
979 # $user->mBlock->mExpiry == 'infinity'
981 $this->user
->mBlockedby
= $this->user
->getName();
982 $this->user
->mBlock
= new SystemBlock( [
983 'address' => '127.0.8.1',
984 'by' => $this->user
->getId(),
985 'reason' => 'no reason given',
987 'systemBlock' => 'test',
990 $errors = [ [ 'systemblockedtext',
991 "[[User:Useruser|\u{202A}Useruser\u{202C}]]", 'no reason given', '127.0.0.1',
992 "\u{202A}Useruser\u{202C}", 'test', 'infinite', '127.0.8.1',
993 $wgLang->timeanddate( wfTimestamp( TS_MW
, $now ), true ) ] ];
995 $this->assertEquals( $errors,
996 $this->title
->getUserPermissionsErrors( 'edit', $this->user
) );
997 $this->assertEquals( $errors,
998 $this->title
->getUserPermissionsErrors( 'move-target', $this->user
) );
999 $this->assertEquals( $errors,
1000 $this->title
->getUserPermissionsErrors( 'rollback', $this->user
) );
1001 $this->assertEquals( $errors,
1002 $this->title
->getUserPermissionsErrors( 'patrol', $this->user
) );
1003 $this->assertEquals( $errors,
1004 $this->title
->getUserPermissionsErrors( 'upload', $this->user
) );
1005 $this->assertEquals( [],
1006 $this->title
->getUserPermissionsErrors( 'purge', $this->user
) );
1008 // partial block message test
1009 $this->user
->mBlockedby
= $this->user
->getName();
1010 $this->user
->mBlock
= new DatabaseBlock( [
1011 'address' => '127.0.8.1',
1012 'by' => $this->user
->getId(),
1013 'reason' => 'no reason given',
1014 'timestamp' => $now,
1015 'sitewide' => false,
1019 $this->assertEquals( [],
1020 $this->title
->getUserPermissionsErrors( 'edit', $this->user
) );
1021 $this->assertEquals( [],
1022 $this->title
->getUserPermissionsErrors( 'move-target', $this->user
) );
1023 $this->assertEquals( [],
1024 $this->title
->getUserPermissionsErrors( 'rollback', $this->user
) );
1025 $this->assertEquals( [],
1026 $this->title
->getUserPermissionsErrors( 'patrol', $this->user
) );
1027 $this->assertEquals( [],
1028 $this->title
->getUserPermissionsErrors( 'upload', $this->user
) );
1029 $this->assertEquals( [],
1030 $this->title
->getUserPermissionsErrors( 'purge', $this->user
) );
1032 $this->user
->mBlock
->setRestrictions( [
1033 ( new PageRestriction( 0, $this->title
->getArticleID() ) )->setTitle( $this->title
),
1036 $errors = [ [ 'blockedtext-partial',
1037 "[[User:Useruser|\u{202A}Useruser\u{202C}]]", 'no reason given', '127.0.0.1',
1038 "\u{202A}Useruser\u{202C}", null, '23:00, 31 December 1969', '127.0.8.1',
1039 $wgLang->timeanddate( wfTimestamp( TS_MW
, $now ), true ) ] ];
1041 $this->assertEquals( $errors,
1042 $this->title
->getUserPermissionsErrors( 'edit', $this->user
) );
1043 $this->assertEquals( $errors,
1044 $this->title
->getUserPermissionsErrors( 'move-target', $this->user
) );
1045 $this->assertEquals( $errors,
1046 $this->title
->getUserPermissionsErrors( 'rollback', $this->user
) );
1047 $this->assertEquals( $errors,
1048 $this->title
->getUserPermissionsErrors( 'patrol', $this->user
) );
1049 $this->assertEquals( [],
1050 $this->title
->getUserPermissionsErrors( 'upload', $this->user
) );
1051 $this->assertEquals( [],
1052 $this->title
->getUserPermissionsErrors( 'purge', $this->user
) );
1055 $this->user
->mBlockedby
= null;
1056 $this->user
->mBlock
= null;
1058 $this->assertEquals( [],
1059 $this->title
->getUserPermissionsErrors( 'edit', $this->user
) );
1063 * @covers \MediaWiki\Permissions\PermissionManager::checkUserBlock
1065 * Tests to determine that the passed in permission does not get mixed up with
1066 * an action of the same name.
1068 public function testUserBlockAction() {
1071 $tester = $this->getMockBuilder( Action
::class )
1072 ->disableOriginalConstructor()
1074 $tester->method( 'getName' )
1075 ->willReturn( 'tester' );
1076 $tester->method( 'getRestriction' )
1077 ->willReturn( 'test' );
1078 $tester->method( 'requiresUnblock' )
1079 ->willReturn( false );
1081 $this->setMwGlobals( [
1083 'tester' => $tester,
1085 'wgGroupPermissions' => [
1091 $this->resetServices();
1094 $this->user
->mBlockedby
= $this->user
->getName();
1095 $this->user
->mBlock
= new DatabaseBlock( [
1096 'address' => '127.0.8.1',
1097 'by' => $this->user
->getId(),
1098 'reason' => 'no reason given',
1099 'timestamp' => $now,
1101 'expiry' => 'infinity',
1104 $errors = [ [ 'blockedtext',
1105 "[[User:Useruser|\u{202A}Useruser\u{202C}]]", 'no reason given', '127.0.0.1',
1106 "\u{202A}Useruser\u{202C}", null, 'infinite', '127.0.8.1',
1107 $wgLang->timeanddate( wfTimestamp( TS_MW
, $now ), true ) ] ];
1109 $this->assertEquals( $errors,
1110 $this->title
->getUserPermissionsErrors( 'tester', $this->user
) );