]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - tests/phpunit/includes/auth/ThrottlePreAuthenticationProviderTest.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / tests / phpunit / includes / auth / ThrottlePreAuthenticationProviderTest.php
1 <?php
2
3 namespace MediaWiki\Auth;
4
5 use Wikimedia\TestingAccessWrapper;
6
7 /**
8  * @group AuthManager
9  * @group Database
10  * @covers MediaWiki\Auth\ThrottlePreAuthenticationProvider
11  */
12 class ThrottlePreAuthenticationProviderTest extends \MediaWikiTestCase {
13         public function testConstructor() {
14                 $provider = new ThrottlePreAuthenticationProvider();
15                 $providerPriv = TestingAccessWrapper::newFromObject( $provider );
16                 $config = new \HashConfig( [
17                         'AccountCreationThrottle' => [ [
18                                 'count' => 123,
19                                 'seconds' => 86400,
20                         ] ],
21                         'PasswordAttemptThrottle' => [ [
22                                 'count' => 5,
23                                 'seconds' => 300,
24                         ] ],
25                 ] );
26                 $provider->setConfig( $config );
27                 $this->assertSame( [
28                         'accountCreationThrottle' => [ [ 'count' => 123, 'seconds' => 86400 ] ],
29                         'passwordAttemptThrottle' => [ [ 'count' => 5, 'seconds' => 300 ] ]
30                 ], $providerPriv->throttleSettings );
31                 $accountCreationThrottle = TestingAccessWrapper::newFromObject(
32                         $providerPriv->accountCreationThrottle );
33                 $this->assertSame( [ [ 'count' => 123, 'seconds' => 86400 ] ],
34                         $accountCreationThrottle->conditions );
35                 $passwordAttemptThrottle = TestingAccessWrapper::newFromObject(
36                         $providerPriv->passwordAttemptThrottle );
37                 $this->assertSame( [ [ 'count' => 5, 'seconds' => 300 ] ],
38                         $passwordAttemptThrottle->conditions );
39
40                 $provider = new ThrottlePreAuthenticationProvider( [
41                         'accountCreationThrottle' => [ [ 'count' => 43, 'seconds' => 10000 ] ],
42                         'passwordAttemptThrottle' => [ [ 'count' => 11, 'seconds' => 100 ] ],
43                 ] );
44                 $providerPriv = TestingAccessWrapper::newFromObject( $provider );
45                 $config = new \HashConfig( [
46                         'AccountCreationThrottle' => [ [
47                                 'count' => 123,
48                                 'seconds' => 86400,
49                         ] ],
50                         'PasswordAttemptThrottle' => [ [
51                                 'count' => 5,
52                                 'seconds' => 300,
53                         ] ],
54                 ] );
55                 $provider->setConfig( $config );
56                 $this->assertSame( [
57                         'accountCreationThrottle' => [ [ 'count' => 43, 'seconds' => 10000 ] ],
58                         'passwordAttemptThrottle' => [ [ 'count' => 11, 'seconds' => 100 ] ],
59                 ], $providerPriv->throttleSettings );
60
61                 $cache = new \HashBagOStuff();
62                 $provider = new ThrottlePreAuthenticationProvider( [ 'cache' => $cache ] );
63                 $providerPriv = TestingAccessWrapper::newFromObject( $provider );
64                 $provider->setConfig( new \HashConfig( [
65                         'AccountCreationThrottle' => [ [ 'count' => 1, 'seconds' => 1 ] ],
66                         'PasswordAttemptThrottle' => [ [ 'count' => 1, 'seconds' => 1 ] ],
67                 ] ) );
68                 $accountCreationThrottle = TestingAccessWrapper::newFromObject(
69                         $providerPriv->accountCreationThrottle );
70                 $this->assertSame( $cache, $accountCreationThrottle->cache );
71                 $passwordAttemptThrottle = TestingAccessWrapper::newFromObject(
72                         $providerPriv->passwordAttemptThrottle );
73                 $this->assertSame( $cache, $passwordAttemptThrottle->cache );
74         }
75
76         public function testDisabled() {
77                 $provider = new ThrottlePreAuthenticationProvider( [
78                         'accountCreationThrottle' => [],
79                         'passwordAttemptThrottle' => [],
80                         'cache' => new \HashBagOStuff(),
81                 ] );
82                 $provider->setLogger( new \Psr\Log\NullLogger() );
83                 $provider->setConfig( new \HashConfig( [
84                         'AccountCreationThrottle' => null,
85                         'PasswordAttemptThrottle' => null,
86                 ] ) );
87                 $provider->setManager( AuthManager::singleton() );
88
89                 $this->assertEquals(
90                         \StatusValue::newGood(),
91                         $provider->testForAccountCreation(
92                                 \User::newFromName( 'Created' ),
93                                 \User::newFromName( 'Creator' ),
94                                 []
95                         )
96                 );
97                 $this->assertEquals(
98                         \StatusValue::newGood(),
99                         $provider->testForAuthentication( [] )
100                 );
101         }
102
103         /**
104          * @dataProvider provideTestForAccountCreation
105          * @param string $creatorname
106          * @param bool $succeed
107          * @param bool $hook
108          */
109         public function testTestForAccountCreation( $creatorname, $succeed, $hook ) {
110                 $provider = new ThrottlePreAuthenticationProvider( [
111                         'accountCreationThrottle' => [ [ 'count' => 2, 'seconds' => 86400 ] ],
112                         'cache' => new \HashBagOStuff(),
113                 ] );
114                 $provider->setLogger( new \Psr\Log\NullLogger() );
115                 $provider->setConfig( new \HashConfig( [
116                         'AccountCreationThrottle' => null,
117                         'PasswordAttemptThrottle' => null,
118                 ] ) );
119                 $provider->setManager( AuthManager::singleton() );
120
121                 $user = \User::newFromName( 'RandomUser' );
122                 $creator = \User::newFromName( $creatorname );
123                 if ( $hook ) {
124                         $mock = $this->getMockBuilder( 'stdClass' )
125                                 ->setMethods( [ 'onExemptFromAccountCreationThrottle' ] )
126                                 ->getMock();
127                         $mock->expects( $this->any() )->method( 'onExemptFromAccountCreationThrottle' )
128                                 ->will( $this->returnValue( false ) );
129                         $this->mergeMwGlobalArrayValue( 'wgHooks', [
130                                 'ExemptFromAccountCreationThrottle' => [ $mock ],
131                         ] );
132                 }
133
134                 $this->assertEquals(
135                         true,
136                         $provider->testForAccountCreation( $user, $creator, [] )->isOK(),
137                         'attempt #1'
138                 );
139                 $this->assertEquals(
140                         true,
141                         $provider->testForAccountCreation( $user, $creator, [] )->isOK(),
142                         'attempt #2'
143                 );
144                 $this->assertEquals(
145                         $succeed ? true : false,
146                         $provider->testForAccountCreation( $user, $creator, [] )->isOK(),
147                         'attempt #3'
148                 );
149         }
150
151         public static function provideTestForAccountCreation() {
152                 return [
153                         'Normal user' => [ 'NormalUser', false, false ],
154                         'Sysop' => [ 'UTSysop', true, false ],
155                         'Normal user with hook' => [ 'NormalUser', true, true ],
156                 ];
157         }
158
159         public function testTestForAuthentication() {
160                 $provider = new ThrottlePreAuthenticationProvider( [
161                         'passwordAttemptThrottle' => [ [ 'count' => 2, 'seconds' => 86400 ] ],
162                         'cache' => new \HashBagOStuff(),
163                 ] );
164                 $provider->setLogger( new \Psr\Log\NullLogger() );
165                 $provider->setConfig( new \HashConfig( [
166                         'AccountCreationThrottle' => null,
167                         'PasswordAttemptThrottle' => null,
168                 ] ) );
169                 $provider->setManager( AuthManager::singleton() );
170
171                 $req = new UsernameAuthenticationRequest;
172                 $req->username = 'SomeUser';
173                 for ( $i = 1; $i <= 3; $i++ ) {
174                         $status = $provider->testForAuthentication( [ $req ] );
175                         $this->assertEquals( $i < 3, $status->isGood(), "attempt #$i" );
176                 }
177                 $this->assertCount( 1, $status->getErrors() );
178                 $msg = new \Message( $status->getErrors()[0]['message'], $status->getErrors()[0]['params'] );
179                 $this->assertEquals( 'login-throttled', $msg->getKey() );
180
181                 $provider->postAuthentication( \User::newFromName( 'SomeUser' ),
182                         AuthenticationResponse::newFail( wfMessage( 'foo' ) ) );
183                 $this->assertFalse( $provider->testForAuthentication( [ $req ] )->isGood(), 'after FAIL' );
184
185                 $provider->postAuthentication( \User::newFromName( 'SomeUser' ),
186                         AuthenticationResponse::newPass() );
187                 $this->assertTrue( $provider->testForAuthentication( [ $req ] )->isGood(), 'after PASS' );
188
189                 $req1 = new UsernameAuthenticationRequest;
190                 $req1->username = 'foo';
191                 $req2 = new UsernameAuthenticationRequest;
192                 $req2->username = 'bar';
193                 $this->assertTrue( $provider->testForAuthentication( [ $req1, $req2 ] )->isGood() );
194
195                 $req = new UsernameAuthenticationRequest;
196                 $req->username = 'Some user';
197                 $provider->testForAuthentication( [ $req ] );
198                 $req->username = 'Some_user';
199                 $provider->testForAuthentication( [ $req ] );
200                 $req->username = 'some user';
201                 $status = $provider->testForAuthentication( [ $req ] );
202                 $this->assertFalse( $status->isGood(), 'denormalized usernames are normalized' );
203         }
204
205         public function testPostAuthentication() {
206                 $provider = new ThrottlePreAuthenticationProvider( [
207                         'passwordAttemptThrottle' => [],
208                         'cache' => new \HashBagOStuff(),
209                 ] );
210                 $provider->setLogger( new \TestLogger );
211                 $provider->setConfig( new \HashConfig( [
212                         'AccountCreationThrottle' => null,
213                         'PasswordAttemptThrottle' => null,
214                 ] ) );
215                 $provider->setManager( AuthManager::singleton() );
216                 $provider->postAuthentication( \User::newFromName( 'SomeUser' ),
217                         AuthenticationResponse::newPass() );
218
219                 $provider = new ThrottlePreAuthenticationProvider( [
220                         'passwordAttemptThrottle' => [ [ 'count' => 2, 'seconds' => 86400 ] ],
221                         'cache' => new \HashBagOStuff(),
222                 ] );
223                 $logger = new \TestLogger( true );
224                 $provider->setLogger( $logger );
225                 $provider->setConfig( new \HashConfig( [
226                         'AccountCreationThrottle' => null,
227                         'PasswordAttemptThrottle' => null,
228                 ] ) );
229                 $provider->setManager( AuthManager::singleton() );
230                 $provider->postAuthentication( \User::newFromName( 'SomeUser' ),
231                         AuthenticationResponse::newPass() );
232                 $this->assertSame( [
233                         [ \Psr\Log\LogLevel::INFO, 'throttler data not found for {user}' ],
234                 ], $logger->getBuffer() );
235         }
236 }