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' => [ [
19 'PasswordAttemptThrottle' => [ [
24 $provider->setConfig( $config );
26 'accountCreationThrottle' => [ [ 'count' => 123, 'seconds' => 86400 ] ],
27 'passwordAttemptThrottle' => [ [ 'count' => 5, 'seconds' => 300 ] ]
28 ], $providerPriv->throttleSettings
);
29 $accountCreationThrottle = \TestingAccessWrapper
::newFromObject(
30 $providerPriv->accountCreationThrottle
);
31 $this->assertSame( [ [ 'count' => 123, 'seconds' => 86400 ] ],
32 $accountCreationThrottle->conditions
);
33 $passwordAttemptThrottle = \TestingAccessWrapper
::newFromObject(
34 $providerPriv->passwordAttemptThrottle
);
35 $this->assertSame( [ [ 'count' => 5, 'seconds' => 300 ] ],
36 $passwordAttemptThrottle->conditions
);
38 $provider = new ThrottlePreAuthenticationProvider( [
39 'accountCreationThrottle' => [ [ 'count' => 43, 'seconds' => 10000 ] ],
40 'passwordAttemptThrottle' => [ [ 'count' => 11, 'seconds' => 100 ] ],
42 $providerPriv = \TestingAccessWrapper
::newFromObject( $provider );
43 $config = new \
HashConfig( [
44 'AccountCreationThrottle' => [ [
48 'PasswordAttemptThrottle' => [ [
53 $provider->setConfig( $config );
55 'accountCreationThrottle' => [ [ 'count' => 43, 'seconds' => 10000 ] ],
56 'passwordAttemptThrottle' => [ [ 'count' => 11, 'seconds' => 100 ] ],
57 ], $providerPriv->throttleSettings
);
59 $cache = new \
HashBagOStuff();
60 $provider = new ThrottlePreAuthenticationProvider( [ 'cache' => $cache ] );
61 $providerPriv = \TestingAccessWrapper
::newFromObject( $provider );
62 $provider->setConfig( new \
HashConfig( [
63 'AccountCreationThrottle' => [ [ 'count' => 1, 'seconds' => 1 ] ],
64 'PasswordAttemptThrottle' => [ [ 'count' => 1, 'seconds' => 1 ] ],
66 $accountCreationThrottle = \TestingAccessWrapper
::newFromObject(
67 $providerPriv->accountCreationThrottle
);
68 $this->assertSame( $cache, $accountCreationThrottle->cache
);
69 $passwordAttemptThrottle = \TestingAccessWrapper
::newFromObject(
70 $providerPriv->passwordAttemptThrottle
);
71 $this->assertSame( $cache, $passwordAttemptThrottle->cache
);
74 public function testDisabled() {
75 $provider = new ThrottlePreAuthenticationProvider( [
76 'accountCreationThrottle' => [],
77 'passwordAttemptThrottle' => [],
78 'cache' => new \
HashBagOStuff(),
80 $provider->setLogger( new \Psr\Log\
NullLogger() );
81 $provider->setConfig( new \
HashConfig( [
82 'AccountCreationThrottle' => null,
83 'PasswordAttemptThrottle' => null,
85 $provider->setManager( AuthManager
::singleton() );
88 \StatusValue
::newGood(),
89 $provider->testForAccountCreation(
90 \User
::newFromName( 'Created' ),
91 \User
::newFromName( 'Creator' ),
96 \StatusValue
::newGood(),
97 $provider->testForAuthentication( [] )
102 * @dataProvider provideTestForAccountCreation
103 * @param string $creatorname
104 * @param bool $succeed
107 public function testTestForAccountCreation( $creatorname, $succeed, $hook ) {
108 $provider = new ThrottlePreAuthenticationProvider( [
109 'accountCreationThrottle' => [ [ 'count' => 2, 'seconds' => 86400 ] ],
110 'cache' => new \
HashBagOStuff(),
112 $provider->setLogger( new \Psr\Log\
NullLogger() );
113 $provider->setConfig( new \
HashConfig( [
114 'AccountCreationThrottle' => null,
115 'PasswordAttemptThrottle' => null,
117 $provider->setManager( AuthManager
::singleton() );
119 $user = \User
::newFromName( 'RandomUser' );
120 $creator = \User
::newFromName( $creatorname );
122 $mock = $this->getMock( 'stdClass', [ 'onExemptFromAccountCreationThrottle' ] );
123 $mock->expects( $this->any() )->method( 'onExemptFromAccountCreationThrottle' )
124 ->will( $this->returnValue( false ) );
125 $this->mergeMwGlobalArrayValue( 'wgHooks', [
126 'ExemptFromAccountCreationThrottle' => [ $mock ],
132 $provider->testForAccountCreation( $user, $creator, [] )->isOK(),
137 $provider->testForAccountCreation( $user, $creator, [] )->isOK(),
141 $succeed ?
true : false,
142 $provider->testForAccountCreation( $user, $creator, [] )->isOK(),
147 public static function provideTestForAccountCreation() {
149 'Normal user' => [ 'NormalUser', false, false ],
150 'Sysop' => [ 'UTSysop', true, false ],
151 'Normal user with hook' => [ 'NormalUser', true, true ],
155 public function testTestForAuthentication() {
156 $provider = new ThrottlePreAuthenticationProvider( [
157 'passwordAttemptThrottle' => [ [ 'count' => 2, 'seconds' => 86400 ] ],
158 'cache' => new \
HashBagOStuff(),
160 $provider->setLogger( new \Psr\Log\
NullLogger() );
161 $provider->setConfig( new \
HashConfig( [
162 'AccountCreationThrottle' => null,
163 'PasswordAttemptThrottle' => null,
165 $provider->setManager( AuthManager
::singleton() );
167 $req = new UsernameAuthenticationRequest
;
168 $req->username
= 'SomeUser';
169 for ( $i = 1; $i <= 3; $i++
) {
170 $status = $provider->testForAuthentication( [ $req ] );
171 $this->assertEquals( $i < 3, $status->isGood(), "attempt #$i" );
173 $this->assertCount( 1, $status->getErrors() );
174 $msg = new \
Message( $status->getErrors()[0]['message'], $status->getErrors()[0]['params'] );
175 $this->assertEquals( 'login-throttled', $msg->getKey() );
177 $provider->postAuthentication( \User
::newFromName( 'SomeUser' ),
178 AuthenticationResponse
::newFail( wfMessage( 'foo' ) ) );
179 $this->assertFalse( $provider->testForAuthentication( [ $req ] )->isGood(), 'after FAIL' );
181 $provider->postAuthentication( \User
::newFromName( 'SomeUser' ),
182 AuthenticationResponse
::newPass() );
183 $this->assertTrue( $provider->testForAuthentication( [ $req ] )->isGood(), 'after PASS' );
185 $req1 = new UsernameAuthenticationRequest
;
186 $req1->username
= 'foo';
187 $req2 = new UsernameAuthenticationRequest
;
188 $req2->username
= 'bar';
189 $this->assertTrue( $provider->testForAuthentication( [ $req1, $req2 ] )->isGood() );
191 $req = new UsernameAuthenticationRequest
;
192 $req->username
= 'Some user';
193 $provider->testForAuthentication( [ $req ] );
194 $req->username
= 'Some_user';
195 $provider->testForAuthentication( [ $req ] );
196 $req->username
= 'some user';
197 $status = $provider->testForAuthentication( [ $req ] );
198 $this->assertFalse( $status->isGood(), 'denormalized usernames are normalized' );
201 public function testPostAuthentication() {
202 $provider = new ThrottlePreAuthenticationProvider( [
203 'passwordAttemptThrottle' => [],
204 'cache' => new \
HashBagOStuff(),
206 $provider->setLogger( new \TestLogger
);
207 $provider->setConfig( new \
HashConfig( [
208 'AccountCreationThrottle' => null,
209 'PasswordAttemptThrottle' => null,
211 $provider->setManager( AuthManager
::singleton() );
212 $provider->postAuthentication( \User
::newFromName( 'SomeUser' ),
213 AuthenticationResponse
::newPass() );
215 $provider = new ThrottlePreAuthenticationProvider( [
216 'passwordAttemptThrottle' => [ [ 'count' => 2, 'seconds' => 86400 ] ],
217 'cache' => new \
HashBagOStuff(),
219 $logger = new \
TestLogger( true );
220 $provider->setLogger( $logger );
221 $provider->setConfig( new \
HashConfig( [
222 'AccountCreationThrottle' => null,
223 'PasswordAttemptThrottle' => null,
225 $provider->setManager( AuthManager
::singleton() );
226 $provider->postAuthentication( \User
::newFromName( 'SomeUser' ),
227 AuthenticationResponse
::newPass() );
229 [ \Psr\Log\LogLevel
::INFO
, 'throttler data not found for {user}' ],
230 ], $logger->getBuffer() );