r47226 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r47225‎ | r47226 | r47227 >
Date:19:47, 13 February 2009
Author:aaron
Status:deferred
Tags:
Comment:
(bug 17018) Automated smallest-CIDR calculation from within Checkuser UI
Modified paths:
  • /trunk/extensions/CheckUser/CheckUser.i18n.php (modified) (history)
  • /trunk/extensions/CheckUser/CheckUser.php (modified) (history)
  • /trunk/extensions/CheckUser/CheckUser_body.php (modified) (history)
  • /trunk/extensions/CheckUser/checkuser.js (added) (history)

Diff [purge]

Index: trunk/extensions/CheckUser/CheckUser_body.php
@@ -116,6 +116,9 @@
117117 $this->doUserEditsRequest( $user, $reason, $period );
118118 }
119119 }
 120+ # Add CIDR calculation convenience form
 121+ $wgOut->addHTML( $this->addJsCIDRForm() );
 122+ $this->addStyles();
120123 }
121124
122125 /**
@@ -190,6 +193,15 @@
191194 $wgOut->addHTML( $form );
192195 }
193196
 197+ /**
 198+ * Add CSS/JS
 199+ */
 200+ protected function addStyles() {
 201+ global $wgScriptPath, $wgCheckUserStyleVersion, $wgOut;
 202+ $encJSFile = htmlspecialchars( "$wgScriptPath/extensions/CheckUser/checkuser.js?$wgCheckUserStyleVersion" );
 203+ $wgOut->addScript( "<script type=\"text/javascript\" src=\"$encJSFile\"></script>" );
 204+ }
 205+
194206 /**
195207 * Get a selector of time period options
196208 * @param int $selected, selected level
@@ -206,6 +218,20 @@
207219 }
208220
209221 /**
 222+ * Make a quick JS form for admins to calculate block ranges
 223+ */
 224+ protected function addJsCIDRForm() {
 225+ $s = '<fieldset id="mw-checkuser-cidrform" style="display:none;">'.
 226+ '<legend>'.wfMsgHtml('checkuser-cidr-label').'</legend>';
 227+ $s .= '<p><textarea id="mw-checkuser-iplist" rows="5" cols="80" onkeyup="updateCIDRresult()"></textarea></p>';
 228+ $s .= '<p>'.wfMsgHtml('checkuser-cidr-res') . '&nbsp;' .
 229+ Xml::input( 'mw-checkuser-ipres',35,'',array('id'=>'mw-checkuser-ipres') ) .
 230+ '<span id="mw-checkuser-ipnote"></span>';
 231+ $s .= '</p></fieldset>';
 232+ return $s;
 233+ }
 234+
 235+ /**
210236 * Block a list of selected users
211237 * @param array $users
212238 * @param string $reason
Index: trunk/extensions/CheckUser/CheckUser.i18n.php
@@ -35,6 +35,8 @@
3636 'checkuser-week-2' => 'last two weeks',
3737 'checkuser-month' => 'last 30 days',
3838 'checkuser-all' => 'all',
 39+ 'checkuser-cidr-label' => 'Find common range and affected addresses for a list of IPs',
 40+ 'checkuser-cidr-res' => 'Common CIDR:',
3941 'checkuser-empty' => 'The log contains no items.',
4042 'checkuser-nomatch' => 'No matches found.',
4143 'checkuser-nomatch-edits' => 'No matches found.
Index: trunk/extensions/CheckUser/CheckUser.php
@@ -34,6 +34,8 @@
3535 # Mass block limits
3636 $wgCheckUserMaxBlocks = 200;
3737
 38+$wgCheckUserStyleVersion = 1;
 39+
3840 # Recent changes data hook
3941 global $wgHooks;
4042 $wgHooks['RecentChange_save'][] = 'efUpdateCheckUserData';
Index: trunk/extensions/CheckUser/checkuser.js
@@ -0,0 +1,115 @@
 2+/* -- (c) Aaron Schulz 2009 */
 3+
 4+/* Every time you change this JS please bump $wgCheckUserStyleVersion in CheckUser.php */
 5+
 6+/*
 7+* This function calculates the common range of a list of
 8+* IPs. It should be set to update on keyUp.
 9+*/
 10+function updateCIDRresult() {
 11+ var form = document.getElementById( 'mw-checkuser-cidrform' );
 12+ if( !form ) return; // no JS form
 13+ form.style.display = 'inline'; // unhide form (JS active)
 14+ var iplist = document.getElementById( 'mw-checkuser-iplist' );
 15+ if( !iplist ) return; // no JS form
 16+ // Each line has one IP or range
 17+ var ips = iplist.value.split("\n");
 18+ var bin_prefix = 0;
 19+ // Go through each IP in the list, get it's binary form, and track
 20+ // the largest binary prefix among them
 21+ for( i=0; i<ips.length; i++ ) {
 22+ // ...in the spirit of block.js, call this "addy"
 23+ var addy = ips[i];
 24+ // Match the first IP in each list (ignore other garbage)
 25+ var ipV4 = addy.match(/\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(\/\d+)?\b/);
 26+ var ipV6 = addy.match(/\b(:(:[0-9A-Fa-f]{1,4}){1,7}|[0-9A-Fa-f]{1,4}(:{1,2}[0-9A-Fa-f]{1,4}|::$){1,7})(\/\d+)?\b/);
 27+ // Binary form
 28+ var bin = new String( "" );
 29+ // Convert the IP to binary form
 30+ if( ipV4 ) {
 31+ var ip = ipV4[1];
 32+ var cidr = ipV4[2]; // CIDR, if it exists
 33+ // Get each quad integer
 34+ var blocs = ip.split('.');
 35+ for( x=0; x<blocs.length; x++ ) {
 36+ bloc = parseInt( blocs[x], 10 );
 37+ if( bloc > 255 ) continue; // bad IP!
 38+ bin_block = bloc.toString(2); // concat bin with binary form of bloc
 39+ while( bin_block.length < 8 ) {
 40+ bin_block = "0" + bin_block; // pad out as needed
 41+ }
 42+ bin += bin_block;
 43+ }
 44+ // Apply any valid CIDRs
 45+ if( cidr ) {
 46+ cidr = cidr.match( /\d+$/ )[0]; // get rid of slash
 47+ if( cidr >= 16 ) bin = bin.substring(0,cidr); // truncate bin
 48+ }
 49+ // Init bin_prefix
 50+ if( bin_prefix === 0 ) {
 51+ bin_prefix = new String( bin );
 52+ // Get largest common bin_prefix
 53+ } else {
 54+ for( x=0; x<bin_prefix.length; x++ ) {
 55+ if( bin_prefix[x] != bin[x] ) {
 56+ bin_prefix = bin_prefix.substring(0,x); // shorten bin_prefix
 57+ break;
 58+ }
 59+ }
 60+ }
 61+ // Build the IP in CIDR form
 62+ var prefix_cidr = bin_prefix.length;
 63+ // CIDR too small?
 64+ if( prefix_cidr < 16 ) {
 65+ document.getElementById( 'mw-checkuser-ipres' ).value = "!";
 66+ document.getElementById( 'mw-checkuser-ipnote' ).innerHTML = '';
 67+ return; // too big
 68+ }
 69+ var prefix = new String( "" );
 70+ // First bloc (/8)
 71+ var bloc = 0;
 72+ for( x=0; x<=7; x++ ) {
 73+ bloc += parseInt(bin_prefix[x],10)*Math.pow(2,7-x);
 74+ }
 75+ prefix += bloc + '.';
 76+ // Second bloc (/16)
 77+ var bloc = 0;
 78+ for( x=8; x<=15; x++ ) {
 79+ bloc += parseInt(bin_prefix[x],10)*Math.pow(2,15-x);
 80+ }
 81+ prefix += bloc + '.';
 82+ // Third bloc (/24)
 83+ var bloc = 0;
 84+ for( x=16; x<=23; x++ ) {
 85+ if( bin_prefix[x] == undefined ) break;
 86+ bloc += parseInt(bin_prefix[x],10)*Math.pow(2,23-x);
 87+ }
 88+ prefix += bloc + '.';
 89+ // First bloc (/32)
 90+ var bloc = 0;
 91+ for( x=24; x<=31; x++ ) {
 92+ if( bin_prefix[x] == undefined ) break;
 93+ bloc += parseInt(bin_prefix[x],10)*Math.pow(2,31-x);
 94+ }
 95+ prefix += bloc;
 96+ document.getElementById( 'mw-checkuser-ipres' ).value = prefix + '/' + prefix_cidr;
 97+ // Get IPs affected
 98+ ip_count = Math.pow(2,32-prefix_cidr);
 99+ document.getElementById( 'mw-checkuser-ipnote' ).innerHTML = '&nbsp;~' + ip_count;
 100+ }
 101+ /*
 102+ TODO: IPv6
 103+ } else if( isIpV6 ) {
 104+ var ip = ipV6[1];
 105+ var cidr = ipV6[2];
 106+ // Get each quad integer
 107+ var blocs = ip.split(':');
 108+ for( x=0; x<blocs.length; x++ ) {
 109+ if( blocs[x] > "ffff" ) continue; // bad IP!
 110+ }
 111+ }
 112+ */
 113+ }
 114+
 115+}
 116+addOnloadHook( updateCIDRresult );
Property changes on: trunk/extensions/CheckUser/checkuser.js
___________________________________________________________________
Name: svn:eol-style
1117 + native

Follow-up revisions

RevisionCommit summaryAuthorDate
r51179(bug 17018) Made IP validation more robust. Also fixed bug that were no range...aaron06:55, 30 May 2009

Status & tagging log