MediaWiki  master
resetUserTokens.php
Go to the documentation of this file.
1 <?php
27 require_once __DIR__ . '/Maintenance.php';
28 
36  public function __construct() {
37  parent::__construct();
38  $this->addDescription(
39  "Reset the user_token of all users on the wiki. Note that this may log some of them out.\n"
40  . "Deprecated, use \$wgAuthenticationTokenVersion instead."
41  );
42  $this->addOption( 'nowarn', "Hides the 5 seconds warning", false, false );
43  $this->addOption(
44  'nulls',
45  'Only reset tokens that are currently null (string of \x00\'s)',
46  false,
47  false
48  );
49  $this->setBatchSize( 1000 );
50  }
51 
52  public function execute() {
53  $nullsOnly = $this->getOption( 'nulls' );
54 
55  if ( !$this->getOption( 'nowarn' ) ) {
56  if ( $nullsOnly ) {
57  $this->output( "The script is about to reset the user_token "
58  . "for USERS WITH NULL TOKENS in the database.\n" );
59  } else {
60  $this->output( "The script is about to reset the user_token for ALL USERS in the database.\n" );
61  $this->output( "This may log some of them out and is not necessary unless you believe your\n" );
62  $this->output( "user table has been compromised.\n" );
63  }
64  $this->output( "\n" );
65  $this->output( "Abort with control-c in the next five seconds "
66  . "(skip this countdown with --nowarn) ... " );
67  $this->countDown( 5 );
68  }
69 
70  // We list user by user_id from one of the replica DBs
71  $dbr = $this->getDB( DB_REPLICA );
72 
73  $where = [];
74  if ( $nullsOnly ) {
75  // Have to build this by hand, because \ is escaped in helper functions
76  $where = [ 'user_token = \'' . str_repeat( '\0', 32 ) . '\'' ];
77  }
78 
79  $maxid = $dbr->selectField( 'user', 'MAX(user_id)', [], __METHOD__ );
80 
81  $min = 0;
82  $max = $this->getBatchSize();
83 
84  do {
85  $result = $dbr->select( 'user',
86  [ 'user_id' ],
87  array_merge(
88  $where,
89  [ 'user_id > ' . $dbr->addQuotes( $min ),
90  'user_id <= ' . $dbr->addQuotes( $max )
91  ]
92  ),
93  __METHOD__
94  );
95 
96  foreach ( $result as $user ) {
97  $this->updateUser( $user->user_id );
98  }
99 
100  $min = $max;
101  $max = $min + $this->getBatchSize();
102 
103  wfWaitForSlaves();
104  } while ( $min <= $maxid );
105  }
106 
107  private function updateUser( $userid ) {
108  $user = User::newFromId( $userid );
109  $username = $user->getName();
110  $this->output( 'Resetting user_token for "' . $username . '": ' );
111  // Change value
112  $user->setToken();
113  $user->saveSettings();
114  $this->output( " OK\n" );
115  }
116 }
117 
118 $maintClass = ResetUserTokens::class;
119 require_once RUN_MAINTENANCE_IF_MAIN;
const RUN_MAINTENANCE_IF_MAIN
Definition: Maintenance.php:39
getOption( $name, $default=null)
Get an option, or return the default.
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
Definition: Maintenance.php:82
setBatchSize( $s=0)
Set the batch size.
Maintenance script to reset the user_token for all users on the wiki.
wfWaitForSlaves( $ifWritesSince=null, $wiki=false, $cluster=false, $timeout=null)
Waits for the replica DBs to catch up to the master position.
addDescription( $text)
Set the description text.
output( $out, $channel=null)
Throw some output to the user.
static newFromId( $id)
Static factory method for creation from a given user ID.
Definition: User.php:539
$maintClass
getBatchSize()
Returns batch size.
countDown( $seconds)
Count down from $seconds to zero on the terminal, with a one-second pause between showing each number...
addOption( $name, $description, $required=false, $withArg=false, $shortName=false, $multiOccurrence=false)
Add a parameter to the script.
const DB_REPLICA
Definition: defines.php:25
getDB( $db, $groups=[], $dbDomain=false)
Returns a database to be used by current maintenance script.