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(
334 $wrap->store->get( $wrap->store->makeKey(
'MWSession', self::SESSIONID ) )
341 $remembered = $backend->shouldRememberUser();
342 $backend->setRememberUser( !$remembered );
343 $this->assertNotEquals( $remembered, $backend->shouldRememberUser() );
344 $backend->setRememberUser( $remembered );
345 $this->assertEquals( $remembered, $backend->shouldRememberUser() );
351 $force = $backend->shouldForceHTTPS();
352 $backend->setForceHTTPS( !$force );
353 $this->assertNotEquals( $force, $backend->shouldForceHTTPS() );
354 $backend->setForceHTTPS( $force );
355 $this->assertEquals( $force, $backend->shouldForceHTTPS() );
361 $backend->setLoggedOutTimestamp( 42 );
362 $this->assertSame( 42, $backend->getLoggedOutTimestamp() );
363 $backend->setLoggedOutTimestamp(
'123' );
364 $this->assertSame( 123, $backend->getLoggedOutTimestamp() );
368 $user = static::getTestSysop()->getUser();
370 $this->provider = $this->getMockBuilder(
'DummySessionProvider' )
371 ->setMethods( [
'canChangeUser' ] )->getMock();
372 $this->provider->expects( $this->
any() )->method(
'canChangeUser' )
373 ->will( $this->returnValue(
false ) );
375 $this->assertFalse( $backend->canSetUser() );
377 $backend->setUser(
$user );
378 $this->fail(
'Expected exception not thrown' );
379 }
catch ( \BadMethodCallException $ex ) {
381 'Cannot set user on this session; check $session->canSetUser() first',
385 $this->assertNotSame(
$user, $backend->getUser() );
387 $this->provider =
null;
389 $this->assertTrue( $backend->canSetUser() );
390 $this->assertNotSame(
$user, $backend->getUser(),
'sanity check' );
391 $backend->setUser(
$user );
392 $this->assertSame(
$user, $backend->getUser() );
397 $priv = TestingAccessWrapper::newFromObject( $backend );
398 $priv->dataDirty =
false;
400 $this->assertTrue( $priv->dataDirty );
405 $data = $backend->getData();
406 $this->assertSame( [], $data );
407 $this->assertTrue( TestingAccessWrapper::newFromObject( $backend )->dataDirty );
408 $data[
'???'] =
'!!!';
409 $this->assertSame( [
'???' =>
'!!!' ], $data );
411 $testData = [
'foo' =>
'foo!',
'bar', [
'baz', null ] ];
412 $this->
store->setSessionData( self::SESSIONID, $testData );
414 $this->assertSame( $testData, $backend->getData() );
415 $this->assertFalse( TestingAccessWrapper::newFromObject( $backend )->dataDirty );
420 $priv = TestingAccessWrapper::newFromObject( $backend );
422 $priv->data = [
'foo' => 1 ];
423 $priv->dataDirty =
false;
424 $backend->addData( [
'foo' => 1 ] );
425 $this->assertSame( [
'foo' => 1 ], $priv->data );
426 $this->assertFalse( $priv->dataDirty );
428 $priv->data = [
'foo' => 1 ];
429 $priv->dataDirty =
false;
430 $backend->addData( [
'foo' =>
'1' ] );
431 $this->assertSame( [
'foo' =>
'1' ], $priv->data );
432 $this->assertTrue( $priv->dataDirty );
434 $priv->data = [
'foo' => 1 ];
435 $priv->dataDirty =
false;
436 $backend->addData( [
'bar' => 2 ] );
437 $this->assertSame( [
'foo' => 1,
'bar' => 2 ], $priv->data );
438 $this->assertTrue( $priv->dataDirty );
444 $priv = TestingAccessWrapper::newFromObject( $backend );
445 $priv->persist =
true;
448 $this->onSessionMetadataCalled =
false;
449 $priv->metaDirty =
true;
451 $this->assertTrue( $this->onSessionMetadataCalled,
'sanity check' );
453 $this->onSessionMetadataCalled =
false;
454 $priv->metaDirty =
true;
456 $this->assertTrue( $this->onSessionMetadataCalled,
'sanity check' );
458 $delay = $backend->delaySave();
461 $this->onSessionMetadataCalled =
false;
462 $priv->metaDirty =
true;
464 $this->assertFalse( $this->onSessionMetadataCalled );
468 $this->assertTrue( $this->onSessionMetadataCalled );
471 $this->onSessionMetadataCalled =
false;
472 $priv->metaDirty =
true;
473 \Wikimedia\ScopedCallback::consume( $delay );
474 $this->assertTrue( $this->onSessionMetadataCalled );
477 $delay1 = $backend->delaySave();
478 $delay2 = $backend->delaySave();
479 $delay3 = $backend->delaySave();
480 $this->onSessionMetadataCalled =
false;
481 $priv->metaDirty =
true;
483 $this->assertFalse( $this->onSessionMetadataCalled );
484 \Wikimedia\ScopedCallback::consume( $delay3 );
485 $this->assertFalse( $this->onSessionMetadataCalled );
486 \Wikimedia\ScopedCallback::consume( $delay1 );
487 $this->assertFalse( $this->onSessionMetadataCalled );
488 \Wikimedia\ScopedCallback::consume( $delay2 );
489 $this->assertTrue( $this->onSessionMetadataCalled );
493 $user = static::getTestSysop()->getUser();
495 $testData = [
'foo' =>
'foo!',
'bar', [
'baz', null ] ];
497 $neverHook = $this->getMockBuilder( __CLASS__ )
498 ->setMethods( [
'onSessionMetadata' ] )->getMock();
499 $neverHook->expects( $this->never() )->method(
'onSessionMetadata' );
501 $builder = $this->getMockBuilder(
'DummySessionProvider' )
502 ->setMethods( [
'persistSession',
'unpersistSession' ] );
504 $neverProvider = $builder->getMock();
505 $neverProvider->expects( $this->never() )->method(
'persistSession' );
506 $neverProvider->expects( $this->never() )->method(
'unpersistSession' );
509 $this->provider = $neverProvider;
511 $this->
store->setSessionData( self::SESSIONID, $testData );
513 $this->
store->deleteSession( self::SESSIONID );
514 $this->assertFalse( $backend->isPersistent(),
'sanity check' );
515 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
false;
516 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
false;
518 $this->assertFalse( $this->
store->getSession( self::SESSIONID ),
'making sure it didn\'t save' );
521 $this->provider = $builder->getMock();
522 $this->provider->expects( $this->never() )->method(
'persistSession' );
523 $this->provider->expects( $this->atLeastOnce() )->method(
'unpersistSession' );
525 $this->
store->setSessionData( self::SESSIONID, $testData );
527 $this->
store->deleteSession( self::SESSIONID );
528 TestingAccessWrapper::newFromObject( $backend )->persist =
false;
529 TestingAccessWrapper::newFromObject( $backend )->forcePersist =
true;
530 $this->assertFalse( $backend->isPersistent(),
'sanity check' );
531 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
false;
532 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
false;
534 $this->assertFalse( $this->
store->getSession( self::SESSIONID ),
'making sure it didn\'t save' );
537 $this->provider = $neverProvider;
539 $this->
store->setSessionData( self::SESSIONID, $testData );
541 TestingAccessWrapper::newFromObject( $backend )->requests[100]
543 $this->
store->deleteSession( self::SESSIONID );
544 TestingAccessWrapper::newFromObject( $backend )->persist =
false;
545 TestingAccessWrapper::newFromObject( $backend )->forcePersist =
true;
546 $this->assertFalse( $backend->isPersistent(),
'sanity check' );
547 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
false;
548 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
false;
550 $this->assertFalse( $this->
store->getSession( self::SESSIONID ),
'making sure it didn\'t save' );
553 $this->provider = $neverProvider;
554 $this->onSessionMetadataCalled =
false;
556 $this->
store->setSessionData( self::SESSIONID, $testData );
558 $this->
store->deleteSession( self::SESSIONID );
559 $this->assertFalse( $backend->isPersistent(),
'sanity check' );
560 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
false;
561 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
true;
563 $this->assertTrue( $this->onSessionMetadataCalled );
564 $blob = $this->
store->getSession( self::SESSIONID );
565 $this->assertInternalType(
'array',
$blob );
566 $this->assertArrayHasKey(
'metadata',
$blob );
567 $metadata =
$blob[
'metadata'];
568 $this->assertInternalType(
'array', $metadata );
569 $this->assertArrayHasKey(
'???', $metadata );
570 $this->assertSame(
'!!!', $metadata[
'???'] );
571 $this->assertFalse( $this->
store->getSessionFromBackend( self::SESSIONID ),
572 'making sure it didn\'t save to backend' );
575 $this->provider = $neverProvider;
577 $this->
store->setSessionData( self::SESSIONID, $testData );
579 $this->
store->deleteSession( self::SESSIONID );
580 TestingAccessWrapper::newFromObject( $backend )->persist =
true;
581 $this->assertTrue( $backend->isPersistent(),
'sanity check' );
582 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
false;
583 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
false;
585 $this->assertFalse( $this->
store->getSession( self::SESSIONID ),
'making sure it didn\'t save' );
588 $this->provider = $builder->getMock();
589 $this->provider->expects( $this->atLeastOnce() )->method(
'persistSession' );
590 $this->provider->expects( $this->never() )->method(
'unpersistSession' );
592 $this->
store->setSessionData( self::SESSIONID, $testData );
594 $this->
store->deleteSession( self::SESSIONID );
595 TestingAccessWrapper::newFromObject( $backend )->persist =
true;
596 TestingAccessWrapper::newFromObject( $backend )->forcePersist =
true;
597 $this->assertTrue( $backend->isPersistent(),
'sanity check' );
598 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
false;
599 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
false;
601 $this->assertFalse( $this->
store->getSession( self::SESSIONID ),
'making sure it didn\'t save' );
604 $this->provider = $neverProvider;
605 $this->onSessionMetadataCalled =
false;
607 $this->
store->setSessionData( self::SESSIONID, $testData );
609 $this->
store->deleteSession( self::SESSIONID );
610 TestingAccessWrapper::newFromObject( $backend )->persist =
true;
611 $this->assertTrue( $backend->isPersistent(),
'sanity check' );
612 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
false;
613 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
true;
615 $this->assertTrue( $this->onSessionMetadataCalled );
616 $blob = $this->
store->getSession( self::SESSIONID );
617 $this->assertInternalType(
'array',
$blob );
618 $this->assertArrayHasKey(
'metadata',
$blob );
619 $metadata =
$blob[
'metadata'];
620 $this->assertInternalType(
'array', $metadata );
621 $this->assertArrayHasKey(
'???', $metadata );
622 $this->assertSame(
'!!!', $metadata[
'???'] );
623 $this->assertNotSame(
false, $this->
store->getSessionFromBackend( self::SESSIONID ),
624 'making sure it did save to backend' );
627 $this->provider = $builder->getMock();
628 $this->provider->expects( $this->atLeastOnce() )->method(
'persistSession' );
629 $this->provider->expects( $this->never() )->method(
'unpersistSession' );
630 $this->onSessionMetadataCalled =
false;
632 $this->
store->setSessionData( self::SESSIONID, $testData );
634 $this->
store->deleteSession( self::SESSIONID );
635 TestingAccessWrapper::newFromObject( $backend )->persist =
true;
636 TestingAccessWrapper::newFromObject( $backend )->forcePersist =
true;
637 $this->assertTrue( $backend->isPersistent(),
'sanity check' );
638 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
false;
639 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
true;
641 $this->assertTrue( $this->onSessionMetadataCalled );
642 $blob = $this->
store->getSession( self::SESSIONID );
643 $this->assertInternalType(
'array',
$blob );
644 $this->assertArrayHasKey(
'metadata',
$blob );
645 $metadata =
$blob[
'metadata'];
646 $this->assertInternalType(
'array', $metadata );
647 $this->assertArrayHasKey(
'???', $metadata );
648 $this->assertSame(
'!!!', $metadata[
'???'] );
649 $this->assertNotSame(
false, $this->
store->getSessionFromBackend( self::SESSIONID ),
650 'making sure it did save to backend' );
653 $this->provider = $builder->getMock();
654 $this->provider->expects( $this->atLeastOnce() )->method(
'persistSession' );
655 $this->provider->expects( $this->never() )->method(
'unpersistSession' );
656 $this->onSessionMetadataCalled =
false;
658 $this->
store->setSessionData( self::SESSIONID, $testData );
660 $this->
store->deleteSession( self::SESSIONID );
661 TestingAccessWrapper::newFromObject( $backend )->persist =
true;
662 $this->assertTrue( $backend->isPersistent(),
'sanity check' );
663 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
true;
664 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
false;
666 $this->assertTrue( $this->onSessionMetadataCalled );
667 $blob = $this->
store->getSession( self::SESSIONID );
668 $this->assertInternalType(
'array',
$blob );
669 $this->assertArrayHasKey(
'metadata',
$blob );
670 $metadata =
$blob[
'metadata'];
671 $this->assertInternalType(
'array', $metadata );
672 $this->assertArrayHasKey(
'???', $metadata );
673 $this->assertSame(
'!!!', $metadata[
'???'] );
674 $this->assertNotSame(
false, $this->
store->getSessionFromBackend( self::SESSIONID ),
675 'making sure it did save to backend' );
679 $this->provider = $neverProvider;
680 $this->onSessionMetadataCalled =
false;
682 $this->
store->setSessionData( self::SESSIONID, $testData );
684 $this->
store->deleteSession( self::SESSIONID );
685 TestingAccessWrapper::newFromObject( $backend )->persist =
true;
686 $this->assertTrue( $backend->isPersistent(),
'sanity check' );
687 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
false;
688 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
false;
689 TestingAccessWrapper::newFromObject( $backend )->dataHash =
'Doesn\'t match';
691 $this->assertTrue( $this->onSessionMetadataCalled );
692 $blob = $this->
store->getSession( self::SESSIONID );
693 $this->assertInternalType(
'array',
$blob );
694 $this->assertArrayHasKey(
'metadata',
$blob );
695 $metadata =
$blob[
'metadata'];
696 $this->assertInternalType(
'array', $metadata );
697 $this->assertArrayHasKey(
'???', $metadata );
698 $this->assertSame(
'!!!', $metadata[
'???'] );
699 $this->assertNotSame(
false, $this->
store->getSessionFromBackend( self::SESSIONID ),
700 'making sure it did save to backend' );
703 $this->provider =
null;
704 $mockHook = $this->getMockBuilder( __CLASS__ )
705 ->setMethods( [
'onSessionMetadata' ] )->getMock();
706 $mockHook->expects( $this->
any() )->method(
'onSessionMetadata' )
707 ->will( $this->returnCallback(
709 $metadata[
'userId']++;
713 $this->
store->setSessionData( self::SESSIONID, $testData );
718 $this->fail(
'Expected exception not thrown' );
719 }
catch ( \UnexpectedValueException $ex ) {
721 'SessionMetadata hook changed metadata key "userId"',
727 TestingAccessWrapper::newFromObject( $this->manager )->preventUsers = [
728 $user->getName() =>
true,
730 $this->provider = $neverProvider;
732 $this->
store->setSessionData( self::SESSIONID, $testData );
734 $this->
store->deleteSession( self::SESSIONID );
735 TestingAccessWrapper::newFromObject( $backend )->persist =
true;
736 $this->assertTrue( $backend->
isPersistent(),
'sanity check' );
737 TestingAccessWrapper::newFromObject( $backend )->metaDirty =
true;
738 TestingAccessWrapper::newFromObject( $backend )->dataDirty =
true;
740 $this->assertFalse( $this->
store->getSession( self::SESSIONID ),
'making sure it didn\'t save' );
744 $user = static::getTestSysop()->getUser();
746 $testData = [
'foo' =>
'foo!',
'bar', [
'baz', null ] ];
749 $this->provider = $this->getMockBuilder(
'DummySessionProvider' )
750 ->setMethods( [
'persistSession' ] )->getMock();
751 $this->provider->expects( $this->never() )->method(
'persistSession' );
752 $this->onSessionMetadataCalled =
false;
754 $this->
store->setSessionData( self::SESSIONID, $testData );
756 $this->
store->deleteSession( self::SESSIONID );
757 $wrap = TestingAccessWrapper::newFromObject( $backend );
758 $this->assertFalse( $backend->isPersistent(),
'sanity check' );
759 $wrap->metaDirty =
false;
760 $wrap->dataDirty =
false;
761 $wrap->forcePersist =
false;
764 $this->assertTrue( $this->onSessionMetadataCalled );
765 $blob = $this->
store->getSession( self::SESSIONID );
766 $this->assertInternalType(
'array',
$blob );
767 $this->assertArrayHasKey(
'metadata',
$blob );
768 $metadata =
$blob[
'metadata'];
769 $this->assertInternalType(
'array', $metadata );
770 $this->assertArrayHasKey(
'???', $metadata );
771 $this->assertSame(
'!!!', $metadata[
'???'] );
772 $this->assertNotEquals( 0, $wrap->expires );
775 $this->provider = $this->getMockBuilder(
'DummySessionProvider' )
776 ->setMethods( [
'persistSession' ] )->getMock();
777 $this->provider->expects( $this->atLeastOnce() )->method(
'persistSession' );
778 $this->onSessionMetadataCalled =
false;
780 $this->
store->setSessionData( self::SESSIONID, $testData );
782 $this->
store->deleteSession( self::SESSIONID );
783 $wrap = TestingAccessWrapper::newFromObject( $backend );
784 $wrap->persist =
true;
785 $this->assertTrue( $backend->isPersistent(),
'sanity check' );
786 $wrap->metaDirty =
false;
787 $wrap->dataDirty =
false;
788 $wrap->forcePersist =
false;
791 $this->assertTrue( $this->onSessionMetadataCalled );
792 $blob = $this->
store->getSession( self::SESSIONID );
793 $this->assertInternalType(
'array',
$blob );
794 $this->assertArrayHasKey(
'metadata',
$blob );
795 $metadata =
$blob[
'metadata'];
796 $this->assertInternalType(
'array', $metadata );
797 $this->assertArrayHasKey(
'???', $metadata );
798 $this->assertSame(
'!!!', $metadata[
'???'] );
799 $this->assertNotEquals( 0, $wrap->expires );
802 $this->provider = $this->getMockBuilder(
'DummySessionProvider' )
803 ->setMethods( [
'persistSession' ] )->getMock();
804 $this->provider->expects( $this->never() )->method(
'persistSession' );
805 $this->onSessionMetadataCalled =
false;
807 $this->
store->setSessionData( self::SESSIONID, $testData );
809 $this->
store->deleteSession( self::SESSIONID );
810 $wrap = TestingAccessWrapper::newFromObject( $backend );
811 $this->assertFalse( $backend->isPersistent(),
'sanity check' );
812 $wrap->metaDirty =
false;
813 $wrap->dataDirty =
false;
814 $wrap->forcePersist =
false;
815 $expires = time() + $wrap->lifetime + 100;
816 $wrap->expires = $expires;
818 $this->assertFalse( $this->onSessionMetadataCalled );
819 $this->assertFalse( $this->
store->getSession( self::SESSIONID ),
'making sure it didn\'t save' );
820 $this->assertEquals( $expires, $wrap->expires );
824 $this->onSessionMetadataCalled =
true;
825 $metadata[
'???'] =
'!!!';
834 $rProp->setAccessible(
true );
835 $handler = TestingAccessWrapper::newFromObject( $rProp->getValue() );
836 $resetHandler = new \Wikimedia\ScopedCallback(
function ()
use (
$handler ) {
837 session_write_close();
843 $backend = $this->
getBackend( static::getTestSysop()->getUser() );
844 TestingAccessWrapper::newFromObject( $backend )->usePhpSessionHandling =
true;
848 $manager = TestingAccessWrapper::newFromObject( $this->manager );
854 TestingAccessWrapper::newFromObject( $backend )->checkPHPSession();
855 $this->assertSame( $backend->getId(), session_id() );
856 session_write_close();
861 TestingAccessWrapper::newFromObject( $backend2 )->usePhpSessionHandling =
true;
864 TestingAccessWrapper::newFromObject( $backend2 )->checkPHPSession();
865 $this->assertSame(
'', session_id() );
874 $rProp->setAccessible(
true );
875 $handler = TestingAccessWrapper::newFromObject( $rProp->getValue() );
876 $resetHandler = new \Wikimedia\ScopedCallback(
function ()
use (
$handler ) {
877 session_write_close();
884 TestingAccessWrapper::newFromObject( $backend )->usePhpSessionHandling =
true;
888 $manager = TestingAccessWrapper::newFromObject( $this->manager );
893 session_id( self::SESSIONID );
894 \MediaWiki\quietCall(
'session_start' );
895 $_SESSION[
'foo'] = __METHOD__;
897 $this->assertNotEquals( self::SESSIONID, $backend->getId() );
898 $this->assertSame( $backend->getId(), session_id() );
899 $this->assertArrayHasKey(
'foo', $_SESSION );
900 $this->assertSame( __METHOD__, $_SESSION[
'foo'] );
901 session_write_close();
910 $rProp->setAccessible(
true );
911 $handler = TestingAccessWrapper::newFromObject( $rProp->getValue() );
912 $resetHandler = new \Wikimedia\ScopedCallback(
function ()
use (
$handler ) {
913 session_write_close();
920 $wrap = TestingAccessWrapper::newFromObject( $backend );
921 $wrap->usePhpSessionHandling =
true;
922 $wrap->persist =
true;
926 $manager = TestingAccessWrapper::newFromObject( $this->manager );
931 session_id( self::SESSIONID .
'x' );
932 \MediaWiki\quietCall(
'session_start' );
933 $backend->unpersist();
934 $this->assertSame( self::SESSIONID .
'x', session_id() );
936 session_id( self::SESSIONID );
937 $wrap->persist =
true;
938 $backend->unpersist();
939 $this->assertSame(
'', session_id() );
943 $this->provider = $this->getMockBuilder(
'DummySessionProvider' )
944 ->setMethods( [
'getAllowedUserRights' ] )
946 $this->provider->expects( $this->
any() )->method(
'getAllowedUserRights' )
947 ->will( $this->returnValue( [
'foo',
'bar' ] ) );
950 $this->assertSame( [
'foo',
'bar' ], $backend->getAllowedUserRights() );