Index: trunk/phase3/docs/hooks.txt |
— | — | @@ -2091,7 +2091,6 @@ |
2092 | 2092 | 'UserGetRights': Called in User::getRights() |
2093 | 2093 | $user: User to get rights for |
2094 | 2094 | &$rights: Current rights |
2095 | | -$namespace: Namespace to get permissions for; if null all namespaces |
2096 | 2095 | |
2097 | 2096 | 'UserIsBlockedFrom': Check if a user is blocked from a specific page (for specific block |
2098 | 2097 | exemptions). |
Index: trunk/phase3/tests/phpunit/includes/ArticleTablesTest.php |
— | — | @@ -11,7 +11,7 @@ |
12 | 12 | $title = Title::newFromText("Bug 14404"); |
13 | 13 | $article = new Article( $title ); |
14 | 14 | $wgUser = new User(); |
15 | | - $wgUser->mRights['*'] = array( 'createpage', 'edit', 'purge' ); |
| 15 | + $wgUser->mRights = array( 'createpage', 'edit', 'purge' ); |
16 | 16 | $wgLanguageCode = 'es'; |
17 | 17 | $wgContLang = Language::factory( 'es' ); |
18 | 18 | |
Index: trunk/phase3/tests/phpunit/includes/UserTest.php |
— | — | @@ -38,13 +38,6 @@ |
39 | 39 | $wgRevokePermissions['formertesters'] = array( |
40 | 40 | 'runtest' => true, |
41 | 41 | ); |
42 | | - |
43 | | - # Data for namespace based $wgGroupPermissions test |
44 | | - $wgGroupPermissions['unittesters']['writedocumentation'] = array( |
45 | | - NS_MAIN => false, NS_UNITTEST => true, |
46 | | - ); |
47 | | - $wgGroupPermissions['testwriters']['writedocumentation'] = true; |
48 | | - |
49 | 42 | } |
50 | 43 | private function setUpUser() { |
51 | 44 | $this->user = new User; |
— | — | @@ -79,89 +72,42 @@ |
80 | 73 | $this->assertNotContains( 'nukeworld', $rights ); |
81 | 74 | } |
82 | 75 | |
83 | | - public function testNamespaceGroupPermissions() { |
84 | | - $rights = User::getGroupPermissions( array( 'unittesters' ) ); |
85 | | - $this->assertNotContains( 'writedocumentation', $rights ); |
86 | | - |
87 | | - $rights = User::getGroupPermissions( array( 'unittesters' ) , NS_MAIN ); |
88 | | - $this->assertNotContains( 'writedocumentation', $rights ); |
89 | | - $this->assertNotContains( 'modifytest', $rights ); |
90 | | - |
91 | | - $rights = User::getGroupPermissions( array( 'unittesters' ), NS_HELP ); |
92 | | - $this->assertNotContains( 'writedocumentation', $rights ); |
93 | | - $this->assertNotContains( 'modifytest', $rights ); |
94 | | - |
95 | | - $rights = User::getGroupPermissions( array( 'unittesters' ), NS_UNITTEST ); |
96 | | - $this->assertContains( 'writedocumentation', $rights ); |
97 | | - |
98 | | - $rights = User::getGroupPermissions( |
99 | | - array( 'unittesters', 'testwriters' ), NS_MAIN ); |
100 | | - $this->assertContains( 'writedocumentation', $rights ); |
101 | | - } |
102 | | - |
103 | 76 | public function testUserPermissions() { |
104 | 77 | $rights = $this->user->getRights(); |
105 | 78 | $this->assertContains( 'runtest', $rights ); |
106 | 79 | $this->assertNotContains( 'writetest', $rights ); |
107 | 80 | $this->assertNotContains( 'modifytest', $rights ); |
108 | 81 | $this->assertNotContains( 'nukeworld', $rights ); |
109 | | - $this->assertNotContains( 'writedocumentation', $rights ); |
110 | | - |
111 | | - $rights = $this->user->getRights( NS_MAIN ); |
112 | | - $this->assertNotContains( 'writedocumentation', $rights ); |
113 | | - $this->assertNotContains( 'modifytest', $rights ); |
114 | | - |
115 | | - $rights = $this->user->getRights( NS_HELP ); |
116 | | - $this->assertNotContains( 'writedocumentation', $rights ); |
117 | | - $this->assertNotContains( 'modifytest', $rights ); |
118 | | - |
119 | | - $rights = $this->user->getRights( NS_UNITTEST ); |
120 | | - $this->assertContains( 'writedocumentation', $rights ); |
121 | 82 | } |
122 | 83 | |
123 | 84 | /** |
124 | 85 | * @dataProvider provideGetGroupsWithPermission |
125 | 86 | */ |
126 | | - public function testGetGroupsWithPermission( $expected, $right, $ns ) { |
127 | | - $result = User::getGroupsWithPermission( $right, $ns ); |
| 87 | + public function testGetGroupsWithPermission( $expected, $right ) { |
| 88 | + $result = User::getGroupsWithPermission( $right ); |
128 | 89 | sort( $result ); |
129 | 90 | sort( $expected ); |
130 | 91 | |
131 | | - $this->assertEquals( $expected, $result, "Groups with permission $right" . |
132 | | - ( is_null( $ns ) ? '' : "in namespace $ns" ) ); |
| 92 | + $this->assertEquals( $expected, $result, "Groups with permission $right" ); |
133 | 93 | } |
134 | 94 | public function provideGetGroupsWithPermission() { |
135 | 95 | return array( |
136 | 96 | array( |
137 | 97 | array( 'unittesters', 'testwriters' ), |
138 | | - 'test', |
139 | | - null |
| 98 | + 'test' |
140 | 99 | ), |
141 | 100 | array( |
142 | 101 | array( 'unittesters' ), |
143 | | - 'runtest', |
144 | | - null |
| 102 | + 'runtest' |
145 | 103 | ), |
146 | 104 | array( |
147 | 105 | array( 'testwriters' ), |
148 | | - 'writetest', |
149 | | - null |
| 106 | + 'writetest' |
150 | 107 | ), |
151 | 108 | array( |
152 | 109 | array( 'testwriters' ), |
153 | | - 'modifytest', |
154 | | - null |
| 110 | + 'modifytest' |
155 | 111 | ), |
156 | | - array( |
157 | | - array( 'testwriters' ), |
158 | | - 'writedocumentation', |
159 | | - NS_MAIN |
160 | | - ), |
161 | | - array( |
162 | | - array( 'unittesters', 'testwriters' ), |
163 | | - 'writedocumentation', |
164 | | - NS_UNITTEST |
165 | | - ), |
166 | 112 | ); |
167 | 113 | } |
168 | 114 | |
Index: trunk/phase3/tests/phpunit/includes/TitlePermissionTest.php |
— | — | @@ -62,15 +62,11 @@ |
63 | 63 | function setUserPerm( $perm ) { |
64 | 64 | // Setting member variables is evil!!! |
65 | 65 | |
66 | | - if ( !is_array( $perm ) ) { |
67 | | - $perm = array( $perm ); |
| 66 | + if ( is_array( $perm ) ) { |
| 67 | + $this->user->mRights = $perm; |
| 68 | + } else { |
| 69 | + $this->user->mRights = array( $perm ); |
68 | 70 | } |
69 | | - for ($i = 0; $i < 100; $i++) { |
70 | | - $this->user->mRights[$i] = $perm; |
71 | | - } |
72 | | - |
73 | | - // Hack, hack hack ... |
74 | | - $this->user->mRights['*'] = $perm; |
75 | 71 | } |
76 | 72 | |
77 | 73 | function setTitle( $ns, $title = "Main_Page" ) { |
Index: trunk/phase3/includes/User.php |
— | — | @@ -2316,29 +2316,16 @@ |
2317 | 2317 | |
2318 | 2318 | /** |
2319 | 2319 | * Get the permissions this user has. |
2320 | | - * @param $ns int If numeric, get permissions for this namespace |
2321 | 2320 | * @return Array of String permission names |
2322 | 2321 | */ |
2323 | | - public function getRights( $ns = null ) { |
2324 | | - $key = is_null( $ns ) ? '*' : intval( $ns ); |
2325 | | - |
| 2322 | + public function getRights() { |
2326 | 2323 | if ( is_null( $this->mRights ) ) { |
2327 | | - $this->mRights = array(); |
2328 | | - } |
2329 | | - |
2330 | | - if ( !isset( $this->mRights[$key] ) ) { |
2331 | | - $this->mRights[$key] = self::getGroupPermissions( $this->getEffectiveGroups(), $ns ); |
2332 | | - wfRunHooks( 'UserGetRights', array( $this, &$this->mRights[$key], $ns ) ); |
| 2324 | + $this->mRights = self::getGroupPermissions( $this->getEffectiveGroups() ); |
| 2325 | + wfRunHooks( 'UserGetRights', array( $this, &$this->mRights ) ); |
2333 | 2326 | // Force reindexation of rights when a hook has unset one of them |
2334 | | - $this->mRights[$key] = array_values( $this->mRights[$key] ); |
| 2327 | + $this->mRights = array_values( $this->mRights ); |
2335 | 2328 | } |
2336 | | - if ( is_null( $ns ) ) { |
2337 | | - return $this->mRights[$key]; |
2338 | | - } else { |
2339 | | - // Merge non namespace specific rights |
2340 | | - return array_merge( $this->mRights[$key], $this->getRights() ); |
2341 | | - } |
2342 | | - |
| 2329 | + return $this->mRights; |
2343 | 2330 | } |
2344 | 2331 | |
2345 | 2332 | /** |
— | — | @@ -2463,7 +2450,7 @@ |
2464 | 2451 | } |
2465 | 2452 | $this->loadGroups(); |
2466 | 2453 | $this->mGroups[] = $group; |
2467 | | - $this->mRights = null; |
| 2454 | + $this->mRights = User::getGroupPermissions( $this->getEffectiveGroups( true ) ); |
2468 | 2455 | |
2469 | 2456 | $this->invalidateCache(); |
2470 | 2457 | } |
— | — | @@ -2493,7 +2480,7 @@ |
2494 | 2481 | } |
2495 | 2482 | $this->loadGroups(); |
2496 | 2483 | $this->mGroups = array_diff( $this->mGroups, array( $group ) ); |
2497 | | - $this->mRights = null; |
| 2484 | + $this->mRights = User::getGroupPermissions( $this->getEffectiveGroups( true ) ); |
2498 | 2485 | |
2499 | 2486 | $this->invalidateCache(); |
2500 | 2487 | } |
— | — | @@ -2550,10 +2537,9 @@ |
2551 | 2538 | /** |
2552 | 2539 | * Internal mechanics of testing a permission |
2553 | 2540 | * @param $action String |
2554 | | - * @param $ns int|null Namespace optional |
2555 | 2541 | * @return bool |
2556 | 2542 | */ |
2557 | | - public function isAllowed( $action = '', $ns = null ) { |
| 2543 | + public function isAllowed( $action = '' ) { |
2558 | 2544 | if ( $action === '' ) { |
2559 | 2545 | return true; // In the spirit of DWIM |
2560 | 2546 | } |
— | — | @@ -2565,7 +2551,7 @@ |
2566 | 2552 | } |
2567 | 2553 | # Use strict parameter to avoid matching numeric 0 accidentally inserted |
2568 | 2554 | # by misconfiguration: 0 == 'foo' |
2569 | | - return in_array( $action, $this->getRights( $ns ), true ); |
| 2555 | + return in_array( $action, $this->getRights(), true ); |
2570 | 2556 | } |
2571 | 2557 | |
2572 | 2558 | /** |
— | — | @@ -3544,70 +3530,40 @@ |
3545 | 3531 | * Get the permissions associated with a given list of groups |
3546 | 3532 | * |
3547 | 3533 | * @param $groups Array of Strings List of internal group names |
3548 | | - * @param $ns int |
3549 | | - * |
3550 | 3534 | * @return Array of Strings List of permission key names for given groups combined |
3551 | 3535 | */ |
3552 | | - public static function getGroupPermissions( array $groups, $ns = null ) { |
| 3536 | + public static function getGroupPermissions( $groups ) { |
3553 | 3537 | global $wgGroupPermissions, $wgRevokePermissions; |
3554 | 3538 | $rights = array(); |
3555 | | - |
3556 | | - // Grant every granted permission first |
| 3539 | + // grant every granted permission first |
3557 | 3540 | foreach( $groups as $group ) { |
3558 | 3541 | if( isset( $wgGroupPermissions[$group] ) ) { |
3559 | | - $rights = array_merge( $rights, self::extractRights( |
3560 | | - $wgGroupPermissions[$group], $ns ) ); |
| 3542 | + $rights = array_merge( $rights, |
| 3543 | + // array_filter removes empty items |
| 3544 | + array_keys( array_filter( $wgGroupPermissions[$group] ) ) ); |
3561 | 3545 | } |
3562 | 3546 | } |
3563 | | - |
3564 | | - // Revoke the revoked permissions |
| 3547 | + // now revoke the revoked permissions |
3565 | 3548 | foreach( $groups as $group ) { |
3566 | 3549 | if( isset( $wgRevokePermissions[$group] ) ) { |
3567 | | - $rights = array_diff( $rights, self::extractRights( |
3568 | | - $wgRevokePermissions[$group], $ns ) ); |
| 3550 | + $rights = array_diff( $rights, |
| 3551 | + array_keys( array_filter( $wgRevokePermissions[$group] ) ) ); |
3569 | 3552 | } |
3570 | 3553 | } |
3571 | 3554 | return array_unique( $rights ); |
3572 | 3555 | } |
3573 | 3556 | |
3574 | 3557 | /** |
3575 | | - * Helper for User::getGroupPermissions |
3576 | | - * @param $list array |
3577 | | - * @param $ns int |
3578 | | - * @return array |
3579 | | - */ |
3580 | | - private static function extractRights( $list, $ns ) { |
3581 | | - $rights = array(); |
3582 | | - foreach( $list as $right => $value ) { |
3583 | | - if ( is_array( $value ) ) { |
3584 | | - # This is a list of namespaces where the permission applies |
3585 | | - if ( !is_null( $ns ) && !empty( $value[$ns] ) ) { |
3586 | | - $rights[] = $right; |
3587 | | - } |
3588 | | - } else { |
3589 | | - # This is a boolean indicating that the permission applies |
3590 | | - if ( $value ) { |
3591 | | - $rights[] = $right; |
3592 | | - } |
3593 | | - } |
3594 | | - } |
3595 | | - return $rights; |
3596 | | - } |
3597 | | - |
3598 | | - /** |
3599 | 3558 | * Get all the groups who have a given permission |
3600 | 3559 | * |
3601 | 3560 | * @param $role String Role to check |
3602 | | - * @param $ns int |
3603 | | - * |
3604 | | - * |
3605 | 3561 | * @return Array of Strings List of internal group names with the given permission |
3606 | 3562 | */ |
3607 | | - public static function getGroupsWithPermission( $role, $ns = null ) { |
| 3563 | + public static function getGroupsWithPermission( $role ) { |
3608 | 3564 | global $wgGroupPermissions; |
3609 | 3565 | $allowedGroups = array(); |
3610 | 3566 | foreach ( $wgGroupPermissions as $group => $rights ) { |
3611 | | - if ( in_array( $role, self::getGroupPermissions( array( $group ), $ns ), true ) ) { |
| 3567 | + if ( isset( $rights[$role] ) && $rights[$role] ) { |
3612 | 3568 | $allowedGroups[] = $group; |
3613 | 3569 | } |
3614 | 3570 | } |
Index: trunk/phase3/includes/Title.php |
— | — | @@ -1559,33 +1559,34 @@ |
1560 | 1560 | * @return Array list of errors |
1561 | 1561 | */ |
1562 | 1562 | private function checkQuickPermissions( $action, $user, $errors, $doExpensiveQueries, $short ) { |
1563 | | - $ns = $this->getNamespace(); |
1564 | | - |
1565 | 1563 | if ( $action == 'create' ) { |
1566 | | - if ( ( $this->isTalkPage() && !$user->isAllowed( 'createtalk', $ns ) ) || |
1567 | | - ( !$this->isTalkPage() && !$user->isAllowed( 'createpage', $ns ) ) ) { |
| 1564 | + if ( ( $this->isTalkPage() && !$user->isAllowed( 'createtalk' ) ) || |
| 1565 | + ( !$this->isTalkPage() && !$user->isAllowed( 'createpage' ) ) ) { |
1568 | 1566 | $errors[] = $user->isAnon() ? array( 'nocreatetext' ) : array( 'nocreate-loggedin' ); |
1569 | 1567 | } |
1570 | 1568 | } elseif ( $action == 'move' ) { |
1571 | | - if ( !$user->isAllowed( 'move-rootuserpages', $ns ) |
1572 | | - && $ns == NS_USER && !$this->isSubpage() ) { |
| 1569 | + if ( !$user->isAllowed( 'move-rootuserpages' ) |
| 1570 | + && $this->mNamespace == NS_USER && !$this->isSubpage() ) { |
1573 | 1571 | // Show user page-specific message only if the user can move other pages |
1574 | 1572 | $errors[] = array( 'cant-move-user-page' ); |
1575 | 1573 | } |
1576 | 1574 | |
1577 | 1575 | // Check if user is allowed to move files if it's a file |
1578 | | - if ( $ns == NS_FILE && !$user->isAllowed( 'movefile', $ns ) ) { |
| 1576 | + if ( $this->mNamespace == NS_FILE && !$user->isAllowed( 'movefile' ) ) { |
1579 | 1577 | $errors[] = array( 'movenotallowedfile' ); |
1580 | 1578 | } |
1581 | 1579 | |
1582 | | - if ( !$user->isAllowed( 'move', $ns) ) { |
| 1580 | + if ( !$user->isAllowed( 'move' ) ) { |
1583 | 1581 | // User can't move anything |
1584 | | - |
1585 | | - $userCanMove = in_array( 'move', User::getGroupPermissions( |
1586 | | - array( 'user' ), $ns ), true ); |
1587 | | - $autoconfirmedCanMove = in_array( 'move', User::getGroupPermissions( |
1588 | | - array( 'autoconfirmed' ), $ns ), true ); |
1589 | | - |
| 1582 | + global $wgGroupPermissions; |
| 1583 | + $userCanMove = false; |
| 1584 | + if ( isset( $wgGroupPermissions['user']['move'] ) ) { |
| 1585 | + $userCanMove = $wgGroupPermissions['user']['move']; |
| 1586 | + } |
| 1587 | + $autoconfirmedCanMove = false; |
| 1588 | + if ( isset( $wgGroupPermissions['autoconfirmed']['move'] ) ) { |
| 1589 | + $autoconfirmedCanMove = $wgGroupPermissions['autoconfirmed']['move']; |
| 1590 | + } |
1590 | 1591 | if ( $user->isAnon() && ( $userCanMove || $autoconfirmedCanMove ) ) { |
1591 | 1592 | // custom message if logged-in users without any special rights can move |
1592 | 1593 | $errors[] = array( 'movenologintext' ); |
— | — | @@ -1594,15 +1595,15 @@ |
1595 | 1596 | } |
1596 | 1597 | } |
1597 | 1598 | } elseif ( $action == 'move-target' ) { |
1598 | | - if ( !$user->isAllowed( 'move', $ns ) ) { |
| 1599 | + if ( !$user->isAllowed( 'move' ) ) { |
1599 | 1600 | // User can't move anything |
1600 | 1601 | $errors[] = array( 'movenotallowed' ); |
1601 | | - } elseif ( !$user->isAllowed( 'move-rootuserpages', $ns ) |
1602 | | - && $ns == NS_USER && !$this->isSubpage() ) { |
| 1602 | + } elseif ( !$user->isAllowed( 'move-rootuserpages' ) |
| 1603 | + && $this->mNamespace == NS_USER && !$this->isSubpage() ) { |
1603 | 1604 | // Show user page-specific message only if the user can move other pages |
1604 | 1605 | $errors[] = array( 'cant-move-to-user-page' ); |
1605 | 1606 | } |
1606 | | - } elseif ( !$user->isAllowed( $action, $ns ) ) { |
| 1607 | + } elseif ( !$user->isAllowed( $action ) ) { |
1607 | 1608 | $errors[] = $this->missingPermissionError( $action, $short ); |
1608 | 1609 | } |
1609 | 1610 | |
— | — | @@ -1740,10 +1741,10 @@ |
1741 | 1742 | if ( $right == 'sysop' ) { |
1742 | 1743 | $right = 'protect'; |
1743 | 1744 | } |
1744 | | - if ( $right != '' && !$user->isAllowed( $right, $this->mNamespace ) ) { |
| 1745 | + if ( $right != '' && !$user->isAllowed( $right ) ) { |
1745 | 1746 | // Users with 'editprotected' permission can edit protected pages |
1746 | 1747 | // without cascading option turned on. |
1747 | | - if ( $action != 'edit' || !$user->isAllowed( 'editprotected', $this->mNamespace ) |
| 1748 | + if ( $action != 'edit' || !$user->isAllowed( 'editprotected' ) |
1748 | 1749 | || $this->mCascadeRestriction ) |
1749 | 1750 | { |
1750 | 1751 | $errors[] = array( 'protectedpagetext', $right ); |
— | — | @@ -1780,7 +1781,7 @@ |
1781 | 1782 | if ( isset( $restrictions[$action] ) ) { |
1782 | 1783 | foreach ( $restrictions[$action] as $right ) { |
1783 | 1784 | $right = ( $right == 'sysop' ) ? 'protect' : $right; |
1784 | | - if ( $right != '' && !$user->isAllowed( $right, $this->mNamespace ) ) { |
| 1785 | + if ( $right != '' && !$user->isAllowed( $right ) ) { |
1785 | 1786 | $pages = ''; |
1786 | 1787 | foreach ( $cascadingSources as $page ) |
1787 | 1788 | $pages .= '* [[:' . $page->getPrefixedText() . "]]\n"; |
— | — | @@ -1817,8 +1818,8 @@ |
1818 | 1819 | $title_protection['pt_create_perm'] = 'protect'; // B/C |
1819 | 1820 | } |
1820 | 1821 | if( $title_protection['pt_create_perm'] == '' || |
1821 | | - !$user->isAllowed( $title_protection['pt_create_perm'], |
1822 | | - $this->mNamespace ) ) { |
| 1822 | + !$user->isAllowed( $title_protection['pt_create_perm'] ) ) |
| 1823 | + { |
1823 | 1824 | $errors[] = array( 'titleprotected', User::whoIs( $title_protection['pt_user'] ), $title_protection['pt_reason'] ); |
1824 | 1825 | } |
1825 | 1826 | } |
— | — | @@ -1950,7 +1951,7 @@ |
1951 | 1952 | } |
1952 | 1953 | |
1953 | 1954 | # If the user is allowed to read pages, he is allowed to read all pages |
1954 | | - if ( $user->isAllowed( 'read', $this->mNamespace ) ) { |
| 1955 | + if ( $user->isAllowed( 'read' ) ) { |
1955 | 1956 | return $errors; |
1956 | 1957 | } |
1957 | 1958 | |
— | — | @@ -2017,7 +2018,7 @@ |
2018 | 2019 | } |
2019 | 2020 | |
2020 | 2021 | $groups = array_map( array( 'User', 'makeGroupLinkWiki' ), |
2021 | | - User::getGroupsWithPermission( $action, $this->mNamespace ) ); |
| 2022 | + User::getGroupsWithPermission( $action ) ); |
2022 | 2023 | |
2023 | 2024 | if ( count( $groups ) ) { |
2024 | 2025 | global $wgLang; |
Index: trunk/phase3/includes/DefaultSettings.php |
— | — | @@ -3379,9 +3379,8 @@ |
3380 | 3380 | |
3381 | 3381 | /** |
3382 | 3382 | * Permission keys given to users in each group. |
3383 | | - * This is an array where the keys are all groups and each value is either: |
3384 | | - * a) An array of the format (right => boolean) |
3385 | | - * b) An array of the format (right => namespace => boolean) |
| 3383 | + * This is an array where the keys are all groups and each value is an |
| 3384 | + * array of the format (right => boolean). |
3386 | 3385 | * |
3387 | 3386 | * The second format is used to support per-namespace permissions. |
3388 | 3387 | * Note that this feature does not fully work for all permission types. |