r100863 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r100862‎ | r100863 | r100864 >
Date:20:07, 26 October 2011
Author:cryptocoryne
Status:deferred (Comments)
Tags:
Comment:
Adding beta-version of extension 'AutoProxyBlock' to repo
Modified paths:
  • /trunk/extensions/AutoProxyBlock (added) (history)
  • /trunk/extensions/AutoProxyBlock/AutoProxyBlock.body.php (added) (history)
  • /trunk/extensions/AutoProxyBlock/AutoProxyBlock.i18n.php (added) (history)
  • /trunk/extensions/AutoProxyBlock/AutoProxyBlock.php (added) (history)

Diff [purge]

Index: trunk/extensions/AutoProxyBlock/AutoProxyBlock.body.php
@@ -0,0 +1,107 @@
 2+<?php
 3+
 4+class AutoProxyBlock {
 5+ function isProxy( $ip ) {
 6+ global $wgAutoProxyBlockSources;
 7+
 8+ if( isset($wgAutoProxyBlockSources['api']) ) {
 9+ foreach($wgAutoProxyBlockSources['api'] as $url) {
 10+ $request_options = array(
 11+ 'action' => 'query',
 12+ 'list' => 'blocks',
 13+ 'bkip' => "$ip",
 14+ 'bklimit' => '1',
 15+ 'bkprop' => 'expiry|reason',
 16+ );
 17+
 18+ $ban = self::requestForeighAPI($url, $request_options);
 19+ if( isset($ban['query']['blocks'][0]) && preg_match($wgAutoProxyBlockSources['key'], $ban['query']['blocks'][0]['reason']) ) {
 20+ return true;
 21+ }
 22+ }
 23+ }
 24+
 25+ if( isset($wgAutoProxyBlockSources['raw']) ) {
 26+ $list = array();
 27+ foreach($wgAutoProxyBlockSources['raw'] as $file) {
 28+ if( file_exists($file) ) {
 29+ $p = file($file);
 30+ if( $p ) {
 31+ array_merge($list, $p);
 32+ }
 33+ }
 34+ }
 35+
 36+ return in_array( $ip, array_unique($list) );
 37+ }
 38+
 39+ return false;
 40+ }
 41+
 42+ function checkProxy( $title, $user, $action, &$result ) {
 43+ global $wgProxyCanPerform, $wgAutoProxyBlockLog;
 44+
 45+ if( in_array( $action, $wgProxyCanPerform ) || $user->isAllowed('proxyunbannable') ) return true;
 46+
 47+ $IP = wfGetIP();
 48+ if( self::isProxy( $IP ) ) {
 49+ if($wgAutoProxyBlockLog) self::addInternalLogEntry( $IP, $title->mTextform, $user->mName, $action, $user );
 50+ $result[] = array( 'proxy-blocked', $IP );
 51+ return false;
 52+ }
 53+
 54+ return true;
 55+ }
 56+
 57+ function AFSetVar( &$vars, $title ) {
 58+ $vars->setVar( 'is_proxy', self::isProxy( wfGetIP() ) ? 1 : 0 );
 59+ return true;
 60+ }
 61+
 62+ function AFBuilderVars( &$builder ) {
 63+ $builder['vars']['is_proxy'] = 'is-proxy';
 64+ return true;
 65+ }
 66+
 67+ function tagProxyChange( $recentChange ) { // -> add check user rights
 68+ global $wgTagProxyActions, $wgUser;
 69+
 70+ if ( $wgTagProxyActions && self::isProxy( wfGetIP() ) && !$wgUser->isAllowed( 'notagproxychanges' ) ) {
 71+ ChangeTags::addTags( 'proxy', $recentChange->mAttribs['rc_id'], $recentChange->mAttribs['rc_this_oldid'], $recentChange->mAttribs['rc_logid'] );
 72+ }
 73+ return true;
 74+ }
 75+
 76+ function addProxyTag( &$emptyTags ) {
 77+ global $wgTagProxyActions;
 78+
 79+ if ( $wgTagProxyActions ) {
 80+ $emptyTags[] = 'proxy';
 81+ }
 82+ return true;
 83+ }
 84+
 85+ function addInternalLogEntry( $ip, $title, $user, $action, $object ) {
 86+ global $wgAutoProxyBlockLog;
 87+
 88+ if( !$object->isAllowed('notagproxychanges') ) {
 89+ $string = $ip . ' ' . $user . ' on page ' . $title . ' perform ' . $action . "\n";
 90+
 91+ $file = fopen($wgAutoProxyBlockLog, 'a');
 92+ fwrite($file, $string);
 93+ fclose($file);
 94+ }
 95+
 96+ return true;
 97+ }
 98+
 99+ function requestForeighAPI( $url, $options ) {
 100+ $url .= '?format=php';
 101+ foreach($options as $param => $value) {
 102+ $url .= '&'.$param.'='.$value;
 103+ }
 104+
 105+ $content = Http::get($url)
 106+ return unserialize($content);
 107+ }
 108+}
\ No newline at end of file
Property changes on: trunk/extensions/AutoProxyBlock/AutoProxyBlock.body.php
___________________________________________________________________
Added: svn:eol-style
1109 + native
Index: trunk/extensions/AutoProxyBlock/AutoProxyBlock.i18n.php
@@ -0,0 +1,18 @@
 2+<?php
 3+$messages = array();
 4+
 5+$messages['en'] = array(
 6+ 'autoproxyblock-desc' => 'Allows to block open proxies from performing actions in wiki',
 7+ 'proxy-blocked' => '$1 is listed as proxy, performed action aborted.',
 8+ 'abusefilter-edit-builder-vars-is-proxy' => 'True if this action was performed through a proxy',
 9+ 'tag-proxy' => 'action through proxy',
 10+ 'right-notagproxychanges' => 'protect from tagging edits through proxies as "proxy"',
 11+);
 12+
 13+$messages['ru'] = array(
 14+ 'autoproxyblock-desc' => 'Позволяет запрещать совершать действия в вики c открытых прокси',
 15+ 'proxy-blocked' => '$1 находится в списках прокси, действие отменено.',
 16+ 'abusefilter-edit-builder-vars-is-proxy' => 'Истинно, если действие совершено через прокси',
 17+ 'tag-proxy' => 'совершено через прокси',
 18+ 'right-notagproxychanges' => 'правки через прокси не отмечаются меткой',
 19+);
\ No newline at end of file
Property changes on: trunk/extensions/AutoProxyBlock/AutoProxyBlock.i18n.php
___________________________________________________________________
Added: svn:eol-style
120 + native
Index: trunk/extensions/AutoProxyBlock/AutoProxyBlock.php
@@ -0,0 +1,42 @@
 2+<?php
 3+if ( !defined( 'MEDIAWIKI' ) ) {
 4+ exit(1);
 5+}
 6+
 7+$dir = dirname(__FILE__);
 8+$wgExtensionCredits['antispam'][] = array(
 9+ 'path' => __FILE__,
 10+ 'name' => 'AutoProxyBlock',
 11+ 'author' => 'Cryptocoryne',
 12+ 'descriptionmsg' => 'autoproxyblock-desc',
 13+ 'url' => 'http://www.mediawiki.org/wiki/Extension:AutoProxyBlock',
 14+);
 15+
 16+$wgExtensionMessagesFiles['AutoProxyBlock'] = "$dir/AutoProxyBlock.i18n.php";
 17+$wgAutoloadClasses['AutoProxyBlock'] = "$dir/AutoProxyBlock.body.php";
 18+
 19+// protect special accounts from tagging proxy edits
 20+$wgAvailableRights[] = 'notagproxychanges';
 21+
 22+// set hooks
 23+$wgHooks['getUserPermissionsErrorsExpensive'][] = 'AutoProxyBlock::checkProxy';
 24+$wgHooks['RecentChange_save'][] = 'AutoProxyBlock::tagProxyChange';
 25+$wgHooks['ListDefinedTags'][] = 'AutoProxyBlock::addProxyTag';
 26+$wgHooks['AbuseFilter-filterAction'][] = 'AutoProxyBlock::AFSetVar';
 27+$wgHooks['AbuseFilter-builder'][] = 'AutoProxyBlock::AFBuilderVars';
 28+
 29+// array of actions, allowed to perform by proxy users
 30+$wgProxyCanPerform = array( 'read', 'edit', 'upload' );
 31+
 32+// add "proxy" tag to all edits, matched by this extension
 33+$wgTagProxyActions = true;
 34+
 35+// api is mediawiki api url, raw is local path to file with raw proxylist
 36+// key is regexp to check reason of block, retrieved from api
 37+$wgAutoProxyBlockSources = array();
 38+$wgAutoProxyBlockSources['api'][] = 'http://en.wikipedia.org/w/api.php';
 39+$wgAutoProxyBlockSources['raw'][] = '/var/www/mediawiki/proxy.list';
 40+$wgAutoProxyBlockSources['key'] = '/blocked proxy/i';
 41+
 42+// if set, log all blocked actions in file
 43+$wgAutoProxyBlockLog = false;
\ No newline at end of file
Property changes on: trunk/extensions/AutoProxyBlock/AutoProxyBlock.php
___________________________________________________________________
Added: svn:eol-style
144 + native

Follow-up revisions

RevisionCommit summaryAuthorDate
r100934Missing semicolon, ping r100863demon01:47, 27 October 2011
r100972Followup r100863, some improves and fixescryptocoryne13:23, 27 October 2011

Comments

#Comment by Jack Phoenix (talk | contribs)   21:33, 26 October 2011
  • There are some minor spacing/brace "issues", i.e. in AutoProxyBlock::checkProxy(), if( in_array( $action, $wgProxyCanPerform ) || $user->isAllowed('proxyunbannable') ) return true; should really be written like this to be perfectly in line with our coding standards:
if( in_array( $action, $wgProxyCanPerform ) || $user->isAllowed( 'proxyunbannable' ) ) {
	return true;
}
  • Also, in AutoProxyBlock::checkProxy(), calling the variable containing the result of wfGetIP() "$IP" is technically correct, but it's confusing, because there is already a global variable called $IP (which stands for Install Path), so I'd recommend changing that to something like $ipAddress or whatever you feel is suitable
    • 'bkip' => "$ip", is silly, you don't need the "double quotes" there (IIRC)
  • AutoProxyBlock::requestForeighAPI() seems like a hacky function that really shouldn't exist
    • On that note, there's a syntax error in that function (missing semicolon): $content = Http::get($url)
  • There are some long lines that could and should be split up, i.e. in AutoProxyBlock::tagProxyChange():
		if ( $wgTagProxyActions && self::isProxy( wfGetIP() ) && !$wgUser->isAllowed( 'notagproxychanges' ) ) {
			ChangeTags::addTags( 'proxy', $recentChange->mAttribs['rc_id'], $recentChange->mAttribs['rc_this_oldid'], $recentChange->mAttribs['rc_logid'] );
		}

would look better like this:

		if ( $wgTagProxyActions && self::isProxy( wfGetIP() ) && !$wgUser->isAllowed( 'notagproxychanges' ) ) {
			ChangeTags::addTags(
				'proxy',
				$recentChange->mAttribs['rc_id'],
				$recentChange->mAttribs['rc_this_oldid'],
				$recentChange->mAttribs['rc_logid']
			);
		}

Remember, space is cheap and readability is everything. :)

  • AutoProxyBlock::addInternalLogEntry() is somewhat hackish and it has hardcoded English. [[Extension:CheckUser|]] used to store its logged data in a text file on the server until it was rewritten to use a database table instead; I'm thinking that you could do something similar here (store the log data on a new database table and create a special page to view the data).
  • Having a version number in $wgExtensionCredits (the 'version' key) might be helpful
  • The AutoProxyBlock class is very scarcely commented...some comments would make reviewers' (and maybe even end-users') life a lot easier; for example, for me it's obvious that the function AFSetVar adds a new variable called is_proxy to AbuseFilter's list of available variables that the user can use in the edit filters, but it won't be obvious for most people reading the code, as I assume that most people aren't very familiar with AbuseFilter.
#Comment by Cryptocoryne (talk | contribs)   13:27, 27 October 2011

See r100972.

Core function LogPage::addEntry is broken for this extension due to MediaWiki Special:Log can't display log entries by anonymous users (with user ID 0).

About "AutoProxyBlock::requestForeighAPI": core has a functions to work with foreign MediaWiki APIs?

#Comment by Aaron Schulz (talk | contribs)   01:54, 27 October 2011

The foreign API requests should be cached in $wgMemc and the overall isProxy() check should have a simple process cache, like a static var. For testing though, you'd want to split up isProxy() into one function with without a process cache and another which is a wrapper around the former.

Status & tagging log