r113953 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r113952‎ | r113953 | r113954 >
Date:20:39, 15 March 2012
Author:bsitu
Status:resolved (Comments)
Tags:
Comment:
fix for bug 35245 - add rate limiter and spam filter check
Modified paths:
  • /trunk/extensions/MoodBar/ApiFeedbackDashboardResponse.php (modified) (history)
  • /trunk/extensions/MoodBar/ApiMoodBar.php (modified) (history)
  • /trunk/extensions/MoodBar/MoodBar.i18n.php (modified) (history)
  • /trunk/extensions/MoodBar/MoodBar.php (modified) (history)
  • /trunk/extensions/MoodBar/include/MoodBarUtil.php (modified) (history)
  • /trunk/extensions/MoodBar/modules/ext.moodBar.dashboard/ext.moodBar.dashboard.js (modified) (history)
  • /trunk/extensions/MoodBar/modules/ext.moodBar/ext.moodBar.core.js (modified) (history)

Diff [purge]

Index: trunk/extensions/MoodBar/include/MoodBarUtil.php
@@ -6,6 +6,67 @@
77 class MoodBarUtil {
88
99 /**
 10+ * Check for abusive or spammy content
 11+ *
 12+ * Check the following in sequence (cheapest processing to most expensive,
 13+ * returning if we get a hit):
 14+ * 1) Respect $wgSpamRegex
 15+ * 2) Check SpamBlacklist
 16+ * 3) Check AbuseFilter
 17+ *
 18+ * @param $value string the text to check
 19+ */
 20+ public static function findAbuse( &$value ) {
 21+
 22+ // Respect $wgSpamRegex
 23+ global $wgSpamRegex;
 24+ if ( ( is_array( $wgSpamRegex ) && count( $wgSpamRegex ) > 0 )
 25+ || ( is_string( $wgSpamRegex ) && strlen( $wgSpamRegex ) > 0 ) ) {
 26+ // In older versions, $wgSpamRegex may be a single string rather than
 27+ // an array of regexes, so make it compatible.
 28+ $regexes = ( array ) $wgSpamRegex;
 29+ foreach ( $regexes as $regex ) {
 30+ if ( preg_match( $regex, $value ) ) {
 31+ return true;
 32+ }
 33+ }
 34+ }
 35+
 36+ // Create a fake title so we can pretend this is an article edit
 37+ $title = Title::newFromText( '__moodbar__' );
 38+
 39+ // Check SpamBlacklist, if installed
 40+ if ( function_exists( 'wfSpamBlacklistObject' ) ) {
 41+ $spam = wfSpamBlacklistObject();
 42+ } elseif ( class_exists( 'BaseBlacklist' ) ) {
 43+ $spam = BaseBlacklist::getInstance( 'spam' );
 44+ }
 45+ if ( $spam ) {
 46+ $ret = $spam->filter( $title, $value, '' );
 47+ if ( $ret !== false ) {
 48+ return true;
 49+ }
 50+ }
 51+
 52+ // Check AbuseFilter, if installed
 53+ if ( class_exists( 'AbuseFilter' ) ) {
 54+ global $wgUser;
 55+ $vars = new AbuseFilterVariableHolder;
 56+ $vars->addHolder( AbuseFilter::generateUserVars( $wgUser ) );
 57+ $vars->addHolder( AbuseFilter::generateTitleVars( $title, 'MOODBAR' ) );
 58+ $vars->setVar( 'SUMMARY', 'moodbar' );
 59+ $vars->setVar( 'ACTION', 'moodbar' );
 60+ $vars->setVar( 'old_wikitext', '' );
 61+ $vars->setVar( 'new_wikitext', $value );
 62+ $vars->addHolder( AbuseFilter::getEditVars( $title ) );
 63+ $filter_result = AbuseFilter::filterAction( $vars, $title );
 64+ return $filter_result != '' && $filter_result !== true;
 65+ }
 66+
 67+ return false;
 68+ }
 69+
 70+ /**
1071 * Calculate the time diff between $time and now, format the time diff to have the largest time block
1172 * or 'less than 1 minute' if the time diff is less than 1 minute
1273 * @param $time string - the UNIX time stamp
Index: trunk/extensions/MoodBar/MoodBar.i18n.php
@@ -66,6 +66,10 @@
6767 'moodbar-error-subtitle' => 'Something went wrong! Please try sharing your feedback again later.',
6868 'moodbar-blocked-title' => 'Oops!',
6969 'moodbar-blocked-subtitle' => 'You have been blocked from editing.',
 70+ 'moodbar-ratelimited-title' => 'Oops!',
 71+ 'moodbar-ratelimited-subtitle' => 'You have exceeded moodbar rate limit. Please wait some time and try again',
 72+ 'moodbar-abuse-title' => 'Oops!',
 73+ 'moodbar-abuse-subtitle' => 'Your feedback violates moodbar rules.',
7074 'moodbar-email-title' => 'Add e-mail',
7175 'moodbar-email-input' => 'Your e-mail address',
7276 'moodbar-email-desc' => 'We will send you an e-mail if someone responds to your feedback.',
@@ -272,6 +276,10 @@
273277 'moodbar-error-subtitle' => 'Subtitle of screen when an error occurred. $1 is the SITENAME',
274278 'moodbar-blocked-title' => 'Title of the screen after blocked user attempts to post feedback.',
275279 'moodbar-blocked-subtitle' => 'Subtitle of screen after blocked user attempts to post feedback.',
 280+ 'moodbar-ratelimited-title' => 'Title of the screen after users have exceeded rate limit and attempt to post feedback.',
 281+ 'moodbar-ratelimited-subtitle' => 'Subtitle of screen after users have exceeded rate limit and attempt to post feedback.',
 282+ 'moodbar-abuse-title' => 'Title of the screen after user attempts to post bad feedback.',
 283+ 'moodbar-abuse-subtitle' => 'Subtitle of the screen after user attempts to post bad feedback.',
276284 'moodbar-email-title' => 'Title of MoodBar when user has no email addresss',
277285 'moodbar-email-input' => 'Field label for Email address',
278286 'moodbar-email-desc' => 'Message prompting user to enter their email address.',
Index: trunk/extensions/MoodBar/ApiFeedbackDashboardResponse.php
@@ -6,7 +6,7 @@
77 private $EnotifWatchlist;
88
99 public function execute() {
10 - global $wgRequest, $wgUser;
 10+ global $wgRequest, $wgUser, $wgMoodBarAbuseFiltering;
1111
1212 if ( $wgUser->isAnon() ) {
1313 $this->dieUsage( "You don't have permission to do that", 'permission-denied' );
@@ -14,12 +14,20 @@
1515 if ( $wgUser->isBlocked( false ) ) {
1616 $this->dieUsageMsg( array( 'blockedtext' ) );
1717 }
 18+ if ( $wgUser->pingLimiter( 'moodbar-response' ) ) {
 19+ $this->dieUsageMsg( array( 'actionthrottledtext' ) );
 20+ }
1821
1922 $params = $this->extractRequestParams();
2023
 24+ if ( $wgMoodBarAbuseFiltering && MoodBarUtil::findAbuse( $params['response'] ) ) {
 25+ $this->getResult()->addValue( null, 'error', array( 'code' => 'abuse' ) );
 26+ return;
 27+ }
 28+
2129 //Response Object
2230 $item = MBFeedbackResponseItem::create( array() );
23 -
 31+
2432 $setParams = array();
2533 foreach( $params as $key => $value ) {
2634 if ( $item->isValidKey( $key ) ) {
Index: trunk/extensions/MoodBar/ApiMoodBar.php
@@ -2,14 +2,25 @@
33
44 class ApiMoodBar extends ApiBase {
55 public function execute() {
6 - global $wgUser;
 6+ global $wgUser, $wgMoodBarAbuseFiltering;
77
 8+ if ( $wgUser->isAnon() ) {
 9+ $this->dieUsage( "You don't have permission to do that", 'permission-denied' );
 10+ }
811 if ( $wgUser->isBlocked( false ) ) {
912 $this->dieUsageMsg( array( 'blockedtext' ) );
1013 }
 14+ if ( $wgUser->pingLimiter( 'moodbar-feedback' ) ) {
 15+ $this->dieUsageMsg( array( 'actionthrottledtext' ) );
 16+ }
1117
1218 $params = $this->extractRequestParams();
1319
 20+ if ( $wgMoodBarAbuseFiltering && MoodBarUtil::findAbuse( $params['comment'] ) ) {
 21+ $this->getResult()->addValue( null, 'error', array( 'code' => 'abuse' ) );
 22+ return;
 23+ }
 24+
1425 $params['page'] = Title::newFromText( $params['page'] );
1526
1627 // Params are deliberately named the same as the properties,
Index: trunk/extensions/MoodBar/modules/ext.moodBar/ext.moodBar.core.js
@@ -94,6 +94,16 @@
9595 <div class="mw-moodBar-state mw-moodBar-state-error">\
9696 <div class="mw-moodBar-state-title"><html:msg key="moodbar-blocked-title" /></div>\
9797 <div class="mw-moodBar-state-subtitle"><html:msg key="moodbar-blocked-subtitle" /></div>\
 98+ </div>',
 99+ ratelimited: '\
 100+ <div class="mw-moodBar-state mw-moodBar-state-error">\
 101+ <div class="mw-moodBar-state-title"><html:msg key="moodbar-ratelimited-title" /></div>\
 102+ <div class="mw-moodBar-state-subtitle"><html:msg key="moodbar-ratelimited-subtitle" /></div>\
 103+ </div>',
 104+ abuse: '\
 105+ <div class="mw-moodBar-state mw-moodBar-state-error">\
 106+ <div class="mw-moodBar-state-title"><html:msg key="moodbar-abuse-title" /></div>\
 107+ <div class="mw-moodBar-state-subtitle"><html:msg key="moodbar-abuse-subtitle" /></div>\
98108 </div>'
99109 },
100110
@@ -163,6 +173,16 @@
164174 setTimeout( function() {
165175 mb.ui.overlay.fadeOut();
166176 }, 3000 );
 177+ } else if (data && data.error && data.error.code === 'ratelimited') {
 178+ mb.swapContent( mb.tpl.ratelimited );
 179+ setTimeout( function() {
 180+ mb.ui.overlay.fadeOut();
 181+ }, 3000 );
 182+ } else if (data && data.error && data.error.code === 'abuse') {
 183+ mb.swapContent( mb.tpl.abuse );
 184+ setTimeout( function() {
 185+ mb.ui.overlay.fadeOut();
 186+ }, 3000 );
167187 } else {
168188 mb.swapContent( mb.tpl.error );
169189 }
Index: trunk/extensions/MoodBar/modules/ext.moodBar.dashboard/ext.moodBar.dashboard.js
@@ -731,7 +731,11 @@
732732 success: function (data) {
733733 // If rejected
734734 if ( data.error !== undefined ) {
735 - responseMessage( $item, 'error', mw.msg( 'response-ajax-error-head' ), data.error.info );
 735+ if ( data.error.code && data.error.code === 'abuse' ) {
 736+ responseMessage( $item, 'error', mw.msg( 'moodbar-abuse-title' ), mw.msg( 'moodbar-abuse-subtitle') );
 737+ } else {
 738+ responseMessage( $item, 'error', mw.msg( 'response-ajax-error-head' ), data.error.info );
 739+ }
736740 } else if ( data.feedbackdashboardresponse !== undefined ) {
737741 responseMessage( $item, 'success', mw.msg( 'response-ajax-success-head' ), mw.msg( 'response-ajax-success-body' ) );
738742 }
Index: trunk/extensions/MoodBar/MoodBar.php
@@ -164,6 +164,10 @@
165165 'moodbar-success-subtitle',
166166 'moodbar-blocked-title',
167167 'moodbar-blocked-subtitle',
 168+ 'moodbar-ratelimited-title',
 169+ 'moodbar-ratelimited-subtitle',
 170+ 'moodbar-abuse-title',
 171+ 'moodbar-abuse-subtitle',
168172 'moodbar-email-title',
169173 'moodbar-email-input',
170174 'moodbar-email-desc',
@@ -246,6 +250,25 @@
247251 /** The registration time after which users will be shown the MoodBar **/
248252 $wgMoodBarCutoffTime = null;
249253
 254+/** Rate limit setting for moodbar **/
 255+$wgMoodBarFeedbackRateLimit = 300;
 256+$wgMoodBarResponseRateLimit = 60;
 257+$wgRateLimits += array(
 258+ 'moodbar-feedback' => array( 'user' => array( 1 => $wgMoodBarFeedbackRateLimit ) ),
 259+ 'moodbar-response' => array( 'user' => array( 1 => $wgMoodBarResponseRateLimit ) )
 260+ );
 261+/**
 262+ * Turn on abuse filtering
 263+ *
 264+ * If this is set to true, feedback/response will be run through:
 265+ * 1. $wgSpamRegex, if set
 266+ * 2. SpamBlacklist, if installed
 267+ * 3. AbuseFilter, if installed
 268+ *
 269+ * @var boolean
 270+ */
 271+$wgMoodBarAbuseFiltering = true;
 272+
250273 /** MoodBar configuration settings **/
251274 $wgMoodBarConfig = array(
252275 'bucketConfig' =>

Sign-offs

UserFlagDate
Reedyinspected22:14, 15 March 2012
Nikerabbitinspected11:24, 16 March 2012
Robmoeninspected23:40, 20 March 2012

Follow-up revisions

RevisionCommit summaryAuthorDate
r113955followup to -r113953 - clean up javascript codebsitu20:53, 15 March 2012
r113984followup to -r113953 - remove misleading global variablesbsitu00:56, 16 March 2012
r114030MFT r113953, r113955, r113984, r114018reedy19:51, 16 March 2012

Comments

#Comment by Reedy (talk | contribs)   23:38, 15 March 2012

Looks fine to me. Just need someone to review the JS, then we can push it live and re-enable Moodbar

#Comment by Reedy (talk | contribs)   23:41, 15 March 2012

One criticism:

+/** Rate limit setting for moodbar **/
 	255	+$wgMoodBarFeedbackRateLimit = 300;
 	256	+$wgMoodBarResponseRateLimit = 60;
 	257	+$wgRateLimits += array( 
 	258	+	'moodbar-feedback' => array( 'user' => array( 1 => $wgMoodBarFeedbackRateLimit ) ),
 	259	+	'moodbar-response' => array( 'user' => array( 1 => $wgMoodBarResponseRateLimit ) )
 	260	+	);

Changing either $wgMoodBarFeedbackRateLimit or $wgMoodBarResponseRateLimit after including Moodbar is going to make no difference.

Do we just pass them by reference, or kill them completely, and just use something like the below to override it if they want to?

$wgRateLimits['moodbar-feedback'] = array( 'user' => array( 1 => 5000 ) );
#Comment by Bsitu (talk | contribs)   23:54, 15 March 2012

Moodbar code would not re-set the value of these two global variables, the error message may reference them.

#Comment by Reedy (talk | contribs)   00:31, 16 March 2012

I'm just wondering if this is likely to be misleading..

#Comment by Nikerabbit (talk | contribs)   11:24, 16 March 2012

I18n looks ok.

#Comment by Robmoen (talk | contribs)   23:39, 20 March 2012

JS looks good to me.

Status & tagging log