MediaWiki  master
resetAuthenticationThrottle.php
Go to the documentation of this file.
1 <?php
27 use Wikimedia\IPUtils;
28 
29 require_once __DIR__ . '/Maintenance.php';
30 
38 
39  public function __construct() {
40  parent::__construct();
41  $this->addDescription( 'Reset login/signup throttling for a specified user and/or IP. '
42  . "\n\n"
43  . 'When resetting signup only, provide the IP. When resetting login (or both), provide '
44  . 'both username (as entered in login screen) and IP. An easy way to obtain them is '
45  . "the 'throttler' log channel." );
46  $this->addOption( 'login', 'Reset login throttle' );
47  $this->addOption( 'signup', 'Reset account creation throttle' );
48  $this->addOption( 'user', 'Username to reset', false, true );
49  $this->addOption( 'ip', 'IP to reset', false, true );
50  }
51 
52  public function execute() {
53  $forLogin = (bool)$this->getOption( 'login' );
54  $forSignup = (bool)$this->getOption( 'signup' );
55  $username = $this->getOption( 'user' );
56  $ip = $this->getOption( 'ip' );
57 
58  if ( !$forLogin && !$forSignup ) {
59  $this->fatalError( 'At least one of --login and --signup is required!' );
60  } elseif ( $forLogin && ( $ip === null || $username === null ) ) {
61  $this->fatalError( '--user and --ip are both required when using --login!' );
62  } elseif ( $forSignup && $ip === null ) {
63  $this->fatalError( '--ip is required when using --signup!' );
64  } elseif ( $ip !== null && !IPUtils::isValid( $ip ) ) {
65  $this->fatalError( "Not a valid IP: $ip" );
66  }
67 
68  if ( $forLogin ) {
69  $this->clearLoginThrottle( $username, $ip );
70  }
71  if ( $forSignup ) {
72  $this->clearSignupThrottle( $ip );
73  }
74 
75  LoggerFactory::getInstance( 'throttler' )->info( 'Manually cleared {type} throttle', [
76  'type' => implode( ' and ', array_filter( [
77  $forLogin ? 'login' : null,
78  $forSignup ? 'signup' : null,
79  ] ) ),
80  'username' => $username,
81  'ipKey' => $ip,
82  ] );
83  }
84 
89  protected function clearLoginThrottle( $rawUsername, $ip ) {
90  $this->output( 'Clearing login throttle...' );
91 
92  $passwordAttemptThrottle = $this->getConfig()->get( MainConfigNames::PasswordAttemptThrottle );
93  if ( !$passwordAttemptThrottle ) {
94  $this->output( "none set\n" );
95  return;
96  }
97 
98  $throttler = new Throttler( $passwordAttemptThrottle, [
99  'type' => 'password',
101  ] );
102  if ( $rawUsername !== null ) {
103  $usernames = $this->getServiceContainer()->getAuthManager()
104  ->normalizeUsername( $rawUsername );
105  if ( !$usernames ) {
106  $this->fatalError( "Not a valid username: $rawUsername" );
107  }
108  } else {
109  $usernames = [ null ];
110  }
111  foreach ( $usernames as $username ) {
112  $throttler->clear( $username, $ip );
113  }
114 
115  $botPasswordThrottler = new Throttler( $passwordAttemptThrottle, [
116  'type' => 'botpassword',
118  ] );
119  // @phan-suppress-next-line PhanPossiblyUndeclaredVariable T240141
120  $botPasswordThrottler->clear( $username, $ip );
121 
122  $this->output( "done\n" );
123  }
124 
128  protected function clearSignupThrottle( $ip ) {
129  $this->output( 'Clearing signup throttle...' );
130 
131  $accountCreationThrottle = $this->getConfig()->get( MainConfigNames::AccountCreationThrottle );
132  if ( !is_array( $accountCreationThrottle ) ) {
133  $accountCreationThrottle = [ [
134  'count' => $accountCreationThrottle,
135  'seconds' => 86400,
136  ] ];
137  }
138  if ( !$accountCreationThrottle ) {
139  $this->output( "none set\n" );
140  return;
141  }
142  $throttler = new Throttler( $accountCreationThrottle, [
143  'type' => 'acctcreate',
145  ] );
146 
147  $throttler->clear( null, $ip );
148 
149  $this->output( "done\n" );
150  }
151 
152 }
153 
154 $maintClass = ResetAuthenticationThrottle::class;
155 require_once RUN_MAINTENANCE_IF_MAIN;
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
Definition: Maintenance.php:66
output( $out, $channel=null)
Throw some output to the user.
getServiceContainer()
Returns the main service container.
addDescription( $text)
Set the description text.
addOption( $name, $description, $required=false, $withArg=false, $shortName=false, $multiOccurrence=false)
Add a parameter to the script.
getOption( $name, $default=null)
Get an option, or return the default.
fatalError( $msg, $exitCode=1)
Output a message and terminate the current script.
PSR-3 logger instance factory.
A class containing constants representing the names of configuration variables.
static getLocalClusterInstance()
Get the main cluster-local cache object.
Reset login/signup throttling for a specified user and/or IP.