Index: trunk/phase3/includes/User.php |
— | — | @@ -164,6 +164,7 @@ |
165 | 165 | 'upload', |
166 | 166 | 'upload_by_url', |
167 | 167 | 'userrights', |
| 168 | + 'userrights-interwiki', |
168 | 169 | ); |
169 | 170 | /** |
170 | 171 | * \type{\string} Cached results of getAllRights() |
Index: trunk/phase3/includes/specials/SpecialUserrights.php |
— | — | @@ -57,7 +57,8 @@ |
58 | 58 | * edit their own groups, automatically set them as the |
59 | 59 | * target. |
60 | 60 | */ |
61 | | - $available = $this->changeableGroups(); |
| 61 | + global $wgUser; |
| 62 | + $available = $this->changeableGroups($wgUser); |
62 | 63 | if (empty($available['add']) && empty($available['remove'])) |
63 | 64 | $this->mTarget = $wgUser->getName(); |
64 | 65 | } |
— | — | @@ -123,7 +124,7 @@ |
124 | 125 | return; |
125 | 126 | } |
126 | 127 | |
127 | | - $allgroups = $this->getAllGroups(); |
| 128 | + $allgroups = $this->getAllGroups($user); |
128 | 129 | $addgroup = array(); |
129 | 130 | $removegroup = array(); |
130 | 131 | |
— | — | @@ -140,7 +141,7 @@ |
141 | 142 | } |
142 | 143 | |
143 | 144 | // Validate input set... |
144 | | - $changeable = $this->changeableGroups(); |
| 145 | + $changeable = $this->changeableGroups($user); |
145 | 146 | $addable = array_merge( $changeable['add'], $this->isself ? $changeable['add-self'] : array() ); |
146 | 147 | $removable = array_merge( $changeable['remove'], $this->isself ? $changeable['remove-self'] : array() ); |
147 | 148 | |
— | — | @@ -321,10 +322,12 @@ |
322 | 323 | * permissions. |
323 | 324 | * |
324 | 325 | * @param $groups Array: list of groups the given user is in |
| 326 | + * @param $user User object to edit. |
325 | 327 | * @return Array: Tuple of addable, then removable groups |
326 | 328 | */ |
327 | | - protected function splitGroups( $groups ) { |
328 | | - list($addable, $removable, $addself, $removeself) = array_values( $this->changeableGroups() ); |
| 329 | + protected function splitGroups( $groups, $user = null ) { |
| 330 | + global $wgGroupsAddToSelf, $wgGroupsRemoveFromSelf; |
| 331 | + list($addable, $removable, $addself, $removeself) = array_values( $this->changeableGroups( $user ) ); |
329 | 332 | |
330 | 333 | $removable = array_intersect( |
331 | 334 | array_merge( $this->isself ? $removeself : array(), $removable ), |
— | — | @@ -345,7 +348,7 @@ |
346 | 349 | protected function showEditUserGroupsForm( $user, $groups ) { |
347 | 350 | global $wgOut, $wgUser, $wgLang; |
348 | 351 | |
349 | | - list( $addable, $removable ) = $this->splitGroups( $groups ); |
| 352 | + list( $addable, $removable ) = $this->splitGroups( $groups, $user ); |
350 | 353 | |
351 | 354 | $list = array(); |
352 | 355 | foreach( $user->getGroups() as $group ) |
— | — | @@ -365,7 +368,7 @@ |
366 | 369 | wfMsgExt( 'editinguser', array( 'parse' ), wfEscapeWikiText( $user->getName() ) ) . |
367 | 370 | wfMsgExt( 'userrights-groups-help', array( 'parse' ) ) . |
368 | 371 | $grouplist . |
369 | | - Xml::tags( 'p', null, $this->groupCheckboxes( $groups ) ) . |
| 372 | + Xml::tags( 'p', null, $this->groupCheckboxes( $groups, $user ) ) . |
370 | 373 | Xml::openElement( 'table', array( 'border' => '0', 'id' => 'mw-userrights-table-outer' ) ) . |
371 | 374 | "<tr> |
372 | 375 | <td class='mw-label'>" . |
— | — | @@ -402,20 +405,62 @@ |
403 | 406 | |
404 | 407 | /** |
405 | 408 | * Returns an array of all groups that may be edited |
| 409 | + * @param $user User object of the user whose groups are being edited. Optional. |
406 | 410 | * @return array Array of groups that may be edited. |
407 | 411 | */ |
408 | | - protected static function getAllGroups() { |
| 412 | + protected static function getAllGroups($user=null) { |
| 413 | + if ($user instanceof UserRightsProxy) { |
| 414 | + // Remote user object. |
| 415 | + return self::getRemoteGroups( $user->database ); |
| 416 | + } |
| 417 | + |
| 418 | + // Regular user object |
409 | 419 | return User::getAllGroups(); |
410 | 420 | } |
| 421 | + |
| 422 | + /** |
| 423 | + * Returns all groups which can be set on a remote wiki. |
| 424 | + * @param $db String - database name of the foreign wiki. |
| 425 | + * @return array Array of groups that may be edited. |
| 426 | + */ |
| 427 | + static function getRemoteGroups( $wiki ) { |
| 428 | + // Stolen from CentralAuth - a dirty hack indeed. |
| 429 | + global $wgConf, $IP; |
| 430 | + static $initialiseSettingsDone = false; |
411 | 431 | |
| 432 | + // This is a damn dirty hack |
| 433 | + if ( !$initialiseSettingsDone ) { |
| 434 | + $initialiseSettingsDone = true; |
| 435 | + if( file_exists( "$IP/InitialiseSettings.php" ) ) { |
| 436 | + require_once "$IP/InitialiseSettings.php"; |
| 437 | + } |
| 438 | + } |
| 439 | + |
| 440 | + list( $major, $minor ) = $wgConf->siteFromDB( $wiki ); |
| 441 | + if( isset( $major ) ) { |
| 442 | + $groupperms = $wgConf->get( 'wgGroupPermissions', $wiki, $major, |
| 443 | + array( 'lang' => $minor, 'site' => $major ) ); |
| 444 | + |
| 445 | + $groups = array_keys($groupperms); |
| 446 | + |
| 447 | + if (count($groups)==0) { |
| 448 | + // Fallback |
| 449 | + return User::getAllGroups(); |
| 450 | + } |
| 451 | + |
| 452 | + return $groups; |
| 453 | + } |
| 454 | + } |
| 455 | + |
412 | 456 | /** |
413 | 457 | * Adds a table with checkboxes where you can select what groups to add/remove |
414 | 458 | * |
415 | 459 | * @param $usergroups Array: groups the user belongs to |
| 460 | + * @param $user User object: the user to build checkboxes for. |
416 | 461 | * @return string XHTML table element with checkboxes |
417 | 462 | */ |
418 | | - private function groupCheckboxes( $usergroups ) { |
419 | | - $allgroups = $this->getAllGroups(); |
| 463 | + private function groupCheckboxes( $usergroups, $user ) { |
| 464 | + $allgroups = $this->getAllGroups( $user ); |
420 | 465 | $ret = ''; |
421 | 466 | |
422 | 467 | $column = 1; |
— | — | @@ -426,12 +471,12 @@ |
427 | 472 | $set = in_array( $group, $usergroups ); |
428 | 473 | # Should the checkbox be disabled? |
429 | 474 | $disabled = !( |
430 | | - ( $set && $this->canRemove( $group ) ) || |
431 | | - ( !$set && $this->canAdd( $group ) ) ); |
| 475 | + ( $set && $this->canRemove( $group, $user ) ) || |
| 476 | + ( !$set && $this->canAdd( $group, $user ) ) ); |
432 | 477 | # Do we need to point out that this action is irreversible? |
433 | 478 | $irreversible = !$disabled && ( |
434 | | - ($set && !$this->canAdd( $group )) || |
435 | | - (!$set && !$this->canRemove( $group ) ) ); |
| 479 | + ($set && !$this->canAdd( $group, $user )) || |
| 480 | + (!$set && !$this->canRemove( $group, $user ) ) ); |
436 | 481 | |
437 | 482 | $attr = $disabled ? array( 'disabled' => 'disabled' ) : array(); |
438 | 483 | $text = $irreversible |
— | — | @@ -483,44 +528,54 @@ |
484 | 529 | |
485 | 530 | /** |
486 | 531 | * @param $group String: the name of the group to check |
| 532 | + * @param $user User object: The user in question. |
487 | 533 | * @return bool Can we remove the group? |
488 | 534 | */ |
489 | | - private function canRemove( $group ) { |
| 535 | + private function canRemove( $group, $user=null ) { |
490 | 536 | // $this->changeableGroups()['remove'] doesn't work, of course. Thanks, |
491 | 537 | // PHP. |
492 | | - $groups = $this->changeableGroups(); |
| 538 | + $groups = $this->changeableGroups($user); |
493 | 539 | return in_array( $group, $groups['remove'] ) || ($this->isself && in_array( $group, $groups['remove-self'] )); |
494 | 540 | } |
495 | 541 | |
496 | 542 | /** |
497 | 543 | * @param $group string: the name of the group to check |
| 544 | + * @param $user User object: The user in question. |
498 | 545 | * @return bool Can we add the group? |
499 | 546 | */ |
500 | | - private function canAdd( $group ) { |
501 | | - $groups = $this->changeableGroups(); |
| 547 | + private function canAdd( $group, $user=null ) { |
| 548 | + $groups = $this->changeableGroups($user); |
502 | 549 | return in_array( $group, $groups['add'] ) || ($this->isself && in_array( $group, $groups['add-self'] )); |
503 | 550 | } |
504 | 551 | |
505 | 552 | /** |
506 | 553 | * Returns an array of the groups that the user can add/remove. |
507 | 554 | * |
| 555 | + * @param $user User object to check groups for. |
508 | 556 | * @return Array array( 'add' => array( addablegroups ), 'remove' => array( removablegroups ) , 'add-self' => array( addablegroups to self), 'remove-self' => array( removable groups from self) ) |
509 | 557 | */ |
510 | | - function changeableGroups() { |
| 558 | + function changeableGroups( $user=null ) { |
511 | 559 | global $wgUser; |
| 560 | + |
| 561 | + if ($user == null) |
| 562 | + $user = $wgUser; // Doesn't make a difference which user, so long as it's a local one. |
512 | 563 | |
513 | | - if( $wgUser->isAllowed( 'userrights' ) ) { |
| 564 | + if( $wgUser->isAllowed( 'userrights' ) || |
| 565 | + $wgUser->isAllowed( 'userrights-interwiki' ) && $user instanceof UserRightsProxy ) { |
514 | 566 | // This group gives the right to modify everything (reverse- |
515 | 567 | // compatibility with old "userrights lets you change |
516 | 568 | // everything") |
517 | 569 | // Using array_merge to make the groups reindexed |
518 | | - $all = array_merge( User::getAllGroups() ); |
| 570 | + $all = array_merge( $this->getAllGroups( $user ) ); |
519 | 571 | return array( |
520 | 572 | 'add' => $all, |
521 | 573 | 'remove' => $all, |
522 | 574 | 'add-self' => array(), |
523 | 575 | 'remove-self' => array() |
524 | 576 | ); |
| 577 | + } elseif ( $user instanceof UserRightsProxy ) { |
| 578 | + // Userrightsproxy without userrights-interwiki rights. Should have already been rejected. |
| 579 | + return array( 'add' => array(), 'remove' => array(), 'add-self' => array(), 'remove-self' => array() ); |
525 | 580 | } |
526 | 581 | |
527 | 582 | // Okay, it's not so simple, we will have to go through the arrays |
Index: trunk/phase3/RELEASE-NOTES |
— | — | @@ -137,7 +137,9 @@ |
138 | 138 | * Avoid recursive crazy expansions in section edit comments for pages which |
139 | 139 | contain '/*' in the title |
140 | 140 | * Fix excessive memory usage when parsing pages with lots of links |
| 141 | +* (bug 12518) Interwiki userrights now reflects remote groups, not local groups |
141 | 142 | |
| 143 | + |
142 | 144 | === API changes in 1.14 === |
143 | 145 | |
144 | 146 | * Registration time of users registered before the DB field was created is now |