resetUserTokens.php 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. <?php
  2. /**
  3. * Reset the user_token for all users on the wiki. Useful if you believe
  4. * that your user table was acidentally leaked to an external source.
  5. *
  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.
  10. *
  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
  22. * @ingroup Maintenance
  23. * @author Daniel Friesen <mediawiki@danielfriesen.name>
  24. * @author Chris Steipp <csteipp@wikimedia.org>
  25. */
  26. require_once __DIR__ . '/Maintenance.php';
  27. /**
  28. * Maintenance script to reset the user_token for all users on the wiki.
  29. *
  30. * @ingroup Maintenance
  31. */
  32. class ResetUserTokens extends Maintenance {
  33. public function __construct() {
  34. parent::__construct();
  35. $this->addDescription(
  36. 'Reset the user_token of all users on the wiki. Note that this may log some of them out.'
  37. );
  38. $this->addOption( 'nowarn', "Hides the 5 seconds warning", false, false );
  39. $this->addOption(
  40. 'nulls',
  41. 'Only reset tokens that are currently null (string of \x00\'s)',
  42. false,
  43. false
  44. );
  45. $this->setBatchSize( 1000 );
  46. }
  47. public function execute() {
  48. $this->nullsOnly = $this->getOption( 'nulls' );
  49. if ( !$this->getOption( 'nowarn' ) ) {
  50. if ( $this->nullsOnly ) {
  51. $this->output( "The script is about to reset the user_token "
  52. . "for USERS WITH NULL TOKENS in the database.\n" );
  53. } else {
  54. $this->output( "The script is about to reset the user_token for ALL USERS in the database.\n" );
  55. $this->output( "This may log some of them out and is not necessary unless you believe your\n" );
  56. $this->output( "user table has been compromised.\n" );
  57. }
  58. $this->output( "\n" );
  59. $this->output( "Abort with control-c in the next five seconds "
  60. . "(skip this countdown with --nowarn) ... " );
  61. wfCountDown( 5 );
  62. }
  63. // We list user by user_id from one of the slave database
  64. $dbr = $this->getDB( DB_SLAVE );
  65. $where = [];
  66. if ( $this->nullsOnly ) {
  67. // Have to build this by hand, because \ is escaped in helper functions
  68. $where = [ 'user_token = \'' . str_repeat( '\0', 32 ) . '\'' ];
  69. }
  70. $maxid = $dbr->selectField( 'user', 'MAX(user_id)', [], __METHOD__ );
  71. $min = 0;
  72. $max = $this->mBatchSize;
  73. do {
  74. $result = $dbr->select( 'user',
  75. [ 'user_id' ],
  76. array_merge(
  77. $where,
  78. [ 'user_id > ' . $dbr->addQuotes( $min ),
  79. 'user_id <= ' . $dbr->addQuotes( $max )
  80. ]
  81. ),
  82. __METHOD__
  83. );
  84. foreach ( $result as $user ) {
  85. $this->updateUser( $user->user_id );
  86. }
  87. $min = $max;
  88. $max = $min + $this->mBatchSize;
  89. wfWaitForSlaves();
  90. } while ( $min <= $maxid );
  91. }
  92. private function updateUser( $userid ) {
  93. $user = User::newFromId( $userid );
  94. $username = $user->getName();
  95. $this->output( 'Resetting user_token for "' . $username . '": ' );
  96. // Change value
  97. $user->setToken();
  98. $user->saveSettings();
  99. $this->output( " OK\n" );
  100. }
  101. }
  102. $maintClass = "ResetUserTokens";
  103. require_once RUN_MAINTENANCE_IF_MAIN;