| Index: trunk/phase3/includes/SpecialUserrights.php |
| — | — | @@ -31,6 +31,7 @@ |
| 32 | 32 | $this->mPosted = $request->wasPosted(); |
| 33 | 33 | $this->mRequest =& $request; |
| 34 | 34 | $this->mName = 'userrights'; |
| | 35 | + $this->mReason = $request->getText( 'user-reason' ); |
| 35 | 36 | |
| 36 | 37 | $titleObj = SpecialPage::getTitleFor( 'Userrights' ); |
| 37 | 38 | $this->action = $titleObj->escapeLocalURL(); |
| — | — | @@ -64,68 +65,206 @@ |
| 65 | 66 | } |
| 66 | 67 | } |
| 67 | 68 | |
| 68 | | - /** Back-end for saveUserGroups() |
| 69 | | - * @param User $u |
| 70 | | - * @param array $removegroup |
| 71 | | - * @param array $addgroup |
| 72 | | - * @param string $reason |
| | 69 | + |
| | 70 | + /** |
| | 71 | + * Save user groups changes in the database. |
| | 72 | + * Data comes from the editUserGroupsForm() form function |
| | 73 | + * |
| | 74 | + * @param string $username Username to apply changes to. |
| | 75 | + * @param array $removegroup id of groups to be removed. |
| | 76 | + * @param array $addgroup id of groups to be added. |
| | 77 | + * @param string $reason Reason for group change |
| | 78 | + * |
| 73 | 79 | */ |
| | 80 | + function saveUserGroups( $username, $removegroup, $addgroup, $reason = '') { |
| | 81 | + $split = $this->splitUsername( $username ); |
| | 82 | + if( WikiError::isError( $split ) ) { |
| | 83 | + $wgOut->addWikiText( wfMsg( 'userrights-nodatabase', $split->getMessage() ) ); |
| | 84 | + return; |
| | 85 | + } |
| 74 | 86 | |
| 75 | | - function doSaveUserGroups($u, $removegroup, $addgroup, $reason) |
| 76 | | - { |
| 77 | | - $oldGroups = $u->getGroups(); |
| | 87 | + list( $database, $name ) = $split; |
| | 88 | + $this->db =& $this->getDB( $database ); |
| | 89 | + $userid = $this->getUserId( $database, $name ); |
| | 90 | + |
| | 91 | + if( $userid == 0) { |
| | 92 | + $wgOut->addWikiText( wfMsg( 'nosuchusershort', wfEscapeWikiText( $username ) ) ); |
| | 93 | + return; |
| | 94 | + } |
| | 95 | + |
| | 96 | + global $wgUser; |
| | 97 | + if ($database != '' && !$wgUser->isAllowed('userrights-interwiki')) { |
| | 98 | + $wgOut->addWikiText( wfMsg( 'userrights-no-interwiki' ) ); |
| | 99 | + return; |
| | 100 | + } |
| | 101 | + |
| | 102 | + $oldGroups = $this->getUserGroups( $database, $userid ); |
| 78 | 103 | $newGroups = $oldGroups; |
| 79 | | - // remove then add groups |
| | 104 | + // remove then add groups |
| 80 | 105 | if(isset($removegroup)) { |
| 81 | 106 | $newGroups = array_diff($newGroups, $removegroup); |
| 82 | 107 | foreach( $removegroup as $group ) { |
| 83 | | - if ( $this->canRemove( $group ) ) { |
| 84 | | - $u->removeGroup( $group ); |
| 85 | | - } |
| | 108 | + $this->removeUserGroup( $database, $userid, $group ); |
| 86 | 109 | } |
| 87 | 110 | } |
| 88 | 111 | if(isset($addgroup)) { |
| 89 | 112 | $newGroups = array_merge($newGroups, $addgroup); |
| 90 | 113 | foreach( $addgroup as $group ) { |
| 91 | | - if ( $this->canAdd( $group ) ) { |
| 92 | | - $u->addGroup( $group ); |
| 93 | | - } |
| | 114 | + $this->addUserGroup( $database, $userid, $group ); |
| 94 | 115 | } |
| 95 | 116 | } |
| 96 | 117 | $newGroups = array_unique( $newGroups ); |
| 97 | 118 | |
| | 119 | + // Ensure that caches are cleared |
| | 120 | + $this->touchUser( $database, $userid ); |
| | 121 | + |
| 98 | 122 | wfDebug( 'oldGroups: ' . print_r( $oldGroups, true ) ); |
| 99 | 123 | wfDebug( 'newGroups: ' . print_r( $newGroups, true ) ); |
| | 124 | + wfRunHooks( 'UserRights', array( &$u, $addgroup, $removegroup ) ); |
| 100 | 125 | |
| 101 | | - wfRunHooks( 'UserRights', array( &$u, $addgroup, $removegroup ) ); |
| 102 | 126 | $log = new LogPage( 'rights' ); |
| 103 | | - $log->addEntry( 'rights', Title::makeTitle( NS_USER, $u->getName() ), $reason, array( $this->makeGroupNameList( $oldGroups ), |
| | 127 | + $log->addEntry( 'rights', Title::makeTitle( NS_USER, $username ), $this->mReason, array( $this->makeGroupNameList( $oldGroups ), |
| 104 | 128 | $this->makeGroupNameList( $newGroups ) ) ); |
| 105 | 129 | } |
| 106 | 130 | |
| 107 | 131 | /** |
| 108 | | - * Save user groups changes in the database. |
| 109 | | - * Data comes from the editUserGroupsForm() form function |
| 110 | | - * |
| 111 | | - * @param string $username Username to apply changes to. |
| 112 | | - * @param array $removegroup id of groups to be removed. |
| 113 | | - * @param array $addgroup id of groups to be added. |
| 114 | | - * @param string $reason Reason for group change |
| 115 | | - * |
| | 132 | + * Edit user groups membership |
| | 133 | + * @param string $username Name of the user. |
| 116 | 134 | */ |
| 117 | | - function saveUserGroups( $username, $removegroup, $addgroup, $reason = '' ) { |
| 118 | | - global $wgOut; |
| 119 | | - $u = User::newFromName($username); |
| 120 | | - if(is_null($u)) { |
| 121 | | - $wgOut->addWikiText( wfMsg( 'nosuchusershort', htmlspecialchars( $username ) ) ); |
| | 135 | + function editUserGroupsForm($username) { |
| | 136 | + global $wgOut, $wgUser; |
| | 137 | + |
| | 138 | + $split = $this->splitUsername( $username ); |
| | 139 | + if( WikiError::isError( $split ) ) { |
| | 140 | + $wgOut->addWikiText( wfMsg( 'userrights-nodatabase', $split->getMessage() ) ); |
| | 141 | + return; |
| 122 | 142 | } |
| 123 | | - if($u->getID() == 0) { |
| 124 | | - $wgOut->addWikiText( wfMsg( 'nosuchusershort', htmlspecialchars( $username ) ) ); |
| | 143 | + |
| | 144 | + list( $database, $name ) = $split; |
| | 145 | + $this->db =& $this->getDB( $database ); |
| | 146 | + $userid = $this->getUserId( $database, $name ); |
| | 147 | + |
| | 148 | + if( $name == '' ) { |
| | 149 | + $wgOut->addWikiText( wfMsg( 'nouserspecified' ) ); |
| | 150 | + return; |
| | 151 | + } elseif( $userid == 0) { |
| | 152 | + $wgOut->addWikiText( wfMsg( 'nosuchusershort', wfEscapeWikiText( $username ) ) ); |
| | 153 | + return; |
| 125 | 154 | } |
| 126 | 155 | |
| 127 | | - $this->doSaveUserGroups($u, $removegroup, $addgroup, $reason); |
| | 156 | + global $wgUser; |
| | 157 | + if ($database != '' && !$wgUser->isAllowed('userrights-interwiki')) { |
| | 158 | + $wgOut->addWikiText( wfMsg( 'userrights-no-interwiki' ) ); |
| | 159 | + return; |
| | 160 | + } |
| | 161 | + |
| | 162 | + $groups = $this->getUserGroups( $database, $userid ); |
| | 163 | + |
| | 164 | + $this->showEditUserGroupsForm( $username, $groups ); |
| | 165 | + |
| | 166 | + if ($database == '') { |
| | 167 | + $this->showLogFragment( User::newFromName($username), $wgOut ); |
| | 168 | + } |
| 128 | 169 | } |
| 129 | 170 | |
| | 171 | + function splitUsername( $username ) { |
| | 172 | + $parts = explode( '@', $username ); |
| | 173 | + if( count( $parts ) < 2 ) { |
| | 174 | + return array( '', $username ); |
| | 175 | + } |
| | 176 | + list( $name, $database ) = $parts; |
| | 177 | + |
| | 178 | + global $wgLocalDatabases; |
| | 179 | + return array_search( $database, $wgLocalDatabases ) !== false |
| | 180 | + ? array( $database, $name ) |
| | 181 | + : new WikiError( 'Bogus database suffix "' . wfEscapeWikiText( $database ) . '"' ); |
| | 182 | + } |
| | 183 | + |
| | 184 | + /** |
| | 185 | + * Open a database connection to work on for the requested user. |
| | 186 | + * This may be a new connection to another database for remote users. |
| | 187 | + * @param string $database |
| | 188 | + * @return Database |
| | 189 | + */ |
| | 190 | + function &getDB( $database ) { |
| | 191 | + if( $database == '' ) { |
| | 192 | + $db =& wfGetDB( DB_MASTER ); |
| | 193 | + } else { |
| | 194 | + global $wgDBuser, $wgDBpassword; |
| | 195 | + $server = $this->getMaster( $database ); |
| | 196 | + $db = new Database( $server, $wgDBuser, $wgDBpassword, $database ); |
| | 197 | + } |
| | 198 | + return $db; |
| | 199 | + } |
| | 200 | + |
| | 201 | + /** |
| | 202 | + * Return the master server to connect to for the requested database. |
| | 203 | + */ |
| | 204 | + function getMaster( $database ) { |
| | 205 | + global $wgDBserver, $wgAlternateMaster; |
| | 206 | + if( isset( $wgAlternateMaster[$database] ) ) { |
| | 207 | + return $wgAlternateMaster[$database]; |
| | 208 | + } |
| | 209 | + return $wgDBserver; |
| | 210 | + } |
| | 211 | + |
| | 212 | + function getUserId( $database, $name ) { |
| | 213 | + if( $name === '' ) |
| | 214 | + return 0; |
| | 215 | + return ( $name{0} == "#" ) |
| | 216 | + ? IntVal( substr( $name, 1 ) ) |
| | 217 | + : IntVal( $this->db->selectField( 'user', |
| | 218 | + 'user_id', |
| | 219 | + array( 'user_name' => $name ), |
| | 220 | + 'MakesysopStewardForm::getUserId' ) ); |
| | 221 | + } |
| | 222 | + |
| | 223 | + function getUserGroups( $database, $userid ) { |
| | 224 | + $res = $this->db->select( 'user_groups', |
| | 225 | + array( 'ug_group' ), |
| | 226 | + array( 'ug_user' => $userid ), |
| | 227 | + 'MakesysopStewardForm::getUserGroups' ); |
| | 228 | + $groups = array(); |
| | 229 | + while( $row = $this->db->fetchObject( $res ) ) { |
| | 230 | + $groups[] = $row->ug_group; |
| | 231 | + } |
| | 232 | + return $groups; |
| | 233 | + } |
| | 234 | + |
| | 235 | + function addUserGroup( $database, $userid, $group ) { |
| | 236 | + $this->db->insert( 'user_groups', |
| | 237 | + array( |
| | 238 | + 'ug_user' => $userid, |
| | 239 | + 'ug_group' => $group, |
| | 240 | + ), |
| | 241 | + 'MakesysopStewardForm::addUserGroup', |
| | 242 | + array( 'IGNORE' ) ); |
| | 243 | + } |
| | 244 | + |
| | 245 | + function removeUserGroup( $database, $userid, $group ) { |
| | 246 | + $this->db->delete( 'user_groups', |
| | 247 | + array( |
| | 248 | + 'ug_user' => $userid, |
| | 249 | + 'ug_group' => $group, |
| | 250 | + ), |
| | 251 | + 'MakesysopStewardForm::addUserGroup' ); |
| | 252 | + } |
| | 253 | + |
| | 254 | + function touchUser( $database, $userid ) { |
| | 255 | + $this->db->update( 'user', |
| | 256 | + array( 'user_touched' => $this->db->timestamp() ), |
| | 257 | + array( 'user_id' => $userid ), |
| | 258 | + 'MakesysopStewardForm::touchUser' ); |
| | 259 | + |
| | 260 | + global $wgMemc; |
| | 261 | + if ( function_exists( 'wfForeignMemcKey' ) ) { |
| | 262 | + $key = wfForeignMemcKey( $database, false, 'user', 'id', $userid ); |
| | 263 | + } else { |
| | 264 | + $key = "$database:user:id:$userid"; |
| | 265 | + } |
| | 266 | + $wgMemc->delete( $key ); |
| | 267 | + } |
| | 268 | + |
| 130 | 269 | function makeGroupNameList( $ids ) { |
| 131 | 270 | return implode( ', ', $ids ); |
| 132 | 271 | } |
| — | — | @@ -144,27 +283,7 @@ |
| 145 | 284 | $form .= '</form>'; |
| 146 | 285 | $wgOut->addHTML( $form ); |
| 147 | 286 | } |
| 148 | | - |
| 149 | | - /** |
| 150 | | - * Edit user groups membership |
| 151 | | - * @param string $username Name of the user. |
| 152 | | - */ |
| 153 | | - function editUserGroupsForm($username) { |
| 154 | | - global $wgOut; |
| 155 | 287 | |
| 156 | | - $user = User::newFromName($username); |
| 157 | | - if( is_null( $user ) ) { |
| 158 | | - $wgOut->addWikiText( wfMsg( 'nouserspecified' ) ); |
| 159 | | - return; |
| 160 | | - } elseif( $user->getID() == 0 ) { |
| 161 | | - $wgOut->addWikiText( wfMsg( 'nosuchusershort', wfEscapeWikiText( $username ) ) ); |
| 162 | | - return; |
| 163 | | - } |
| 164 | | - |
| 165 | | - $this->showEditUserGroupsForm( $username, $user->getGroups() ); |
| 166 | | - $this->showLogFragment( $user, $wgOut ); |
| 167 | | - } |
| 168 | | - |
| 169 | 288 | /** |
| 170 | 289 | * Go through used and available groups and return the ones that this |
| 171 | 290 | * form will be able to manipulate based on the current user's system |
| — | — | @@ -351,11 +470,7 @@ |
| 352 | 471 | private function changeableByGroup( $group ) { |
| 353 | 472 | global $wgGroupPermissions, $wgAddGroups, $wgRemoveGroups; |
| 354 | 473 | |
| 355 | | - if( empty($wgGroupPermissions[$group]['userrights']) ) { |
| 356 | | - // This group doesn't give the right to modify anything |
| 357 | | - return array( 'add' => array(), 'remove' => array() ); |
| 358 | | - } |
| 359 | | - if( empty($wgAddGroups[$group]) and empty($wgRemoveGroups[$group]) ) { |
| | 474 | + if( $wgGroupPermissions[$group]['userrights'] == true ) { |
| 360 | 475 | // This group gives the right to modify everything (reverse- |
| 361 | 476 | // compatibility with old "userrights lets you change |
| 362 | 477 | // everything") |
| — | — | @@ -407,4 +522,4 @@ |
| 408 | 523 | $viewer->showList( $output ); |
| 409 | 524 | } |
| 410 | 525 | |
| 411 | | -} |
| | 526 | +} |
| \ No newline at end of file |
| Index: trunk/phase3/includes/SpecialPage.php |
| — | — | @@ -135,7 +135,7 @@ |
| 136 | 136 | 'Import' => array( 'SpecialPage', 'Import', 'import' ), |
| 137 | 137 | 'Lockdb' => array( 'SpecialPage', 'Lockdb', 'siteadmin' ), |
| 138 | 138 | 'Unlockdb' => array( 'SpecialPage', 'Unlockdb', 'siteadmin' ), |
| 139 | | - 'Userrights' => array( 'SpecialPage', 'Userrights', 'userrights' ), |
| | 139 | + 'Userrights' => array( 'SpecialPage', 'Userrights' ), |
| 140 | 140 | 'MIMEsearch' => array( 'SpecialPage', 'MIMEsearch' ), |
| 141 | 141 | 'Unwatchedpages' => array( 'SpecialPage', 'Unwatchedpages', 'unwatchedpages' ), |
| 142 | 142 | 'Listredirects' => array( 'SpecialPage', 'Listredirects' ), |
| Index: trunk/phase3/languages/messages/MessagesEn.php |
| — | — | @@ -1338,6 +1338,7 @@ |
| 1339 | 1339 | 'userrights-available-none' => 'You may not alter group membership.', |
| 1340 | 1340 | 'userrights-available-add' => 'You can add users to $1.', |
| 1341 | 1341 | 'userrights-available-remove' => 'You can remove users from $1.', |
| | 1342 | +'userrights-no-interwiki' => 'You do not have permission to edit user rights on other wikis.', |
| 1342 | 1343 | |
| 1343 | 1344 | # Groups |
| 1344 | 1345 | 'group' => 'Group:', |