r92512 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r92511‎ | r92512 | r92513 >
Date:00:52, 19 July 2011
Author:catrope
Status:ok
Tags:
Comment:
1.18: Back out r92364, partial implementation that we don't want in 1.18 yet
Modified paths:
  • /branches/REL1_18/phase3/RELEASE-NOTES-1.18 (modified) (history)
  • /branches/REL1_18/phase3/includes/DefaultSettings.php (modified) (history)
  • /branches/REL1_18/phase3/includes/Title.php (modified) (history)
  • /branches/REL1_18/phase3/includes/User.php (modified) (history)
  • /branches/REL1_18/phase3/tests/phpunit/includes/ArticleTablesTest.php (modified) (history)
  • /branches/REL1_18/phase3/tests/phpunit/includes/TitlePermissionTest.php (modified) (history)
  • /branches/REL1_18/phase3/tests/phpunit/includes/UserTest.php (modified) (history)

Diff [purge]

Index: branches/REL1_18/phase3/RELEASE-NOTES-1.18
@@ -81,7 +81,6 @@
8282 hooks have been removed.
8383 * New hook "Collation::factory" to allow extensions to create custom
8484 category collations.
85 -* $wgGroupPermissions now supports per namespace permissions.
8685
8786 === New features in 1.18 ===
8887 * BREAKING CHANGE: action=watch / action=unwatch now requires a token.
Index: branches/REL1_18/phase3/tests/phpunit/includes/ArticleTablesTest.php
@@ -11,7 +11,7 @@
1212 $title = Title::newFromText("Bug 14404");
1313 $article = new Article( $title );
1414 $wgUser = new User();
15 - $wgUser->mRights['*'] = array( 'createpage', 'edit', 'purge' );
 15+ $wgUser->mRights = array( 'createpage', 'edit', 'purge' );
1616 $wgLanguageCode = 'es';
1717 $wgContLang = Language::factory( 'es' );
1818
Index: branches/REL1_18/phase3/tests/phpunit/includes/UserTest.php
@@ -1,11 +1,7 @@
22 <?php
33
4 -define( 'NS_UNITTEST', 5600 );
5 -define( 'NS_UNITTEST_TALK', 5601 );
6 -
74 class UserTest extends MediaWikiTestCase {
85 protected $savedGroupPermissions, $savedRevokedPermissions;
9 - protected $user;
106
117 public function setUp() {
128 parent::setUp();
@@ -14,40 +10,24 @@
1511 $this->savedRevokedPermissions = $GLOBALS['wgRevokePermissions'];
1612
1713 $this->setUpPermissionGlobals();
18 - $this->setUpUser();
1914 }
2015 private function setUpPermissionGlobals() {
2116 global $wgGroupPermissions, $wgRevokePermissions;
2217
23 - # Data for regular $wgGroupPermissions test
2418 $wgGroupPermissions['unittesters'] = array(
25 - 'test' => true,
2619 'runtest' => true,
2720 'writetest' => false,
2821 'nukeworld' => false,
2922 );
3023 $wgGroupPermissions['testwriters'] = array(
31 - 'test' => true,
3224 'writetest' => true,
3325 'modifytest' => true,
3426 );
35 - # Data for regular $wgRevokePermissions test
 27+
3628 $wgRevokePermissions['formertesters'] = array(
3729 'runtest' => true,
3830 );
39 -
40 - # Data for namespace based $wgGroupPermissions test
41 - $wgGroupPermissions['unittesters']['writedocumentation'] = array(
42 - NS_MAIN => false, NS_UNITTEST => true,
43 - );
44 - $wgGroupPermissions['testwriters']['writedocumentation'] = true;
45 -
4631 }
47 - private function setUpUser() {
48 - $this->user = new User;
49 - $this->user->addGroup( 'unittesters' );
50 - }
51 -
5232 public function tearDown() {
5333 parent::tearDown();
5434
@@ -75,90 +55,4 @@
7656 $this->assertNotContains( 'modifytest', $rights );
7757 $this->assertNotContains( 'nukeworld', $rights );
7858 }
79 -
80 - public function testNamespaceGroupPermissions() {
81 - $rights = User::getGroupPermissions( array( 'unittesters' ) );
82 - $this->assertNotContains( 'writedocumentation', $rights );
83 -
84 - $rights = User::getGroupPermissions( array( 'unittesters' ) , NS_MAIN );
85 - $this->assertNotContains( 'writedocumentation', $rights );
86 - $this->assertNotContains( 'modifytest', $rights );
87 -
88 - $rights = User::getGroupPermissions( array( 'unittesters' ), NS_HELP );
89 - $this->assertNotContains( 'writedocumentation', $rights );
90 - $this->assertNotContains( 'modifytest', $rights );
91 -
92 - $rights = User::getGroupPermissions( array( 'unittesters' ), NS_UNITTEST );
93 - $this->assertContains( 'writedocumentation', $rights );
94 -
95 - $rights = User::getGroupPermissions(
96 - array( 'unittesters', 'testwriters' ), NS_MAIN );
97 - $this->assertContains( 'writedocumentation', $rights );
98 - }
99 -
100 - public function testUserPermissions() {
101 - $rights = $this->user->getRights();
102 - $this->assertContains( 'runtest', $rights );
103 - $this->assertNotContains( 'writetest', $rights );
104 - $this->assertNotContains( 'modifytest', $rights );
105 - $this->assertNotContains( 'nukeworld', $rights );
106 - $this->assertNotContains( 'writedocumentation', $rights );
107 -
108 - $rights = $this->user->getRights( NS_MAIN );
109 - $this->assertNotContains( 'writedocumentation', $rights );
110 - $this->assertNotContains( 'modifytest', $rights );
111 -
112 - $rights = $this->user->getRights( NS_HELP );
113 - $this->assertNotContains( 'writedocumentation', $rights );
114 - $this->assertNotContains( 'modifytest', $rights );
115 -
116 - $rights = $this->user->getRights( NS_UNITTEST );
117 - $this->assertContains( 'writedocumentation', $rights );
118 - }
119 -
120 - /**
121 - * @dataProvider provideGetGroupsWithPermission
122 - */
123 - public function testGetGroupsWithPermission( $expected, $right, $ns ) {
124 - $result = User::getGroupsWithPermission( $right, $ns );
125 - sort( $result );
126 - sort( $expected );
127 -
128 - $this->assertEquals( $expected, $result, "Groups with permission $right" .
129 - ( is_null( $ns ) ? '' : "in namespace $ns" ) );
130 - }
131 - public function provideGetGroupsWithPermission() {
132 - return array(
133 - array(
134 - array( 'unittesters', 'testwriters' ),
135 - 'test',
136 - null
137 - ),
138 - array(
139 - array( 'unittesters' ),
140 - 'runtest',
141 - null
142 - ),
143 - array(
144 - array( 'testwriters' ),
145 - 'writetest',
146 - null
147 - ),
148 - array(
149 - array( 'testwriters' ),
150 - 'modifytest',
151 - null
152 - ),
153 - array(
154 - array( 'testwriters' ),
155 - 'writedocumentation',
156 - NS_MAIN
157 - ),
158 - array(
159 - array( 'unittesters', 'testwriters' ),
160 - 'writedocumentation',
161 - NS_UNITTEST
162 - ),
163 - );
164 - }
16559 }
\ No newline at end of file
Index: branches/REL1_18/phase3/tests/phpunit/includes/TitlePermissionTest.php
@@ -56,17 +56,11 @@
5757 }
5858
5959 function setUserPerm( $perm ) {
60 - // Setting member variables is evil!!!
61 -
62 - if ( !is_array( $perm ) ) {
63 - $perm = array( $perm );
 60+ if ( is_array( $perm ) ) {
 61+ $this->user->mRights = $perm;
 62+ } else {
 63+ $this->user->mRights = array( $perm );
6464 }
65 - for ($i = 0; $i < 100; $i++) {
66 - $this->user->mRights[$i] = $perm;
67 - }
68 -
69 - // Hack, hack hack ...
70 - $this->user->mRights['*'] = $perm;
7165 }
7266
7367 function setTitle( $ns, $title = "Main_Page" ) {
Index: branches/REL1_18/phase3/includes/User.php
@@ -2252,29 +2252,16 @@
22532253
22542254 /**
22552255 * Get the permissions this user has.
2256 - * @param $ns int If numeric, get permissions for this namespace
22572256 * @return Array of String permission names
22582257 */
2259 - public function getRights( $ns = null ) {
2260 - $key = is_null( $ns ) ? '*' : intval( $ns );
2261 -
 2258+ function getRights() {
22622259 if ( is_null( $this->mRights ) ) {
2263 - $this->mRights = array();
2264 - }
2265 -
2266 - if ( !isset( $this->mRights[$key] ) ) {
2267 - $this->mRights[$key] = self::getGroupPermissions( $this->getEffectiveGroups(), $ns );
2268 - wfRunHooks( 'UserGetRights', array( $this, &$this->mRights[$key], $ns ) );
 2260+ $this->mRights = self::getGroupPermissions( $this->getEffectiveGroups() );
 2261+ wfRunHooks( 'UserGetRights', array( $this, &$this->mRights ) );
22692262 // Force reindexation of rights when a hook has unset one of them
2270 - $this->mRights[$key] = array_values( $this->mRights[$key] );
 2263+ $this->mRights = array_values( $this->mRights );
22712264 }
2272 - if ( is_null( $ns ) ) {
2273 - return $this->mRights[$key];
2274 - } else {
2275 - // Merge non namespace specific rights
2276 - return array_merge( $this->mRights[$key], $this->getRights() );
2277 - }
2278 -
 2265+ return $this->mRights;
22792266 }
22802267
22812268 /**
@@ -2398,7 +2385,7 @@
23992386 }
24002387 $this->loadGroups();
24012388 $this->mGroups[] = $group;
2402 - $this->mRights = null;
 2389+ $this->mRights = User::getGroupPermissions( $this->getEffectiveGroups( true ) );
24032390
24042391 $this->invalidateCache();
24052392 }
@@ -2428,7 +2415,7 @@
24292416 }
24302417 $this->loadGroups();
24312418 $this->mGroups = array_diff( $this->mGroups, array( $group ) );
2432 - $this->mRights = null;
 2419+ $this->mRights = User::getGroupPermissions( $this->getEffectiveGroups( true ) );
24332420
24342421 $this->invalidateCache();
24352422 }
@@ -2485,10 +2472,9 @@
24862473 /**
24872474 * Internal mechanics of testing a permission
24882475 * @param $action String
2489 - * @param $ns int|null Namespace optional
24902476 * @return bool
24912477 */
2492 - public function isAllowed( $action = '', $ns = null ) {
 2478+ public function isAllowed( $action = '' ) {
24932479 if ( $action === '' ) {
24942480 return true; // In the spirit of DWIM
24952481 }
@@ -2500,7 +2486,7 @@
25012487 }
25022488 # Use strict parameter to avoid matching numeric 0 accidentally inserted
25032489 # by misconfiguration: 0 == 'foo'
2504 - return in_array( $action, $this->getRights( $ns ), true );
 2490+ return in_array( $action, $this->getRights(), true );
25052491 }
25062492
25072493 /**
@@ -3452,53 +3438,30 @@
34533439 *
34543440 * @return Array of Strings List of permission key names for given groups combined
34553441 */
3456 - public static function getGroupPermissions( $groups, $ns = null ) {
 3442+ public static function getGroupPermissions( $groups ) {
34573443 global $wgGroupPermissions, $wgRevokePermissions;
34583444 $rights = array();
34593445
34603446 // Grant every granted permission first
34613447 foreach( $groups as $group ) {
34623448 if( isset( $wgGroupPermissions[$group] ) ) {
3463 - $rights = array_merge( $rights, self::extractRights(
3464 - $wgGroupPermissions[$group], $ns ) );
 3449+ $rights = array_merge( $rights,
 3450+ // array_filter removes empty items
 3451+ array_keys( array_filter( $wgGroupPermissions[$group] ) ) );
34653452 }
34663453 }
34673454
34683455 // Revoke the revoked permissions
34693456 foreach( $groups as $group ) {
34703457 if( isset( $wgRevokePermissions[$group] ) ) {
3471 - $rights = array_diff( $rights, self::extractRights(
3472 - $wgRevokePermissions[$group], $ns ) );
 3458+ $rights = array_diff( $rights,
 3459+ array_keys( array_filter( $wgRevokePermissions[$group] ) ) );
34733460 }
34743461 }
34753462 return array_unique( $rights );
34763463 }
34773464
34783465 /**
3479 - * Helper for User::getGroupPermissions
3480 - * @param $list array
3481 - * @param $ns int
3482 - * @return array
3483 - */
3484 - private static function extractRights( $list, $ns ) {
3485 - $rights = array();
3486 - foreach( $list as $right => $value ) {
3487 - if ( is_array( $value ) ) {
3488 - # This is a list of namespaces where the permission applies
3489 - if ( !is_null( $ns ) && !empty( $value[$ns] ) ) {
3490 - $rights[] = $right;
3491 - }
3492 - } else {
3493 - # This is a boolean indicating that the permission applies
3494 - if ( $value ) {
3495 - $rights[] = $right;
3496 - }
3497 - }
3498 - }
3499 - return $rights;
3500 - }
3501 -
3502 - /**
35033466 * Get all the groups who have a given permission
35043467 *
35053468 * @param $role String Role to check
@@ -3507,11 +3470,11 @@
35083471 *
35093472 * @return Array of Strings List of internal group names with the given permission
35103473 */
3511 - public static function getGroupsWithPermission( $role, $ns = null ) {
 3474+ public static function getGroupsWithPermission( $role ) {
35123475 global $wgGroupPermissions;
35133476 $allowedGroups = array();
35143477 foreach ( $wgGroupPermissions as $group => $rights ) {
3515 - if ( in_array( $role, self::getGroupPermissions( array( $group ), $ns ), true ) ) {
 3478+ if ( isset( $rights[$role] ) && $rights[$role] ) {
35163479 $allowedGroups[] = $group;
35173480 }
35183481 }
Index: branches/REL1_18/phase3/includes/Title.php
@@ -1239,33 +1239,34 @@
12401240 * @return Array list of errors
12411241 */
12421242 private function checkQuickPermissions( $action, $user, $errors, $doExpensiveQueries, $short ) {
1243 - $ns = $this->getNamespace();
1244 -
12451243 if ( $action == 'create' ) {
1246 - if ( ( $this->isTalkPage() && !$user->isAllowed( 'createtalk', $ns ) ) ||
1247 - ( !$this->isTalkPage() && !$user->isAllowed( 'createpage', $ns ) ) ) {
 1244+ if ( ( $this->isTalkPage() && !$user->isAllowed( 'createtalk' ) ) ||
 1245+ ( !$this->isTalkPage() && !$user->isAllowed( 'createpage' ) ) ) {
12481246 $errors[] = $user->isAnon() ? array( 'nocreatetext' ) : array( 'nocreate-loggedin' );
12491247 }
12501248 } elseif ( $action == 'move' ) {
1251 - if ( !$user->isAllowed( 'move-rootuserpages', $ns )
1252 - && $ns == NS_USER && !$this->isSubpage() ) {
 1249+ if ( !$user->isAllowed( 'move-rootuserpages' )
 1250+ && $this->mNamespace == NS_USER && !$this->isSubpage() ) {
12531251 // Show user page-specific message only if the user can move other pages
12541252 $errors[] = array( 'cant-move-user-page' );
12551253 }
12561254
12571255 // Check if user is allowed to move files if it's a file
1258 - if ( $ns == NS_FILE && !$user->isAllowed( 'movefile', $ns ) ) {
 1256+ if ( $this->mNamespace == NS_FILE && !$user->isAllowed( 'movefile' ) ) {
12591257 $errors[] = array( 'movenotallowedfile' );
12601258 }
12611259
1262 - if ( !$user->isAllowed( 'move', $ns) ) {
 1260+ if ( !$user->isAllowed( 'move' ) ) {
12631261 // User can't move anything
1264 -
1265 - $userCanMove = in_array( 'move', User::getGroupPermissions(
1266 - array( 'user' ), $ns ), true );
1267 - $autoconfirmedCanMove = in_array( 'move', User::getGroupPermissions(
1268 - array( 'autoconfirmed' ), $ns ), true );
1269 -
 1262+ global $wgGroupPermissions;
 1263+ $userCanMove = false;
 1264+ if ( isset( $wgGroupPermissions['user']['move'] ) ) {
 1265+ $userCanMove = $wgGroupPermissions['user']['move'];
 1266+ }
 1267+ $autoconfirmedCanMove = false;
 1268+ if ( isset( $wgGroupPermissions['autoconfirmed']['move'] ) ) {
 1269+ $autoconfirmedCanMove = $wgGroupPermissions['autoconfirmed']['move'];
 1270+ }
12701271 if ( $user->isAnon() && ( $userCanMove || $autoconfirmedCanMove ) ) {
12711272 // custom message if logged-in users without any special rights can move
12721273 $errors[] = array( 'movenologintext' );
@@ -1274,20 +1275,20 @@
12751276 }
12761277 }
12771278 } elseif ( $action == 'move-target' ) {
1278 - if ( !$user->isAllowed( 'move', $ns ) ) {
 1279+ if ( !$user->isAllowed( 'move' ) ) {
12791280 // User can't move anything
12801281 $errors[] = array( 'movenotallowed' );
1281 - } elseif ( !$user->isAllowed( 'move-rootuserpages', $ns )
1282 - && $ns == NS_USER && !$this->isSubpage() ) {
 1282+ } elseif ( !$user->isAllowed( 'move-rootuserpages' )
 1283+ && $this->mNamespace == NS_USER && !$this->isSubpage() ) {
12831284 // Show user page-specific message only if the user can move other pages
12841285 $errors[] = array( 'cant-move-to-user-page' );
12851286 }
1286 - } elseif ( !$user->isAllowed( $action, $ns ) ) {
 1287+ } elseif ( !$user->isAllowed( $action ) ) {
12871288 // We avoid expensive display logic for quickUserCan's and such
12881289 $groups = false;
12891290 if ( !$short ) {
12901291 $groups = array_map( array( 'User', 'makeGroupLinkWiki' ),
1291 - User::getGroupsWithPermission( $action, $ns ) );
 1292+ User::getGroupsWithPermission( $action ) );
12921293 }
12931294
12941295 if ( $groups ) {
@@ -1439,9 +1440,9 @@
14401441 if ( $right == 'sysop' ) {
14411442 $right = 'protect';
14421443 }
1443 - if ( $right != '' && !$user->isAllowed( $right, $this->mNamespace ) ) {
 1444+ if ( $right != '' && !$user->isAllowed( $right ) ) {
14441445 // Users with 'editprotected' permission can edit protected pages
1445 - if ( $action == 'edit' && $user->isAllowed( 'editprotected', $this->mNamespace ) ) {
 1446+ if ( $action == 'edit' && $user->isAllowed( 'editprotected' ) ) {
14461447 // Users with 'editprotected' permission cannot edit protected pages
14471448 // with cascading option turned on.
14481449 if ( $this->mCascadeRestriction ) {
@@ -1482,7 +1483,7 @@
14831484 if ( isset( $restrictions[$action] ) ) {
14841485 foreach ( $restrictions[$action] as $right ) {
14851486 $right = ( $right == 'sysop' ) ? 'protect' : $right;
1486 - if ( $right != '' && !$user->isAllowed( $right, $this->mNamespace ) ) {
 1487+ if ( $right != '' && !$user->isAllowed( $right ) ) {
14871488 $pages = '';
14881489 foreach ( $cascadingSources as $page )
14891490 $pages .= '* [[:' . $page->getPrefixedText() . "]]\n";
@@ -1518,9 +1519,7 @@
15191520 if( $title_protection['pt_create_perm'] == 'sysop' ) {
15201521 $title_protection['pt_create_perm'] = 'protect'; // B/C
15211522 }
1522 - if( $title_protection['pt_create_perm'] == '' ||
1523 - !$user->isAllowed( $title_protection['pt_create_perm'],
1524 - $this->mNamespace ) ) {
 1523+ if( $title_protection['pt_create_perm'] == '' || !$user->isAllowed( $title_protection['pt_create_perm'] ) ) {
15251524 $errors[] = array( 'titleprotected', User::whoIs( $title_protection['pt_user'] ), $title_protection['pt_reason'] );
15261525 }
15271526 }
Index: branches/REL1_18/phase3/includes/DefaultSettings.php
@@ -3304,10 +3304,6 @@
33053305 * unable to perform certain essential tasks or access new functionality
33063306 * when new permissions are introduced and default grants established.
33073307 *
3308 - * If set to an array instead of a boolean, it is assumed that the array is in
3309 - * NS => bool form in order to support per-namespace permissions. Note that
3310 - * this feature does not fully work for all permission types.
3311 - *
33123308 * Functionality to make pages inaccessible has not been extensively tested
33133309 * for security. Use at your own risk!
33143310 *

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r92364First steps for bug 14801: add backend support for per-namespace permissions ...btongminh16:09, 16 July 2011

Status & tagging log