MediaWiki r46497 - Code Review

Jump to: navigation, search
Repository:MediaWiki
Revision:r46496‎ | r46497 (on ViewVC)‎ | r46498 >
Date:23:54, 28 January 2009
Author:werdna
Status:deferred
Tags:
Comment:
Add Special:AbuseFilter/test, which allows (trusted for now, due to DoS potential) users to enter a filter, and have it checked against the last 100 RecentChanges items while-u-wait.
Some related cleanup to change tagging in ChangesList.
Modified paths:

Diff [purge]

Index: trunk/phase3/includes/ChangesList.php
===================================================================
--- trunk/phase3/includes/ChangesList.php	(revision 46496)
+++ trunk/phase3/includes/ChangesList.php	(revision 46497)
@@ -340,6 +340,9 @@
 	}
 
 	protected function insertTags( &$s, &$rc, &$classes ) {
+		if ( empty($rc->mAttribs['ts_tags']) )
+			return;
+			
 		list($tagSummary, $newClasses) = ChangeTags::formatSummaryRow( $rc->mAttribs['ts_tags'], 'changeslist' );
 		$classes = array_merge( $classes, $newClasses );
 		$s .= ' ' . $tagSummary;
Index: trunk/extensions/AbuseFilter/AbuseFilter.php
===================================================================
--- trunk/extensions/AbuseFilter/AbuseFilter.php	(revision 46496)
+++ trunk/extensions/AbuseFilter/AbuseFilter.php	(revision 46497)
@@ -39,6 +39,7 @@
 $wgAutoloadClasses['AbuseFilterViewTools'] = "$dir/Views/AbuseFilterViewTools.php";
 $wgAutoloadClasses['AbuseFilterViewHistory'] = "$dir/Views/AbuseFilterViewHistory.php";
 $wgAutoloadClasses['AbuseFilterViewRevert'] = "$dir/Views/AbuseFilterViewRevert.php";
+$wgAutoloadClasses['AbuseFilterViewTest'] = "$dir/Views/AbuseFilterViewTest.php";
 
 $wgSpecialPages['AbuseLog'] = 'SpecialAbuseLog';
 $wgSpecialPages['AbuseFilter'] = 'SpecialAbuseFilter';
@@ -81,6 +82,7 @@
 $wgAjaxExportList[] = 'AbuseFilter::ajaxCheckSyntax';
 $wgAjaxExportList[] = 'AbuseFilter::ajaxEvaluateExpression';
 $wgAjaxExportList[] = 'AbuseFilter::ajaxReAutoconfirm';
+$wgAjaxExportList[] = 'AbuseFilter::ajaxGetFilter';
 
 // Bump the version number every time you change any of the .css/.js files
 $wgAbuseFilterStyleVersion = 3;
Index: trunk/extensions/AbuseFilter/SpecialAbuseFilter.php
===================================================================
--- trunk/extensions/AbuseFilter/SpecialAbuseFilter.php	(revision 46496)
+++ trunk/extensions/AbuseFilter/SpecialAbuseFilter.php	(revision 46497)
@@ -49,6 +49,10 @@
 			$this->mFilter = $params[1];
 			$view = 'AbuseFilterViewRevert';
 		}
+
+		if ( !empty($params[0]) && $params[0] == 'test' ) {
+			$view = 'AbuseFilterViewTest';
+		}
 		
 		if (!empty($params[0]) && ($params[0] == 'history' || $params[0] == 'log') ) {
 			if (count($params) == 1) {
Index: trunk/extensions/AbuseFilter/Views/AbuseFilterViewList.php
===================================================================
--- trunk/extensions/AbuseFilter/Views/AbuseFilterViewList.php	(revision 46496)
+++ trunk/extensions/AbuseFilter/Views/AbuseFilterViewList.php	(revision 46497)
@@ -14,7 +14,7 @@
 
 		// Quick links
 		$wgOut->addWikiMsg( 'abusefilter-links' );
-		$lists = array( 'tools' );
+		$lists = array( 'tools', 'test' );
 		if ($this->canEdit())
 			$lists[] = 'new';
 		$links = '';
Index: trunk/extensions/AbuseFilter/Views/AbuseFilterViewTest.php
===================================================================
--- trunk/extensions/AbuseFilter/Views/AbuseFilterViewTest.php	(revision 0)
+++ trunk/extensions/AbuseFilter/Views/AbuseFilterViewTest.php	(revision 46497)
@@ -0,0 +1,84 @@
+<?php
+
+if (!defined( 'MEDIAWIKI' ))
+	die();
+
+class AbuseFilterViewTest extends AbuseFilterView {
+	// Hard-coded for now.
+	static $mChangeLimit = 100;
+	
+	function show( ) {
+		global $wgOut, $wgUser, $wgRequest;
+		
+		AbuseFilter::disableConditionLimit();
+
+		$this->loadParameters();
+		
+		$wgOut->setPageTitle( wfMsg( 'abusefilter-test' ) );
+		$wgOut->addWikiMsg( 'abusefilter-test-intro', self::$mChangeLimit );
+
+		$output = '';
+		$output .= AbuseFilter::buildEditBox( $this->mFilter, 'wpTestFilter' ) . "\n";
+		$output .= Xml::inputLabel( wfMsg( 'abusefilter-test-load-filter' ), 'wpInsertFilter', 'mw-abusefilter-load-filter', 10, '' ) . '&nbsp;' .
+			Xml::element( 'input', array( 'type' => 'button', 'value' => wfMsg( 'abusefilter-test-load' ), 'id' => 'mw-abusefilter-load' ) );
+		$output = Xml::tags( 'div', array( 'id' => 'mw-abusefilter-test-editor' ), $output );
+
+		// Removed until I can distinguish between positives and negatives :)
+// 		$output .= Xml::tags( 'p', null, Xml::checkLabel( wfMsg( 'abusefilter-test-shownegative' ), 'wpShowNegative', 'wpShowNegative', $this->mShowNegative ) );
+		$output .= Xml::tags( 'p', null, Xml::submitButton( wfMsg( 'abusefilter-test-submit' ) ) );
+		$output .= Xml::hidden( 'title', $this->getTitle("test")->getPrefixedText() );
+		$output = Xml::tags( 'form', array( 'action' => $this->getTitle("test")->getLocalURL(), 'method' => 'POST' ), $output );
+
+		$output = Xml::fieldset( wfMsg( 'abusefilter-test-legend' ), $output );
+
+		$wgOut->addHTML( $output );
+
+		if ($wgRequest->wasPosted()) {
+			$this->doTest();
+		}
+	}
+
+	function doTest() {
+		// Quick syntax check.
+		if ( ($result = AbuseFilter::checkSyntax( $this->mFilter )) !== true ) {
+			$wgOut->addWikiMsg( 'abusefilter-test-syntaxerr' );
+			return;
+		}
+
+		// Get our ChangesList
+		global $wgUser, $wgOut;
+		$changesList = ChangesList::newFromUser( $wgUser );
+		$output = $changesList->beginRecentChangesList();
+
+		$dbr = wfGetDB( DB_SLAVE );
+		$res = $dbr->select( 'recentchanges', '*', array(), __METHOD__, array( 'LIMIT' => self::$mChangeLimit, 'ORDER BY' => 'rc_timestamp asc' ) );
+
+		$counter = 1;
+
+		while ( $row = $dbr->fetchObject( $res ) ) {
+			$vars = AbuseFilter::getVarsFromRCRow( $row );
+
+			if (!$vars)
+				continue;
+
+			$result = AbuseFilter::checkConditions( $this->mFilter, $vars );
+
+			if ($result || $this->mShowNegative) {
+				$rc = RecentChange::newFromRow( $row );
+				$rc->counter = $counter++;
+				$output .= $changesList->recentChangesLine( $rc, false );
+			}
+		}
+
+		$output .= $changesList->endRecentChangesList();
+
+		$wgOut->addHTML( $output );
+	}
+
+	function loadParameters() {
+		global $wgRequest;
+
+		$this->mFilter = $wgRequest->getText( 'wpTestFilter' );
+		$this->mShowNegative = $wgRequest->getBool( 'wpShowNegative' );
+	}
+}
\ No newline at end of file
Index: trunk/extensions/AbuseFilter/AbuseFilter.class.php
===================================================================
--- trunk/extensions/AbuseFilter/AbuseFilter.class.php	(revision 46496)
+++ trunk/extensions/AbuseFilter/AbuseFilter.class.php	(revision 46497)
@@ -52,6 +52,22 @@
 		}
 	}
 
+	public static function ajaxGetFilter( $filter ) {
+		global $wgUser;
+		if ( !$wgUser->isAllowed( 'abusefilter-view' ) ) {
+			return false;
+		}
+
+		$dbr = wfGetDB( DB_SLAVE );
+		$row = $dbr->selectRow( 'abuse_filter', '*', array( 'af_id' => $filter ), __METHOD__ );
+
+		if ( $row->af_hidden && !$wgUser->isAllowed( 'abusefilter-modify' ) ) {
+			return false;
+		}
+
+		return strval($row->af_pattern);
+	}
+
 	public static function triggerLimiter( $val = 1 ) {
 		self::$condCount += $val;
 
@@ -759,4 +775,111 @@
 		$display = wfEmptyMsg( "abusefilter-action-$action", $display ) ? $action : $display;
 		return $display;
 	}
+
+	public static function getVarsFromRCRow( $row ) {
+		if ($row->rc_this_oldid) {
+			// It's an edit.
+			return self::getEditVarsFromRCRow( $row );
+		} elseif ( $row->rc_log_type == 'move' ) {
+			return self::getMoveVarsFromRCRow( $row );
+		} elseif ( $row->rc_log_type == 'newusers' ) {
+			return self::getCreateVarsFromRCRow( $row );
+		}
+	}
+
+	public static function getCreateVarsFromRCRow( $row ) {
+		$vars = array('ACTION' => 'createaccount');
+		$vars['USER_NAME'] = $vars['ACCOUNTNAME'] = Title::makeTitle( $row->rc_namespace, $row->rc_title )->getText();
+		return $vars;
+	}
+
+	public static function getEditVarsFromRCRow( $row ) {
+		$vars = array();
+		$title = Title::makeTitle( $row->rc_namespace, $row->rc_title );
+		
+		$vars = array_merge( $vars, self::generateUserVars( User::newFromId( $row->rc_user ) ) );
+		$vars = array_merge( $vars, self::generateTitleVars( $title, 'ARTICLE_' ) );
+		$vars['ACTION'] = 'edit';
+		$vars['SUMMARY'] = $row->rc_comment;
+
+		$newRev = Revision::newFromId( $row->rc_this_oldid );
+		$new_text = $newRev->getText();
+
+		if ($row->rc_last_oldid) {
+			$oldRev = Revision::newFromId( $row->rc_last_oldid );
+			$old_text = $oldRev->getText();
+		} else {
+			$old_text = '';
+		}
+
+		$vars = array_merge( $vars, self::getEditVars( $title, $old_text, $new_text, null, $row->rc_this_oldid, $row->rc_last_oldid ) );
+
+		return $vars;
+	}
+
+	public static function getMoveVarsFromRCRow( $row ) {
+		$vars = array();
+		
+		$user = User::newFromId( $row->rc_user );
+		$oldTitle = Title::makeTitle( $row->rc_namespace, $row->rc_title );
+		$newTitle = Title::newFromText( trim($row->rc_params) );
+		
+		$vars = array_merge( $vars, AbuseFilter::generateUserVars( $user ),
+			AbuseFilter::generateTitleVars( $oldTitle, 'MOVED_FROM' ),
+			AbuseFilter::generateTitleVars( $newTitle, 'MOVED_TO' ) );
+
+		$vars['SUMMARY'] = $row->rc_comment;
+		$vars['ACTION'] = 'move';
+
+		return $vars;
+	}
+
+	public static function getEditVars( $title, $old_text, $new_text, $oldLinks = null, $revid=null, $oldid=null ) {
+		$vars = array();
+		$article = new Article( $title );
+
+		$vars['EDIT_DELTA'] = strlen($new_text) - strlen($old_text);
+		$vars['OLD_SIZE'] = strlen($old_text);
+		$diff = wfDiff( $old_text, $new_text );
+		$diff = trim( str_replace( '\No newline at end of file', '', $diff ) );
+		$vars['EDIT_DIFF'] = $diff;
+		$vars['NEW_SIZE'] = strlen($new_text);
+
+		$vars['OLD_WIKITEXT'] = $old_text;
+		$vars['NEW_WIKITEXT'] = $new_text;
+
+		// Some more specific/useful details about the changes.
+		$diff_lines = explode( "\n", $diff );
+		$added_lines = array();
+		$removed_lines = array();
+		foreach( $diff_lines as $line ) {
+			if (strpos( $line, '-' )===0) {
+				$removed_lines[] = substr($line,1);
+			} elseif (strpos( $line, '+' )===0) {
+				$added_lines[] = substr($line,1);
+			}
+		}
+		$vars['ADDED_LINES'] = implode( "\n", $added_lines );
+		$vars['REMOVED_LINES'] = implode( "\n", $removed_lines );
+
+		if ($oldLinks === null && $oldid) {
+			$oldInfo = $article->prepareTextForEdit( $old_text, $oldid );
+			$oldLinks = $oldInfo->output->getExternalLinks();
+		} elseif ($oldLinks === null) {
+			$oldLinks = array();
+		}
+
+		// Added links...
+		$editInfo = $article->prepareTextForEdit( $old_text, $revid );
+		$newLinks = array_keys( $editInfo->output->getExternalLinks() );
+		$vars['ALL_LINKS'] = implode( "\n", $newLinks );
+		$vars['ADDED_LINKS'] = implode( "\n", array_diff( $newLinks, array_intersect( $newLinks, $oldLinks ) ) );
+		$vars['REMOVED_LINKS'] = implode( "\n", array_diff( $oldLinks, array_intersect( $newLinks, $oldLinks ) ) );
+
+		// Pull other useful stuff from $editInfo.
+		$newHTML = $vars['NEW_HTML'] = $editInfo->output->getText();
+		$newText = $vars['NEW_TEXT'] = preg_replace( '/<[^>]+>/', '', $newHTML );
+
+		return $vars;
+	}
 }
Index: trunk/extensions/AbuseFilter/edit.js
===================================================================
--- trunk/extensions/AbuseFilter/edit.js	(revision 46496)
+++ trunk/extensions/AbuseFilter/edit.js	(revision 46497)
@@ -49,6 +49,15 @@
 	document.getElementById('wpFilterBuilder').selectedIndex = 0;
 }
 
+function fetchFilter() {
+	var filter = document.getElementById( 'mw-abusefilter-load-filter' ).value;
+
+	sajax_do_call( 'AbuseFilter::ajaxGetFilter', [filter], function(request) {
+		var filter = request.responseText;
+		document.getElementById( wgFilterBoxName ).value = filter;
+	} );
+}
+
 //From http://clipmarks.com/clipmark/CEFC94CB-94D6-4495-A7AA-791B7355E284/
 function insertAtCursor(myField, myValue) {
 	//IE support
@@ -107,5 +116,10 @@
 		}
 	} );
 
+	var loader = document.getElementById( 'mw-abusefilter-load' );
+	if (loader) {
+		addHandler( loader, 'click', fetchFilter );
+	}
+
 	setupActions();
 } );
\ No newline at end of file
Index: trunk/extensions/AbuseFilter/AbuseFilter.i18n.php
===================================================================
--- trunk/extensions/AbuseFilter/AbuseFilter.i18n.php	(revision 46496)
+++ trunk/extensions/AbuseFilter/AbuseFilter.i18n.php	(revision 46497)
@@ -315,6 +315,13 @@
 	'abusefilter-revert-reason' => 'Automatic revert of all actions taken by the abuse filter due to filter $1.
 Reason given: $2',
 	'abusefilter-revert-reasonfield' => 'Reason for revert:',
+
+	'abusefilter-test' => 'Test a filter against previous edits',
+	'abusefilter-test-intro' => 'This page allows you to check a filter entered in the box below against the last $1 changes. To load an existing filter, type its filter ID into the box below the edit textbox, and click the "Load" button.',
+	'abusefilter-test-legend' => 'Filter testing',
+	'abusefilter-test-load-filter' => 'Load filter ID:',
+	'abusefilter-test-submit' => 'Test',
+	'abusefilter-test-load' => 'Load',
 );
 
 /** Message documentation (Message documentation)
Index: trunk/extensions/AbuseFilter/AbuseFilter.hooks.php
===================================================================
--- trunk/extensions/AbuseFilter/AbuseFilter.hooks.php	(revision 46496)
+++ trunk/extensions/AbuseFilter/AbuseFilter.hooks.php	(revision 46497)
@@ -19,44 +19,11 @@
 		
 		$old_text = $editor->getBaseRevision() ? $editor->getBaseRevision()->getText() : '';
 		$new_text = $editor->textbox1;
-		
-		$vars['EDIT_DELTA'] = strlen($new_text) - strlen($old_text);
-		$vars['OLD_SIZE'] = strlen($old_text);
-		$diff = wfDiff( $old_text, $new_text );
-		$diff = trim( str_replace( '\No newline at end of file', '', $diff ) );
-		$vars['EDIT_DIFF'] = $diff;
-		$vars['NEW_SIZE'] = strlen($new_text);
-
-		$vars['OLD_WIKITEXT'] = $old_text;
-		$vars['NEW_WIKITEXT'] = $new_text;
-		
-		// Some more specific/useful details about the changes.
-		$diff_lines = explode( "\n", $diff );
-		$added_lines = array();
-		$removed_lines = array();
-		foreach( $diff_lines as $line ) {
-			if (strpos( $line, '-' )===0) {
-				$removed_lines[] = substr($line,1);
-			} elseif (strpos( $line, '+' )===0) {
-				$added_lines[] = substr($line,1);
-			}
-		}
-		$vars['ADDED_LINES'] = implode( "\n", $added_lines );
-		$vars['REMOVED_LINES'] = implode( "\n", $removed_lines );
-		
-		// Added links...
 		$oldLinks = self::getOldLinks( $editor->mTitle );
-		$editInfo = $editor->mArticle->prepareTextForEdit( $text );
-		$newLinks = array_keys( $editInfo->output->getExternalLinks() );
-		$vars['ALL_LINKS'] = implode( "\n", $newLinks );
-		$vars['ADDED_LINKS'] = implode( "\n", array_diff( $newLinks, array_intersect( $newLinks, $oldLinks ) ) );
-		$vars['REMOVED_LINKS'] = implode( "\n", array_diff( $oldLinks, array_intersect( $newLinks, $oldLinks ) ) );
 
-		// Pull other useful stuff from $editInfo.
-		$newHTML = $vars['NEW_HTML'] = $editInfo->output->getText();
-		$newText = $vars['NEW_TEXT'] = preg_replace( '/<[^>]+>/', '', $newHTML );
+		$vars = array_merge( $vars, AbuseFilter::getEditVars( $editor->mTitle, $old_text, $new_text, $oldLinks ) );
 
-		$filter_result = AbuseFilter::filterAction( $vars, $editor->mTitle );
+		$filter_result = AbuseFilter::filterAction( $vars, $editor->mTitle, $oldLinks );
 
 		if( $filter_result !== true ){
 			$error = $filter_result;

Status & tagging log

  • 23:06, 5 February 2009 Werdna (Talk | contribs) changed the status of r46497 [removed: new added: deferred]
Personal tools
Namespaces
Variants
Views
Actions
Site
Support
Download
Development
Communication
Toolbox