r84534 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r84533‎ | r84534 | r84535 >
Date:17:18, 22 March 2011
Author:happy-melon
Status:resolved (Comments)
Tags:
Comment:
(hopefully) last bit of heavy lifting in Block.php: now that we've internalised most of the variables, untangle their twisted connections to the database layer and remove various now-unused protected methods and variables.
Modified paths:
  • /trunk/extensions/TorBlock/TorBlock.class.php (modified) (history)
  • /trunk/phase3/includes/Block.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/Block.php
@@ -1,35 +1,33 @@
22 <?php
33 /**
4 - * @file
54 * Blocks and bans object
6 - */
7 -
8 -/**
9 - * The block class
10 - * All the functions in this class assume the object is either explicitly
11 - * loaded or filled. It is not load-on-demand. There are no accessors.
125 *
13 - * Globals used: $wgAutoblockExpiry, $wgAntiLockFlags
 6+ * This program is free software; you can redistribute it and/or modify
 7+ * it under the terms of the GNU General Public License as published by
 8+ * the Free Software Foundation; either version 2 of the License, or
 9+ * (at your option) any later version.
1410 *
15 - * @todo This could be used everywhere, but it isn't.
16 - * FIXME: this whole class is a cesspit, needs a complete rewrite
 11+ * This program is distributed in the hope that it will be useful,
 12+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 14+ * GNU General Public License for more details.
 15+ *
 16+ * You should have received a copy of the GNU General Public License along
 17+ * with this program; if not, write to the Free Software Foundation, Inc.,
 18+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 19+ * http://www.gnu.org/copyleft/gpl.html
 20+ *
 21+ * @file
1722 */
1823 class Block {
19 - /* public*/ var $mUser, $mReason, $mTimestamp, $mAuto, $mExpiry,
20 - $mHideName,
21 - $mAngryAutoblock;
 24+ /* public*/ var $mReason, $mTimestamp, $mAuto, $mExpiry, $mHideName, $mAngryAutoblock;
 25+
2226 protected
23 - $mAddress,
2427 $mId,
25 - $mBy,
26 - $mByName,
2728 $mFromMaster,
28 - $mRangeStart,
29 - $mRangeEnd,
30 - $mAnonOnly,
31 - $mEnableAutoblock,
 29+
3230 $mBlockEmail,
33 - $mAllowUsertalk,
 31+ $mDisableUsertalk,
3432 $mCreateAccount;
3533
3634 /// @var User|String
@@ -41,6 +39,12 @@
4240 /// @var User
4341 protected $blocker;
4442
 43+ /// @var Bool
 44+ protected $isHardblock = true;
 45+
 46+ /// @var Bool
 47+ protected $isAutoblocking = true;
 48+
4549 # TYPE constants
4650 const TYPE_USER = 1;
4751 const TYPE_IP = 2;
@@ -55,32 +59,32 @@
5660 */
5761 function __construct( $address = '', $user = 0, $by = 0, $reason = '',
5862 $timestamp = 0, $auto = 0, $expiry = '', $anonOnly = 0, $createAccount = 0, $enableAutoblock = 0,
59 - $hideName = 0, $blockEmail = 0, $allowUsertalk = 0, $byName = false )
 63+ $hideName = 0, $blockEmail = 0, $allowUsertalk = 0 )
6064 {
6165 if( $timestamp === 0 ){
6266 $timestamp = wfTimestampNow();
6367 }
6468
65 - $this->mId = 0;
66 - # Expand valid IPv6 addresses
67 - $address = IP::sanitizeIP( $address );
68 - $this->mAddress = $address;
69 - $this->mUser = $user;
70 - $this->mBy = $by;
 69+ if( count( func_get_args() ) > 0 ){
 70+ # Soon... :D
 71+ # wfDeprecated( __METHOD__ . " with arguments" );
 72+ }
 73+
 74+ $this->setTarget( $address );
 75+ $this->setBlocker( User::newFromID( $by ) );
7176 $this->mReason = $reason;
7277 $this->mTimestamp = wfTimestamp( TS_MW, $timestamp );
7378 $this->mAuto = $auto;
74 - $this->mAnonOnly = $anonOnly;
75 - $this->mCreateAccount = $createAccount;
 79+ $this->isHardblock( !$anonOnly );
 80+ $this->prevents( 'createaccount', $createAccount );
7681 $this->mExpiry = $expiry;
77 - $this->mEnableAutoblock = $enableAutoblock;
 82+ $this->isAutoblocking( $enableAutoblock );
7883 $this->mHideName = $hideName;
79 - $this->mBlockEmail = $blockEmail;
80 - $this->mAllowUsertalk = $allowUsertalk;
 84+ $this->prevents( 'sendemail', $blockEmail );
 85+ $this->prevents( 'editownusertalk', !$allowUsertalk );
 86+
8187 $this->mFromMaster = false;
82 - $this->mByName = $byName;
8388 $this->mAngryAutoblock = false;
84 - $this->initialiseRange();
8589 }
8690
8791 /**
@@ -92,15 +96,10 @@
9397 * @param $user Integer: user id of user
9498 * @param $killExpired Boolean: delete expired blocks on load
9599 * @return Block Object
 100+ * @deprecated since 1.18
96101 */
97 - public static function newFromDB( $address, $user = 0, $killExpired = true ) {
98 - $block = new Block;
99 - $block->load( $address, $user, $killExpired );
100 - if ( $block->isValid() ) {
101 - return $block;
102 - } else {
103 - return null;
104 - }
 102+ public static function newFromDB( $address, $user = 0 ) {
 103+ return self::newFromTarget( User::whoIs( $user ), $address );
105104 }
106105
107106 /**
@@ -111,34 +110,32 @@
112111 */
113112 public static function newFromID( $id ) {
114113 $dbr = wfGetDB( DB_SLAVE );
115 - $res = $dbr->resultObject( $dbr->select( 'ipblocks', '*',
116 - array( 'ipb_id' => $id ), __METHOD__ ) );
117 - $block = new Block;
118 -
119 - if ( $block->loadFromResult( $res ) ) {
120 - return $block;
121 - } else {
122 - return null;
123 - }
 114+ $res = $dbr->selectRow(
 115+ 'ipblocks',
 116+ '*',
 117+ array( 'ipb_id' => $id ),
 118+ __METHOD__
 119+ );
 120+ return Block::newFromRow( $res );
124121 }
125122
126123 /**
127 - * Check if two blocks are effectively equal
128 - *
 124+ * Check if two blocks are effectively equal. Doesn't check irrelevant things like
 125+ * the blocking user or the block timestamp, only things which affect the blocked user *
129126 * @return Boolean
130127 */
131128 public function equals( Block $block ) {
132129 return (
133 - $this->mAddress == $block->mAddress
134 - && $this->mUser == $block->mUser
 130+ (string)$this->target == (string)$block->target
 131+ && $this->type == $block->type
135132 && $this->mAuto == $block->mAuto
136 - && $this->mAnonOnly == $block->mAnonOnly
137 - && $this->mCreateAccount == $block->mCreateAccount
 133+ && $this->isHardblock() == $block->isHardblock()
 134+ && $this->prevents( 'createaccount' ) == $block->prevents( 'createaccount' )
138135 && $this->mExpiry == $block->mExpiry
139 - && $this->mEnableAutoblock == $block->mEnableAutoblock
 136+ && $this->isAutoblocking() == $block->isAutoblocking()
140137 && $this->mHideName == $block->mHideName
141 - && $this->mBlockEmail == $block->mBlockEmail
142 - && $this->mAllowUsertalk == $block->mAllowUsertalk
 138+ && $this->prevents( 'sendemail' ) == $block->prevents( 'sendemail' )
 139+ && $this->prevents( 'editownusertalk' ) == $block->prevents( 'editownusertalk' )
143140 && $this->mReason == $block->mReason
144141 );
145142 }
@@ -146,13 +143,10 @@
147144 /**
148145 * Clear all member variables in the current object. Does not clear
149146 * the block from the DB.
 147+ * @deprecated since 1.18
150148 */
151149 public function clear() {
152 - $this->mAddress = $this->mReason = $this->mTimestamp = '';
153 - $this->mId = $this->mAnonOnly = $this->mCreateAccount =
154 - $this->mEnableAutoblock = $this->mAuto = $this->mUser =
155 - $this->mBy = $this->mHideName = $this->mBlockEmail = $this->mAllowUsertalk = 0;
156 - $this->mByName = false;
 150+ # Noop
157151 }
158152
159153 /**
@@ -164,7 +158,7 @@
165159 * @return Boolean: the user is blocked from editing
166160 * @deprecated since 1.18
167161 */
168 - public function load( $address = '', $user = 0, $killExpired = true ) {
 162+ public function load( $address = '', $user = 0 ) {
169163 wfDeprecated( __METHOD__ );
170164 if( $user ){
171165 $username = User::whoIs( $user );
@@ -335,108 +329,27 @@
336330 }
337331
338332 /**
339 - * Fill in member variables from a result wrapper
340 - *
341 - * @param $res ResultWrapper: row from the ipblocks table
342 - * @param $killExpired Boolean: whether to delete expired rows while loading
343 - * @return Boolean
344 - */
345 - protected function loadFromResult( ResultWrapper $res, $killExpired = true ) {
346 - $ret = false;
347 -
348 - if ( 0 != $res->numRows() ) {
349 - # Get first block
350 - $row = $res->fetchObject();
351 - $this->initFromRow( $row );
352 -
353 - if ( $killExpired ) {
354 - # If requested, delete expired rows
355 - do {
356 - $killed = $this->deleteIfExpired();
357 - if ( $killed ) {
358 - $row = $res->fetchObject();
359 - if ( $row ) {
360 - $this->initFromRow( $row );
361 - }
362 - }
363 - } while ( $killed && $row );
364 -
365 - # If there were any left after the killing finished, return true
366 - if ( $row ) {
367 - $ret = true;
368 - }
369 - } else {
370 - $ret = true;
371 - }
372 - }
373 - $res->free();
374 -
375 - return $ret;
376 - }
377 -
378 - /**
379 - * Search the database for any range blocks matching the given address, and
380 - * load the row if one is found.
381 - *
382 - * @param $address String: IP address range
383 - * @param $killExpired Boolean: whether to delete expired rows while loading
384 - * @param $user Integer: if not 0, then sets ipb_anon_only
385 - * @return Boolean
386 - */
387 - protected function loadRange( $address, $killExpired = true, $user = 0 ) {
388 - $iaddr = IP::toHex( $address );
389 -
390 - if ( $iaddr === false ) {
391 - # Invalid address
392 - return false;
393 - }
394 -
395 - # Only scan ranges which start in this /16, this improves search speed
396 - # Blocks should not cross a /16 boundary.
397 - $range = substr( $iaddr, 0, 4 );
398 -
399 - $db = wfGetDB( $this->mFromMaster ? DB_MASTER : DB_SLAVE );
400 - $conds = array(
401 - 'ipb_range_start' . $db->buildLike( $range, $db->anyString() ),
402 - "ipb_range_start <= '$iaddr'",
403 - "ipb_range_end >= '$iaddr'"
404 - );
405 -
406 - if ( $user ) {
407 - $conds['ipb_anon_only'] = 0;
408 - }
409 -
410 - $res = $db->resultObject( $db->select( 'ipblocks', '*', $conds, __METHOD__ ) );
411 - $success = $this->loadFromResult( $res, $killExpired );
412 -
413 - return $success;
414 - }
415 -
416 - /**
417333 * Given a database row from the ipblocks table, initialize
418334 * member variables
419 - *
420335 * @param $row ResultWrapper: a row from the ipblocks table
421336 */
422337 protected function initFromRow( $row ) {
423 - list( $this->target, $this->type ) = self::parseTarget( $row->ipb_address );
424 -
425338 $this->setTarget( $row->ipb_address );
426339 $this->setBlocker( User::newFromId( $row->ipb_by ) );
427340
428341 $this->mReason = $row->ipb_reason;
429342 $this->mTimestamp = wfTimestamp( TS_MW, $row->ipb_timestamp );
430343 $this->mAuto = $row->ipb_auto;
431 - $this->mAnonOnly = $row->ipb_anon_only;
432 - $this->mCreateAccount = $row->ipb_create_account;
433 - $this->mEnableAutoblock = $row->ipb_enable_autoblock;
434 - $this->mBlockEmail = $row->ipb_block_email;
435 - $this->mAllowUsertalk = $row->ipb_allow_usertalk;
436344 $this->mHideName = $row->ipb_deleted;
437345 $this->mId = $row->ipb_id;
438346 $this->mExpiry = $row->ipb_expiry;
439 - $this->mRangeStart = $row->ipb_range_start;
440 - $this->mRangeEnd = $row->ipb_range_end;
 347+
 348+ $this->isHardblock( !$row->ipb_anon_only );
 349+ $this->isAutoblocking( $row->ipb_enable_autoblock );
 350+
 351+ $this->prevents( 'createaccount', $row->ipb_create_account );
 352+ $this->prevents( 'sendemail', $row->ipb_block_email );
 353+ $this->prevents( 'editownusertalk', !$row->ipb_allow_usertalk );
441354 }
442355
443356 /**
@@ -451,19 +364,6 @@
452365 }
453366
454367 /**
455 - * Once $mAddress has been set, get the range they came from.
456 - * Wrapper for IP::parseRange
457 - */
458 - protected function initialiseRange() {
459 - $this->mRangeStart = '';
460 - $this->mRangeEnd = '';
461 -
462 - if ( $this->mUser == 0 ) {
463 - list( $this->mRangeStart, $this->mRangeEnd ) = IP::parseRange( $this->mAddress );
464 - }
465 - }
466 -
467 - /**
468368 * Delete the row from the IP blocks table.
469369 *
470370 * @return Boolean
@@ -473,12 +373,12 @@
474374 return false;
475375 }
476376
477 - if ( !$this->mId ) {
478 - throw new MWException( "Block::delete() now requires that the mId member be filled\n" );
 377+ if ( !$this->getId() ) {
 378+ throw new MWException( "Block::delete() requires that the mId member be filled\n" );
479379 }
480380
481381 $dbw = wfGetDB( DB_MASTER );
482 - $dbw->delete( 'ipblocks', array( 'ipb_id' => $this->mId ), __METHOD__ );
 382+ $dbw->delete( 'ipblocks', array( 'ipb_id' => $this->getId() ), __METHOD__ );
483383
484384 return $dbw->affectedRows() > 0;
485385 }
@@ -497,35 +397,14 @@
498398 $dbw = wfGetDB( DB_MASTER );
499399 }
500400
501 - $this->validateBlockParams();
502 - $this->initialiseRange();
503 -
504401 # Don't collide with expired blocks
505402 Block::purgeExpired();
506403
507404 $ipb_id = $dbw->nextSequenceValue( 'ipblocks_ipb_id_seq' );
508405 $dbw->insert(
509406 'ipblocks',
510 - array(
511 - 'ipb_id' => $ipb_id,
512 - 'ipb_address' => $this->mAddress,
513 - 'ipb_user' => $this->mUser,
514 - 'ipb_by' => $this->mBy,
515 - 'ipb_by_text' => $this->mByName,
516 - 'ipb_reason' => $this->mReason,
517 - 'ipb_timestamp' => $dbw->timestamp( $this->mTimestamp ),
518 - 'ipb_auto' => $this->mAuto,
519 - 'ipb_anon_only' => $this->mAnonOnly,
520 - 'ipb_create_account' => $this->mCreateAccount,
521 - 'ipb_enable_autoblock' => $this->mEnableAutoblock,
522 - 'ipb_expiry' => $dbw->encodeExpiry( $this->mExpiry ),
523 - 'ipb_range_start' => $this->mRangeStart,
524 - 'ipb_range_end' => $this->mRangeEnd,
525 - 'ipb_deleted' => intval( $this->mHideName ), // typecast required for SQLite
526 - 'ipb_block_email' => $this->mBlockEmail,
527 - 'ipb_allow_usertalk' => $this->mAllowUsertalk
528 - ),
529 - 'Block::insert',
 407+ $this->getDatabaseArray(),
 408+ __METHOD__,
530409 array( 'IGNORE' )
531410 );
532411 $affected = $dbw->affectedRows();
@@ -546,62 +425,46 @@
547426 wfDebug( "Block::update; timestamp {$this->mTimestamp}\n" );
548427 $dbw = wfGetDB( DB_MASTER );
549428
550 - $this->validateBlockParams();
551 -
552429 $dbw->update(
553430 'ipblocks',
554 - array(
555 - 'ipb_user' => $this->mUser,
556 - 'ipb_by' => $this->mBy,
557 - 'ipb_by_text' => $this->mByName,
558 - 'ipb_reason' => $this->mReason,
559 - 'ipb_timestamp' => $dbw->timestamp( $this->mTimestamp ),
560 - 'ipb_auto' => $this->mAuto,
561 - 'ipb_anon_only' => $this->mAnonOnly,
562 - 'ipb_create_account' => $this->mCreateAccount,
563 - 'ipb_enable_autoblock' => $this->mEnableAutoblock,
564 - 'ipb_expiry' => $dbw->encodeExpiry( $this->mExpiry ),
565 - 'ipb_range_start' => $this->mRangeStart,
566 - 'ipb_range_end' => $this->mRangeEnd,
567 - 'ipb_deleted' => $this->mHideName,
568 - 'ipb_block_email' => $this->mBlockEmail,
569 - 'ipb_allow_usertalk' => $this->mAllowUsertalk
570 - ),
571 - array( 'ipb_id' => $this->mId ),
572 - 'Block::update'
 431+ $this->getDatabaseArray( $dbw ),
 432+ array( 'ipb_id' => $this->getId() ),
 433+ __METHOD__
573434 );
574435
575436 return $dbw->affectedRows();
576437 }
577438
578439 /**
579 - * Make sure all the proper members are set to sane values
580 - * before adding/updating a block
 440+ * Get an array suitable for passing to $dbw->insert() or $dbw->update()
 441+ * @param $db DatabaseBase
 442+ * @return Array
581443 */
582 - protected function validateBlockParams() {
583 - # Unset ipb_anon_only for user blocks, makes no sense
584 - if ( $this->mUser ) {
585 - $this->mAnonOnly = 0;
 444+ protected function getDatabaseArray( $db = null ){
 445+ if( !$db ){
 446+ $db = wfGetDB( DB_SLAVE );
586447 }
587448
588 - # Unset ipb_enable_autoblock for IP blocks, makes no sense
589 - if ( !$this->mUser ) {
590 - $this->mEnableAutoblock = 0;
591 - }
 449+ $a = array(
 450+ 'ipb_address' => (string)$this->target,
 451+ 'ipb_user' => $this->target instanceof User ? $this->target->getID() : 0,
 452+ 'ipb_by' => $this->getBlocker()->getId(),
 453+ 'ipb_by_text' => $this->getBlocker()->getName(),
 454+ 'ipb_reason' => $this->mReason,
 455+ 'ipb_timestamp' => $db->timestamp( $this->mTimestamp ),
 456+ 'ipb_auto' => $this->mAuto,
 457+ 'ipb_anon_only' => !$this->isHardblock(),
 458+ 'ipb_create_account' => $this->prevents( 'createaccount' ),
 459+ 'ipb_enable_autoblock' => $this->isAutoblocking(),
 460+ 'ipb_expiry' => $db->encodeExpiry( $this->mExpiry ),
 461+ 'ipb_range_start' => $this->getRangeStart(),
 462+ 'ipb_range_end' => $this->getRangeEnd(),
 463+ 'ipb_deleted' => intval( $this->mHideName ), // typecast required for SQLite
 464+ 'ipb_block_email' => $this->prevents( 'sendemail' ),
 465+ 'ipb_allow_usertalk' => !$this->prevents( 'editownusertalk' )
 466+ );
592467
593 - # bug 18860: non-anon-only IP blocks should be allowed to block email
594 - if ( !$this->mUser && $this->mAnonOnly ) {
595 - $this->mBlockEmail = 0;
596 - }
597 -
598 - if ( !$this->mByName ) {
599 - if ( $this->mBy ) {
600 - $this->mByName = User::whoIs( $this->mBy );
601 - } else {
602 - global $wgUser;
603 - $this->mByName = $wgUser->getName();
604 - }
605 - }
 468+ return $a;
606469 }
607470
608471 /**
@@ -617,11 +480,11 @@
618481 # If autoblock is enabled, autoblock the LAST IP used
619482 # - stolen shamelessly from CheckUser_body.php
620483
621 - if ( $this->mEnableAutoblock && $this->mUser ) {
622 - wfDebug( "Doing retroactive autoblocks for " . $this->mAddress . "\n" );
 484+ if ( $this->isAutoblocking() && $this->getType() == self::TYPE_USER ) {
 485+ wfDebug( "Doing retroactive autoblocks for " . $this->getTarget() . "\n" );
623486
624487 $options = array( 'ORDER BY' => 'rc_timestamp DESC' );
625 - $conds = array( 'rc_user_text' => $this->mAddress );
 488+ $conds = array( 'rc_user_text' => (string)$this->getTarget() );
626489
627490 if ( $this->mAngryAutoblock ) {
628491 // Block any IP used in the last 7 days. Up to five IPs.
@@ -653,6 +516,7 @@
654517
655518 /**
656519 * Checks whether a given IP is on the autoblock whitelist.
 520+ * TODO: this probably belongs somewhere else, but not sure where...
657521 *
658522 * @param $ip String: The IP to check
659523 * @return Boolean
@@ -703,12 +567,12 @@
704568 */
705569 public function doAutoblock( $autoblockIP, $justInserted = false ) {
706570 # If autoblocks are disabled, go away.
707 - if ( !$this->mEnableAutoblock ) {
 571+ if ( !$this->isAutoblocking() ) {
708572 return false;
709573 }
710574
711575 # Check for presence on the autoblock whitelist
712 - if ( Block::isWhitelistedFromAutoblocks( $autoblockIP ) ) {
 576+ if ( self::isWhitelistedFromAutoblocks( $autoblockIP ) ) {
713577 return false;
714578 }
715579
@@ -742,18 +606,16 @@
743607 }
744608
745609 # Make a new block object with the desired properties
746 - wfDebug( "Autoblocking {$this->mAddress}@" . $autoblockIP . "\n" );
747 - $ipblock->mAddress = $autoblockIP;
748 - $ipblock->mUser = 0;
749 - $ipblock->mBy = $this->mBy;
750 - $ipblock->mByName = $this->mByName;
751 - $ipblock->mReason = wfMsgForContent( 'autoblocker', $this->mAddress, $this->mReason );
 610+ wfDebug( "Autoblocking {$this->getTarget()}@" . $autoblockIP . "\n" );
 611+ $ipblock->setTarget( $autoblockIP );
 612+ $ipblock->setBlocker( $this->getBlocker() );
 613+ $ipblock->mReason = wfMsgForContent( 'autoblocker', $this->getTarget(), $this->mReason );
752614 $ipblock->mTimestamp = wfTimestampNow();
753615 $ipblock->mAuto = 1;
754616 $ipblock->mCreateAccount = $this->mCreateAccount;
755617 # Continue suppressing the name if needed
756618 $ipblock->mHideName = $this->mHideName;
757 - $ipblock->mAllowUsertalk = $this->mAllowUsertalk;
 619+ $ipblock->mDisableUsertalk = $this->mDisableUsertalk;
758620
759621 # If the user is already blocked with an expiry date, we don't
760622 # want to pile on top of that!
@@ -807,7 +669,7 @@
808670 * @return Boolean
809671 */
810672 public function isValid() {
811 - return $this->mAddress != '';
 673+ return $this->getTarget() != null;
812674 }
813675
814676 /**
@@ -823,9 +685,11 @@
824686 array( /* SET */
825687 'ipb_timestamp' => $dbw->timestamp( $this->mTimestamp ),
826688 'ipb_expiry' => $dbw->timestamp( $this->mExpiry ),
827 - ), array( /* WHERE */
828 - 'ipb_address' => $this->mAddress
829 - ), 'Block::updateTimestamp'
 689+ ),
 690+ array( /* WHERE */
 691+ 'ipb_address' => (string)$this->getTarget()
 692+ ),
 693+ __METHOD__
830694 );
831695 }
832696 }
@@ -841,7 +705,8 @@
842706 case self::TYPE_IP:
843707 return IP::toHex( $this->target );
844708 case self::TYPE_RANGE:
845 - return $this->mRangeStart;
 709+ list( $start, /*...*/ ) = IP::parseRange( $this->target );
 710+ return $start;
846711 default: throw new MWException( "Block with invalid type" );
847712 }
848713 }
@@ -857,7 +722,8 @@
858723 case self::TYPE_IP:
859724 return IP::toHex( $this->target );
860725 case self::TYPE_RANGE:
861 - return $this->mRangeEnd;
 726+ list( /*...*/, $end ) = IP::parseRange( $this->target );
 727+ return $end;
862728 default: throw new MWException( "Block with invalid type" );
863729 }
864730 }
@@ -868,7 +734,9 @@
869735 * @return Integer
870736 */
871737 public function getBy() {
872 - return $this->mBy;
 738+ return $this->getBlocker() instanceof User
 739+ ? $this->getBlocker()->getId()
 740+ : 0;
873741 }
874742
875743 /**
@@ -877,7 +745,9 @@
878746 * @return String
879747 */
880748 public function getByName() {
881 - return $this->mByName;
 749+ return $this->getBlocker() instanceof User
 750+ ? $this->getBlocker()->getName()
 751+ : null;
882752 }
883753
884754 /**
@@ -909,15 +779,22 @@
910780 * @return Bool
911781 */
912782 public function isHardblock( $x = null ) {
913 - $y = $this->mAnonOnly;
914 - if ( $x !== null ) {
915 - $this->mAnonOnly = !$x;
916 - }
917 - return !$y;
 783+ wfSetVar( $this->isHardblock, $x );
 784+
 785+ # You can't *not* hardblock a user
 786+ return $this->getType() == self::TYPE_USER
 787+ ? true
 788+ : $this->isHardblock;
918789 }
919790
920791 public function isAutoblocking( $x = null ) {
921 - return wfSetVar( $this->mEnableAutoblock, $x );
 792+ wfSetVar( $this->isAutoblocking, $x );
 793+
 794+ # You can't put an autoblock on an IP or range as we don't have any history to
 795+ # look over to get more IPs from
 796+ return $this->getType() == self::TYPE_USER
 797+ ? $this->isAutoblocking
 798+ : false;
922799 }
923800
924801 /**
@@ -939,11 +816,7 @@
940817 return wfSetVar( $this->mBlockEmail, $x );
941818
942819 case 'editownusertalk':
943 - $y = $this->mAllowUsertalk;
944 - if ( $x !== null ) {
945 - $this->mAllowUsertalk = !$x;
946 - }
947 - return !$y;
 820+ return wfSetVar( $this->mDisableUsertalk, $x );
948821
949822 default:
950823 return null;
@@ -962,7 +835,7 @@
963836 wfMessage( 'autoblockid', $this->mId )
964837 );
965838 } else {
966 - return htmlspecialchars( $this->mAddress );
 839+ return htmlspecialchars( $this->getTarget() );
967840 }
968841 }
969842
@@ -1064,8 +937,6 @@
1065938 return $expirystr;
1066939 }
1067940
1068 - # FIXME: everything above here is a mess, needs much cleaning up
1069 -
1070941 /**
1071942 * Convert a submitted expiry time, which may be relative ("2 weeks", etc) or absolute
1072943 * ("24 May 2034"), into an absolute timestamp we can put into the database.
@@ -1211,18 +1082,6 @@
12121083 */
12131084 public function setTarget( $target ){
12141085 list( $this->target, $this->type ) = self::parseTarget( $target );
1215 -
1216 - $this->mAddress = (string)$this->target;
1217 - if( $this->type == self::TYPE_USER ){
1218 - if( $this->target instanceof User ){
1219 - # Cheat
1220 - $this->mUser = $this->target->getID();
1221 - } else {
1222 - $this->mUser = User::idFromName( $this->target );
1223 - }
1224 - } else {
1225 - $this->mUser = 0;
1226 - }
12271086 }
12281087
12291088 /**
@@ -1239,8 +1098,5 @@
12401099 */
12411100 public function setBlocker( User $user ){
12421101 $this->blocker = $user;
1243 -
1244 - $this->mBy = $user->getID();
1245 - $this->mByName = $user->getName();
12461102 }
12471103 }
Index: trunk/extensions/TorBlock/TorBlock.class.php
@@ -200,7 +200,7 @@
201201 */
202202 public static function onGetBlockedStatus( &$user ) {
203203 global $wgTorDisableAdminBlocks;
204 - if ($wgTorDisableAdminBlocks && self::isExitNode() && $user->mBlock && !$user->mBlock->mUser) {
 204+ if ( $wgTorDisableAdminBlocks && self::isExitNode() && $user->mBlock && $user->mBlock->getType() != Block::TYPE_USER ) {
205205 wfDebug( "User using Tor node. Disabling IP block as it was probably targetted at the tor node." );
206206
207207 // Node is probably blocked for being a Tor node. Remove block.

Follow-up revisions

RevisionCommit summaryAuthorDate
r90137Fix for partial regression in r84534: Block::newFromId was no longer handling...brion19:05, 15 June 2011

Comments

#Comment by Aaron Schulz (talk | contribs)   02:10, 29 September 2011

The removal of $byName severaly broke CentralAuth crossWiki suppression blocks. A live hack is running on the WMF wikis. See: 01:20 logmsgbot: tstarling synchronized php-1.17/includes/specials/SpecialIpblocklist.php 'privacy patch'

CA relied on being able to set an arbitrary blocker name but with an ID of zero, which is slightly tricky to do now.

A hacky patch to fix CA is at http://pastebin.com/Ead2eYf3.

#Comment by Happy-melon (talk | contribs)   21:13, 29 September 2011

Presumably the blocking steward could have different IDs on different wikis. But will they definitely have an account on the local wiki, for which we could find the ID if we put our mind to it? Can stewards do blocks on wikis where they do not have a merged account?

#Comment by Brion VIBBER (talk | contribs)   22:38, 15 October 2011

Per Aaron these are blocks made from meta (the CentralAuth control host), and being read on other wikis. No guarantee that the stewards have ever visited that particular wiki.

#Comment by ArielGlenn (talk | contribs)   13:39, 29 September 2011
#Comment by Happy-melon (talk | contribs)   22:46, 6 October 2011

Does that patch actually work? My IDE complains about User::setItemLoaded() being private...

#Comment by Happy-melon (talk | contribs)   14:42, 7 October 2011

http://pastebin.com/ikAauVQs is the patch I would suggest to resolve the problem, but I do not have a working CentralAuth system set up to test it on. Would anyone mind having a look? It's basically the same method as the orgiginal patch, but a) suggests a long-term plan to resolve the issue more cleanly, and b) makes an attempt to find the steward's local id and uses it if possible. I think these blocks would be displayed wrongly in Special:BlockList (both with and without this patch), although since their entire purpose is to not be displayed, that's not a major concern.

#Comment by Aaron Schulz (talk | contribs)   22:20, 15 October 2011

They are displayed to Oversight users. They should still display the text name properly.

#Comment by Aaron Schulz (talk | contribs)   22:40, 15 October 2011

Looks like the "$byName = $byUser->getName();" line should just go in one place instead of two. Otherwise the patch looks sane (aside from not dealing with BlockList display).

#Comment by Aaron Schulz (talk | contribs)   22:42, 15 October 2011

Forgot to mention that the instanceof check and corresponding "else" are useless.

#Comment by Brion VIBBER (talk | contribs)   22:41, 15 October 2011
+                       $byUser = new self( $by );
+                       if( $byUser instanceof CentralAuthUser ){

Since this code is in CentralAuthUser, won't it by definition be a CentralAuthUser?

#Comment by Happy-melon (talk | contribs)   16:18, 19 October 2011

I was originally using one of the CAU factory methods which *could* return null. In the final implementation it is indeed superfluous.

#Comment by Brion VIBBER (talk | contribs)   22:57, 15 October 2011

Looks like it ought to work in theory, but it's a hack on a hack on a hack on a hack on a hack on a hack. The entire local suppression thingy seems to be abusing Block::insert's database parameter to insert blocks directly into a foreign database, which should generally not be done -- I don't _think_ there's any active corruption from it but it looks very scary.

Would probably recommend applying the live hack to trunk -- as it's been tested in production -- rather than increasing the amount of code without a solid refactor.

#Comment by Brion VIBBER (talk | contribs)   23:05, 15 October 2011

The live hack is not in the deployment branch. This is very bad. Cannot confirm what the current live hack code is.

#Comment by Happy-melon (talk | contribs)   16:19, 19 October 2011

Can someone please pull out the actual livehack code?

#Comment by Aaron Schulz (talk | contribs)   18:22, 19 October 2011

Done...but it is totally not suitable for trunk.

#Comment by Happy-melon (talk | contribs)   18:29, 19 October 2011

That's r100247, yes? I do see what you mean; and the problem is not actually what I thought it was: it's stewards' IP addresses being exposed, right?

#Comment by Brion VIBBER (talk | contribs)   22:09, 19 October 2011

Is that 1.17wmf1-only or is something like it also present on 1.18wmf1? Is the bug in both 1.17 and 1.18 or only in 1.18? What's the cause of the bug? What's saving an IP address instead of a username etc?

#Comment by Happy-melon (talk | contribs)   22:23, 19 October 2011

It's introduced in the blocking rewrite, so only 1.18wmf1. Basically:

  • CentralAuth is saving blocks into the foreign wikis' databases
  • In the new code Block takes a User object or userid rather than id/name separately
  • The User CentralAuth creates is given id 0 because the steward might not have an account on the foreign wiki
  • When Block->update() is called, it gets the user name and id from the User; because the userid is 0, the 'name' is the current IP address

What ultimately needs to happen is we need to be able to send $block->setBlocker() a ForeignUser subclassing User, which returns the steward's name from getName() but still returns getId() of 0 (or even better, returns the steward's actual ID if they do have a local account).

#Comment by Brion VIBBER (talk | contribs)   22:26, 19 October 2011

Ok, so this should not be in 1.17wmf1 and should be in 1.18wmf1?

Do the various patches submitted on the bug actually help resolve this?

Any plans on cleanup of DB, or should an output hack also be present forever?

#Comment by Happy-melon (talk | contribs)   23:13, 19 October 2011

I don't think it will do any harm in 1.17wmf1, but it shouldn't be necessary.

The patches both solve the immediate problem by ensuring that the steward's IP address is not saved into ipb_by_text. Once that is in place (and the DB is swept for existing instances) the output hack can be removed. There isn't anything wrong per se with the core code; it just doesn't play nicely with the CentralAuth code. There is no fundamental reason why anonymous users can't be given the block permission, in which case we would want to display their IPs.

What's needed is to ensure that CentralAuth is sending User objects with the correct data to $block->setBlocker(); currently that can be achieved by a hack (patches); there is scope for a nicer implementation. I could write that implementation if you'd like, but without a CentralAuth test environment for me to test it on it wouldn't be very productive.

#Comment by Happy-melon (talk | contribs)   22:39, 3 November 2011

Is this issue resolved by r100254??

#Comment by Aaron Schulz (talk | contribs)   22:42, 3 November 2011

And r101442, yes.

Status & tagging log