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