resetUserTokens.php 3.7 KB

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