Index: branches/wmf/1.18wmf1/maintenance/findBug32198.php |
— | — | @@ -0,0 +1,27 @@ |
| 2 | +<?php |
| 3 | +require_once( dirname( __FILE__ ) . '/Maintenance.php' ); |
| 4 | + |
| 5 | +class FindBug32198 extends Maintenance { |
| 6 | + public function __construct() { |
| 7 | + parent::__construct(); |
| 8 | + $this->mDescription = "Find rows with ipb_by=0 and ibp_by_text=<IP address>"; |
| 9 | + } |
| 10 | + |
| 11 | + function execute() { |
| 12 | + $epoch = '20110900000000'; // Sept 2011 |
| 13 | + |
| 14 | + $db = wfGetDB( DB_SLAVE ); |
| 15 | + $res = $db->select( 'ipblocks', '*', |
| 16 | + array( 'ipb_by' => 0, 'ipb_timestamp > ' . $db->addQuotes( $db->timestamp( $epoch ) ) ), |
| 17 | + __METHOD__ |
| 18 | + ); |
| 19 | + foreach ( $res as $row ) { |
| 20 | + if ( IP::isIPAddress( $row->ipb_by_text ) ) { |
| 21 | + $this->output( "{$row->ipb_id} {$row->ipb_by_text} {$row->ipb_timestamp}\n" ); |
| 22 | + } |
| 23 | + } |
| 24 | + } |
| 25 | +} |
| 26 | + |
| 27 | +$maintClass = "FindBug32198"; |
| 28 | +require_once( RUN_MAINTENANCE_IF_MAIN ); |
Index: branches/wmf/1.18wmf1/maintenance/fixBug32198.php |
— | — | @@ -0,0 +1,91 @@ |
| 2 | +<?php |
| 3 | +require_once( dirname( __FILE__ ) . '/Maintenance.php' ); |
| 4 | + |
| 5 | +class FixBug32198 extends Maintenance { |
| 6 | + public function __construct() { |
| 7 | + parent::__construct(); |
| 8 | + $this->mDescription = "Fix rows with ipb_by=0 and ibp_by_text=<IP address>"; |
| 9 | + } |
| 10 | + |
| 11 | + function execute() { |
| 12 | + global $wgDBname; |
| 13 | + $epoch = '20110900000000'; // Sept 2011 |
| 14 | + |
| 15 | + if ( $wgDBname !== 'metawiki' ) { |
| 16 | + die( "Must run on metawiki.\n" ); // sanity |
| 17 | + } |
| 18 | + |
| 19 | + $fixedBlockees = array(); |
| 20 | + |
| 21 | + $db = wfGetDB( DB_SLAVE ); |
| 22 | + $res = $db->select( 'logging', '*', |
| 23 | + array( |
| 24 | + 'log_type' => 'suppress', |
| 25 | + 'log_action' => 'setstatus', |
| 26 | + 'log_namespace' => NS_USER, // sanity |
| 27 | + 'log_timestamp > ' . $db->addQuotes( $db->timestamp( $epoch ) ) ), |
| 28 | + __METHOD__, |
| 29 | + array( 'ORDER BY' => 'log_timestamp DESC' ) // different admins may change blocks |
| 30 | + ); |
| 31 | + |
| 32 | + $this->output( "Scanning {$res->numRows()} CentralAuth suppress block log rows...\n" ); |
| 33 | + |
| 34 | + $blocksFixed = 0; |
| 35 | + foreach ( $res as $row ) { |
| 36 | + $m = explode( '@', $row->log_title ); |
| 37 | + if ( count( $m ) != 2 || $m[1] !== 'global' ) { |
| 38 | + continue; // not global |
| 39 | + } |
| 40 | + $blockeeName = Title::makeTitle( NS_USER, $m[0] )->getText(); // the bad username |
| 41 | + // Given the ORDER BY clause in the logging table query, we can make sure |
| 42 | + // that the last admin to change the block status of a user "owns" it via |
| 43 | + // ipb_by_text. If we hit changes to the block status for the same user again |
| 44 | + // we will have already set $fixedBlockees and will skip it. |
| 45 | + if ( isset( $fixedBlockees[$blockeeName] ) ) { |
| 46 | + $blocksFixed++; // blocking admin name already set |
| 47 | + $this->output( "Skipped a block of `{$blockeeName}`, block was later overridden.\n" ); |
| 48 | + continue; |
| 49 | + } |
| 50 | + $blockee = new CentralAuthUser( $blockeeName ); // the bad user |
| 51 | + |
| 52 | + $blockerName = $row->log_user_text; // the blocking admin |
| 53 | + |
| 54 | + $rowsFixedForBlock = 0; |
| 55 | + // Search block log on all wikis with local accounts for this user... |
| 56 | + foreach ( $blockee->listAttached() as $wiki ) { |
| 57 | + $wikiDB = wfGetDB( DB_MASTER, array(), $wiki ); // DB used by $wiki |
| 58 | + // Dry run |
| 59 | + $res = $wikiDB->select( 'ipblocks', '*', |
| 60 | + array( |
| 61 | + 'ipb_address' => $blockeeName, |
| 62 | + 'ipb_by' => 0, |
| 63 | + 'ipb_timestamp > ' . $wikiDB->addQuotes( $wikiDB->timestamp( $epoch ) ) ), |
| 64 | + __METHOD__ |
| 65 | + ); |
| 66 | + $rowsFixedForBlock = $res->numRows(); |
| 67 | + /* |
| 68 | + $wikiDB->update( 'ipblocks', |
| 69 | + array( 'ipb_by_text' => $blockerName ), |
| 70 | + array( |
| 71 | + 'ipb_address' => $blockeeName, |
| 72 | + 'ipb_by' => 0, |
| 73 | + 'ipb_timestamp > ' . $wikiDB->addQuotes( $wikiDB->timestamp( $epoch ) ) ), |
| 74 | + __METHOD__ |
| 75 | + ); |
| 76 | + */ |
| 77 | + unset( $wikiDB ); // outer loop is fast so this is just for fun :) |
| 78 | + } |
| 79 | + |
| 80 | + if ( $res->numRows() ) { // normally 1 row |
| 81 | + $this->output( "Fixed $rowsFixedForBlock row(s) for `{$blockeeName}` on $wiki.\n" ); |
| 82 | + } |
| 83 | + |
| 84 | + $blocksFixed++; |
| 85 | + } |
| 86 | + |
| 87 | + $this->output( "...done [fixed $blocksFixed global suppress blocks]\n" ); |
| 88 | + } |
| 89 | +} |
| 90 | + |
| 91 | +$maintClass = "FixBug32198"; |
| 92 | +require_once( RUN_MAINTENANCE_IF_MAIN ); |