Merge "Revert "Remove unused functions from unroll of Article::__call""
[lhc/web/wiklou.git] / tests / phpunit / includes / session / CookieSessionProviderTest.php
1 <?php
2
3 namespace MediaWiki\Session;
4
5 use MediaWikiTestCase;
6 use User;
7
8 /**
9 * @group Session
10 * @group Database
11 * @covers MediaWiki\Session\CookieSessionProvider
12 */
13 class CookieSessionProviderTest extends MediaWikiTestCase {
14
15 private function getConfig() {
16 global $wgCookieExpiration;
17 return new \HashConfig( array(
18 'CookiePrefix' => 'CookiePrefix',
19 'CookiePath' => 'CookiePath',
20 'CookieDomain' => 'CookieDomain',
21 'CookieSecure' => true,
22 'CookieHttpOnly' => true,
23 'SessionName' => false,
24 'ExtendedLoginCookies' => array( 'UserID', 'Token' ),
25 'ExtendedLoginCookieExpiration' => $wgCookieExpiration * 2,
26 ) );
27 }
28
29 public function testConstructor() {
30 try {
31 new CookieSessionProvider();
32 $this->fail( 'Expected exception not thrown' );
33 } catch ( \InvalidArgumentException $ex ) {
34 $this->assertSame(
35 'MediaWiki\\Session\\CookieSessionProvider::__construct: priority must be specified',
36 $ex->getMessage()
37 );
38 }
39
40 try {
41 new CookieSessionProvider( array( 'priority' => 'foo' ) );
42 $this->fail( 'Expected exception not thrown' );
43 } catch ( \InvalidArgumentException $ex ) {
44 $this->assertSame(
45 'MediaWiki\\Session\\CookieSessionProvider::__construct: Invalid priority',
46 $ex->getMessage()
47 );
48 }
49 try {
50 new CookieSessionProvider( array( 'priority' => SessionInfo::MIN_PRIORITY - 1 ) );
51 $this->fail( 'Expected exception not thrown' );
52 } catch ( \InvalidArgumentException $ex ) {
53 $this->assertSame(
54 'MediaWiki\\Session\\CookieSessionProvider::__construct: Invalid priority',
55 $ex->getMessage()
56 );
57 }
58 try {
59 new CookieSessionProvider( array( 'priority' => SessionInfo::MAX_PRIORITY + 1 ) );
60 $this->fail( 'Expected exception not thrown' );
61 } catch ( \InvalidArgumentException $ex ) {
62 $this->assertSame(
63 'MediaWiki\\Session\\CookieSessionProvider::__construct: Invalid priority',
64 $ex->getMessage()
65 );
66 }
67
68 try {
69 new CookieSessionProvider( array( 'priority' => 1, 'cookieOptions' => null ) );
70 $this->fail( 'Expected exception not thrown' );
71 } catch ( \InvalidArgumentException $ex ) {
72 $this->assertSame(
73 'MediaWiki\\Session\\CookieSessionProvider::__construct: cookieOptions must be an array',
74 $ex->getMessage()
75 );
76 }
77
78 $config = $this->getConfig();
79 $p = \TestingAccessWrapper::newFromObject(
80 new CookieSessionProvider( array( 'priority' => 1 ) )
81 );
82 $p->setLogger( new \TestLogger() );
83 $p->setConfig( $config );
84 $this->assertEquals( 1, $p->priority );
85 $this->assertEquals( array(
86 'callUserSetCookiesHook' => false,
87 'sessionName' => 'CookiePrefix_session',
88 ), $p->params );
89 $this->assertEquals( array(
90 'prefix' => 'CookiePrefix',
91 'path' => 'CookiePath',
92 'domain' => 'CookieDomain',
93 'secure' => true,
94 'httpOnly' => true,
95 ), $p->cookieOptions );
96
97 $config->set( 'SessionName', 'SessionName' );
98 $p = \TestingAccessWrapper::newFromObject(
99 new CookieSessionProvider( array( 'priority' => 3 ) )
100 );
101 $p->setLogger( new \TestLogger() );
102 $p->setConfig( $config );
103 $this->assertEquals( 3, $p->priority );
104 $this->assertEquals( array(
105 'callUserSetCookiesHook' => false,
106 'sessionName' => 'SessionName',
107 ), $p->params );
108 $this->assertEquals( array(
109 'prefix' => 'CookiePrefix',
110 'path' => 'CookiePath',
111 'domain' => 'CookieDomain',
112 'secure' => true,
113 'httpOnly' => true,
114 ), $p->cookieOptions );
115
116 $p = \TestingAccessWrapper::newFromObject( new CookieSessionProvider( array(
117 'priority' => 10,
118 'callUserSetCookiesHook' => true,
119 'cookieOptions' => array(
120 'prefix' => 'XPrefix',
121 'path' => 'XPath',
122 'domain' => 'XDomain',
123 'secure' => 'XSecure',
124 'httpOnly' => 'XHttpOnly',
125 ),
126 'sessionName' => 'XSession',
127 ) ) );
128 $p->setLogger( new \TestLogger() );
129 $p->setConfig( $config );
130 $this->assertEquals( 10, $p->priority );
131 $this->assertEquals( array(
132 'callUserSetCookiesHook' => true,
133 'sessionName' => 'XSession',
134 ), $p->params );
135 $this->assertEquals( array(
136 'prefix' => 'XPrefix',
137 'path' => 'XPath',
138 'domain' => 'XDomain',
139 'secure' => 'XSecure',
140 'httpOnly' => 'XHttpOnly',
141 ), $p->cookieOptions );
142 }
143
144 public function testBasics() {
145 $provider = new CookieSessionProvider( array( 'priority' => 10 ) );
146
147 $this->assertTrue( $provider->persistsSessionID() );
148 $this->assertTrue( $provider->canChangeUser() );
149
150 $msg = $provider->whyNoSession();
151 $this->assertInstanceOf( 'Message', $msg );
152 $this->assertSame( 'sessionprovider-nocookies', $msg->getKey() );
153 }
154
155 public function testProvideSessionInfo() {
156 $params = array(
157 'priority' => 20,
158 'sessionName' => 'session',
159 'cookieOptions' => array( 'prefix' => 'x' ),
160 );
161 $provider = new CookieSessionProvider( $params );
162 $provider->setLogger( new \TestLogger() );
163 $provider->setConfig( $this->getConfig() );
164 $provider->setManager( new SessionManager() );
165
166 $user = User::newFromName( 'UTSysop' );
167 $id = $user->getId();
168 $name = $user->getName();
169 $token = $user->getToken( true );
170
171 $sessionId = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
172
173 // No data
174 $request = new \FauxRequest();
175 $info = $provider->provideSessionInfo( $request );
176 $this->assertNull( $info );
177
178 // Session key only
179 $request = new \FauxRequest();
180 $request->setCookies( array(
181 'session' => $sessionId,
182 ), '' );
183 $info = $provider->provideSessionInfo( $request );
184 $this->assertNotNull( $info );
185 $this->assertSame( $params['priority'], $info->getPriority() );
186 $this->assertSame( $sessionId, $info->getId() );
187 $this->assertNotNull( $info->getUserInfo() );
188 $this->assertSame( 0, $info->getUserInfo()->getId() );
189 $this->assertNull( $info->getUserInfo()->getName() );
190 $this->assertFalse( $info->forceHTTPS() );
191
192 // User, no session key
193 $request = new \FauxRequest();
194 $request->setCookies( array(
195 'xUserID' => $id,
196 'xToken' => $token,
197 ), '' );
198 $info = $provider->provideSessionInfo( $request );
199 $this->assertNotNull( $info );
200 $this->assertSame( $params['priority'], $info->getPriority() );
201 $this->assertNotSame( $sessionId, $info->getId() );
202 $this->assertNotNull( $info->getUserInfo() );
203 $this->assertSame( $id, $info->getUserInfo()->getId() );
204 $this->assertSame( $name, $info->getUserInfo()->getName() );
205 $this->assertFalse( $info->forceHTTPS() );
206
207 // User and session key
208 $request = new \FauxRequest();
209 $request->setCookies( array(
210 'session' => $sessionId,
211 'xUserID' => $id,
212 'xToken' => $token,
213 ), '' );
214 $info = $provider->provideSessionInfo( $request );
215 $this->assertNotNull( $info );
216 $this->assertSame( $params['priority'], $info->getPriority() );
217 $this->assertSame( $sessionId, $info->getId() );
218 $this->assertNotNull( $info->getUserInfo() );
219 $this->assertSame( $id, $info->getUserInfo()->getId() );
220 $this->assertSame( $name, $info->getUserInfo()->getName() );
221 $this->assertFalse( $info->forceHTTPS() );
222
223 // User with bad token
224 $request = new \FauxRequest();
225 $request->setCookies( array(
226 'session' => $sessionId,
227 'xUserID' => $id,
228 'xToken' => 'BADTOKEN',
229 ), '' );
230 $info = $provider->provideSessionInfo( $request );
231 $this->assertNull( $info );
232
233 // User id with no token
234 $request = new \FauxRequest();
235 $request->setCookies( array(
236 'session' => $sessionId,
237 'xUserID' => $id,
238 ), '' );
239 $info = $provider->provideSessionInfo( $request );
240 $this->assertNotNull( $info );
241 $this->assertSame( $params['priority'], $info->getPriority() );
242 $this->assertSame( $sessionId, $info->getId() );
243 $this->assertNotNull( $info->getUserInfo() );
244 $this->assertFalse( $info->getUserInfo()->isVerified() );
245 $this->assertSame( $id, $info->getUserInfo()->getId() );
246 $this->assertSame( $name, $info->getUserInfo()->getName() );
247 $this->assertFalse( $info->forceHTTPS() );
248
249 $request = new \FauxRequest();
250 $request->setCookies( array(
251 'xUserID' => $id,
252 ), '' );
253 $info = $provider->provideSessionInfo( $request );
254 $this->assertNull( $info );
255
256 // User and session key, with forceHTTPS flag
257 $request = new \FauxRequest();
258 $request->setCookies( array(
259 'session' => $sessionId,
260 'xUserID' => $id,
261 'xToken' => $token,
262 'forceHTTPS' => true,
263 ), '' );
264 $info = $provider->provideSessionInfo( $request );
265 $this->assertNotNull( $info );
266 $this->assertSame( $params['priority'], $info->getPriority() );
267 $this->assertSame( $sessionId, $info->getId() );
268 $this->assertNotNull( $info->getUserInfo() );
269 $this->assertSame( $id, $info->getUserInfo()->getId() );
270 $this->assertSame( $name, $info->getUserInfo()->getName() );
271 $this->assertTrue( $info->forceHTTPS() );
272
273 // Invalid user id
274 $request = new \FauxRequest();
275 $request->setCookies( array(
276 'session' => $sessionId,
277 'xUserID' => '-1',
278 ), '' );
279 $info = $provider->provideSessionInfo( $request );
280 $this->assertNull( $info );
281
282 // User id with matching name
283 $request = new \FauxRequest();
284 $request->setCookies( array(
285 'session' => $sessionId,
286 'xUserID' => $id,
287 'xUserName' => $name,
288 ), '' );
289 $info = $provider->provideSessionInfo( $request );
290 $this->assertNotNull( $info );
291 $this->assertSame( $params['priority'], $info->getPriority() );
292 $this->assertSame( $sessionId, $info->getId() );
293 $this->assertNotNull( $info->getUserInfo() );
294 $this->assertFalse( $info->getUserInfo()->isVerified() );
295 $this->assertSame( $id, $info->getUserInfo()->getId() );
296 $this->assertSame( $name, $info->getUserInfo()->getName() );
297 $this->assertFalse( $info->forceHTTPS() );
298
299 // User id with wrong name
300 $request = new \FauxRequest();
301 $request->setCookies( array(
302 'session' => $sessionId,
303 'xUserID' => $id,
304 'xUserName' => 'Wrong',
305 ), '' );
306 $info = $provider->provideSessionInfo( $request );
307 $this->assertNull( $info );
308 }
309
310 public function testGetVaryCookies() {
311 $provider = new CookieSessionProvider( array(
312 'priority' => 1,
313 'sessionName' => 'MySessionName',
314 'cookieOptions' => array( 'prefix' => 'MyCookiePrefix' ),
315 ) );
316 $this->assertArrayEquals( array(
317 'MyCookiePrefixToken',
318 'MyCookiePrefixLoggedOut',
319 'MySessionName',
320 'forceHTTPS',
321 ), $provider->getVaryCookies() );
322 }
323
324 public function testSuggestLoginUsername() {
325 $provider = new CookieSessionProvider( array(
326 'priority' => 1,
327 'sessionName' => 'MySessionName',
328 'cookieOptions' => array( 'prefix' => 'x' ),
329 ) );
330
331 $request = new \FauxRequest();
332 $this->assertEquals( null, $provider->suggestLoginUsername( $request ) );
333
334 $request->setCookies( array(
335 'xUserName' => 'Example',
336 ), '' );
337 $this->assertEquals( 'Example', $provider->suggestLoginUsername( $request ) );
338 }
339
340 public function testPersistSession() {
341 $this->setMwGlobals( array( 'wgCookieExpiration' => 100 ) );
342
343 $provider = new CookieSessionProvider( array(
344 'priority' => 1,
345 'sessionName' => 'MySessionName',
346 'callUserSetCookiesHook' => false,
347 'cookieOptions' => array( 'prefix' => 'x' ),
348 ) );
349 $config = $this->getConfig();
350 $provider->setLogger( new \TestLogger() );
351 $provider->setConfig( $config );
352 $provider->setManager( SessionManager::singleton() );
353
354 $sessionId = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
355 $store = new \HashBagOStuff();
356 $user = User::newFromName( 'UTSysop' );
357 $anon = new User;
358
359 $backend = new SessionBackend(
360 new SessionId( $sessionId ),
361 new SessionInfo( SessionInfo::MIN_PRIORITY, array(
362 'provider' => $provider,
363 'id' => $sessionId,
364 'persisted' => true,
365 'idIsSafe' => true,
366 ) ),
367 $store,
368 $store,
369 new \Psr\Log\NullLogger(),
370 10
371 );
372 \TestingAccessWrapper::newFromObject( $backend )->usePhpSessionHandling = false;
373
374 $mock = $this->getMock( 'stdClass', array( 'onUserSetCookies' ) );
375 $mock->expects( $this->never() )->method( 'onUserSetCookies' );
376 $this->mergeMwGlobalArrayValue( 'wgHooks', array( 'UserSetCookies' => array( $mock ) ) );
377
378 // Anonymous user
379 $backend->setUser( $anon );
380 $backend->setRememberUser( true );
381 $backend->setForceHTTPS( false );
382 $request = new \FauxRequest();
383 $provider->persistSession( $backend, $request );
384 $this->assertSame( $sessionId, $request->response()->getCookie( 'MySessionName' ) );
385 $this->assertSame( '', $request->response()->getCookie( 'xUserID' ) );
386 $this->assertSame( null, $request->response()->getCookie( 'xUserName' ) );
387 $this->assertSame( '', $request->response()->getCookie( 'xToken' ) );
388 $this->assertSame( '', $request->response()->getCookie( 'forceHTTPS' ) );
389 $this->assertSame( array(), $backend->getData() );
390
391 // Logged-in user, no remember
392 $backend->setUser( $user );
393 $backend->setRememberUser( false );
394 $backend->setForceHTTPS( false );
395 $request = new \FauxRequest();
396 $provider->persistSession( $backend, $request );
397 $this->assertSame( $sessionId, $request->response()->getCookie( 'MySessionName' ) );
398 $this->assertSame( (string)$user->getId(), $request->response()->getCookie( 'xUserID' ) );
399 $this->assertSame( $user->getName(), $request->response()->getCookie( 'xUserName' ) );
400 $this->assertSame( '', $request->response()->getCookie( 'xToken' ) );
401 $this->assertSame( '', $request->response()->getCookie( 'forceHTTPS' ) );
402 $this->assertSame( array(), $backend->getData() );
403
404 // Logged-in user, remember
405 $backend->setUser( $user );
406 $backend->setRememberUser( true );
407 $backend->setForceHTTPS( true );
408 $request = new \FauxRequest();
409 $time = time();
410 $provider->persistSession( $backend, $request );
411 $this->assertSame( $sessionId, $request->response()->getCookie( 'MySessionName' ) );
412 $this->assertSame( (string)$user->getId(), $request->response()->getCookie( 'xUserID' ) );
413 $this->assertSame( $user->getName(), $request->response()->getCookie( 'xUserName' ) );
414 $this->assertSame( $user->getToken(), $request->response()->getCookie( 'xToken' ) );
415 $this->assertSame( 'true', $request->response()->getCookie( 'forceHTTPS' ) );
416 $this->assertSame( array(), $backend->getData() );
417 }
418
419 /**
420 * @dataProvider provideCookieData
421 * @param bool $secure
422 * @param bool $remember
423 */
424 public function testCookieData( $secure, $remember ) {
425 $this->setMwGlobals( array(
426 'wgCookieExpiration' => 100,
427 'wgSecureLogin' => false,
428 ) );
429
430 $provider = new CookieSessionProvider( array(
431 'priority' => 1,
432 'sessionName' => 'MySessionName',
433 'callUserSetCookiesHook' => false,
434 'cookieOptions' => array( 'prefix' => 'x' ),
435 ) );
436 $config = $this->getConfig();
437 $config->set( 'CookieSecure', $secure );
438 $provider->setLogger( new \TestLogger() );
439 $provider->setConfig( $config );
440 $provider->setManager( SessionManager::singleton() );
441
442 $sessionId = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
443 $user = User::newFromName( 'UTSysop' );
444 $this->assertFalse( $user->requiresHTTPS(), 'sanity check' );
445
446 $backend = new SessionBackend(
447 new SessionId( $sessionId ),
448 new SessionInfo( SessionInfo::MIN_PRIORITY, array(
449 'provider' => $provider,
450 'id' => $sessionId,
451 'persisted' => true,
452 'idIsSafe' => true,
453 ) ),
454 new \EmptyBagOStuff(),
455 new \EmptyBagOStuff(),
456 new \Psr\Log\NullLogger(),
457 10
458 );
459 \TestingAccessWrapper::newFromObject( $backend )->usePhpSessionHandling = false;
460 $backend->setUser( $user );
461 $backend->setRememberUser( $remember );
462 $backend->setForceHTTPS( $secure );
463 $request = new \FauxRequest();
464 $time = time();
465 $provider->persistSession( $backend, $request );
466
467 $defaults = array(
468 'expire' => (int)100,
469 'path' => $config->get( 'CookiePath' ),
470 'domain' => $config->get( 'CookieDomain' ),
471 'secure' => $secure,
472 'httpOnly' => $config->get( 'CookieHttpOnly' ),
473 'raw' => false,
474 );
475 $extendedExpiry = $config->get( 'ExtendedLoginCookieExpiration' );
476 $extendedExpiry = (int)( $extendedExpiry === null ? 0 : $extendedExpiry );
477 $this->assertEquals( array( 'UserID', 'Token' ), $config->get( 'ExtendedLoginCookies' ),
478 'sanity check' );
479 $expect = array(
480 'MySessionName' => array(
481 'value' => (string)$sessionId,
482 'expire' => 0,
483 ) + $defaults,
484 'xUserID' => array(
485 'value' => (string)$user->getId(),
486 'expire' => $extendedExpiry,
487 ) + $defaults,
488 'xUserName' => array(
489 'value' => $user->getName(),
490 ) + $defaults,
491 'xToken' => array(
492 'value' => $remember ? $user->getToken() : '',
493 'expire' => $remember ? $extendedExpiry : -31536000,
494 ) + $defaults,
495 'forceHTTPS' => array(
496 'value' => $secure ? 'true' : '',
497 'secure' => false,
498 'expire' => $secure ? $remember ? $defaults['expire'] : 0 : -31536000,
499 ) + $defaults,
500 );
501 foreach ( $expect as $key => $value ) {
502 $actual = $request->response()->getCookieData( $key );
503 if ( $actual && $actual['expire'] > 0 ) {
504 // Round expiry so we don't randomly fail if the seconds ticked during the test.
505 $actual['expire'] = round( $actual['expire'] - $time, -2 );
506 }
507 $this->assertEquals( $value, $actual, "Cookie $key" );
508 }
509 }
510
511 public static function provideCookieData() {
512 return array(
513 array( false, false ),
514 array( false, true ),
515 array( true, false ),
516 array( true, true ),
517 );
518 }
519
520 protected function getSentRequest() {
521 $sentResponse = $this->getMock( 'FauxResponse', array( 'headersSent', 'setCookie', 'header' ) );
522 $sentResponse->expects( $this->any() )->method( 'headersSent' )
523 ->will( $this->returnValue( true ) );
524 $sentResponse->expects( $this->never() )->method( 'setCookie' );
525 $sentResponse->expects( $this->never() )->method( 'header' );
526
527 $sentRequest = $this->getMock( 'FauxRequest', array( 'response' ) );
528 $sentRequest->expects( $this->any() )->method( 'response' )
529 ->will( $this->returnValue( $sentResponse ) );
530 return $sentRequest;
531 }
532
533 public function testPersistSessionWithHook() {
534 $that = $this;
535
536 $provider = new CookieSessionProvider( array(
537 'priority' => 1,
538 'sessionName' => 'MySessionName',
539 'callUserSetCookiesHook' => true,
540 'cookieOptions' => array( 'prefix' => 'x' ),
541 ) );
542 $provider->setLogger( new \Psr\Log\NullLogger() );
543 $provider->setConfig( $this->getConfig() );
544 $provider->setManager( SessionManager::singleton() );
545
546 $sessionId = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
547 $store = new \HashBagOStuff();
548 $user = User::newFromName( 'UTSysop' );
549 $anon = new User;
550
551 $backend = new SessionBackend(
552 new SessionId( $sessionId ),
553 new SessionInfo( SessionInfo::MIN_PRIORITY, array(
554 'provider' => $provider,
555 'id' => $sessionId,
556 'persisted' => true,
557 'idIsSafe' => true,
558 ) ),
559 $store,
560 $store,
561 new \Psr\Log\NullLogger(),
562 10
563 );
564 \TestingAccessWrapper::newFromObject( $backend )->usePhpSessionHandling = false;
565
566 // Anonymous user
567 $mock = $this->getMock( 'stdClass', array( 'onUserSetCookies' ) );
568 $mock->expects( $this->never() )->method( 'onUserSetCookies' );
569 $this->mergeMwGlobalArrayValue( 'wgHooks', array( 'UserSetCookies' => array( $mock ) ) );
570 $backend->setUser( $anon );
571 $backend->setRememberUser( true );
572 $backend->setForceHTTPS( false );
573 $request = new \FauxRequest();
574 $provider->persistSession( $backend, $request );
575 $this->assertSame( $sessionId, $request->response()->getCookie( 'MySessionName' ) );
576 $this->assertSame( '', $request->response()->getCookie( 'xUserID' ) );
577 $this->assertSame( null, $request->response()->getCookie( 'xUserName' ) );
578 $this->assertSame( '', $request->response()->getCookie( 'xToken' ) );
579 $this->assertSame( '', $request->response()->getCookie( 'forceHTTPS' ) );
580 $this->assertSame( array(), $backend->getData() );
581
582 $provider->persistSession( $backend, $this->getSentRequest() );
583
584 // Logged-in user, no remember
585 $mock = $this->getMock( __CLASS__, array( 'onUserSetCookies' ) );
586 $mock->expects( $this->once() )->method( 'onUserSetCookies' )
587 ->will( $this->returnCallback( function ( $u, &$sessionData, &$cookies ) use ( $that, $user ) {
588 $that->assertSame( $user, $u );
589 $that->assertEquals( array(
590 'wsUserID' => $user->getId(),
591 'wsUserName' => $user->getName(),
592 'wsToken' => $user->getToken(),
593 ), $sessionData );
594 $that->assertEquals( array(
595 'UserID' => $user->getId(),
596 'UserName' => $user->getName(),
597 'Token' => false,
598 ), $cookies );
599
600 $sessionData['foo'] = 'foo!';
601 $cookies['bar'] = 'bar!';
602 return true;
603 } ) );
604 $this->mergeMwGlobalArrayValue( 'wgHooks', array( 'UserSetCookies' => array( $mock ) ) );
605 $backend->setUser( $user );
606 $backend->setRememberUser( false );
607 $backend->setForceHTTPS( false );
608 $backend->setLoggedOutTimestamp( $loggedOut = time() );
609 $request = new \FauxRequest();
610 $provider->persistSession( $backend, $request );
611 $this->assertSame( $sessionId, $request->response()->getCookie( 'MySessionName' ) );
612 $this->assertSame( (string)$user->getId(), $request->response()->getCookie( 'xUserID' ) );
613 $this->assertSame( $user->getName(), $request->response()->getCookie( 'xUserName' ) );
614 $this->assertSame( '', $request->response()->getCookie( 'xToken' ) );
615 $this->assertSame( '', $request->response()->getCookie( 'forceHTTPS' ) );
616 $this->assertSame( 'bar!', $request->response()->getCookie( 'xbar' ) );
617 $this->assertSame( (string)$loggedOut, $request->response()->getCookie( 'xLoggedOut' ) );
618 $this->assertEquals( array(
619 'wsUserID' => $user->getId(),
620 'wsUserName' => $user->getName(),
621 'wsToken' => $user->getToken(),
622 'foo' => 'foo!',
623 ), $backend->getData() );
624
625 $provider->persistSession( $backend, $this->getSentRequest() );
626
627 // Logged-in user, remember
628 $mock = $this->getMock( __CLASS__, array( 'onUserSetCookies' ) );
629 $mock->expects( $this->once() )->method( 'onUserSetCookies' )
630 ->will( $this->returnCallback( function ( $u, &$sessionData, &$cookies ) use ( $that, $user ) {
631 $that->assertSame( $user, $u );
632 $that->assertEquals( array(
633 'wsUserID' => $user->getId(),
634 'wsUserName' => $user->getName(),
635 'wsToken' => $user->getToken(),
636 ), $sessionData );
637 $that->assertEquals( array(
638 'UserID' => $user->getId(),
639 'UserName' => $user->getName(),
640 'Token' => $user->getToken(),
641 ), $cookies );
642
643 $sessionData['foo'] = 'foo 2!';
644 $cookies['bar'] = 'bar 2!';
645 return true;
646 } ) );
647 $this->mergeMwGlobalArrayValue( 'wgHooks', array( 'UserSetCookies' => array( $mock ) ) );
648 $backend->setUser( $user );
649 $backend->setRememberUser( true );
650 $backend->setForceHTTPS( true );
651 $backend->setLoggedOutTimestamp( 0 );
652 $request = new \FauxRequest();
653 $provider->persistSession( $backend, $request );
654 $this->assertSame( $sessionId, $request->response()->getCookie( 'MySessionName' ) );
655 $this->assertSame( (string)$user->getId(), $request->response()->getCookie( 'xUserID' ) );
656 $this->assertSame( $user->getName(), $request->response()->getCookie( 'xUserName' ) );
657 $this->assertSame( $user->getToken(), $request->response()->getCookie( 'xToken' ) );
658 $this->assertSame( 'true', $request->response()->getCookie( 'forceHTTPS' ) );
659 $this->assertSame( 'bar 2!', $request->response()->getCookie( 'xbar' ) );
660 $this->assertSame( null, $request->response()->getCookie( 'xLoggedOut' ) );
661 $this->assertEquals( array(
662 'wsUserID' => $user->getId(),
663 'wsUserName' => $user->getName(),
664 'wsToken' => $user->getToken(),
665 'foo' => 'foo 2!',
666 ), $backend->getData() );
667
668 $provider->persistSession( $backend, $this->getSentRequest() );
669 }
670
671 public function testUnpersistSession() {
672 $provider = new CookieSessionProvider( array(
673 'priority' => 1,
674 'sessionName' => 'MySessionName',
675 'cookieOptions' => array( 'prefix' => 'x' ),
676 ) );
677 $provider->setLogger( new \Psr\Log\NullLogger() );
678 $provider->setConfig( $this->getConfig() );
679 $provider->setManager( SessionManager::singleton() );
680
681 $request = new \FauxRequest();
682 $provider->unpersistSession( $request );
683 $this->assertSame( '', $request->response()->getCookie( 'MySessionName' ) );
684 $this->assertSame( '', $request->response()->getCookie( 'xUserID' ) );
685 $this->assertSame( null, $request->response()->getCookie( 'xUserName' ) );
686 $this->assertSame( '', $request->response()->getCookie( 'xToken' ) );
687 $this->assertSame( '', $request->response()->getCookie( 'forceHTTPS' ) );
688
689 $provider->unpersistSession( $this->getSentRequest() );
690 }
691
692 public function testSetLoggedOutCookie() {
693 $provider = \TestingAccessWrapper::newFromObject( new CookieSessionProvider( array(
694 'priority' => 1,
695 'sessionName' => 'MySessionName',
696 'cookieOptions' => array( 'prefix' => 'x' ),
697 ) ) );
698 $provider->setLogger( new \Psr\Log\NullLogger() );
699 $provider->setConfig( $this->getConfig() );
700 $provider->setManager( SessionManager::singleton() );
701
702 $t1 = time();
703 $t2 = time() - 86400 * 2;
704
705 // Set it
706 $request = new \FauxRequest();
707 $provider->setLoggedOutCookie( $t1, $request );
708 $this->assertSame( (string)$t1, $request->response()->getCookie( 'xLoggedOut' ) );
709
710 // Too old
711 $request = new \FauxRequest();
712 $provider->setLoggedOutCookie( $t2, $request );
713 $this->assertSame( null, $request->response()->getCookie( 'xLoggedOut' ) );
714
715 // Don't reset if it's already set
716 $request = new \FauxRequest();
717 $request->setCookies( array(
718 'xLoggedOut' => $t1,
719 ), '' );
720 $provider->setLoggedOutCookie( $t1, $request );
721 $this->assertSame( null, $request->response()->getCookie( 'xLoggedOut' ) );
722 }
723
724 /**
725 * To be mocked for hooks, since PHPUnit can't otherwise mock methods that
726 * take references.
727 */
728 public function onUserSetCookies( $user, &$sessionData, &$cookies ) {
729 }
730
731 }