Wikia - creating communities
<?php
/**
* The RightsControl Extension's task's are:
* - Managements of UserRights in a manor similar to Special:Userrights but safe like
* Special:Makesysop, Special:Makebot, and Special:Desysop.
*
* @package GENetwork Extensions
* @subpackage RightsControl
* @author Daniel Friesen (http://www.wikia.com/wiki/User:Dantman) (dan_the_man@telus.net)
* @license http://www.gnu.org/copyleft/gpl.html GNU General Public Licence 2.0 or later
*/
if( !defined( 'MEDIAWIKI' ) ) die( "This is an extension to the MediaWiki package and cannot be run standalone." );
require_once( "$IP/includes/SpecialPage.php" );
/**
* Constructor
*/
class SpecialRightsControl extends SpecialPage {
function SpecialRightsControl() {
global $wgRequest;
SpecialPage::SpecialPage( 'RightsControl', 'rc-use', true, false, 'default', false );
}
/**
* Execute
*/
function execute( $par = null ) {
global $wgUser, $wgOut, $wgRequest;
# Check rights
if ( $wgUser->isAllowed( 'userrights' ) ) {
$wgOut->redirect( SpecialPage::getTitleFor( 'Userrights' )->getFullURL() );
return false;
}
wfDebug( $wgRequest->getBool( 'pass-error', false ) . "\n" . $wgRequest->getText( 'pass-error', '' ) );
if ( !$wgUser->isAllowed( 'rc-use' ) ) {
$wgOut->permissionRequired( "re-use" );
return false;
}
# Don't allow blocked users to move pages
if ( $wgUser->isBlocked() ) {
$wgOut->blockedPage();
return false;
}
# Check for database lock
if ( wfReadOnly() ) {
$wgOut->readOnlyPage();
return false;
}
$this->setHeaders();
$f = new SpecialRightsControlForm( $par );
//Show Error form if we have errors
if( count( $f->errors ) > 0 ) $f->showErrorForm();
//Always show the user form
$f->showUserForm();
if( !is_null( $f->userObject ) && $f->userObject->getID() != 0 ) {
//Continue with this if we have a user
if( $wgRequest->wasPosted() && $wgRequest->getCheck( 'yes-dogroups' ) && count( $f->errors ) <= 0 ) {
//If there was a yes from the confirmation form
// and we have no errors then run the rights changer
// and redirect us back after finished to refresh the info
$f->doGroups();
$wgOut->redirect( SpecialPage::getTitleFor( 'RightsControl' )->getFullURL(
'username='.wfUrlencode($f->userName).'&rightsControlMainpageFallback=true' ) );
} elseif( $wgRequest->wasPosted() && $wgRequest->getCheck( 'savegroups' ) && count( $f->errors ) <= 0 ) {
//If we requested an action display the confirmation form
$f->showConfirmForm();
} else {
//If nothing else, show the rights form if we have a user chosen
$f->showRightsForm();
}
}
}
}
class SpecialRightsControlForm {
var $allGroups, $selfAction, $errors;
var $userName, $userObject, $userGroups;
var $addGroups, $removeGroups;
/**
* Setup
*/
function SpecialRightsControlForm( $par = NULL ) {
global $wgOut, $wgUser, $wgRequest;
$titleObj = SpecialPage::getTitleFor( 'RightsControl' );
$this->selfAction = $titleObj->escapeLocalURL();
$this->allGroups = User::getAllGroups();
$this->userName = $wgRequest->getVal( 'username', NULL );
$this->userObject = User::newFromName( $this->userName );
$this->userGroups = !is_null( $this->userObject ) ? $this->userObject->getGroups() : array();
$this->addGroups = $wgRequest->getArray( 'add', array() );
$this->removeGroups = $wgRequest->getArray( 'remove', array() );
$this->errors = array();
if( ( is_null( $this->userObject ) && $wgRequest->wasPosted() ) || $this->userName === '' ) {
$this->errors[] = $wgOut->parse( wfMsg( 'nouserspecified' ) );
} elseif( !is_null( $this->userObject ) && $this->userObject->getID() == 0 ) {
$this->errors[] = $wgOut->parse( wfMsg( 'nosuchusershort', wfEscapeWikiText( $this->userName ) ) );
} else {
if( $wgRequest->wasPosted() && $wgRequest->getCheck( 'savegroups' ) ) {
//We requested action, validate it
if( count( $this->addGroups + $this->removeGroups ) > 0 ) {
//If we selected groups to change
foreach( $this->addGroups as $group ) {
if( in_array( $group, $this->userObject->getGroups() ) ) {
//User already has this group to be added
$this->errors[] = $wgOut->parse( wfMsg( 'userrights-alreadyhas', $group ) );
}
if( !$wgUser->isAllowed( "rc-mk-$group" ) ) {
//You can't add this group
$this->errors[] = $wgOut->parse( wfMsg( 'badaccess-addgroup', $group ) );
}
}
foreach( $this->removeGroups as $group ) {
//User dosen't have this group to be removed
if( !in_array( $group, $this->userObject->getGroups() ) ) {
$this->errors[] = $wgOut->parse( wfMsg( 'userrights-isnotgroup', $group ) );
}
if( !$wgUser->isAllowed( "rc-de-$group" ) &&
( !$wgUser->isAllowed( "rc-sr-$group" ) &&
$wgUser->getName() == $this->userObject->getName() ) ) {
//You can't remove this group
$this->errors[] = $wgOut->parse( wfMsg( 'badaccess-removegroup', $group ) );
}
}
} else {
//You didn't select anything
$this->errors[] = $wgOut->parse( wfMsg( 'userrights-noneselected' ) );
}
}
}
}
/**
* Error Box
*/
function showErrorForm() {
global $wgOut;
$wgOut->addHTML(
Xml::openElement( 'fieldset' ).
Xml::element( 'legend', NULL, wfMsg( 'userrights-error' ) ).
Xml::openElement( 'div', array( 'class' => 'error' ) )
);
foreach( $this->errors as $error )
$wgOut->addHTML( $error );
$wgOut->addHTML(
Xml::closeElement( 'div' ).
Xml::closeElement( 'fieldset' )
);
}
/**
* User Search Form
*/
function showUserForm() {
global $wgOut;
$wgOut->addHTML(
Xml::openElement( 'fieldset' ).
Xml::element( 'legend', NULL, wfMsg( 'userrights-lookup-user' ) ).
Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->selfAction, 'name' => 'userform' ) ).
//Username
Xml::openElement( 'p' ).
Xml::inputLabel( wfMsg( 'userrights-user-editname' ),
'username', 'username', 30,
$this->userName ).
Xml::closeElement( 'p' ).
//Submit
Xml::openElement( 'p' ).
Xml::submitButton( wfMsg( 'editusergroup' ) ).
Xml::closeElement( 'p' ).
Xml::closeElement( 'form' ).
Xml::closeElement( 'fieldset' )
);
}
/**
* User Rights Control Form
*/
function showRightsForm() {
global $wgOut, $wgUser;
$wgOut->addHTML(
Xml::openElement( 'fieldset' ).
Xml::element( 'legend', NULL, wfMsg( 'editusergroup' ) ).
Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->selfAction, 'name' => 'userrights' ) ).
Xml::hidden( 'username', $this->userName ).
$wgOut->parse( wfMsg( 'editinguser', $this->userObject->getName() ) ).
Xml::openElement( 'table', array(
'style' => 'width: 100%;'
) ).
Xml::openElement( 'tr' ).
//Headers
Xml::element( 'th' ).
Xml::openElement( 'th' ).
$wgOut->parse( wfMsg( 'userremovefrom' ) ).
Xml::closeElement( 'th' ).
Xml::openElement( 'th' ).
$wgOut->parse( wfMsg( 'useraddto' ) ).
Xml::closeElement( 'th' ).
Xml::closeElement( 'tr' ).
Xml::openElement( 'tr' ).
Xml::openElement( 'td', array( 'style' => 'vertical-align: top;' ) ).
Xml::openElement( 'ul' ).
$wgOut->parse( wfMsg( 'useringroups' ) )
);
//List groups
foreach( $this->userGroups as $group )
$wgOut->addHTML(
Xml::openElement( 'li' ).
User::makeGroupLinkHTML( $group, User::getGroupMember( $group ) ).
Xml::closeElement( 'li' )
);
$wgOut->addHTML(
Xml::closeElement( 'ul' ).
Xml::closeElement( 'td' ).
Xml::openElement( 'td', array( 'style' => 'width: 20%; text-align: center;' ) ).
Xml::openElement( 'select', array( 'name' => 'remove[]', 'multiple'=> 'multiple', 'size' => 6 ) )
);
//Remove from
foreach( $this->userGroups as $group )
if( $wgUser->isAllowed( "rc-de-$group" ) ||
( $wgUser->isAllowed( "rc-sr-$group" ) &&
$wgUser->getName() == $this->userObject->getName() ) )
$wgOut->addHTML( Xml::option( User::getGroupMember( $group ), $group ) );
$wgOut->addHTML(
Xml::closeElement( 'select' ).
Xml::closeElement( 'td' ).
Xml::openElement( 'td', array( 'style' => 'width: 20%; text-align: center;' ) ).
Xml::openElement( 'select', array( 'name' => 'add[]', 'multiple'=> 'multiple', 'size' => 6 ) )
);
//Add to
foreach( $this->allGroups as $group )
if( !in_array( $group, $this->userGroups ) )
if( $wgUser->isAllowed( "rc-mk-$group" ) )
$wgOut->addHTML( Xml::option( User::getGroupMember( $group ), $group ) );
$wgOut->addHTML(
Xml::closeElement( 'select' ).
Xml::closeElement( 'td' ).
Xml::closeElement( 'tr' ).
Xml::closeElement( 'table' ).
$wgOut->parse( wfMsg( 'userrights-limitedhelp' ) ).
$wgOut->parse( wfMsg( 'userrights-groupshelp' ) ).
Xml::submitButton( wfMsg( 'saveusergroups' ), array( 'name' => 'savegroups' ) ).
Xml::closeElement( 'form' ).
Xml::closeElement( 'fieldset' )
);
}
/**
* Confirmation Form
*/
function showConfirmForm() {
global $wgOut, $wgUser, $wgRequest;
$wgOut->addHTML(
Xml::openElement( 'fieldset' ).
Xml::element( 'legend', NULL, wfMsg( 'userrights-confirm' ) ).
Xml::openElement( 'form', array( 'method' => 'post', 'action' => $this->selfAction, 'name' => 'userform' ) ).
Xml::hidden( 'username', $this->userName )
);
//Add the change data into hidden elements
foreach( $this->removeGroups as $group )
$wgOut->addHTML( Xml::hidden( 'remove[]', $group ) );
foreach( $this->addGroups as $group )
$wgOut->addHTML( Xml::hidden( 'add[]', $group ) );
//Output the info
foreach( $this->addGroups as $group ) {
//Add this group
$wgOut->addHTML(
$wgOut->parse( wfMsg( 'userrights-addgroup', User::getGroupMember( $group ), $group ) )
);
if( $wgUser->isAllowed( "rc-mk-$group" ) && !$wgUser->isAllowed( "rc-de-$group" ) ) {
//You can add this, but you won't be able to remove it
$wgOut->addHTML(
$wgOut->parse( wfMsg( 'userrights-oneway-noremove', User::getGroupMember( $group ), $group ) )
);
}
}
foreach( $this->removeGroups as $group ) {
//Remove this group
$wgOut->addHTML(
$wgOut->parse( wfMsg( 'userrights-removegroup', User::getGroupMember( $group ), $group ) )
);
if( $wgUser->isAllowed( "rc-de-$group" ) && !$wgUser->isAllowed( "rc-mk-$group" ) ) {
//You can remove this, but you won't be able to add it
$wgOut->addHTML(
$wgOut->parse( wfMsg( 'userrights-oneway-nogrant', User::getGroupMember( $group ), $group ) )
);
}
}
$wgOut->addHTML(
$wgOut->parse( wfMsg( 'userrights-sure' ) ).
Xml::submitButton( wfMsg( 'userrights-yes' ), array( 'name' => 'yes-dogroups' ) ).
Xml::submitButton( wfMsg( 'userrights-no' ), array( 'name' => 'no-dogroups' ) ).
Xml::closeElement( 'form' ).
Xml::closeElement( 'fieldset' )
);
}
/**
* Actually change the groups.
*
* @note This function has no validation, this is all done at setup and this must NOT be
* executed unless you have already made sure that there are no errors in the
* $errors array.
* @note Most of this is actually directly copied from includes/SpecialUserrights.php
* but while that page itself is a security issue for permissions, the actual
* code managing permissions is alright, we already made sure everything was ok.
*/
function doGroups() {
$oldGroups = $this->userGroups;
$newGroups = $oldGroups;
// remove then add groups
$newGroups = array_diff($newGroups, $this->removeGroups);
foreach( $this->removeGroups as $group ) {
$this->userObject->removeGroup( $group );
}
$newGroups = array_merge($newGroups, $this->addGroups);
foreach( $this->addGroups as $group ) {
$this->userObject->addGroup( $group );
}
$newGroups = array_unique( $newGroups );
wfDebug( 'oldGroups: ' . print_r( $oldGroups, true ) );
wfDebug( 'newGroups: ' . print_r( $newGroups, true ) );
wfRunHooks( 'UserRights', array( &$u, $this->addGroups, $this->removeGroups ) );
$log = new LogPage( 'rights' );
$log->addEntry( 'rights',
Title::makeTitle( NS_USER, $this->userObject->getName() ), '',
array(
implode( ', ', $oldGroups ),
implode( ', ', $newGroups )
) );
}
}
?>