2009-01-28 00:36:49 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
if (!defined( 'MEDIAWIKI' ))
|
|
|
|
die();
|
|
|
|
|
|
|
|
class AbuseFilterViewRevert extends AbuseFilterView {
|
|
|
|
function show( ) {
|
|
|
|
$filter = $this->mPage->mFilter;
|
|
|
|
|
|
|
|
global $wgUser, $wgRequest, $wgOut;
|
|
|
|
$sk = $wgUser->getSkin();
|
|
|
|
|
|
|
|
if ( !$wgUser->isAllowed( 'abusefilter-revert' ) ) {
|
|
|
|
$wgOut->permissionRequired( 'abusefilter-revert' );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->loadParameters();
|
|
|
|
|
|
|
|
if ($this->attemptRevert())
|
|
|
|
return;
|
|
|
|
|
|
|
|
$wgOut->addWikiMsg( 'abusefilter-revert-intro', $filter );
|
|
|
|
$wgOut->setPageTitle( wfMsg('abusefilter-revert-title', $filter) );
|
|
|
|
|
|
|
|
// First, the search form.
|
|
|
|
$searchFields = array();
|
2009-02-07 09:34:11 +00:00
|
|
|
$searchFields['abusefilter-revert-filter'] =
|
|
|
|
Xml::element( 'strong', null, $filter );
|
|
|
|
$searchFields['abusefilter-revert-periodstart'] =
|
|
|
|
Xml::input( 'wpPeriodStart', 45, $this->origPeriodStart );
|
|
|
|
$searchFields['abusefilter-revert-periodend'] =
|
|
|
|
Xml::input( 'wpPeriodEnd', 45, $this->origPeriodEnd );
|
2009-01-28 00:36:49 +00:00
|
|
|
$searchForm = Xml::buildForm( $searchFields, 'abusefilter-revert-search' );
|
|
|
|
$searchForm .= "\n" . Xml::hidden( 'submit', 1 );
|
2009-02-07 09:34:11 +00:00
|
|
|
$searchForm =
|
|
|
|
Xml::tags(
|
|
|
|
'form',
|
|
|
|
array(
|
|
|
|
'action' => $this->getTitle( "revert/$filter" )->getLocalURL(),
|
|
|
|
'method' => 'POST'
|
|
|
|
),
|
|
|
|
$searchForm
|
|
|
|
);
|
|
|
|
$searchForm =
|
|
|
|
Xml::fieldset( wfMsg( 'abusefilter-revert-search-legend' ), $searchForm );
|
2009-01-28 00:36:49 +00:00
|
|
|
|
|
|
|
$wgOut->addHTML( $searchForm );
|
|
|
|
|
|
|
|
if ($this->mSubmit) {
|
|
|
|
// Add a summary of everything that will be reversed.
|
|
|
|
$wgOut->addWikiMsg( 'abusefilter-revert-preview-intro' );
|
|
|
|
|
|
|
|
// Look up all of them.
|
|
|
|
$results = $this->doLookup();
|
|
|
|
$list = array();
|
|
|
|
|
|
|
|
foreach( $results as $result ) {
|
|
|
|
$displayActions = array();
|
|
|
|
|
|
|
|
global $wgLang;
|
2009-02-07 09:34:11 +00:00
|
|
|
$displayActions = array_map(
|
|
|
|
array( 'AbuseFilter', 'getActionDisplay' ),
|
|
|
|
$result['actions'] );
|
2009-01-28 00:36:49 +00:00
|
|
|
|
2009-02-07 09:34:11 +00:00
|
|
|
$msg = wfMsgExt(
|
|
|
|
'abusefilter-revert-preview-item',
|
|
|
|
array( 'parseinline', 'replaceafter' ),
|
|
|
|
array(
|
|
|
|
$wgLang->timeanddate( $result['timestamp'] ),
|
|
|
|
$sk->userLink( $result['userid'], $result['user'] ),
|
|
|
|
$result['action'],
|
|
|
|
$sk->link( $result['title'] ),
|
|
|
|
implode( ', ', $displayActions ),
|
|
|
|
$sk->link(
|
|
|
|
SpecialPage::getTitleFor( 'AbuseLog' ),
|
|
|
|
wfMsgNoTrans( 'abusefilter-log-detailslink' ),
|
|
|
|
array(),
|
|
|
|
array('details' =>$result['id'])
|
|
|
|
)
|
|
|
|
)
|
|
|
|
);
|
2009-01-28 00:36:49 +00:00
|
|
|
$list[] = Xml::tags( 'li', null, $msg );
|
|
|
|
}
|
|
|
|
|
|
|
|
$wgOut->addHTML( Xml::tags( 'ul', null, implode("\n", $list) ) );
|
|
|
|
|
|
|
|
// Add a button down the bottom.
|
2009-02-07 09:34:11 +00:00
|
|
|
$confirmForm =
|
|
|
|
Xml::hidden( 'editToken', $wgUser->editToken( "abusefilter-revert-$filter" ) ) .
|
|
|
|
Xml::hidden( 'title', $this->getTitle("revert/$filter")->getPrefixedText() ) .
|
|
|
|
Xml::hidden( 'wpPeriodStart', $this->origPeriodStart ) .
|
|
|
|
Xml::hidden( 'wpPeriodEnd', $this->origPeriodEnd ) .
|
|
|
|
Xml::inputLabel(
|
|
|
|
wfMsg( 'abusefilter-revert-reasonfield' ),
|
|
|
|
'wpReason', 'wpReason', 45
|
|
|
|
) .
|
|
|
|
"\n" .
|
|
|
|
Xml::submitButton( wfMsg( 'abusefilter-revert-confirm' ) );
|
|
|
|
$confirmForm = Xml::tags(
|
|
|
|
'form',
|
|
|
|
array(
|
|
|
|
'action' => $this->getTitle("revert/$filter")->getLocalURL(),
|
|
|
|
'method' => 'post'
|
|
|
|
),
|
|
|
|
$confirmForm
|
|
|
|
);
|
2009-01-28 00:36:49 +00:00
|
|
|
$wgOut->addHTML( $confirmForm );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function doLookup() {
|
|
|
|
$periodStart = $this->mPeriodStart;
|
|
|
|
$periodEnd = $this->mPeriodEnd;
|
|
|
|
$filter = $this->mPage->mFilter;
|
|
|
|
|
|
|
|
$conds = array( 'afl_filter' => $filter );
|
|
|
|
|
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
|
|
|
|
|
|
|
if ($periodStart)
|
|
|
|
$conds[] = 'afl_timestamp>'.$dbr->addQuotes( $dbr->timestamp( $periodStart ) );
|
|
|
|
if ($periodEnd)
|
|
|
|
$conds[] = 'afl_timestamp<'.$dbr->addQuotes( $dbr->timestamp( $periodEnd ) );
|
|
|
|
|
|
|
|
// Database query.
|
|
|
|
$res = $dbr->select( 'abuse_filter_log', '*', $conds, __METHOD__ );
|
|
|
|
|
|
|
|
$results = array();
|
|
|
|
while ( $row = $dbr->fetchObject( $res ) ) {
|
|
|
|
if (!$row->afl_actions)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
$actions = explode(',', $row->afl_actions);
|
|
|
|
$reversibleActions = array( 'block', 'blockautopromote', 'degroup' );
|
|
|
|
$currentReversibleActions = array_intersect( $actions, $reversibleActions );
|
|
|
|
if ( count( $currentReversibleActions ) ) {
|
2009-02-07 09:34:11 +00:00
|
|
|
$results[] = array(
|
|
|
|
'id' => $row->afl_id,
|
|
|
|
'actions' => $currentReversibleActions,
|
|
|
|
'user' => $row->afl_user_text,
|
|
|
|
'userid' => $row->afl_user,
|
|
|
|
'vars' => unserialize( $row->afl_var_dump ),
|
|
|
|
'title' => Title::makeTitle( $row->afl_namespace, $row->afl_title ),
|
|
|
|
'action' => $row->afl_action,
|
|
|
|
'timestamp' => $row->afl_timestamp
|
|
|
|
);
|
2009-01-28 00:36:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $results;
|
|
|
|
}
|
|
|
|
|
|
|
|
function loadParameters() {
|
|
|
|
global $wgRequest;
|
2009-02-07 09:34:11 +00:00
|
|
|
|
|
|
|
$this->origPeriodStart = $wgRequest->getText( 'wpPeriodStart' );
|
|
|
|
$this->mPeriodStart = strtotime( $this->origPeriodStart );
|
|
|
|
$this->origPeriodEnd = $wgRequest->getText( 'wpPeriodEnd' );
|
|
|
|
$this->mPeriodEnd = strtotime( $this->origPeriodEnd );
|
2009-01-28 00:36:49 +00:00
|
|
|
$this->mSubmit = $wgRequest->getVal( 'submit' );
|
|
|
|
$this->mReason = $wgRequest->getVal( 'wpReason' );
|
|
|
|
}
|
|
|
|
|
|
|
|
function attemptRevert() {
|
|
|
|
global $wgUser, $wgRequest, $wgOut;
|
|
|
|
|
|
|
|
$filter = $this->mPage->mFilter;
|
|
|
|
$token = $wgRequest->getVal( 'editToken' );
|
|
|
|
if ( !$wgUser->matchEditToken( $token, "abusefilter-revert-$filter" ) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
$results = $this->doLookup();
|
|
|
|
foreach( $results as $result ) {
|
|
|
|
$actions = $result['actions'];
|
|
|
|
foreach( $actions as $action ) {
|
|
|
|
$this->revertAction( $action, $result );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$wgOut->addWikiMsg( 'abusefilter-revert-success', $filter );
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
function revertAction( $action, $result ) {
|
|
|
|
switch( $action ) {
|
|
|
|
case 'block':
|
|
|
|
$block = Block::newFromDB( '', $result['userid'], false );
|
|
|
|
if (!$block || $block->getBy() != AbuseFilter::getFilterUser()->getId())
|
|
|
|
return false; // Not blocked by abuse filter.
|
|
|
|
|
|
|
|
$block->delete();
|
|
|
|
$log = new LogPage( 'block' );
|
2009-02-07 09:34:11 +00:00
|
|
|
$log->addEntry(
|
|
|
|
'unblock',
|
|
|
|
Title::makeTitle( NS_USER, $result['user'] ),
|
|
|
|
wfMsgForContent(
|
|
|
|
'abusefilter-revert-reason', $this->mPage->mFilter, $this->mReason
|
|
|
|
)
|
|
|
|
);
|
2009-01-28 00:36:49 +00:00
|
|
|
break;
|
|
|
|
case 'blockautopromote':
|
|
|
|
global $wgMemc;
|
2009-02-07 09:34:11 +00:00
|
|
|
$wgMemc->delete( AbuseFilter::autopromoteBlockKey(
|
|
|
|
User::newFromId( $result['userid'] ) ) );
|
2009-01-28 00:36:49 +00:00
|
|
|
break;
|
|
|
|
case 'degroup':
|
|
|
|
// Pull the user's groups from the vars.
|
|
|
|
$oldGroups = $result['vars']['USER_GROUPS'];
|
|
|
|
$oldGroups = explode(',', $oldGroups);
|
2009-02-07 09:34:11 +00:00
|
|
|
$oldGroups = array_diff(
|
|
|
|
$oldGroups,
|
|
|
|
array_intersect( $oldGroups, User::getImplicitGroups() )
|
|
|
|
);
|
2009-01-28 00:36:49 +00:00
|
|
|
|
|
|
|
$rows = array();
|
|
|
|
foreach( $oldGroups as $group ) {
|
|
|
|
$rows[] = array( 'ug_user' => $result['userid'], 'ug_group' => $group );
|
|
|
|
}
|
|
|
|
|
|
|
|
// Cheat a little bit. User::addGroup repeatedly is too slow.
|
|
|
|
$user = User::newFromId( $result['userid'] );
|
|
|
|
$currentGroups = $user->getGroups();
|
|
|
|
$newGroups = array_merge( $oldGroups, $currentGroups );
|
|
|
|
|
|
|
|
// Don't do anything if there are no groups to add.
|
|
|
|
if ( !count( array_diff( $newGroups, $currentGroups ) ) )
|
|
|
|
return;
|
|
|
|
|
|
|
|
$dbw = wfGetDB( DB_MASTER );
|
|
|
|
$dbw->insert( 'user_groups', $rows, __METHOD__, array('IGNORE') );
|
|
|
|
$user->invalidateCache();
|
|
|
|
|
|
|
|
$log = new LogPage( 'rights' );
|
2009-02-07 09:34:11 +00:00
|
|
|
$log->addEntry( 'rights', $user->getUserPage(),
|
|
|
|
wfMsgForContent(
|
|
|
|
'abusefilter-revert-reason',
|
|
|
|
$this->mPage->mFilter,
|
|
|
|
$this->mReason
|
|
|
|
),
|
|
|
|
array( implode(',', $currentGroups), implode(',', $newGroups) )
|
|
|
|
);
|
2009-01-28 00:36:49 +00:00
|
|
|
}
|
|
|
|
}
|
2009-02-07 09:34:11 +00:00
|
|
|
}
|