3 namespace MediaWiki\Auth
;
8 * @covers MediaWiki\Auth\ThrottlePreAuthenticationProvider
10 class ThrottlePreAuthenticationProviderTest
extends \MediaWikiTestCase
{
11 public function testConstructor() {
12 $provider = new ThrottlePreAuthenticationProvider();
13 $providerPriv = \TestingAccessWrapper
::newFromObject( $provider );
14 $config = new \
HashConfig( [
15 'AccountCreationThrottle' => 123,
16 'PasswordAttemptThrottle' => [ [
21 $provider->setConfig( $config );
23 'accountCreationThrottle' => [ [ 'count' => 123, 'seconds' => 86400 ] ],
24 'passwordAttemptThrottle' => [ [ 'count' => 5, 'seconds' => 300 ] ]
25 ], $providerPriv->throttleSettings
);
26 $accountCreationThrottle = \TestingAccessWrapper
::newFromObject(
27 $providerPriv->accountCreationThrottle
);
28 $this->assertSame( [ [ 'count' => 123, 'seconds' => 86400 ] ],
29 $accountCreationThrottle->conditions
);
30 $passwordAttemptThrottle = \TestingAccessWrapper
::newFromObject(
31 $providerPriv->passwordAttemptThrottle
);
32 $this->assertSame( [ [ 'count' => 5, 'seconds' => 300 ] ],
33 $passwordAttemptThrottle->conditions
);
35 $provider = new ThrottlePreAuthenticationProvider( [
36 'accountCreationThrottle' => [ [ 'count' => 43, 'seconds' => 10000 ] ],
37 'passwordAttemptThrottle' => [ [ 'count' => 11, 'seconds' => 100 ] ],
39 $providerPriv = \TestingAccessWrapper
::newFromObject( $provider );
40 $config = new \
HashConfig( [
41 'AccountCreationThrottle' => 123,
42 'PasswordAttemptThrottle' => [ [
47 $provider->setConfig( $config );
49 'accountCreationThrottle' => [ [ 'count' => 43, 'seconds' => 10000 ] ],
50 'passwordAttemptThrottle' => [ [ 'count' => 11, 'seconds' => 100 ] ],
51 ], $providerPriv->throttleSettings
);
53 $cache = new \
HashBagOStuff();
54 $provider = new ThrottlePreAuthenticationProvider( [ 'cache' => $cache ] );
55 $providerPriv = \TestingAccessWrapper
::newFromObject( $provider );
56 $provider->setConfig( new \
HashConfig( [
57 'AccountCreationThrottle' => [ [ 'count' => 1, 'seconds' => 1 ] ],
58 'PasswordAttemptThrottle' => [ [ 'count' => 1, 'seconds' => 1 ] ],
60 $accountCreationThrottle = \TestingAccessWrapper
::newFromObject(
61 $providerPriv->accountCreationThrottle
);
62 $this->assertSame( $cache, $accountCreationThrottle->cache
);
63 $passwordAttemptThrottle = \TestingAccessWrapper
::newFromObject(
64 $providerPriv->passwordAttemptThrottle
);
65 $this->assertSame( $cache, $passwordAttemptThrottle->cache
);
68 public function testDisabled() {
69 $provider = new ThrottlePreAuthenticationProvider( [
70 'accountCreationThrottle' => [],
71 'passwordAttemptThrottle' => [],
72 'cache' => new \
HashBagOStuff(),
74 $provider->setLogger( new \Psr\Log\
NullLogger() );
75 $provider->setConfig( new \
HashConfig( [
76 'AccountCreationThrottle' => null,
77 'PasswordAttemptThrottle' => null,
79 $provider->setManager( AuthManager
::singleton() );
82 \StatusValue
::newGood(),
83 $provider->testForAccountCreation(
84 \User
::newFromName( 'Created' ),
85 \User
::newFromName( 'Creator' ),
90 \StatusValue
::newGood(),
91 $provider->testForAuthentication( [] )
96 * @dataProvider provideTestForAccountCreation
97 * @param string $creatorname
98 * @param bool $succeed
101 public function testTestForAccountCreation( $creatorname, $succeed, $hook ) {
102 $provider = new ThrottlePreAuthenticationProvider( [
103 'accountCreationThrottle' => [ [ 'count' => 2, 'seconds' => 86400 ] ],
104 'cache' => new \
HashBagOStuff(),
106 $provider->setLogger( new \Psr\Log\
NullLogger() );
107 $provider->setConfig( new \
HashConfig( [
108 'AccountCreationThrottle' => null,
109 'PasswordAttemptThrottle' => null,
111 $provider->setManager( AuthManager
::singleton() );
113 $user = \User
::newFromName( 'RandomUser' );
114 $creator = \User
::newFromName( $creatorname );
116 $mock = $this->getMock( 'stdClass', [ 'onExemptFromAccountCreationThrottle' ] );
117 $mock->expects( $this->any() )->method( 'onExemptFromAccountCreationThrottle' )
118 ->will( $this->returnValue( false ) );
119 $this->mergeMwGlobalArrayValue( 'wgHooks', [
120 'ExemptFromAccountCreationThrottle' => [ $mock ],
125 \StatusValue
::newGood(),
126 $provider->testForAccountCreation( $user, $creator, [] ),
130 \StatusValue
::newGood(),
131 $provider->testForAccountCreation( $user, $creator, [] ),
135 $succeed ? \StatusValue
::newGood() : \StatusValue
::newFatal( 'acct_creation_throttle_hit', 2 ),
136 $provider->testForAccountCreation( $user, $creator, [] ),
141 public static function provideTestForAccountCreation() {
143 'Normal user' => [ 'NormalUser', false, false ],
144 'Sysop' => [ 'UTSysop', true, false ],
145 'Normal user with hook' => [ 'NormalUser', true, true ],
149 public function testTestForAuthentication() {
150 $provider = new ThrottlePreAuthenticationProvider( [
151 'passwordAttemptThrottle' => [ [ 'count' => 2, 'seconds' => 86400 ] ],
152 'cache' => new \
HashBagOStuff(),
154 $provider->setLogger( new \Psr\Log\
NullLogger() );
155 $provider->setConfig( new \
HashConfig( [
156 'AccountCreationThrottle' => null,
157 'PasswordAttemptThrottle' => null,
159 $provider->setManager( AuthManager
::singleton() );
161 $req = new UsernameAuthenticationRequest
;
162 $req->username
= 'SomeUser';
163 for ( $i = 1; $i <= 3; $i++
) {
164 $status = $provider->testForAuthentication( [ $req ] );
165 $this->assertEquals( $i < 3, $status->isGood(), "attempt #$i" );
167 $this->assertCount( 1, $status->getErrors() );
168 $msg = new \
Message( $status->getErrors()[0]['message'], $status->getErrors()[0]['params'] );
169 $this->assertEquals( 'login-throttled', $msg->getKey() );
171 $provider->postAuthentication( \User
::newFromName( 'SomeUser' ),
172 AuthenticationResponse
::newFail( wfMessage( 'foo' ) ) );
173 $this->assertFalse( $provider->testForAuthentication( [ $req ] )->isGood(), 'after FAIL' );
175 $provider->postAuthentication( \User
::newFromName( 'SomeUser' ),
176 AuthenticationResponse
::newPass() );
177 $this->assertTrue( $provider->testForAuthentication( [ $req ] )->isGood(), 'after PASS' );
179 $req1 = new UsernameAuthenticationRequest
;
180 $req1->username
= 'foo';
181 $req2 = new UsernameAuthenticationRequest
;
182 $req2->username
= 'bar';
183 $this->assertTrue( $provider->testForAuthentication( [ $req1, $req2 ] )->isGood() );
185 $req = new UsernameAuthenticationRequest
;
186 $req->username
= 'Some user';
187 $provider->testForAuthentication( [ $req ] );
188 $req->username
= 'Some_user';
189 $provider->testForAuthentication( [ $req ] );
190 $req->username
= 'some user';
191 $status = $provider->testForAuthentication( [ $req ] );
192 $this->assertFalse( $status->isGood(), 'denormalized usernames are normalized' );
195 public function testPostAuthentication() {
196 $provider = new ThrottlePreAuthenticationProvider( [
197 'passwordAttemptThrottle' => [],
198 'cache' => new \
HashBagOStuff(),
200 $provider->setLogger( new \TestLogger
);
201 $provider->setConfig( new \
HashConfig( [
202 'AccountCreationThrottle' => null,
203 'PasswordAttemptThrottle' => null,
205 $provider->setManager( AuthManager
::singleton() );
206 $provider->postAuthentication( \User
::newFromName( 'SomeUser' ),
207 AuthenticationResponse
::newPass() );
209 $provider = new ThrottlePreAuthenticationProvider( [
210 'passwordAttemptThrottle' => [ [ 'count' => 2, 'seconds' => 86400 ] ],
211 'cache' => new \
HashBagOStuff(),
213 $logger = new \
TestLogger( true );
214 $provider->setLogger( $logger );
215 $provider->setConfig( new \
HashConfig( [
216 'AccountCreationThrottle' => null,
217 'PasswordAttemptThrottle' => null,
219 $provider->setManager( AuthManager
::singleton() );
220 $provider->postAuthentication( \User
::newFromName( 'SomeUser' ),
221 AuthenticationResponse
::newPass() );
223 [ \Psr\Log\LogLevel
::ERROR
, 'throttler data not found for {user}' ],
224 ], $logger->getBuffer() );