7 use Wikimedia\TestingAccessWrapper;
15 const SESSIONID =
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
30 if ( !$this->config ) {
31 $this->config = new \HashConfig();
32 $this->manager =
null;
34 if ( !$this->
store ) {
36 $this->manager =
null;
39 $logger = new \Psr\Log\NullLogger();
40 if ( !$this->manager ) {
42 'store' => $this->
store,
44 'config' => $this->config,
48 if ( !$this->provider ) {
49 $this->provider = new \DummySessionProvider();
51 $this->provider->setLogger( $logger );
52 $this->provider->setConfig( $this->config );
53 $this->provider->setManager( $this->manager );
56 'provider' => $this->provider,
57 'id' => $id ?: self::SESSIONID,
65 $priv = TestingAccessWrapper::newFromObject( $backend );
66 $priv->persist =
false;
67 $priv->requests = [ 100 => new \FauxRequest() ];
68 $priv->requests[100]->setSessionId( $id );
69 $priv->usePhpSessionHandling =
false;
71 $manager = TestingAccessWrapper::newFromObject( $this->manager );
74 $manager->sessionProviders = [ (
string)$this->provider => $this->provider ];
84 'provider' => $this->provider,
85 'id' => self::SESSIONID,
91 $logger = new \Psr\Log\NullLogger();
94 $this->fail(
'Expected exception not thrown' );
95 }
catch ( \InvalidArgumentException $ex ) {
97 "Refusing to create session for unverified user {$info->getUserInfo()}",
103 'id' => self::SESSIONID,
110 $this->fail(
'Expected exception not thrown' );
111 }
catch ( \InvalidArgumentException $ex ) {
112 $this->assertSame(
'Cannot create session without a provider', $ex->getMessage() );
116 'provider' => $this->provider,
117 'id' => self::SESSIONID,
122 $id =
new SessionId(
'!' . $info->getId() );
125 $this->fail(
'Expected exception not thrown' );
126 }
catch ( \InvalidArgumentException $ex ) {
128 'SessionId and SessionInfo don\'t match',
134 'provider' => $this->provider,
135 'id' => self::SESSIONID,
142 $this->assertSame( self::SESSIONID, $backend->
getId() );
143 $this->assertSame( $id, $backend->getSessionId() );
144 $this->assertSame( $this->provider, $backend->getProvider() );
145 $this->assertInstanceOf(
'User', $backend->getUser() );
146 $this->assertSame(
'UTSysop', $backend->getUser()->getName() );
147 $this->assertSame( $info->wasPersisted(), $backend->isPersistent() );
148 $this->assertSame( $info->wasRemembered(), $backend->shouldRememberUser() );
149 $this->assertSame( $info->forceHTTPS(), $backend->shouldForceHTTPS() );
151 $expire = time() + 100;
152 $this->
store->setSessionMeta( self::SESSIONID, [
'expires' => $expire ], 2 );
155 'provider' => $this->provider,
156 'id' => self::SESSIONID,
158 'forceHTTPS' =>
true,
159 'metadata' => [
'foo' ],
164 $this->assertSame( self::SESSIONID, $backend->
getId() );
165 $this->assertSame( $id, $backend->getSessionId() );
166 $this->assertSame( $this->provider, $backend->getProvider() );
167 $this->assertInstanceOf(
'User', $backend->getUser() );
168 $this->assertTrue( $backend->getUser()->isAnon() );
169 $this->assertSame( $info->wasPersisted(), $backend->isPersistent() );
170 $this->assertSame( $info->wasRemembered(), $backend->shouldRememberUser() );
171 $this->assertSame( $info->forceHTTPS(), $backend->shouldForceHTTPS() );
172 $this->assertSame( $expire, TestingAccessWrapper::newFromObject( $backend )->expires );
173 $this->assertSame( [
'foo' ], $backend->getProviderMetadata() );
178 $priv = TestingAccessWrapper::newFromObject( $backend );
179 $priv->requests = [];
181 $manager = TestingAccessWrapper::newFromObject( $this->manager );
183 $request1 = new \FauxRequest();
184 $session1 = $backend->getSession( $request1 );
185 $request2 = new \FauxRequest();
186 $session2 = $backend->getSession( $request2 );
190 $this->assertSame( 2,
count( $priv->requests ) );
192 $index = TestingAccessWrapper::newFromObject( $session1 )->index;
194 $this->assertSame( $request1, $backend->getRequest( $index ) );
195 $this->assertSame(
null, $backend->suggestLoginUsername( $index ) );
196 $request1->setCookie(
'UserName',
'Example' );
197 $this->assertSame(
'Example', $backend->suggestLoginUsername( $index ) );
200 $this->assertSame( 1,
count( $priv->requests ) );
201 $this->assertArrayHasKey( $backend->getId(),
$manager->allSessionBackends );
202 $this->assertSame( $backend,
$manager->allSessionBackends[$backend->getId()] );
204 $backend->getRequest( $index );
205 $this->fail(
'Expected exception not thrown' );
206 }
catch ( \InvalidArgumentException $ex ) {
207 $this->assertSame(
'Invalid session index', $ex->getMessage() );
210 $backend->suggestLoginUsername( $index );
211 $this->fail(
'Expected exception not thrown' );
212 }
catch ( \InvalidArgumentException $ex ) {
213 $this->assertSame(
'Invalid session index', $ex->getMessage() );
217 $this->assertSame( 0,
count( $priv->requests ) );
218 $this->assertArrayNotHasKey( $backend->getId(),
$manager->allSessionBackends );
219 $this->assertArrayHasKey( $backend->getId(),
$manager->allSessionIds );
224 $priv = TestingAccessWrapper::newFromObject( $backend );
225 $priv->providerMetadata = [
'dummy' ];
228 $backend->setProviderMetadata(
'foo' );
229 $this->fail(
'Expected exception not thrown' );
230 }
catch ( \InvalidArgumentException $ex ) {
231 $this->assertSame(
'$metadata must be an array or null', $ex->getMessage() );
235 $backend->setProviderMetadata( (
object)[] );
236 $this->fail(
'Expected exception not thrown' );
237 }
catch ( \InvalidArgumentException $ex ) {
238 $this->assertSame(
'$metadata must be an array or null', $ex->getMessage() );
241 $this->assertFalse( $this->
store->getSession( self::SESSIONID ),
'sanity check' );
242 $backend->setProviderMetadata( [
'dummy' ] );
243 $this->assertFalse( $this->
store->getSession( self::SESSIONID ) );
245 $this->assertFalse( $this->
store->getSession( self::SESSIONID ),
'sanity check' );
246 $backend->setProviderMetadata( [
'test' ] );
247 $this->assertNotFalse( $this->
store->getSession( self::SESSIONID ) );
248 $this->assertSame( [
'test' ], $backend->getProviderMetadata() );
249 $this->
store->deleteSession( self::SESSIONID );
251 $this->assertFalse( $this->
store->getSession( self::SESSIONID ),
'sanity check' );
252 $backend->setProviderMetadata(
null );
253 $this->assertNotFalse( $this->
store->getSession( self::SESSIONID ) );
254 $this->assertSame(
null, $backend->getProviderMetadata() );
255 $this->
store->deleteSession( self::SESSIONID );
261 $builder = $this->getMockBuilder(
'DummySessionProvider' )
262 ->setMethods( [
'persistsSessionId',
'sessionIdWasReset' ] );
264 $this->provider = $builder->getMock();
265 $this->provider->expects( $this->
any() )->method(
'persistsSessionId' )
266 ->will( $this->returnValue(
false ) );
267 $this->provider->expects( $this->never() )->method(
'sessionIdWasReset' );
269 $manager = TestingAccessWrapper::newFromObject( $this->manager );
270 $sessionId = $backend->getSessionId();
272 $this->assertSame( self::SESSIONID, $backend->getId() );
273 $this->assertSame( $backend->getId(), $sessionId->getId() );
274 $this->assertSame( $id, session_id() );
275 $this->assertSame( $backend,
$manager->allSessionBackends[self::SESSIONID] );
277 $this->provider = $builder->getMock();
278 $this->provider->expects( $this->
any() )->method(
'persistsSessionId' )
279 ->will( $this->returnValue(
true ) );
281 $this->provider->expects( $this->once() )->method(
'sessionIdWasReset' )
282 ->with( $this->identicalTo( $backend ), $this->identicalTo( self::SESSIONID ) );
283 $manager = TestingAccessWrapper::newFromObject( $this->manager );
284 $sessionId = $backend->getSessionId();
286 $this->assertNotEquals( self::SESSIONID, $backend->getId() );
287 $this->assertSame( $backend->getId(), $sessionId->getId() );
288 $this->assertInternalType(
'array', $this->
store->getSession( $backend->getId() ) );
289 $this->assertFalse( $this->
store->getSession( self::SESSIONID ) );
290 $this->assertSame( $id, session_id() );
291 $this->assertArrayNotHasKey( self::SESSIONID,
$manager->allSessionBackends );
292 $this->assertArrayHasKey( $backend->getId(),
$manager->allSessionBackends );
293 $this->assertSame( $backend,
$manager->allSessionBackends[$backend->getId()] );
297 $this->provider = $this->getMockBuilder(
'DummySessionProvider' )
298 ->setMethods( [
'persistSession' ] )->getMock();
299 $this->provider->expects( $this->once() )->method(
'persistSession' );
301 $this->assertFalse( $backend->isPersistent(),
'sanity check' );
305 $this->assertTrue( $backend->isPersistent(),
'sanity check' );
307 $this->provider =
null;
309 $wrap = TestingAccessWrapper::newFromObject( $backend );
310 $wrap->persist =
true;
313 $this->assertNotEquals( 0, $wrap->expires );
317 $this->provider = $this->getMockBuilder(
'DummySessionProvider' )
318 ->setMethods( [
'unpersistSession' ] )->getMock();
319 $this->provider->expects( $this->once() )->method(
'unpersistSession' );
321 $wrap = TestingAccessWrapper::newFromObject( $backend );
322 $wrap->store = new \CachedBagOStuff( $this->
store );
323 $wrap->persist =
true;
324 $wrap->dataDirty =
true;
327 $this->assertTrue( $backend->isPersistent(),
'sanity check' );
328 $this->assertNotFalse( $this->
store->getSession( self::SESSIONID ),
'sanity check' );
330 $backend->unpersist();
331 $this->assertFalse( $backend->isPersistent() );
332 $this->assertFalse( $this->
store->getSession( self::SESSIONID ) );
333 $this->assertNotFalse( $wrap->store->get(
wfMemcKey(
'MWSession', self::SESSIONID ) ) );
339 $remembered = $backend->shouldRememberUser();
340 $backend->setRememberUser( !$remembered );
341 $this->assertNotEquals( $remembered, $backend->shouldRememberUser() );
342 $backend->setRememberUser( $remembered );
343 $this->assertEquals( $remembered, $backend->shouldRememberUser() );
349 $force = $backend->shouldForceHTTPS();
350 $backend->setForceHTTPS( !$force );
351 $this->assertNotEquals( $force, $backend->shouldForceHTTPS() );
352 $backend->setForceHTTPS( $force );
353 $this->assertEquals( $force, $backend->shouldForceHTTPS() );
359 $backend->setLoggedOutTimestamp( 42 );
360 $this->assertSame( 42, $backend->getLoggedOutTimestamp() );
361 $backend->setLoggedOutTimestamp(
'123' );
362 $this->assertSame( 123, $backend->getLoggedOutTimestamp() );
366 $user = static::getTestSysop()->getUser();
368 $this->provider = $this->getMockBuilder(
'DummySessionProvider' )
369 ->setMethods( [
'canChangeUser' ] )->getMock();
370 $this->provider->expects( $this->
any() )->method(
'canChangeUser' )
371 ->will( $this->returnValue(
false ) );
373 $this->assertFalse( $backend->canSetUser() );
375 $backend->setUser(
$user );
376 $this->fail(
'Expected exception not thrown' );
377 }
catch ( \BadMethodCallException $ex ) {
379 'Cannot set user on this session; check $session->canSetUser() first',
383 $this->assertNotSame(
$user, $backend->getUser() );
385 $this->provider =
null;
387 $this->assertTrue( $backend->canSetUser() );
388 $this->assertNotSame(
$user, $backend->getUser(),
'sanity check' );
389 $backend->setUser(
$user );
390 $this->assertSame(
$user, $backend->getUser() );
395 $priv = TestingAccessWrapper::newFromObject( $backend );
396 $priv->dataDirty =
false;
398 $this->assertTrue( $priv->dataDirty );
403 $data = $backend->getData();
404 $this->assertSame( [], $data );
405 $this->assertTrue( TestingAccessWrapper::newFromObject( $backend )->dataDirty );
406 $data[
'???'] =
'!!!';
407 $this->assertSame( [
'???' =>
'!!!' ], $data );
409 $testData = [
'foo' =>
'foo!',
'bar', [
'baz', null ] ];
410 $this->
store->setSessionData( self::SESSIONID, $testData );
412 $this->assertSame( $testData, $backend->getData() );
413 $this->assertFalse( TestingAccessWrapper::newFromObject( $backend )->dataDirty );
418 $priv = TestingAccessWrapper::newFromObject( $backend );
420 $priv->data = [
'foo' => 1 ];
421 $priv->dataDirty =
false;
422 $backend->addData( [
'foo' => 1 ] );
423 $this->assertSame( [
'foo' => 1 ], $priv->data );
424 $this->assertFalse( $priv->dataDirty );
426 $priv->data = [
'foo' => 1 ];
427 $priv->dataDirty =
false;
428 $backend->addData( [
'foo' =>
'1' ] );
429 $this->assertSame( [
'foo' =>
'1' ], $priv->data );
430 $this->assertTrue( $priv->dataDirty );
432 $priv->data = [
'foo' => 1 ];
433 $priv->dataDirty =
false;
434 $backend->addData( [
'bar' => 2 ] );
435 $this->assertSame( [
'foo' => 1,
'bar' => 2 ], $priv->data );
436 $this->assertTrue( $priv->dataDirty );
442 $priv = TestingAccessWrapper::newFromObject( $backend );
443 $priv->persist =
true;
446 $this->onSessionMetadataCalled =
false;
447 $priv->metaDirty =
true;
449 $this->assertTrue( $this->onSessionMetadataCalled,
'sanity check' );
451 $this->onSessionMetadataCalled =
false;
452 $priv->metaDirty =
true;
454 $this->assertTrue( $this->onSessionMetadataCalled,
'sanity check' );
456 $delay = $backend->delaySave();
459 $this->onSessionMetadataCalled =
false;
460 $priv->metaDirty =
true;
462 $this->assertFalse( $this->onSessionMetadataCalled );
466 $this->assertTrue( $this->onSessionMetadataCalled );
469 $this->onSessionMetadataCalled =
false;
470 $priv->metaDirty =
true;
471 \Wikimedia\ScopedCallback::consume( $delay );
472 $this->assertTrue( $this->onSessionMetadataCalled );
475 $delay1 = $backend->delaySave();
476 $delay2 = $backend->delaySave();
477 $delay3 = $backend->delaySave();
478 $this->onSessionMetadataCalled =
false;
479 $priv->metaDirty =
true;
481 $this->assertFalse( $this->onSessionMetadataCalled );
482 \Wikimedia\ScopedCallback::consume( $delay3 );
483 $this->assertFalse( $this->onSessionMetadataCalled );
484 \Wikimedia\ScopedCallback::consume( $delay1 );
485 $this->assertFalse( $this->onSessionMetadataCalled );
486 \Wikimedia\ScopedCallback::consume( $delay2 );
487 $this->assertTrue( $this->onSessionMetadataCalled );
491 $user = static::getTestSysop()->getUser();
493 $testData = [
'foo' =>
'foo!',
'bar', [
'baz', null ] ];
495 $neverHook = $this->getMockBuilder( __CLASS__ )
496 ->setMethods( [
'onSessionMetadata' ] )->getMock();
497 $neverHook->expects( $this->never() )->method(
'onSessionMetadata' );
499 $builder = $this->getMockBuilder(
'DummySessionProvider' )
500 ->setMethods( [
'persistSession',
'unpersistSession' ] );
502 $neverProvider = $builder->getMock();
503 $neverProvider->expects( $this->never() )->method(
'persistSession' );
504 $neverProvider->expects( $this->never() )->method(
'unpersistSession' );
507 $this->provider = $neverProvider;
509 $this->
store->setSessionData( self::SESSIONID, $testData );
511 $this->
store->deleteSession( self::SESSIONID );
512 $this->assertFalse( $backend->isPersistent(),
'sanity check' );
513 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
false;
514 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
false;
516 $this->assertFalse( $this->
store->getSession( self::SESSIONID ),
'making sure it didn\'t save' );
519 $this->provider = $builder->getMock();
520 $this->provider->expects( $this->never() )->method(
'persistSession' );
521 $this->provider->expects( $this->atLeastOnce() )->method(
'unpersistSession' );
523 $this->
store->setSessionData( self::SESSIONID, $testData );
525 $this->
store->deleteSession( self::SESSIONID );
526 TestingAccessWrapper::newFromObject( $backend )->persist =
false;
527 TestingAccessWrapper::newFromObject( $backend )->forcePersist =
true;
528 $this->assertFalse( $backend->isPersistent(),
'sanity check' );
529 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
false;
530 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
false;
532 $this->assertFalse( $this->
store->getSession( self::SESSIONID ),
'making sure it didn\'t save' );
535 $this->provider = $neverProvider;
537 $this->
store->setSessionData( self::SESSIONID, $testData );
539 TestingAccessWrapper::newFromObject( $backend )->requests[100]
541 $this->
store->deleteSession( self::SESSIONID );
542 TestingAccessWrapper::newFromObject( $backend )->persist =
false;
543 TestingAccessWrapper::newFromObject( $backend )->forcePersist =
true;
544 $this->assertFalse( $backend->isPersistent(),
'sanity check' );
545 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
false;
546 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
false;
548 $this->assertFalse( $this->
store->getSession( self::SESSIONID ),
'making sure it didn\'t save' );
551 $this->provider = $neverProvider;
552 $this->onSessionMetadataCalled =
false;
554 $this->
store->setSessionData( self::SESSIONID, $testData );
556 $this->
store->deleteSession( self::SESSIONID );
557 $this->assertFalse( $backend->isPersistent(),
'sanity check' );
558 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
false;
559 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
true;
561 $this->assertTrue( $this->onSessionMetadataCalled );
562 $blob = $this->
store->getSession( self::SESSIONID );
563 $this->assertInternalType(
'array',
$blob );
564 $this->assertArrayHasKey(
'metadata',
$blob );
565 $metadata =
$blob[
'metadata'];
566 $this->assertInternalType(
'array', $metadata );
567 $this->assertArrayHasKey(
'???', $metadata );
568 $this->assertSame(
'!!!', $metadata[
'???'] );
569 $this->assertFalse( $this->
store->getSessionFromBackend( self::SESSIONID ),
570 'making sure it didn\'t save to backend' );
573 $this->provider = $neverProvider;
575 $this->
store->setSessionData( self::SESSIONID, $testData );
577 $this->
store->deleteSession( self::SESSIONID );
578 TestingAccessWrapper::newFromObject( $backend )->persist =
true;
579 $this->assertTrue( $backend->isPersistent(),
'sanity check' );
580 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
false;
581 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
false;
583 $this->assertFalse( $this->
store->getSession( self::SESSIONID ),
'making sure it didn\'t save' );
586 $this->provider = $builder->getMock();
587 $this->provider->expects( $this->atLeastOnce() )->method(
'persistSession' );
588 $this->provider->expects( $this->never() )->method(
'unpersistSession' );
590 $this->
store->setSessionData( self::SESSIONID, $testData );
592 $this->
store->deleteSession( self::SESSIONID );
593 TestingAccessWrapper::newFromObject( $backend )->persist =
true;
594 TestingAccessWrapper::newFromObject( $backend )->forcePersist =
true;
595 $this->assertTrue( $backend->isPersistent(),
'sanity check' );
596 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
false;
597 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
false;
599 $this->assertFalse( $this->
store->getSession( self::SESSIONID ),
'making sure it didn\'t save' );
602 $this->provider = $neverProvider;
603 $this->onSessionMetadataCalled =
false;
605 $this->
store->setSessionData( self::SESSIONID, $testData );
607 $this->
store->deleteSession( self::SESSIONID );
608 TestingAccessWrapper::newFromObject( $backend )->persist =
true;
609 $this->assertTrue( $backend->isPersistent(),
'sanity check' );
610 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
false;
611 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
true;
613 $this->assertTrue( $this->onSessionMetadataCalled );
614 $blob = $this->
store->getSession( self::SESSIONID );
615 $this->assertInternalType(
'array',
$blob );
616 $this->assertArrayHasKey(
'metadata',
$blob );
617 $metadata =
$blob[
'metadata'];
618 $this->assertInternalType(
'array', $metadata );
619 $this->assertArrayHasKey(
'???', $metadata );
620 $this->assertSame(
'!!!', $metadata[
'???'] );
621 $this->assertNotSame(
false, $this->
store->getSessionFromBackend( self::SESSIONID ),
622 'making sure it did save to backend' );
625 $this->provider = $builder->getMock();
626 $this->provider->expects( $this->atLeastOnce() )->method(
'persistSession' );
627 $this->provider->expects( $this->never() )->method(
'unpersistSession' );
628 $this->onSessionMetadataCalled =
false;
630 $this->
store->setSessionData( self::SESSIONID, $testData );
632 $this->
store->deleteSession( self::SESSIONID );
633 TestingAccessWrapper::newFromObject( $backend )->persist =
true;
634 TestingAccessWrapper::newFromObject( $backend )->forcePersist =
true;
635 $this->assertTrue( $backend->isPersistent(),
'sanity check' );
636 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
false;
637 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
true;
639 $this->assertTrue( $this->onSessionMetadataCalled );
640 $blob = $this->
store->getSession( self::SESSIONID );
641 $this->assertInternalType(
'array',
$blob );
642 $this->assertArrayHasKey(
'metadata',
$blob );
643 $metadata =
$blob[
'metadata'];
644 $this->assertInternalType(
'array', $metadata );
645 $this->assertArrayHasKey(
'???', $metadata );
646 $this->assertSame(
'!!!', $metadata[
'???'] );
647 $this->assertNotSame(
false, $this->
store->getSessionFromBackend( self::SESSIONID ),
648 'making sure it did save to backend' );
651 $this->provider = $builder->getMock();
652 $this->provider->expects( $this->atLeastOnce() )->method(
'persistSession' );
653 $this->provider->expects( $this->never() )->method(
'unpersistSession' );
654 $this->onSessionMetadataCalled =
false;
656 $this->
store->setSessionData( self::SESSIONID, $testData );
658 $this->
store->deleteSession( self::SESSIONID );
659 TestingAccessWrapper::newFromObject( $backend )->persist =
true;
660 $this->assertTrue( $backend->isPersistent(),
'sanity check' );
661 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
true;
662 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
false;
664 $this->assertTrue( $this->onSessionMetadataCalled );
665 $blob = $this->
store->getSession( self::SESSIONID );
666 $this->assertInternalType(
'array',
$blob );
667 $this->assertArrayHasKey(
'metadata',
$blob );
668 $metadata =
$blob[
'metadata'];
669 $this->assertInternalType(
'array', $metadata );
670 $this->assertArrayHasKey(
'???', $metadata );
671 $this->assertSame(
'!!!', $metadata[
'???'] );
672 $this->assertNotSame(
false, $this->
store->getSessionFromBackend( self::SESSIONID ),
673 'making sure it did save to backend' );
677 $this->provider = $neverProvider;
678 $this->onSessionMetadataCalled =
false;
680 $this->
store->setSessionData( self::SESSIONID, $testData );
682 $this->
store->deleteSession( self::SESSIONID );
683 TestingAccessWrapper::newFromObject( $backend )->persist =
true;
684 $this->assertTrue( $backend->isPersistent(),
'sanity check' );
685 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
false;
686 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
false;
687 TestingAccessWrapper::newFromObject( $backend )->dataHash =
'Doesn\'t match';
689 $this->assertTrue( $this->onSessionMetadataCalled );
690 $blob = $this->
store->getSession( self::SESSIONID );
691 $this->assertInternalType(
'array',
$blob );
692 $this->assertArrayHasKey(
'metadata',
$blob );
693 $metadata =
$blob[
'metadata'];
694 $this->assertInternalType(
'array', $metadata );
695 $this->assertArrayHasKey(
'???', $metadata );
696 $this->assertSame(
'!!!', $metadata[
'???'] );
697 $this->assertNotSame(
false, $this->
store->getSessionFromBackend( self::SESSIONID ),
698 'making sure it did save to backend' );
701 $this->provider =
null;
702 $mockHook = $this->getMockBuilder( __CLASS__ )
703 ->setMethods( [
'onSessionMetadata' ] )->getMock();
704 $mockHook->expects( $this->
any() )->method(
'onSessionMetadata' )
705 ->will( $this->returnCallback(
707 $metadata[
'userId']++;
711 $this->
store->setSessionData( self::SESSIONID, $testData );
716 $this->fail(
'Expected exception not thrown' );
717 }
catch ( \UnexpectedValueException $ex ) {
719 'SessionMetadata hook changed metadata key "userId"',
725 TestingAccessWrapper::newFromObject( $this->manager )->preventUsers = [
726 $user->getName() =>
true,
728 $this->provider = $neverProvider;
730 $this->
store->setSessionData( self::SESSIONID, $testData );
732 $this->
store->deleteSession( self::SESSIONID );
733 TestingAccessWrapper::newFromObject( $backend )->persist =
true;
734 $this->assertTrue( $backend->
isPersistent(),
'sanity check' );
735 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
true;
736 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
true;
738 $this->assertFalse( $this->
store->getSession( self::SESSIONID ),
'making sure it didn\'t save' );
742 $user = static::getTestSysop()->getUser();
744 $testData = [
'foo' =>
'foo!',
'bar', [
'baz', null ] ];
747 $this->provider = $this->getMockBuilder(
'DummySessionProvider' )
748 ->setMethods( [
'persistSession' ] )->getMock();
749 $this->provider->expects( $this->never() )->method(
'persistSession' );
750 $this->onSessionMetadataCalled =
false;
752 $this->
store->setSessionData( self::SESSIONID, $testData );
754 $this->
store->deleteSession( self::SESSIONID );
755 $wrap = TestingAccessWrapper::newFromObject( $backend );
756 $this->assertFalse( $backend->isPersistent(),
'sanity check' );
757 $wrap->metaDirty =
false;
758 $wrap->dataDirty =
false;
759 $wrap->forcePersist =
false;
762 $this->assertTrue( $this->onSessionMetadataCalled );
763 $blob = $this->
store->getSession( self::SESSIONID );
764 $this->assertInternalType(
'array',
$blob );
765 $this->assertArrayHasKey(
'metadata',
$blob );
766 $metadata =
$blob[
'metadata'];
767 $this->assertInternalType(
'array', $metadata );
768 $this->assertArrayHasKey(
'???', $metadata );
769 $this->assertSame(
'!!!', $metadata[
'???'] );
770 $this->assertNotEquals( 0, $wrap->expires );
773 $this->provider = $this->getMockBuilder(
'DummySessionProvider' )
774 ->setMethods( [
'persistSession' ] )->getMock();
775 $this->provider->expects( $this->atLeastOnce() )->method(
'persistSession' );
776 $this->onSessionMetadataCalled =
false;
778 $this->
store->setSessionData( self::SESSIONID, $testData );
780 $this->
store->deleteSession( self::SESSIONID );
781 $wrap = TestingAccessWrapper::newFromObject( $backend );
782 $wrap->persist =
true;
783 $this->assertTrue( $backend->isPersistent(),
'sanity check' );
784 $wrap->metaDirty =
false;
785 $wrap->dataDirty =
false;
786 $wrap->forcePersist =
false;
789 $this->assertTrue( $this->onSessionMetadataCalled );
790 $blob = $this->
store->getSession( self::SESSIONID );
791 $this->assertInternalType(
'array',
$blob );
792 $this->assertArrayHasKey(
'metadata',
$blob );
793 $metadata =
$blob[
'metadata'];
794 $this->assertInternalType(
'array', $metadata );
795 $this->assertArrayHasKey(
'???', $metadata );
796 $this->assertSame(
'!!!', $metadata[
'???'] );
797 $this->assertNotEquals( 0, $wrap->expires );
800 $this->provider = $this->getMockBuilder(
'DummySessionProvider' )
801 ->setMethods( [
'persistSession' ] )->getMock();
802 $this->provider->expects( $this->never() )->method(
'persistSession' );
803 $this->onSessionMetadataCalled =
false;
805 $this->
store->setSessionData( self::SESSIONID, $testData );
807 $this->
store->deleteSession( self::SESSIONID );
808 $wrap = TestingAccessWrapper::newFromObject( $backend );
809 $this->assertFalse( $backend->isPersistent(),
'sanity check' );
810 $wrap->metaDirty =
false;
811 $wrap->dataDirty =
false;
812 $wrap->forcePersist =
false;
813 $expires = time() + $wrap->lifetime + 100;
814 $wrap->expires = $expires;
816 $this->assertFalse( $this->onSessionMetadataCalled );
817 $this->assertFalse( $this->
store->getSession( self::SESSIONID ),
'making sure it didn\'t save' );
818 $this->assertEquals( $expires, $wrap->expires );
822 $this->onSessionMetadataCalled =
true;
823 $metadata[
'???'] =
'!!!';
832 $rProp->setAccessible(
true );
833 $handler = TestingAccessWrapper::newFromObject( $rProp->getValue() );
834 $resetHandler = new \Wikimedia\ScopedCallback(
function ()
use (
$handler ) {
835 session_write_close();
841 $backend = $this->
getBackend( static::getTestSysop()->getUser() );
842 TestingAccessWrapper::newFromObject( $backend )->usePhpSessionHandling =
true;
846 $manager = TestingAccessWrapper::newFromObject( $this->manager );
852 TestingAccessWrapper::newFromObject( $backend )->checkPHPSession();
853 $this->assertSame( $backend->getId(), session_id() );
854 session_write_close();
859 TestingAccessWrapper::newFromObject( $backend2 )->usePhpSessionHandling =
true;
862 TestingAccessWrapper::newFromObject( $backend2 )->checkPHPSession();
863 $this->assertSame(
'', session_id() );
872 $rProp->setAccessible(
true );
873 $handler = TestingAccessWrapper::newFromObject( $rProp->getValue() );
874 $resetHandler = new \Wikimedia\ScopedCallback(
function ()
use (
$handler ) {
875 session_write_close();
882 TestingAccessWrapper::newFromObject( $backend )->usePhpSessionHandling =
true;
886 $manager = TestingAccessWrapper::newFromObject( $this->manager );
891 session_id( self::SESSIONID );
892 \MediaWiki\quietCall(
'session_start' );
893 $_SESSION[
'foo'] = __METHOD__;
895 $this->assertNotEquals( self::SESSIONID, $backend->getId() );
896 $this->assertSame( $backend->getId(), session_id() );
897 $this->assertArrayHasKey(
'foo', $_SESSION );
898 $this->assertSame( __METHOD__, $_SESSION[
'foo'] );
899 session_write_close();
908 $rProp->setAccessible(
true );
909 $handler = TestingAccessWrapper::newFromObject( $rProp->getValue() );
910 $resetHandler = new \Wikimedia\ScopedCallback(
function ()
use (
$handler ) {
911 session_write_close();
918 $wrap = TestingAccessWrapper::newFromObject( $backend );
919 $wrap->usePhpSessionHandling =
true;
920 $wrap->persist =
true;
924 $manager = TestingAccessWrapper::newFromObject( $this->manager );
929 session_id( self::SESSIONID .
'x' );
930 \MediaWiki\quietCall(
'session_start' );
931 $backend->unpersist();
932 $this->assertSame( self::SESSIONID .
'x', session_id() );
934 session_id( self::SESSIONID );
935 $wrap->persist =
true;
936 $backend->unpersist();
937 $this->assertSame(
'', session_id() );
941 $this->provider = $this->getMockBuilder(
'DummySessionProvider' )
942 ->setMethods( [
'getAllowedUserRights' ] )
944 $this->provider->expects( $this->
any() )->method(
'getAllowedUserRights' )
945 ->will( $this->returnValue( [
'foo',
'bar' ] ) );
948 $this->assertSame( [
'foo',
'bar' ], $backend->getAllowedUserRights() );