From e12889412117110bd4f6a2e9a8cfac408e982d3a Mon Sep 17 00:00:00 2001 From: Ryan Schmidt Date: Thu, 14 Aug 2008 21:55:17 +0000 Subject: [PATCH] * $wgGroupsAddToSelf and $wgGroupsRemoveFromSelf now work more like $wgAddGroups and $wgRemoveGroups, where the user must belong to a specified group in order to add or remove those groups from themselves. Backwards compatibility is maintained. * Added hook 'UserrightsChangeableGroups' to allow modification of what groups may be added or removed via the Special:UserRights interface. --- RELEASE-NOTES | 10 +++- docs/hooks.txt | 12 +++++ includes/specials/SpecialUserrights.php | 70 ++++++++++++++++++------- 3 files changed, 72 insertions(+), 20 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index f5f53fbe96..f6441a0a3a 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -31,7 +31,11 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN * $wgSQLiteDataDirMode has been introduced as the default directory mode for SQLite data directories on creation. Note this setting is separate from $wgDirectoryMode, which applies to all normal directories created by MediaWiki. - +* $wgGroupsAddToSelf and $wgGroupsRemoveFromSelf now work more like + $wgAddGroups and $wgRemoveGroups, where the user must belong to a specified + group in order to add or remove those groups from themselves. + Backwards compatibility is maintained. + === New features in 1.14 === * New URL syntaxes for Special:ListUsers - 'Special:ListUsers/USER' and @@ -80,7 +84,9 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN option enabled on Special:ProtectedPages * (bug 15157) Special:Watchlist has the same options as Special:Watchlist: Show/Hide logged in users, Show/Hide anonymous, Invert namespace selection - +* Added hook 'UserrightsChangeableGroups' to allow modification of what + groups may be added or removed via the Special:UserRights interface. + === Bug fixes in 1.14 === * (bug 14907) DatabasePostgres::fieldType now defined. diff --git a/docs/hooks.txt b/docs/hooks.txt index caec45824d..31eb43b66c 100644 --- a/docs/hooks.txt +++ b/docs/hooks.txt @@ -1343,6 +1343,18 @@ $user : User object that was changed $add : Array of strings corresponding to groups added $remove: Array of strings corresponding to groups removed +'UserrightsChangeableGroups': allows modification of the groups a user may add or remove via Special:UserRights +$userrights : UserrightsPage object +$user : User object of the current user +$addergroups : Array of groups that the user is in +&$groups : Array of groups that can be added or removed. In format of + array( + 'add' => array( addablegroups ), + 'remove' => array( removablegroups ), + 'add-self' => array( addablegroups to self ), + 'remove-self' => array( removable groups from self ) + ) + 'UserRetrieveNewTalks': called when retrieving "You have new messages!" message(s) $user: user retrieving new talks messages $talks: array of new talks page(s) diff --git a/includes/specials/SpecialUserrights.php b/includes/specials/SpecialUserrights.php index 9837cc73d4..d91386788e 100644 --- a/includes/specials/SpecialUserrights.php +++ b/includes/specials/SpecialUserrights.php @@ -141,13 +141,8 @@ class UserrightsPage extends SpecialPage { // Validate input set... $changeable = $this->changeableGroups(); - if ($wgUser->getId() != 0 && $wgUser->getId() == $user->getId()) { - $addable = array_merge($changeable['add'], $wgGroupsAddToSelf); - $removable = array_merge($changeable['remove'], $wgGroupsRemoveFromSelf); - } else { - $addable = $changeable['add']; - $removable = $changeable['remove']; - } + $addable = array_merge( $changeable['add'], $this->isself ? $changeable['add-self'] : array() ); + $removable = array_merge( $changeable['remove'], $this->isself ? $changeable['remove-self'] : array() ); $removegroup = array_unique( array_intersect( (array)$removegroup, $removable ) ); @@ -329,14 +324,13 @@ class UserrightsPage extends SpecialPage { * @return Array: Tuple of addable, then removable groups */ protected function splitGroups( $groups ) { - global $wgGroupsAddToSelf, $wgGroupsRemoveFromSelf; - list($addable, $removable) = array_values( $this->changeableGroups() ); + list($addable, $removable, $addself, $removeself) = array_values( $this->changeableGroups() ); $removable = array_intersect( - array_merge($this->isself ? $wgGroupsRemoveFromSelf : array(), $removable), + array_merge( $this->isself ? $removeself : array(), $removable ), $groups ); // Can't remove groups the user doesn't have $addable = array_diff( - array_merge($this->isself ? $wgGroupsAddToSelf : array(), $addable), + array_merge( $this->isself ? $addself : array(), $addable ), $groups ); // Can't add groups the user does have return array( $addable, $removable ); @@ -510,10 +504,10 @@ class UserrightsPage extends SpecialPage { /** * Returns an array of the groups that the user can add/remove. * - * @return Array array( 'add' => array( addablegroups ), 'remove' => array( removablegroups ) ) + * @return Array array( 'add' => array( addablegroups ), 'remove' => array( removablegroups ) , 'add-self' => array( addablegroups to self), 'remove-self' => array( removable groups from self) ) */ function changeableGroups() { - global $wgUser, $wgGroupsAddToSelf, $wgGroupsRemoveFromSelf; + global $wgUser; if( $wgUser->isAllowed( 'userrights' ) ) { // This group gives the right to modify everything (reverse- @@ -533,8 +527,8 @@ class UserrightsPage extends SpecialPage { $groups = array( 'add' => array(), 'remove' => array(), - 'add-self' => $wgGroupsAddToSelf, - 'remove-self' => $wgGroupsRemoveFromSelf); + 'add-self' => array(), + 'remove-self' => array() ); $addergroups = $wgUser->getEffectiveGroups(); foreach ($addergroups as $addergroup) { @@ -543,7 +537,13 @@ class UserrightsPage extends SpecialPage { ); $groups['add'] = array_unique( $groups['add'] ); $groups['remove'] = array_unique( $groups['remove'] ); + $groups['add-self'] = array_unique( $groups['add-self'] ); + $groups['remove-self'] = array_unique( $groups['remove-self'] ); } + + // Run a hook because we can + wfRunHooks( 'UserrightsChangeableGroups', array( $this, $wgUser, $addergroups, &$groups ) ); + return $groups; } @@ -551,12 +551,12 @@ class UserrightsPage extends SpecialPage { * Returns an array of the groups that a particular group can add/remove. * * @param $group String: the group to check for whether it can add/remove - * @return Array array( 'add' => array( addablegroups ), 'remove' => array( removablegroups ) ) + * @return Array array( 'add' => array( addablegroups ), 'remove' => array( removablegroups ) , 'add-self' => array( addablegroups to self), 'remove-self' => array( removable groups from self) ) */ private function changeableByGroup( $group ) { - global $wgAddGroups, $wgRemoveGroups; + global $wgAddGroups, $wgRemoveGroups, $wgGroupsAddToSelf, $wgGroupsRemoveFromSelf; - $groups = array( 'add' => array(), 'remove' => array() ); + $groups = array( 'add' => array(), 'remove' => array(), 'add-self' => array(), 'remove-self' => array() ); if( empty($wgAddGroups[$group]) ) { // Don't add anything to $groups } elseif( $wgAddGroups[$group] === true ) { @@ -573,6 +573,40 @@ class UserrightsPage extends SpecialPage { } elseif( is_array($wgRemoveGroups[$group]) ) { $groups['remove'] = $wgRemoveGroups[$group]; } + + // Re-map numeric keys of AddToSelf/RemoveFromSelf to the 'user' key for backwards compatibility + if( empty($wgGroupsAddToSelf['user']) || $wgGroupsAddToSelf['user'] !== true ) { + foreach($wgGroupsAddToSelf as $key => $value) { + if( is_int($key) ) { + $wgGroupsAddToSelf['user'][] = $value; + } + } + } + + if( empty($wgGroupsRemoveFromSelf['user']) || $wgGroupsRemoveFromSelf['user'] !== true ) { + foreach($wgGroupsRemoveFromSelf as $key => $value) { + if( is_int($key) ) { + $wgGroupsRemoveFromSelf['user'][] = $value; + } + } + } + + // Now figure out what groups the user can add to him/herself + if( empty($wgGroupsAddToSelf[$group]) ) { + } elseif( $wgGroupsAddToSelf[$group] === true ) { + // No idea WHY this would be used, but it's there + $groups['add-self'] = User::getAllGroups(); + } elseif( is_array($wgGroupsAddToSelf[$group]) ) { + $groups['add-self'] = $wgGroupsAddToSelf[$group]; + } + + if( empty($wgGroupsRemoveFromSelf[$group]) ) { + } elseif( $wgGroupsRemoveFromSelf[$group] === true ) { + $groups['remove-self'] = User::getAllGroups(); + } elseif( is_array($wgGroupsRemoveFromSelf[$group]) ) { + $groups['remove-self'] = $wgGroupsRemoveFromSelf[$group]; + } + return $groups; } -- 2.20.1