From: Andrew Garrett Date: Wed, 19 Dec 2007 02:05:48 +0000 (+0000) Subject: Userrights work. Changes: X-Git-Tag: 1.31.0-rc.0~50349 X-Git-Url: https://git.cyclocoop.org/%27.WWW_URL.%27admin/?a=commitdiff_plain;h=c3ef834c0400b18ecc75e9ff9a98ec2e240b34df;p=lhc%2Fweb%2Fwiklou.git Userrights work. Changes: * Behaviour of $wgAddGroups and $wgRemoveGroups changed. New behaviour: * * Granting the userrights privilege allows arbitrary changing of rights. * * Without the userrights privilege, a user will be able to add and/or remove the groups specified in $wgAddGroups and $wgRemoveGroups for any groups they are in. * Merge interwiki code from the MakeSysop extension into core. * New permission userrights-interwiki for changing user rights on foreign wikis. --- diff --git a/includes/SpecialPage.php b/includes/SpecialPage.php index 7cffa12fc7..9193e1ce58 100644 --- a/includes/SpecialPage.php +++ b/includes/SpecialPage.php @@ -135,7 +135,7 @@ class SpecialPage 'Import' => array( 'SpecialPage', 'Import', 'import' ), 'Lockdb' => array( 'SpecialPage', 'Lockdb', 'siteadmin' ), 'Unlockdb' => array( 'SpecialPage', 'Unlockdb', 'siteadmin' ), - 'Userrights' => array( 'SpecialPage', 'Userrights', 'userrights' ), + 'Userrights' => array( 'SpecialPage', 'Userrights' ), 'MIMEsearch' => array( 'SpecialPage', 'MIMEsearch' ), 'Unwatchedpages' => array( 'SpecialPage', 'Unwatchedpages', 'unwatchedpages' ), 'Listredirects' => array( 'SpecialPage', 'Listredirects' ), diff --git a/includes/SpecialUserrights.php b/includes/SpecialUserrights.php index a2a877bd69..2f1cf02033 100644 --- a/includes/SpecialUserrights.php +++ b/includes/SpecialUserrights.php @@ -31,6 +31,7 @@ class UserrightsForm extends HTMLForm { $this->mPosted = $request->wasPosted(); $this->mRequest =& $request; $this->mName = 'userrights'; + $this->mReason = $request->getText( 'user-reason' ); $titleObj = SpecialPage::getTitleFor( 'Userrights' ); $this->action = $titleObj->escapeLocalURL(); @@ -64,66 +65,204 @@ class UserrightsForm extends HTMLForm { } } - /** Back-end for saveUserGroups() - * @param User $u - * @param array $removegroup - * @param array $addgroup - * @param string $reason + + /** + * Save user groups changes in the database. + * Data comes from the editUserGroupsForm() form function + * + * @param string $username Username to apply changes to. + * @param array $removegroup id of groups to be removed. + * @param array $addgroup id of groups to be added. + * @param string $reason Reason for group change + * */ + function saveUserGroups( $username, $removegroup, $addgroup, $reason = '') { + $split = $this->splitUsername( $username ); + if( WikiError::isError( $split ) ) { + $wgOut->addWikiText( wfMsg( 'userrights-nodatabase', $split->getMessage() ) ); + return; + } - function doSaveUserGroups($u, $removegroup, $addgroup, $reason) - { - $oldGroups = $u->getGroups(); + list( $database, $name ) = $split; + $this->db =& $this->getDB( $database ); + $userid = $this->getUserId( $database, $name ); + + if( $userid == 0) { + $wgOut->addWikiText( wfMsg( 'nosuchusershort', wfEscapeWikiText( $username ) ) ); + return; + } + + global $wgUser; + if ($database != '' && !$wgUser->isAllowed('userrights-interwiki')) { + $wgOut->addWikiText( wfMsg( 'userrights-no-interwiki' ) ); + return; + } + + $oldGroups = $this->getUserGroups( $database, $userid ); $newGroups = $oldGroups; - // remove then add groups + // remove then add groups if(isset($removegroup)) { $newGroups = array_diff($newGroups, $removegroup); foreach( $removegroup as $group ) { - if ( $this->canRemove( $group ) ) { - $u->removeGroup( $group ); - } + $this->removeUserGroup( $database, $userid, $group ); } } if(isset($addgroup)) { $newGroups = array_merge($newGroups, $addgroup); foreach( $addgroup as $group ) { - if ( $this->canAdd( $group ) ) { - $u->addGroup( $group ); - } + $this->addUserGroup( $database, $userid, $group ); } } $newGroups = array_unique( $newGroups ); + // Ensure that caches are cleared + $this->touchUser( $database, $userid ); + wfDebug( 'oldGroups: ' . print_r( $oldGroups, true ) ); wfDebug( 'newGroups: ' . print_r( $newGroups, true ) ); + wfRunHooks( 'UserRights', array( &$u, $addgroup, $removegroup ) ); - wfRunHooks( 'UserRights', array( &$u, $addgroup, $removegroup ) ); $log = new LogPage( 'rights' ); - $log->addEntry( 'rights', Title::makeTitle( NS_USER, $u->getName() ), $reason, array( $this->makeGroupNameList( $oldGroups ), + $log->addEntry( 'rights', Title::makeTitle( NS_USER, $username ), $this->mReason, array( $this->makeGroupNameList( $oldGroups ), $this->makeGroupNameList( $newGroups ) ) ); } /** - * Save user groups changes in the database. - * Data comes from the editUserGroupsForm() form function - * - * @param string $username Username to apply changes to. - * @param array $removegroup id of groups to be removed. - * @param array $addgroup id of groups to be added. - * @param string $reason Reason for group change - * + * Edit user groups membership + * @param string $username Name of the user. */ - function saveUserGroups( $username, $removegroup, $addgroup, $reason = '' ) { - global $wgOut; - $u = User::newFromName($username); - if(is_null($u)) { - $wgOut->addWikiText( wfMsg( 'nosuchusershort', htmlspecialchars( $username ) ) ); + function editUserGroupsForm($username) { + global $wgOut, $wgUser; + + $split = $this->splitUsername( $username ); + if( WikiError::isError( $split ) ) { + $wgOut->addWikiText( wfMsg( 'userrights-nodatabase', $split->getMessage() ) ); + return; + } + + list( $database, $name ) = $split; + $this->db =& $this->getDB( $database ); + $userid = $this->getUserId( $database, $name ); + + if( $name == '' ) { + $wgOut->addWikiText( wfMsg( 'nouserspecified' ) ); + return; + } elseif( $userid == 0) { + $wgOut->addWikiText( wfMsg( 'nosuchusershort', wfEscapeWikiText( $username ) ) ); + return; } - if($u->getID() == 0) { - $wgOut->addWikiText( wfMsg( 'nosuchusershort', htmlspecialchars( $username ) ) ); + + global $wgUser; + if ($database != '' && !$wgUser->isAllowed('userrights-interwiki')) { + $wgOut->addWikiText( wfMsg( 'userrights-no-interwiki' ) ); + return; } - $this->doSaveUserGroups($u, $removegroup, $addgroup, $reason); + $groups = $this->getUserGroups( $database, $userid ); + + $this->showEditUserGroupsForm( $username, $groups ); + + if ($database == '') { + $this->showLogFragment( User::newFromName($username), $wgOut ); + } + } + + function splitUsername( $username ) { + $parts = explode( '@', $username ); + if( count( $parts ) < 2 ) { + return array( '', $username ); + } + list( $name, $database ) = $parts; + + global $wgLocalDatabases; + return array_search( $database, $wgLocalDatabases ) !== false + ? array( $database, $name ) + : new WikiError( 'Bogus database suffix "' . wfEscapeWikiText( $database ) . '"' ); + } + + /** + * Open a database connection to work on for the requested user. + * This may be a new connection to another database for remote users. + * @param string $database + * @return Database + */ + function &getDB( $database ) { + if( $database == '' ) { + $db =& wfGetDB( DB_MASTER ); + } else { + global $wgDBuser, $wgDBpassword; + $server = $this->getMaster( $database ); + $db = new Database( $server, $wgDBuser, $wgDBpassword, $database ); + } + return $db; + } + + /** + * Return the master server to connect to for the requested database. + */ + function getMaster( $database ) { + global $wgDBserver, $wgAlternateMaster; + if( isset( $wgAlternateMaster[$database] ) ) { + return $wgAlternateMaster[$database]; + } + return $wgDBserver; + } + + function getUserId( $database, $name ) { + if( $name === '' ) + return 0; + return ( $name{0} == "#" ) + ? IntVal( substr( $name, 1 ) ) + : IntVal( $this->db->selectField( 'user', + 'user_id', + array( 'user_name' => $name ), + 'MakesysopStewardForm::getUserId' ) ); + } + + function getUserGroups( $database, $userid ) { + $res = $this->db->select( 'user_groups', + array( 'ug_group' ), + array( 'ug_user' => $userid ), + 'MakesysopStewardForm::getUserGroups' ); + $groups = array(); + while( $row = $this->db->fetchObject( $res ) ) { + $groups[] = $row->ug_group; + } + return $groups; + } + + function addUserGroup( $database, $userid, $group ) { + $this->db->insert( 'user_groups', + array( + 'ug_user' => $userid, + 'ug_group' => $group, + ), + 'MakesysopStewardForm::addUserGroup', + array( 'IGNORE' ) ); + } + + function removeUserGroup( $database, $userid, $group ) { + $this->db->delete( 'user_groups', + array( + 'ug_user' => $userid, + 'ug_group' => $group, + ), + 'MakesysopStewardForm::addUserGroup' ); + } + + function touchUser( $database, $userid ) { + $this->db->update( 'user', + array( 'user_touched' => $this->db->timestamp() ), + array( 'user_id' => $userid ), + 'MakesysopStewardForm::touchUser' ); + + global $wgMemc; + if ( function_exists( 'wfForeignMemcKey' ) ) { + $key = wfForeignMemcKey( $database, false, 'user', 'id', $userid ); + } else { + $key = "$database:user:id:$userid"; + } + $wgMemc->delete( $key ); } function makeGroupNameList( $ids ) { @@ -144,26 +283,6 @@ class UserrightsForm extends HTMLForm { $form .= ''; $wgOut->addHTML( $form ); } - - /** - * Edit user groups membership - * @param string $username Name of the user. - */ - function editUserGroupsForm($username) { - global $wgOut; - - $user = User::newFromName($username); - if( is_null( $user ) ) { - $wgOut->addWikiText( wfMsg( 'nouserspecified' ) ); - return; - } elseif( $user->getID() == 0 ) { - $wgOut->addWikiText( wfMsg( 'nosuchusershort', wfEscapeWikiText( $username ) ) ); - return; - } - - $this->showEditUserGroupsForm( $username, $user->getGroups() ); - $this->showLogFragment( $user, $wgOut ); - } /** * Go through used and available groups and return the ones that this @@ -351,11 +470,7 @@ class UserrightsForm extends HTMLForm { private function changeableByGroup( $group ) { global $wgGroupPermissions, $wgAddGroups, $wgRemoveGroups; - if( empty($wgGroupPermissions[$group]['userrights']) ) { - // This group doesn't give the right to modify anything - return array( 'add' => array(), 'remove' => array() ); - } - if( empty($wgAddGroups[$group]) and empty($wgRemoveGroups[$group]) ) { + if( $wgGroupPermissions[$group]['userrights'] == true ) { // This group gives the right to modify everything (reverse- // compatibility with old "userrights lets you change // everything") @@ -407,4 +522,4 @@ class UserrightsForm extends HTMLForm { $viewer->showList( $output ); } -} +} \ No newline at end of file diff --git a/languages/messages/MessagesEn.php b/languages/messages/MessagesEn.php index ca587f6ec0..13f8e0a399 100644 --- a/languages/messages/MessagesEn.php +++ b/languages/messages/MessagesEn.php @@ -1338,6 +1338,7 @@ Unselected groups will not be changed. You can deselect a group with CTRL + Left 'userrights-available-none' => 'You may not alter group membership.', 'userrights-available-add' => 'You can add users to $1.', 'userrights-available-remove' => 'You can remove users from $1.', +'userrights-no-interwiki' => 'You do not have permission to edit user rights on other wikis.', # Groups 'group' => 'Group:',