TitlePermissionTest.php 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939
  1. <?php
  2. use MediaWiki\MediaWikiServices;
  3. /**
  4. * @group Database
  5. *
  6. * @covers Title::getUserPermissionsErrors
  7. * @covers Title::getUserPermissionsErrorsInternal
  8. */
  9. class TitlePermissionTest extends MediaWikiLangTestCase {
  10. /**
  11. * @var string
  12. */
  13. protected $userName, $altUserName;
  14. /**
  15. * @var Title
  16. */
  17. protected $title;
  18. /**
  19. * @var User
  20. */
  21. protected $user, $anonUser, $userUser, $altUser;
  22. protected function setUp() {
  23. parent::setUp();
  24. $localZone = 'UTC';
  25. $localOffset = date( 'Z' ) / 60;
  26. $this->setMwGlobals( [
  27. 'wgLocaltimezone' => $localZone,
  28. 'wgLocalTZoffset' => $localOffset,
  29. 'wgNamespaceProtection' => [
  30. NS_MEDIAWIKI => 'editinterface',
  31. ],
  32. ] );
  33. // Without this testUserBlock will use a non-English context on non-English MediaWiki
  34. // installations (because of how Title::checkUserBlock is implemented) and fail.
  35. RequestContext::resetMain();
  36. $this->userName = 'Useruser';
  37. $this->altUserName = 'Altuseruser';
  38. date_default_timezone_set( $localZone );
  39. $this->title = Title::makeTitle( NS_MAIN, "Main Page" );
  40. if ( !isset( $this->userUser ) || !( $this->userUser instanceof User ) ) {
  41. $this->userUser = User::newFromName( $this->userName );
  42. if ( !$this->userUser->getId() ) {
  43. $this->userUser = User::createNew( $this->userName, [
  44. "email" => "test@example.com",
  45. "real_name" => "Test User" ] );
  46. $this->userUser->load();
  47. }
  48. $this->altUser = User::newFromName( $this->altUserName );
  49. if ( !$this->altUser->getId() ) {
  50. $this->altUser = User::createNew( $this->altUserName, [
  51. "email" => "alttest@example.com",
  52. "real_name" => "Test User Alt" ] );
  53. $this->altUser->load();
  54. }
  55. $this->anonUser = User::newFromId( 0 );
  56. $this->user = $this->userUser;
  57. }
  58. $this->overrideMwServices();
  59. }
  60. protected function setUserPerm( $perm ) {
  61. // Setting member variables is evil!!!
  62. if ( is_array( $perm ) ) {
  63. $this->user->mRights = $perm;
  64. } else {
  65. $this->user->mRights = [ $perm ];
  66. }
  67. }
  68. protected function setTitle( $ns, $title = "Main_Page" ) {
  69. $this->title = Title::makeTitle( $ns, $title );
  70. }
  71. protected function setUser( $userName = null ) {
  72. if ( $userName === 'anon' ) {
  73. $this->user = $this->anonUser;
  74. } elseif ( $userName === null || $userName === $this->userName ) {
  75. $this->user = $this->userUser;
  76. } else {
  77. $this->user = $this->altUser;
  78. }
  79. }
  80. /**
  81. * @todo This test method should be split up into separate test methods and
  82. * data providers
  83. *
  84. * This test is failing per T201776.
  85. *
  86. * @group Broken
  87. * @covers Title::checkQuickPermissions
  88. */
  89. public function testQuickPermissions() {
  90. $prefix = MediaWikiServices::getInstance()->getContentLanguage()->
  91. getFormattedNsText( NS_PROJECT );
  92. $this->setUser( 'anon' );
  93. $this->setTitle( NS_TALK );
  94. $this->setUserPerm( "createtalk" );
  95. $res = $this->title->getUserPermissionsErrors( 'create', $this->user );
  96. $this->assertEquals( [], $res );
  97. $this->setTitle( NS_TALK );
  98. $this->setUserPerm( "createpage" );
  99. $res = $this->title->getUserPermissionsErrors( 'create', $this->user );
  100. $this->assertEquals( [ [ "nocreatetext" ] ], $res );
  101. $this->setTitle( NS_TALK );
  102. $this->setUserPerm( "" );
  103. $res = $this->title->getUserPermissionsErrors( 'create', $this->user );
  104. $this->assertEquals( [ [ 'nocreatetext' ] ], $res );
  105. $this->setTitle( NS_MAIN );
  106. $this->setUserPerm( "createpage" );
  107. $res = $this->title->getUserPermissionsErrors( 'create', $this->user );
  108. $this->assertEquals( [], $res );
  109. $this->setTitle( NS_MAIN );
  110. $this->setUserPerm( "createtalk" );
  111. $res = $this->title->getUserPermissionsErrors( 'create', $this->user );
  112. $this->assertEquals( [ [ 'nocreatetext' ] ], $res );
  113. $this->setUser( $this->userName );
  114. $this->setTitle( NS_TALK );
  115. $this->setUserPerm( "createtalk" );
  116. $res = $this->title->getUserPermissionsErrors( 'create', $this->user );
  117. $this->assertEquals( [], $res );
  118. $this->setTitle( NS_TALK );
  119. $this->setUserPerm( "createpage" );
  120. $res = $this->title->getUserPermissionsErrors( 'create', $this->user );
  121. $this->assertEquals( [ [ 'nocreate-loggedin' ] ], $res );
  122. $this->setTitle( NS_TALK );
  123. $this->setUserPerm( "" );
  124. $res = $this->title->getUserPermissionsErrors( 'create', $this->user );
  125. $this->assertEquals( [ [ 'nocreate-loggedin' ] ], $res );
  126. $this->setTitle( NS_MAIN );
  127. $this->setUserPerm( "createpage" );
  128. $res = $this->title->getUserPermissionsErrors( 'create', $this->user );
  129. $this->assertEquals( [], $res );
  130. $this->setTitle( NS_MAIN );
  131. $this->setUserPerm( "createtalk" );
  132. $res = $this->title->getUserPermissionsErrors( 'create', $this->user );
  133. $this->assertEquals( [ [ 'nocreate-loggedin' ] ], $res );
  134. $this->setTitle( NS_MAIN );
  135. $this->setUserPerm( "" );
  136. $res = $this->title->getUserPermissionsErrors( 'create', $this->user );
  137. $this->assertEquals( [ [ 'nocreate-loggedin' ] ], $res );
  138. $this->setUser( 'anon' );
  139. $this->setTitle( NS_USER, $this->userName . '' );
  140. $this->setUserPerm( "" );
  141. $res = $this->title->getUserPermissionsErrors( 'move', $this->user );
  142. $this->assertEquals( [ [ 'cant-move-user-page' ], [ 'movenologintext' ] ], $res );
  143. $this->setTitle( NS_USER, $this->userName . '/subpage' );
  144. $this->setUserPerm( "" );
  145. $res = $this->title->getUserPermissionsErrors( 'move', $this->user );
  146. $this->assertEquals( [ [ 'movenologintext' ] ], $res );
  147. $this->setTitle( NS_USER, $this->userName . '' );
  148. $this->setUserPerm( "move-rootuserpages" );
  149. $res = $this->title->getUserPermissionsErrors( 'move', $this->user );
  150. $this->assertEquals( [ [ 'movenologintext' ] ], $res );
  151. $this->setTitle( NS_USER, $this->userName . '/subpage' );
  152. $this->setUserPerm( "move-rootuserpages" );
  153. $res = $this->title->getUserPermissionsErrors( 'move', $this->user );
  154. $this->assertEquals( [ [ 'movenologintext' ] ], $res );
  155. $this->setTitle( NS_USER, $this->userName . '' );
  156. $this->setUserPerm( "" );
  157. $res = $this->title->getUserPermissionsErrors( 'move', $this->user );
  158. $this->assertEquals( [ [ 'cant-move-user-page' ], [ 'movenologintext' ] ], $res );
  159. $this->setTitle( NS_USER, $this->userName . '/subpage' );
  160. $this->setUserPerm( "" );
  161. $res = $this->title->getUserPermissionsErrors( 'move', $this->user );
  162. $this->assertEquals( [ [ 'movenologintext' ] ], $res );
  163. $this->setTitle( NS_USER, $this->userName . '' );
  164. $this->setUserPerm( "move-rootuserpages" );
  165. $res = $this->title->getUserPermissionsErrors( 'move', $this->user );
  166. $this->assertEquals( [ [ 'movenologintext' ] ], $res );
  167. $this->setTitle( NS_USER, $this->userName . '/subpage' );
  168. $this->setUserPerm( "move-rootuserpages" );
  169. $res = $this->title->getUserPermissionsErrors( 'move', $this->user );
  170. $this->assertEquals( [ [ 'movenologintext' ] ], $res );
  171. $this->setUser( $this->userName );
  172. $this->setTitle( NS_FILE, "img.png" );
  173. $this->setUserPerm( "" );
  174. $res = $this->title->getUserPermissionsErrors( 'move', $this->user );
  175. $this->assertEquals( [ [ 'movenotallowedfile' ], [ 'movenotallowed' ] ], $res );
  176. $this->setTitle( NS_FILE, "img.png" );
  177. $this->setUserPerm( "movefile" );
  178. $res = $this->title->getUserPermissionsErrors( 'move', $this->user );
  179. $this->assertEquals( [ [ 'movenotallowed' ] ], $res );
  180. $this->setUser( 'anon' );
  181. $this->setTitle( NS_FILE, "img.png" );
  182. $this->setUserPerm( "" );
  183. $res = $this->title->getUserPermissionsErrors( 'move', $this->user );
  184. $this->assertEquals( [ [ 'movenotallowedfile' ], [ 'movenologintext' ] ], $res );
  185. $this->setTitle( NS_FILE, "img.png" );
  186. $this->setUserPerm( "movefile" );
  187. $res = $this->title->getUserPermissionsErrors( 'move', $this->user );
  188. $this->assertEquals( [ [ 'movenologintext' ] ], $res );
  189. $this->setUser( $this->userName );
  190. $this->setUserPerm( "move" );
  191. $this->runGroupPermissions( 'move', [ [ 'movenotallowedfile' ] ] );
  192. $this->setUserPerm( "" );
  193. $this->runGroupPermissions(
  194. 'move',
  195. [ [ 'movenotallowedfile' ], [ 'movenotallowed' ] ]
  196. );
  197. $this->setUser( 'anon' );
  198. $this->setUserPerm( "move" );
  199. $this->runGroupPermissions( 'move', [ [ 'movenotallowedfile' ] ] );
  200. $this->setUserPerm( "" );
  201. $this->runGroupPermissions(
  202. 'move',
  203. [ [ 'movenotallowedfile' ], [ 'movenotallowed' ] ],
  204. [ [ 'movenotallowedfile' ], [ 'movenologintext' ] ]
  205. );
  206. if ( $this->isWikitextNS( NS_MAIN ) ) {
  207. // NOTE: some content models don't allow moving
  208. // @todo find a Wikitext namespace for testing
  209. $this->setTitle( NS_MAIN );
  210. $this->setUser( 'anon' );
  211. $this->setUserPerm( "move" );
  212. $this->runGroupPermissions( 'move', [] );
  213. $this->setUserPerm( "" );
  214. $this->runGroupPermissions( 'move', [ [ 'movenotallowed' ] ],
  215. [ [ 'movenologintext' ] ] );
  216. $this->setUser( $this->userName );
  217. $this->setUserPerm( "" );
  218. $this->runGroupPermissions( 'move', [ [ 'movenotallowed' ] ] );
  219. $this->setUserPerm( "move" );
  220. $this->runGroupPermissions( 'move', [] );
  221. $this->setUser( 'anon' );
  222. $this->setUserPerm( 'move' );
  223. $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
  224. $this->assertEquals( [], $res );
  225. $this->setUserPerm( '' );
  226. $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
  227. $this->assertEquals( [ [ 'movenotallowed' ] ], $res );
  228. }
  229. $this->setTitle( NS_USER );
  230. $this->setUser( $this->userName );
  231. $this->setUserPerm( [ "move", "move-rootuserpages" ] );
  232. $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
  233. $this->assertEquals( [], $res );
  234. $this->setUserPerm( "move" );
  235. $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
  236. $this->assertEquals( [ [ 'cant-move-to-user-page' ] ], $res );
  237. $this->setUser( 'anon' );
  238. $this->setUserPerm( [ "move", "move-rootuserpages" ] );
  239. $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
  240. $this->assertEquals( [], $res );
  241. $this->setTitle( NS_USER, "User/subpage" );
  242. $this->setUserPerm( [ "move", "move-rootuserpages" ] );
  243. $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
  244. $this->assertEquals( [], $res );
  245. $this->setUserPerm( "move" );
  246. $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user );
  247. $this->assertEquals( [], $res );
  248. $this->setUser( 'anon' );
  249. $check = [
  250. 'edit' => [
  251. [ [ 'badaccess-groups', "*, [[$prefix:Users|Users]]", 2 ] ],
  252. [ [ 'badaccess-group0' ] ],
  253. [],
  254. true
  255. ],
  256. 'protect' => [
  257. [ [
  258. 'badaccess-groups',
  259. "[[$prefix:Administrators|Administrators]]", 1 ],
  260. [ 'protect-cantedit'
  261. ] ],
  262. [ [ 'badaccess-group0' ], [ 'protect-cantedit' ] ],
  263. [ [ 'protect-cantedit' ] ],
  264. false
  265. ],
  266. '' => [ [], [], [], true ]
  267. ];
  268. foreach ( [ "edit", "protect", "" ] as $action ) {
  269. $this->setUserPerm( null );
  270. $this->assertEquals( $check[$action][0],
  271. $this->title->getUserPermissionsErrors( $action, $this->user, true ) );
  272. $this->assertEquals( $check[$action][0],
  273. $this->title->getUserPermissionsErrors( $action, $this->user, 'full' ) );
  274. $this->assertEquals( $check[$action][0],
  275. $this->title->getUserPermissionsErrors( $action, $this->user, 'secure' ) );
  276. global $wgGroupPermissions;
  277. $old = $wgGroupPermissions;
  278. $wgGroupPermissions = [];
  279. $this->assertEquals( $check[$action][1],
  280. $this->title->getUserPermissionsErrors( $action, $this->user, true ) );
  281. $this->assertEquals( $check[$action][1],
  282. $this->title->getUserPermissionsErrors( $action, $this->user, 'full' ) );
  283. $this->assertEquals( $check[$action][1],
  284. $this->title->getUserPermissionsErrors( $action, $this->user, 'secure' ) );
  285. $wgGroupPermissions = $old;
  286. $this->setUserPerm( $action );
  287. $this->assertEquals( $check[$action][2],
  288. $this->title->getUserPermissionsErrors( $action, $this->user, true ) );
  289. $this->assertEquals( $check[$action][2],
  290. $this->title->getUserPermissionsErrors( $action, $this->user, 'full' ) );
  291. $this->assertEquals( $check[$action][2],
  292. $this->title->getUserPermissionsErrors( $action, $this->user, 'secure' ) );
  293. $this->setUserPerm( $action );
  294. $this->assertEquals( $check[$action][3],
  295. $this->title->userCan( $action, $this->user, true ) );
  296. $this->assertEquals( $check[$action][3],
  297. $this->title->quickUserCan( $action, $this->user ) );
  298. # count( User::getGroupsWithPermissions( $action ) ) < 1
  299. }
  300. }
  301. protected function runGroupPermissions( $action, $result, $result2 = null ) {
  302. global $wgGroupPermissions;
  303. if ( $result2 === null ) {
  304. $result2 = $result;
  305. }
  306. $wgGroupPermissions['autoconfirmed']['move'] = false;
  307. $wgGroupPermissions['user']['move'] = false;
  308. $res = $this->title->getUserPermissionsErrors( $action, $this->user );
  309. $this->assertEquals( $result, $res );
  310. $wgGroupPermissions['autoconfirmed']['move'] = true;
  311. $wgGroupPermissions['user']['move'] = false;
  312. $res = $this->title->getUserPermissionsErrors( $action, $this->user );
  313. $this->assertEquals( $result2, $res );
  314. $wgGroupPermissions['autoconfirmed']['move'] = true;
  315. $wgGroupPermissions['user']['move'] = true;
  316. $res = $this->title->getUserPermissionsErrors( $action, $this->user );
  317. $this->assertEquals( $result2, $res );
  318. $wgGroupPermissions['autoconfirmed']['move'] = false;
  319. $wgGroupPermissions['user']['move'] = true;
  320. $res = $this->title->getUserPermissionsErrors( $action, $this->user );
  321. $this->assertEquals( $result2, $res );
  322. }
  323. /**
  324. * @todo This test method should be split up into separate test methods and
  325. * data providers
  326. * @covers Title::checkSpecialsAndNSPermissions
  327. */
  328. public function testSpecialsAndNSPermissions() {
  329. global $wgNamespaceProtection;
  330. $this->setUser( $this->userName );
  331. $this->setTitle( NS_SPECIAL );
  332. $this->assertEquals( [ [ 'badaccess-group0' ], [ 'ns-specialprotected' ] ],
  333. $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
  334. $this->setTitle( NS_MAIN );
  335. $this->setUserPerm( 'bogus' );
  336. $this->assertEquals( [],
  337. $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
  338. $this->setTitle( NS_MAIN );
  339. $this->setUserPerm( '' );
  340. $this->assertEquals( [ [ 'badaccess-group0' ] ],
  341. $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
  342. $wgNamespaceProtection[NS_USER] = [ 'bogus' ];
  343. $this->setTitle( NS_USER );
  344. $this->setUserPerm( '' );
  345. $this->assertEquals( [ [ 'badaccess-group0' ],
  346. [ 'namespaceprotected', 'User', 'bogus' ] ],
  347. $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
  348. $this->setTitle( NS_MEDIAWIKI );
  349. $this->setUserPerm( 'bogus' );
  350. $this->assertEquals( [ [ 'protectedinterface', 'bogus' ] ],
  351. $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
  352. $this->setTitle( NS_MEDIAWIKI );
  353. $this->setUserPerm( 'bogus' );
  354. $this->assertEquals( [ [ 'protectedinterface', 'bogus' ] ],
  355. $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
  356. $wgNamespaceProtection = null;
  357. $this->setUserPerm( 'bogus' );
  358. $this->assertEquals( [],
  359. $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
  360. $this->assertEquals( true,
  361. $this->title->userCan( 'bogus', $this->user ) );
  362. $this->setUserPerm( '' );
  363. $this->assertEquals( [ [ 'badaccess-group0' ] ],
  364. $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
  365. $this->assertEquals( false,
  366. $this->title->userCan( 'bogus', $this->user ) );
  367. }
  368. /**
  369. * @todo This test method should be split up into separate test methods and
  370. * data providers
  371. * @covers Title::checkUserConfigPermissions
  372. */
  373. public function testJsConfigEditPermissions() {
  374. $this->setUser( $this->userName );
  375. $this->setTitle( NS_USER, $this->userName . '/test.js' );
  376. $this->runConfigEditPermissions(
  377. [ [ 'badaccess-group0' ], [ 'mycustomjsprotected', 'bogus' ] ],
  378. [ [ 'badaccess-group0' ], [ 'mycustomjsprotected', 'bogus' ] ],
  379. [ [ 'badaccess-group0' ], [ 'mycustomjsprotected', 'bogus' ] ],
  380. [ [ 'badaccess-group0' ] ],
  381. [ [ 'badaccess-group0' ], [ 'mycustomjsprotected', 'bogus' ] ],
  382. [ [ 'badaccess-group0' ], [ 'mycustomjsprotected', 'bogus' ] ],
  383. [ [ 'badaccess-group0' ] ]
  384. );
  385. }
  386. /**
  387. * @todo This test method should be split up into separate test methods and
  388. * data providers
  389. * @covers Title::checkUserConfigPermissions
  390. */
  391. public function testJsonConfigEditPermissions() {
  392. $this->setUser( $this->userName );
  393. $this->setTitle( NS_USER, $this->userName . '/test.json' );
  394. $this->runConfigEditPermissions(
  395. [ [ 'badaccess-group0' ], [ 'mycustomjsonprotected', 'bogus' ] ],
  396. [ [ 'badaccess-group0' ], [ 'mycustomjsonprotected', 'bogus' ] ],
  397. [ [ 'badaccess-group0' ] ],
  398. [ [ 'badaccess-group0' ], [ 'mycustomjsonprotected', 'bogus' ] ],
  399. [ [ 'badaccess-group0' ], [ 'mycustomjsonprotected', 'bogus' ] ],
  400. [ [ 'badaccess-group0' ] ],
  401. [ [ 'badaccess-group0' ], [ 'mycustomjsonprotected', 'bogus' ] ]
  402. );
  403. }
  404. /**
  405. * @todo This test method should be split up into separate test methods and
  406. * data providers
  407. * @covers Title::checkUserConfigPermissions
  408. */
  409. public function testCssConfigEditPermissions() {
  410. $this->setUser( $this->userName );
  411. $this->setTitle( NS_USER, $this->userName . '/test.css' );
  412. $this->runConfigEditPermissions(
  413. [ [ 'badaccess-group0' ], [ 'mycustomcssprotected', 'bogus' ] ],
  414. [ [ 'badaccess-group0' ] ],
  415. [ [ 'badaccess-group0' ], [ 'mycustomcssprotected', 'bogus' ] ],
  416. [ [ 'badaccess-group0' ], [ 'mycustomcssprotected', 'bogus' ] ],
  417. [ [ 'badaccess-group0' ] ],
  418. [ [ 'badaccess-group0' ], [ 'mycustomcssprotected', 'bogus' ] ],
  419. [ [ 'badaccess-group0' ], [ 'mycustomcssprotected', 'bogus' ] ]
  420. );
  421. }
  422. /**
  423. * @todo This test method should be split up into separate test methods and
  424. * data providers
  425. * @covers Title::checkUserConfigPermissions
  426. */
  427. public function testOtherJsConfigEditPermissions() {
  428. $this->setUser( $this->userName );
  429. $this->setTitle( NS_USER, $this->altUserName . '/test.js' );
  430. $this->runConfigEditPermissions(
  431. [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
  432. [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
  433. [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
  434. [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
  435. [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
  436. [ [ 'badaccess-group0' ], [ 'customjsprotected', 'bogus' ] ],
  437. [ [ 'badaccess-group0' ] ]
  438. );
  439. }
  440. /**
  441. * @todo This test method should be split up into separate test methods and
  442. * data providers
  443. * @covers Title::checkUserConfigPermissions
  444. */
  445. public function testOtherJsonConfigEditPermissions() {
  446. $this->setUser( $this->userName );
  447. $this->setTitle( NS_USER, $this->altUserName . '/test.json' );
  448. $this->runConfigEditPermissions(
  449. [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
  450. [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
  451. [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
  452. [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
  453. [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ],
  454. [ [ 'badaccess-group0' ] ],
  455. [ [ 'badaccess-group0' ], [ 'customjsonprotected', 'bogus' ] ]
  456. );
  457. }
  458. /**
  459. * @todo This test method should be split up into separate test methods and
  460. * data providers
  461. * @covers Title::checkUserConfigPermissions
  462. */
  463. public function testOtherCssConfigEditPermissions() {
  464. $this->setUser( $this->userName );
  465. $this->setTitle( NS_USER, $this->altUserName . '/test.css' );
  466. $this->runConfigEditPermissions(
  467. [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
  468. [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
  469. [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
  470. [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
  471. [ [ 'badaccess-group0' ] ],
  472. [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ],
  473. [ [ 'badaccess-group0' ], [ 'customcssprotected', 'bogus' ] ]
  474. );
  475. }
  476. /**
  477. * @todo This test method should be split up into separate test methods and
  478. * data providers
  479. * @covers Title::checkUserConfigPermissions
  480. */
  481. public function testOtherNonConfigEditPermissions() {
  482. $this->setUser( $this->userName );
  483. $this->setTitle( NS_USER, $this->altUserName . '/tempo' );
  484. $this->runConfigEditPermissions(
  485. [ [ 'badaccess-group0' ] ],
  486. [ [ 'badaccess-group0' ] ],
  487. [ [ 'badaccess-group0' ] ],
  488. [ [ 'badaccess-group0' ] ],
  489. [ [ 'badaccess-group0' ] ],
  490. [ [ 'badaccess-group0' ] ],
  491. [ [ 'badaccess-group0' ] ]
  492. );
  493. }
  494. protected function runConfigEditPermissions(
  495. $resultNone,
  496. $resultMyCss,
  497. $resultMyJson,
  498. $resultMyJs,
  499. $resultUserCss,
  500. $resultUserJson,
  501. $resultUserJs
  502. ) {
  503. $this->setUserPerm( '' );
  504. $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user );
  505. $this->assertEquals( $resultNone, $result );
  506. $this->setUserPerm( 'editmyusercss' );
  507. $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user );
  508. $this->assertEquals( $resultMyCss, $result );
  509. $this->setUserPerm( 'editmyuserjson' );
  510. $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user );
  511. $this->assertEquals( $resultMyJson, $result );
  512. $this->setUserPerm( 'editmyuserjs' );
  513. $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user );
  514. $this->assertEquals( $resultMyJs, $result );
  515. $this->setUserPerm( 'editusercss' );
  516. $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user );
  517. $this->assertEquals( $resultUserCss, $result );
  518. $this->setUserPerm( 'edituserjson' );
  519. $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user );
  520. $this->assertEquals( $resultUserJson, $result );
  521. $this->setUserPerm( 'edituserjs' );
  522. $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user );
  523. $this->assertEquals( $resultUserJs, $result );
  524. $this->setUserPerm( [ 'edituserjs', 'edituserjson', 'editusercss' ] );
  525. $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user );
  526. $this->assertEquals( [ [ 'badaccess-group0' ] ], $result );
  527. }
  528. /**
  529. * @todo This test method should be split up into separate test methods and
  530. * data providers
  531. *
  532. * This test is failing per T201776.
  533. *
  534. * @group Broken
  535. * @covers Title::checkPageRestrictions
  536. */
  537. public function testPageRestrictions() {
  538. $prefix = MediaWikiServices::getInstance()->getContentLanguage()->
  539. getFormattedNsText( NS_PROJECT );
  540. $this->setTitle( NS_MAIN );
  541. $this->title->mRestrictionsLoaded = true;
  542. $this->setUserPerm( "edit" );
  543. $this->title->mRestrictions = [ "bogus" => [ 'bogus', "sysop", "protect", "" ] ];
  544. $this->assertEquals( [],
  545. $this->title->getUserPermissionsErrors( 'edit',
  546. $this->user ) );
  547. $this->assertEquals( true,
  548. $this->title->quickUserCan( 'edit', $this->user ) );
  549. $this->title->mRestrictions = [ "edit" => [ 'bogus', "sysop", "protect", "" ],
  550. "bogus" => [ 'bogus', "sysop", "protect", "" ] ];
  551. $this->assertEquals( [ [ 'badaccess-group0' ],
  552. [ 'protectedpagetext', 'bogus', 'bogus' ],
  553. [ 'protectedpagetext', 'editprotected', 'bogus' ],
  554. [ 'protectedpagetext', 'protect', 'bogus' ] ],
  555. $this->title->getUserPermissionsErrors( 'bogus',
  556. $this->user ) );
  557. $this->assertEquals( [ [ 'protectedpagetext', 'bogus', 'edit' ],
  558. [ 'protectedpagetext', 'editprotected', 'edit' ],
  559. [ 'protectedpagetext', 'protect', 'edit' ] ],
  560. $this->title->getUserPermissionsErrors( 'edit',
  561. $this->user ) );
  562. $this->setUserPerm( "" );
  563. $this->assertEquals( [ [ 'badaccess-group0' ],
  564. [ 'protectedpagetext', 'bogus', 'bogus' ],
  565. [ 'protectedpagetext', 'editprotected', 'bogus' ],
  566. [ 'protectedpagetext', 'protect', 'bogus' ] ],
  567. $this->title->getUserPermissionsErrors( 'bogus',
  568. $this->user ) );
  569. $this->assertEquals( [ [ 'badaccess-groups', "*, [[$prefix:Users|Users]]", 2 ],
  570. [ 'protectedpagetext', 'bogus', 'edit' ],
  571. [ 'protectedpagetext', 'editprotected', 'edit' ],
  572. [ 'protectedpagetext', 'protect', 'edit' ] ],
  573. $this->title->getUserPermissionsErrors( 'edit',
  574. $this->user ) );
  575. $this->setUserPerm( [ "edit", "editprotected" ] );
  576. $this->assertEquals( [ [ 'badaccess-group0' ],
  577. [ 'protectedpagetext', 'bogus', 'bogus' ],
  578. [ 'protectedpagetext', 'protect', 'bogus' ] ],
  579. $this->title->getUserPermissionsErrors( 'bogus',
  580. $this->user ) );
  581. $this->assertEquals( [
  582. [ 'protectedpagetext', 'bogus', 'edit' ],
  583. [ 'protectedpagetext', 'protect', 'edit' ] ],
  584. $this->title->getUserPermissionsErrors( 'edit',
  585. $this->user ) );
  586. $this->title->mCascadeRestriction = true;
  587. $this->setUserPerm( "edit" );
  588. $this->assertEquals( false,
  589. $this->title->quickUserCan( 'bogus', $this->user ) );
  590. $this->assertEquals( false,
  591. $this->title->quickUserCan( 'edit', $this->user ) );
  592. $this->assertEquals( [ [ 'badaccess-group0' ],
  593. [ 'protectedpagetext', 'bogus', 'bogus' ],
  594. [ 'protectedpagetext', 'editprotected', 'bogus' ],
  595. [ 'protectedpagetext', 'protect', 'bogus' ] ],
  596. $this->title->getUserPermissionsErrors( 'bogus',
  597. $this->user ) );
  598. $this->assertEquals( [ [ 'protectedpagetext', 'bogus', 'edit' ],
  599. [ 'protectedpagetext', 'editprotected', 'edit' ],
  600. [ 'protectedpagetext', 'protect', 'edit' ] ],
  601. $this->title->getUserPermissionsErrors( 'edit',
  602. $this->user ) );
  603. $this->setUserPerm( [ "edit", "editprotected" ] );
  604. $this->assertEquals( false,
  605. $this->title->quickUserCan( 'bogus', $this->user ) );
  606. $this->assertEquals( false,
  607. $this->title->quickUserCan( 'edit', $this->user ) );
  608. $this->assertEquals( [ [ 'badaccess-group0' ],
  609. [ 'protectedpagetext', 'bogus', 'bogus' ],
  610. [ 'protectedpagetext', 'protect', 'bogus' ],
  611. [ 'protectedpagetext', 'protect', 'bogus' ] ],
  612. $this->title->getUserPermissionsErrors( 'bogus',
  613. $this->user ) );
  614. $this->assertEquals( [ [ 'protectedpagetext', 'bogus', 'edit' ],
  615. [ 'protectedpagetext', 'protect', 'edit' ],
  616. [ 'protectedpagetext', 'protect', 'edit' ] ],
  617. $this->title->getUserPermissionsErrors( 'edit',
  618. $this->user ) );
  619. }
  620. /**
  621. * @covers Title::checkCascadingSourcesRestrictions
  622. */
  623. public function testCascadingSourcesRestrictions() {
  624. $this->setTitle( NS_MAIN, "test page" );
  625. $this->setUserPerm( [ "edit", "bogus" ] );
  626. $this->title->mCascadeSources = [
  627. Title::makeTitle( NS_MAIN, "Bogus" ),
  628. Title::makeTitle( NS_MAIN, "UnBogus" )
  629. ];
  630. $this->title->mCascadingRestrictions = [
  631. "bogus" => [ 'bogus', "sysop", "protect", "" ]
  632. ];
  633. $this->assertEquals( false,
  634. $this->title->userCan( 'bogus', $this->user ) );
  635. $this->assertEquals( [
  636. [ "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n", 'bogus' ],
  637. [ "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n", 'bogus' ],
  638. [ "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n", 'bogus' ] ],
  639. $this->title->getUserPermissionsErrors( 'bogus', $this->user ) );
  640. $this->assertEquals( true,
  641. $this->title->userCan( 'edit', $this->user ) );
  642. $this->assertEquals( [],
  643. $this->title->getUserPermissionsErrors( 'edit', $this->user ) );
  644. }
  645. /**
  646. * @todo This test method should be split up into separate test methods and
  647. * data providers
  648. * @covers Title::checkActionPermissions
  649. */
  650. public function testActionPermissions() {
  651. $this->setUserPerm( [ "createpage" ] );
  652. $this->setTitle( NS_MAIN, "test page" );
  653. $this->title->mTitleProtection['permission'] = '';
  654. $this->title->mTitleProtection['user'] = $this->user->getId();
  655. $this->title->mTitleProtection['expiry'] = 'infinity';
  656. $this->title->mTitleProtection['reason'] = 'test';
  657. $this->title->mCascadeRestriction = false;
  658. $this->assertEquals( [ [ 'titleprotected', 'Useruser', 'test' ] ],
  659. $this->title->getUserPermissionsErrors( 'create', $this->user ) );
  660. $this->assertEquals( false,
  661. $this->title->userCan( 'create', $this->user ) );
  662. $this->title->mTitleProtection['permission'] = 'editprotected';
  663. $this->setUserPerm( [ 'createpage', 'protect' ] );
  664. $this->assertEquals( [ [ 'titleprotected', 'Useruser', 'test' ] ],
  665. $this->title->getUserPermissionsErrors( 'create', $this->user ) );
  666. $this->assertEquals( false,
  667. $this->title->userCan( 'create', $this->user ) );
  668. $this->setUserPerm( [ 'createpage', 'editprotected' ] );
  669. $this->assertEquals( [],
  670. $this->title->getUserPermissionsErrors( 'create', $this->user ) );
  671. $this->assertEquals( true,
  672. $this->title->userCan( 'create', $this->user ) );
  673. $this->setUserPerm( [ 'createpage' ] );
  674. $this->assertEquals( [ [ 'titleprotected', 'Useruser', 'test' ] ],
  675. $this->title->getUserPermissionsErrors( 'create', $this->user ) );
  676. $this->assertEquals( false,
  677. $this->title->userCan( 'create', $this->user ) );
  678. $this->setTitle( NS_MEDIA, "test page" );
  679. $this->setUserPerm( [ "move" ] );
  680. $this->assertEquals( false,
  681. $this->title->userCan( 'move', $this->user ) );
  682. $this->assertEquals( [ [ 'immobile-source-namespace', 'Media' ] ],
  683. $this->title->getUserPermissionsErrors( 'move', $this->user ) );
  684. $this->setTitle( NS_HELP, "test page" );
  685. $this->assertEquals( [],
  686. $this->title->getUserPermissionsErrors( 'move', $this->user ) );
  687. $this->assertEquals( true,
  688. $this->title->userCan( 'move', $this->user ) );
  689. $this->title->mInterwiki = "no";
  690. $this->assertEquals( [ [ 'immobile-source-page' ] ],
  691. $this->title->getUserPermissionsErrors( 'move', $this->user ) );
  692. $this->assertEquals( false,
  693. $this->title->userCan( 'move', $this->user ) );
  694. $this->setTitle( NS_MEDIA, "test page" );
  695. $this->assertEquals( false,
  696. $this->title->userCan( 'move-target', $this->user ) );
  697. $this->assertEquals( [ [ 'immobile-target-namespace', 'Media' ] ],
  698. $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
  699. $this->setTitle( NS_HELP, "test page" );
  700. $this->assertEquals( [],
  701. $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
  702. $this->assertEquals( true,
  703. $this->title->userCan( 'move-target', $this->user ) );
  704. $this->title->mInterwiki = "no";
  705. $this->assertEquals( [ [ 'immobile-target-page' ] ],
  706. $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
  707. $this->assertEquals( false,
  708. $this->title->userCan( 'move-target', $this->user ) );
  709. }
  710. /**
  711. * @covers Title::checkUserBlock
  712. */
  713. public function testUserBlock() {
  714. $this->setMwGlobals( [
  715. 'wgEmailConfirmToEdit' => true,
  716. 'wgEmailAuthentication' => true,
  717. ] );
  718. $this->setUserPerm( [ "createpage", "move" ] );
  719. $this->setTitle( NS_HELP, "test page" );
  720. # $wgEmailConfirmToEdit only applies to 'edit' action
  721. $this->assertEquals( [],
  722. $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
  723. $this->assertContains( [ 'confirmedittext' ],
  724. $this->title->getUserPermissionsErrors( 'edit', $this->user ) );
  725. $this->setMwGlobals( 'wgEmailConfirmToEdit', false );
  726. $this->assertNotContains( [ 'confirmedittext' ],
  727. $this->title->getUserPermissionsErrors( 'edit', $this->user ) );
  728. # $wgEmailConfirmToEdit && !$user->isEmailConfirmed() && $action != 'createaccount'
  729. $this->assertEquals( [],
  730. $this->title->getUserPermissionsErrors( 'move-target',
  731. $this->user ) );
  732. global $wgLang;
  733. $prev = time();
  734. $now = time() + 120;
  735. $this->user->mBlockedby = $this->user->getId();
  736. $this->user->mBlock = new Block( [
  737. 'address' => '127.0.8.1',
  738. 'by' => $this->user->getId(),
  739. 'reason' => 'no reason given',
  740. 'timestamp' => $prev + 3600,
  741. 'auto' => true,
  742. 'expiry' => 0
  743. ] );
  744. $this->user->mBlock->mTimestamp = 0;
  745. $this->assertEquals( [ [ 'autoblockedtext',
  746. '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
  747. 'Useruser', null, 'infinite', '127.0.8.1',
  748. $wgLang->timeanddate( wfTimestamp( TS_MW, $prev ), true ) ] ],
  749. $this->title->getUserPermissionsErrors( 'move-target',
  750. $this->user ) );
  751. $this->assertEquals( false, $this->title->userCan( 'move-target', $this->user ) );
  752. // quickUserCan should ignore user blocks
  753. $this->assertEquals( true, $this->title->quickUserCan( 'move-target', $this->user ) );
  754. global $wgLocalTZoffset;
  755. $wgLocalTZoffset = -60;
  756. $this->user->mBlockedby = $this->user->getName();
  757. $this->user->mBlock = new Block( [
  758. 'address' => '127.0.8.1',
  759. 'by' => $this->user->getId(),
  760. 'reason' => 'no reason given',
  761. 'timestamp' => $now,
  762. 'auto' => false,
  763. 'expiry' => 10,
  764. ] );
  765. $this->assertEquals( [ [ 'blockedtext',
  766. '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
  767. 'Useruser', null, '23:00, 31 December 1969', '127.0.8.1',
  768. $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ],
  769. $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
  770. # $action != 'read' && $action != 'createaccount' && $user->isBlockedFrom( $this )
  771. # $user->blockedFor() == ''
  772. # $user->mBlock->mExpiry == 'infinity'
  773. $this->user->mBlockedby = $this->user->getName();
  774. $this->user->mBlock = new Block( [
  775. 'address' => '127.0.8.1',
  776. 'by' => $this->user->getId(),
  777. 'reason' => 'no reason given',
  778. 'timestamp' => $now,
  779. 'auto' => false,
  780. 'expiry' => 10,
  781. 'systemBlock' => 'test',
  782. ] );
  783. $this->assertEquals( [ [ 'systemblockedtext',
  784. '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1',
  785. 'Useruser', 'test', '23:00, 31 December 1969', '127.0.8.1',
  786. $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ],
  787. $this->title->getUserPermissionsErrors( 'move-target', $this->user ) );
  788. }
  789. }