Improve documentation of foreign-structured-upload-form-label-own-work-message-local
[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->assertNull( $info->getUserInfo() );
188 $this->assertFalse( $info->forceHTTPS() );
189
190 // User, no session key
191 $request = new \FauxRequest();
192 $request->setCookies( array(
193 'xUserID' => $id,
194 'xToken' => $token,
195 ), '' );
196 $info = $provider->provideSessionInfo( $request );
197 $this->assertNotNull( $info );
198 $this->assertSame( $params['priority'], $info->getPriority() );
199 $this->assertNotSame( $sessionId, $info->getId() );
200 $this->assertNotNull( $info->getUserInfo() );
201 $this->assertSame( $id, $info->getUserInfo()->getId() );
202 $this->assertSame( $name, $info->getUserInfo()->getName() );
203 $this->assertFalse( $info->forceHTTPS() );
204
205 // User and session key
206 $request = new \FauxRequest();
207 $request->setCookies( array(
208 'session' => $sessionId,
209 'xUserID' => $id,
210 'xToken' => $token,
211 ), '' );
212 $info = $provider->provideSessionInfo( $request );
213 $this->assertNotNull( $info );
214 $this->assertSame( $params['priority'], $info->getPriority() );
215 $this->assertSame( $sessionId, $info->getId() );
216 $this->assertNotNull( $info->getUserInfo() );
217 $this->assertSame( $id, $info->getUserInfo()->getId() );
218 $this->assertSame( $name, $info->getUserInfo()->getName() );
219 $this->assertFalse( $info->forceHTTPS() );
220
221 // User with bad token
222 $request = new \FauxRequest();
223 $request->setCookies( array(
224 'session' => $sessionId,
225 'xUserID' => $id,
226 'xToken' => 'BADTOKEN',
227 ), '' );
228 $info = $provider->provideSessionInfo( $request );
229 $this->assertNull( $info );
230
231 // User id with no token
232 $request = new \FauxRequest();
233 $request->setCookies( array(
234 'session' => $sessionId,
235 'xUserID' => $id,
236 ), '' );
237 $info = $provider->provideSessionInfo( $request );
238 $this->assertNotNull( $info );
239 $this->assertSame( $params['priority'], $info->getPriority() );
240 $this->assertSame( $sessionId, $info->getId() );
241 $this->assertNotNull( $info->getUserInfo() );
242 $this->assertFalse( $info->getUserInfo()->isVerified() );
243 $this->assertSame( $id, $info->getUserInfo()->getId() );
244 $this->assertSame( $name, $info->getUserInfo()->getName() );
245 $this->assertFalse( $info->forceHTTPS() );
246
247 $request = new \FauxRequest();
248 $request->setCookies( array(
249 'xUserID' => $id,
250 ), '' );
251 $info = $provider->provideSessionInfo( $request );
252 $this->assertNull( $info );
253
254 // User and session key, with forceHTTPS flag
255 $request = new \FauxRequest();
256 $request->setCookies( array(
257 'session' => $sessionId,
258 'xUserID' => $id,
259 'xToken' => $token,
260 'forceHTTPS' => true,
261 ), '' );
262 $info = $provider->provideSessionInfo( $request );
263 $this->assertNotNull( $info );
264 $this->assertSame( $params['priority'], $info->getPriority() );
265 $this->assertSame( $sessionId, $info->getId() );
266 $this->assertNotNull( $info->getUserInfo() );
267 $this->assertSame( $id, $info->getUserInfo()->getId() );
268 $this->assertSame( $name, $info->getUserInfo()->getName() );
269 $this->assertTrue( $info->forceHTTPS() );
270
271 // Invalid user id
272 $request = new \FauxRequest();
273 $request->setCookies( array(
274 'session' => $sessionId,
275 'xUserID' => '-1',
276 ), '' );
277 $info = $provider->provideSessionInfo( $request );
278 $this->assertNull( $info );
279
280 // User id with matching name
281 $request = new \FauxRequest();
282 $request->setCookies( array(
283 'session' => $sessionId,
284 'xUserID' => $id,
285 'xUserName' => $name,
286 ), '' );
287 $info = $provider->provideSessionInfo( $request );
288 $this->assertNotNull( $info );
289 $this->assertSame( $params['priority'], $info->getPriority() );
290 $this->assertSame( $sessionId, $info->getId() );
291 $this->assertNotNull( $info->getUserInfo() );
292 $this->assertFalse( $info->getUserInfo()->isVerified() );
293 $this->assertSame( $id, $info->getUserInfo()->getId() );
294 $this->assertSame( $name, $info->getUserInfo()->getName() );
295 $this->assertFalse( $info->forceHTTPS() );
296
297 // User id with wrong name
298 $request = new \FauxRequest();
299 $request->setCookies( array(
300 'session' => $sessionId,
301 'xUserID' => $id,
302 'xUserName' => 'Wrong',
303 ), '' );
304 $info = $provider->provideSessionInfo( $request );
305 $this->assertNull( $info );
306 }
307
308 public function testGetVaryCookies() {
309 $provider = new CookieSessionProvider( array(
310 'priority' => 1,
311 'sessionName' => 'MySessionName',
312 'cookieOptions' => array( 'prefix' => 'MyCookiePrefix' ),
313 ) );
314 $this->assertArrayEquals( array(
315 'MyCookiePrefixToken',
316 'MyCookiePrefixLoggedOut',
317 'MySessionName',
318 'forceHTTPS',
319 ), $provider->getVaryCookies() );
320 }
321
322 public function testSuggestLoginUsername() {
323 $provider = new CookieSessionProvider( array(
324 'priority' => 1,
325 'sessionName' => 'MySessionName',
326 'cookieOptions' => array( 'prefix' => 'x' ),
327 ) );
328
329 $request = new \FauxRequest();
330 $this->assertEquals( null, $provider->suggestLoginUsername( $request ) );
331
332 $request->setCookies( array(
333 'xUserName' => 'Example',
334 ), '' );
335 $this->assertEquals( 'Example', $provider->suggestLoginUsername( $request ) );
336 }
337
338 public function testPersistSession() {
339 $this->setMwGlobals( array( 'wgCookieExpiration' => 100 ) );
340
341 $provider = new CookieSessionProvider( array(
342 'priority' => 1,
343 'sessionName' => 'MySessionName',
344 'callUserSetCookiesHook' => false,
345 'cookieOptions' => array( 'prefix' => 'x' ),
346 ) );
347 $config = $this->getConfig();
348 $provider->setLogger( new \TestLogger() );
349 $provider->setConfig( $config );
350 $provider->setManager( SessionManager::singleton() );
351
352 $sessionId = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
353 $store = new \HashBagOStuff();
354 $user = User::newFromName( 'UTSysop' );
355 $anon = new User;
356
357 $backend = new SessionBackend(
358 new SessionId( $sessionId ),
359 new SessionInfo( SessionInfo::MIN_PRIORITY, array(
360 'provider' => $provider,
361 'id' => $sessionId,
362 'persisted' => true,
363 'idIsSafe' => true,
364 ) ),
365 $store,
366 new \Psr\Log\NullLogger(),
367 10
368 );
369 \TestingAccessWrapper::newFromObject( $backend )->usePhpSessionHandling = false;
370
371 $mock = $this->getMock( 'stdClass', array( 'onUserSetCookies' ) );
372 $mock->expects( $this->never() )->method( 'onUserSetCookies' );
373 $this->mergeMwGlobalArrayValue( 'wgHooks', array( 'UserSetCookies' => array( $mock ) ) );
374
375 // Anonymous user
376 $backend->setUser( $anon );
377 $backend->setRememberUser( true );
378 $backend->setForceHTTPS( false );
379 $request = new \FauxRequest();
380 $provider->persistSession( $backend, $request );
381 $this->assertSame( $sessionId, $request->response()->getCookie( 'MySessionName' ) );
382 $this->assertSame( '', $request->response()->getCookie( 'xUserID' ) );
383 $this->assertSame( null, $request->response()->getCookie( 'xUserName' ) );
384 $this->assertSame( '', $request->response()->getCookie( 'xToken' ) );
385 $this->assertSame( null, $request->response()->getCookie( 'forceHTTPS' ) );
386 $this->assertSame( array(), $backend->getData() );
387
388 // Logged-in user, no remember
389 $backend->setUser( $user );
390 $backend->setRememberUser( false );
391 $backend->setForceHTTPS( false );
392 $request = new \FauxRequest();
393 $provider->persistSession( $backend, $request );
394 $this->assertSame( $sessionId, $request->response()->getCookie( 'MySessionName' ) );
395 $this->assertSame( (string)$user->getId(), $request->response()->getCookie( 'xUserID' ) );
396 $this->assertSame( $user->getName(), $request->response()->getCookie( 'xUserName' ) );
397 $this->assertSame( '', $request->response()->getCookie( 'xToken' ) );
398 $this->assertSame( null, $request->response()->getCookie( 'forceHTTPS' ) );
399 $this->assertSame( array(), $backend->getData() );
400
401 // Logged-in user, remember
402 $backend->setUser( $user );
403 $backend->setRememberUser( true );
404 $backend->setForceHTTPS( true );
405 $request = new \FauxRequest();
406 $time = time();
407 $provider->persistSession( $backend, $request );
408 $this->assertSame( $sessionId, $request->response()->getCookie( 'MySessionName' ) );
409 $this->assertSame( (string)$user->getId(), $request->response()->getCookie( 'xUserID' ) );
410 $this->assertSame( $user->getName(), $request->response()->getCookie( 'xUserName' ) );
411 $this->assertSame( $user->getToken(), $request->response()->getCookie( 'xToken' ) );
412 $this->assertSame( 'true', $request->response()->getCookie( 'forceHTTPS' ) );
413 $this->assertSame( array(), $backend->getData() );
414 }
415
416 /**
417 * @dataProvider provideCookieData
418 * @param bool $secure
419 * @param bool $remember
420 */
421 public function testCookieData( $secure, $remember ) {
422 $this->setMwGlobals( array(
423 'wgCookieExpiration' => 100,
424 'wgSecureLogin' => false,
425 ) );
426
427 $provider = new CookieSessionProvider( array(
428 'priority' => 1,
429 'sessionName' => 'MySessionName',
430 'callUserSetCookiesHook' => false,
431 'cookieOptions' => array( 'prefix' => 'x' ),
432 ) );
433 $config = $this->getConfig();
434 $config->set( 'CookieSecure', false );
435 $provider->setLogger( new \TestLogger() );
436 $provider->setConfig( $config );
437 $provider->setManager( SessionManager::singleton() );
438
439 $sessionId = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
440 $user = User::newFromName( 'UTSysop' );
441 $this->assertFalse( $user->requiresHTTPS(), 'sanity check' );
442
443 $backend = new SessionBackend(
444 new SessionId( $sessionId ),
445 new SessionInfo( SessionInfo::MIN_PRIORITY, array(
446 'provider' => $provider,
447 'id' => $sessionId,
448 'persisted' => true,
449 'idIsSafe' => true,
450 ) ),
451 new \EmptyBagOStuff(),
452 new \Psr\Log\NullLogger(),
453 10
454 );
455 \TestingAccessWrapper::newFromObject( $backend )->usePhpSessionHandling = false;
456 $backend->setUser( $user );
457 $backend->setRememberUser( $remember );
458 $backend->setForceHTTPS( $secure );
459 $request = new \FauxRequest();
460 $time = time();
461 $provider->persistSession( $backend, $request );
462
463 $defaults = array(
464 'expire' => (int)100,
465 'path' => $config->get( 'CookiePath' ),
466 'domain' => $config->get( 'CookieDomain' ),
467 'secure' => $secure,
468 'httpOnly' => $config->get( 'CookieHttpOnly' ),
469 'raw' => false,
470 );
471 $extendedExpiry = $config->get( 'ExtendedLoginCookieExpiration' );
472 $extendedExpiry = (int)( $extendedExpiry === null ? 0 : $extendedExpiry );
473 $this->assertEquals( array( 'UserID', 'Token' ), $config->get( 'ExtendedLoginCookies' ),
474 'sanity check' );
475 $expect = array(
476 'MySessionName' => array(
477 'value' => (string)$sessionId,
478 'expire' => 0,
479 ) + $defaults,
480 'xUserID' => array(
481 'value' => (string)$user->getId(),
482 'expire' => $extendedExpiry,
483 ) + $defaults,
484 'xUserName' => array(
485 'value' => $user->getName(),
486 ) + $defaults,
487 'xToken' => array(
488 'value' => $remember ? $user->getToken() : '',
489 'expire' => $remember ? $extendedExpiry : -31536000,
490 ) + $defaults,
491 'forceHTTPS' => !$secure ? null : array(
492 'value' => 'true',
493 'secure' => false,
494 'expire' => $remember ? $defaults['expire'] : null,
495 ) + $defaults,
496 );
497 foreach ( $expect as $key => $value ) {
498 $actual = $request->response()->getCookieData( $key );
499 if ( $actual && $actual['expire'] > 0 ) {
500 // Round expiry so we don't randomly fail if the seconds ticked during the test.
501 $actual['expire'] = round( $actual['expire'] - $time, -2 );
502 }
503 $this->assertEquals( $value, $actual, "Cookie $key" );
504 }
505 }
506
507 public static function provideCookieData() {
508 return array(
509 array( false, false ),
510 array( false, true ),
511 array( true, false ),
512 array( true, true ),
513 );
514 }
515
516 protected function getSentRequest() {
517 $sentResponse = $this->getMock( 'FauxResponse', array( 'headersSent', 'setCookie', 'header' ) );
518 $sentResponse->expects( $this->any() )->method( 'headersSent' )
519 ->will( $this->returnValue( true ) );
520 $sentResponse->expects( $this->never() )->method( 'setCookie' );
521 $sentResponse->expects( $this->never() )->method( 'header' );
522
523 $sentRequest = $this->getMock( 'FauxRequest', array( 'response' ) );
524 $sentRequest->expects( $this->any() )->method( 'response' )
525 ->will( $this->returnValue( $sentResponse ) );
526 return $sentRequest;
527 }
528
529 public function testPersistSessionWithHook() {
530 $that = $this;
531
532 $provider = new CookieSessionProvider( array(
533 'priority' => 1,
534 'sessionName' => 'MySessionName',
535 'callUserSetCookiesHook' => true,
536 'cookieOptions' => array( 'prefix' => 'x' ),
537 ) );
538 $provider->setLogger( new \Psr\Log\NullLogger() );
539 $provider->setConfig( $this->getConfig() );
540 $provider->setManager( SessionManager::singleton() );
541
542 $sessionId = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
543 $store = new \HashBagOStuff();
544 $user = User::newFromName( 'UTSysop' );
545 $anon = new User;
546
547 $backend = new SessionBackend(
548 new SessionId( $sessionId ),
549 new SessionInfo( SessionInfo::MIN_PRIORITY, array(
550 'provider' => $provider,
551 'id' => $sessionId,
552 'persisted' => true,
553 'idIsSafe' => true,
554 ) ),
555 $store,
556 new \Psr\Log\NullLogger(),
557 10
558 );
559 \TestingAccessWrapper::newFromObject( $backend )->usePhpSessionHandling = false;
560
561 // Anonymous user
562 $mock = $this->getMock( 'stdClass', array( 'onUserSetCookies' ) );
563 $mock->expects( $this->never() )->method( 'onUserSetCookies' );
564 $this->mergeMwGlobalArrayValue( 'wgHooks', array( 'UserSetCookies' => array( $mock ) ) );
565 $backend->setUser( $anon );
566 $backend->setRememberUser( true );
567 $backend->setForceHTTPS( false );
568 $request = new \FauxRequest();
569 $provider->persistSession( $backend, $request );
570 $this->assertSame( $sessionId, $request->response()->getCookie( 'MySessionName' ) );
571 $this->assertSame( '', $request->response()->getCookie( 'xUserID' ) );
572 $this->assertSame( null, $request->response()->getCookie( 'xUserName' ) );
573 $this->assertSame( '', $request->response()->getCookie( 'xToken' ) );
574 $this->assertSame( null, $request->response()->getCookie( 'forceHTTPS' ) );
575 $this->assertSame( array(), $backend->getData() );
576
577 $provider->persistSession( $backend, $this->getSentRequest() );
578
579 // Logged-in user, no remember
580 $mock = $this->getMock( __CLASS__, array( 'onUserSetCookies' ) );
581 $mock->expects( $this->once() )->method( 'onUserSetCookies' )
582 ->will( $this->returnCallback( function ( $u, &$sessionData, &$cookies ) use ( $that, $user ) {
583 $that->assertSame( $user, $u );
584 $that->assertEquals( array(
585 'wsUserID' => $user->getId(),
586 'wsUserName' => $user->getName(),
587 'wsToken' => $user->getToken(),
588 ), $sessionData );
589 $that->assertEquals( array(
590 'UserID' => $user->getId(),
591 'UserName' => $user->getName(),
592 'Token' => false,
593 ), $cookies );
594
595 $sessionData['foo'] = 'foo!';
596 $cookies['bar'] = 'bar!';
597 return true;
598 } ) );
599 $this->mergeMwGlobalArrayValue( 'wgHooks', array( 'UserSetCookies' => array( $mock ) ) );
600 $backend->setUser( $user );
601 $backend->setRememberUser( false );
602 $backend->setForceHTTPS( false );
603 $backend->setLoggedOutTimestamp( $loggedOut = time() );
604 $request = new \FauxRequest();
605 $provider->persistSession( $backend, $request );
606 $this->assertSame( $sessionId, $request->response()->getCookie( 'MySessionName' ) );
607 $this->assertSame( (string)$user->getId(), $request->response()->getCookie( 'xUserID' ) );
608 $this->assertSame( $user->getName(), $request->response()->getCookie( 'xUserName' ) );
609 $this->assertSame( '', $request->response()->getCookie( 'xToken' ) );
610 $this->assertSame( null, $request->response()->getCookie( 'forceHTTPS' ) );
611 $this->assertSame( 'bar!', $request->response()->getCookie( 'xbar' ) );
612 $this->assertSame( (string)$loggedOut, $request->response()->getCookie( 'xLoggedOut' ) );
613 $this->assertEquals( array(
614 'wsUserID' => $user->getId(),
615 'wsUserName' => $user->getName(),
616 'wsToken' => $user->getToken(),
617 'foo' => 'foo!',
618 ), $backend->getData() );
619
620 $provider->persistSession( $backend, $this->getSentRequest() );
621
622 // Logged-in user, remember
623 $mock = $this->getMock( __CLASS__, array( 'onUserSetCookies' ) );
624 $mock->expects( $this->once() )->method( 'onUserSetCookies' )
625 ->will( $this->returnCallback( function ( $u, &$sessionData, &$cookies ) use ( $that, $user ) {
626 $that->assertSame( $user, $u );
627 $that->assertEquals( array(
628 'wsUserID' => $user->getId(),
629 'wsUserName' => $user->getName(),
630 'wsToken' => $user->getToken(),
631 ), $sessionData );
632 $that->assertEquals( array(
633 'UserID' => $user->getId(),
634 'UserName' => $user->getName(),
635 'Token' => $user->getToken(),
636 ), $cookies );
637
638 $sessionData['foo'] = 'foo 2!';
639 $cookies['bar'] = 'bar 2!';
640 return true;
641 } ) );
642 $this->mergeMwGlobalArrayValue( 'wgHooks', array( 'UserSetCookies' => array( $mock ) ) );
643 $backend->setUser( $user );
644 $backend->setRememberUser( true );
645 $backend->setForceHTTPS( true );
646 $backend->setLoggedOutTimestamp( 0 );
647 $request = new \FauxRequest();
648 $provider->persistSession( $backend, $request );
649 $this->assertSame( $sessionId, $request->response()->getCookie( 'MySessionName' ) );
650 $this->assertSame( (string)$user->getId(), $request->response()->getCookie( 'xUserID' ) );
651 $this->assertSame( $user->getName(), $request->response()->getCookie( 'xUserName' ) );
652 $this->assertSame( $user->getToken(), $request->response()->getCookie( 'xToken' ) );
653 $this->assertSame( 'true', $request->response()->getCookie( 'forceHTTPS' ) );
654 $this->assertSame( 'bar 2!', $request->response()->getCookie( 'xbar' ) );
655 $this->assertSame( null, $request->response()->getCookie( 'xLoggedOut' ) );
656 $this->assertEquals( array(
657 'wsUserID' => $user->getId(),
658 'wsUserName' => $user->getName(),
659 'wsToken' => $user->getToken(),
660 'foo' => 'foo 2!',
661 ), $backend->getData() );
662
663 $provider->persistSession( $backend, $this->getSentRequest() );
664 }
665
666 public function testUnpersistSession() {
667 $provider = new CookieSessionProvider( array(
668 'priority' => 1,
669 'sessionName' => 'MySessionName',
670 'cookieOptions' => array( 'prefix' => 'x' ),
671 ) );
672 $provider->setLogger( new \Psr\Log\NullLogger() );
673 $provider->setConfig( $this->getConfig() );
674 $provider->setManager( SessionManager::singleton() );
675
676 $request = new \FauxRequest();
677 $provider->unpersistSession( $request );
678 $this->assertSame( '', $request->response()->getCookie( 'MySessionName' ) );
679 $this->assertSame( '', $request->response()->getCookie( 'xUserID' ) );
680 $this->assertSame( null, $request->response()->getCookie( 'xUserName' ) );
681 $this->assertSame( '', $request->response()->getCookie( 'xToken' ) );
682 $this->assertSame( '', $request->response()->getCookie( 'forceHTTPS' ) );
683
684 $provider->unpersistSession( $this->getSentRequest() );
685 }
686
687 public function testSetLoggedOutCookie() {
688 $provider = \TestingAccessWrapper::newFromObject( new CookieSessionProvider( array(
689 'priority' => 1,
690 'sessionName' => 'MySessionName',
691 'cookieOptions' => array( 'prefix' => 'x' ),
692 ) ) );
693 $provider->setLogger( new \Psr\Log\NullLogger() );
694 $provider->setConfig( $this->getConfig() );
695 $provider->setManager( SessionManager::singleton() );
696
697 $t1 = time();
698 $t2 = time() - 86400 * 2;
699
700 // Set it
701 $request = new \FauxRequest();
702 $provider->setLoggedOutCookie( $t1, $request );
703 $this->assertSame( (string)$t1, $request->response()->getCookie( 'xLoggedOut' ) );
704
705 // Too old
706 $request = new \FauxRequest();
707 $provider->setLoggedOutCookie( $t2, $request );
708 $this->assertSame( null, $request->response()->getCookie( 'xLoggedOut' ) );
709
710 // Don't reset if it's already set
711 $request = new \FauxRequest();
712 $request->setCookies( array(
713 'xLoggedOut' => $t1,
714 ), '' );
715 $provider->setLoggedOutCookie( $t1, $request );
716 $this->assertSame( null, $request->response()->getCookie( 'xLoggedOut' ) );
717 }
718
719 /**
720 * To be mocked for hooks, since PHPUnit can't otherwise mock methods that
721 * take references.
722 */
723 public function onUserSetCookies( $user, &$sessionData, &$cookies ) {
724 }
725
726 }