147 $idEmpty =
'empty-session-------------------';
149 $providerBuilder = $this->
getMockBuilder( \DummySessionProvider::class )
151 [
'provideSessionInfo',
'newSessionInfo',
'__toString',
'describe',
'unpersistSession' ]
154 $provider1 = $providerBuilder->getMock();
155 $provider1->expects( $this->
any() )->method(
'provideSessionInfo' )
160 $provider1->expects( $this->
any() )->method(
'newSessionInfo' )
161 ->will( $this->
returnCallback(
function () use ( $idEmpty, $provider1 ) {
163 'provider' => $provider1,
169 $provider1->expects( $this->
any() )->method(
'__toString' )
171 $provider1->expects( $this->
any() )->method(
'describe' )
173 $provider1->expects( $this->
any() )->method(
'unpersistSession' )
178 $provider2 = $providerBuilder->getMock();
179 $provider2->expects( $this->
any() )->method(
'provideSessionInfo' )
184 $provider2->expects( $this->
any() )->method(
'__toString' )
186 $provider2->expects( $this->
any() )->method(
'describe' )
188 $provider2->expects( $this->
any() )->method(
'unpersistSession' )
193 $this->config->set(
'SessionProviders', [
201 $session = $manager->getSessionForRequest(
$request );
203 $this->
assertSame( $idEmpty, $session->getId() );
209 'provider' => $provider1,
210 'id' => ( $id1 = $manager->generateSessionId() ),
215 'provider' => $provider2,
216 'id' => ( $id2 = $manager->generateSessionId() ),
220 $session = $manager->getSessionForRequest(
$request );
227 'provider' => $provider1,
228 'id' => ( $id1 = $manager->generateSessionId() ),
233 'provider' => $provider2,
234 'id' => ( $id2 = $manager->generateSessionId() ),
238 $session = $manager->getSessionForRequest(
$request );
246 'provider' => $provider1,
247 'id' => ( $id1 = $manager->generateSessionId() ),
253 'provider' => $provider2,
254 'id' => ( $id2 = $manager->generateSessionId() ),
260 $manager->getSessionForRequest(
$request );
261 $this->fail(
'Expcected exception not thrown' );
262 }
catch ( \OverflowException $ex ) {
264 'Multiple sessions for this request tied for top priority: ',
276 'provider' => $provider2,
277 'id' => ( $id1 = $manager->generateSessionId() ),
283 $manager->getSessionForRequest(
$request );
284 $this->fail(
'Expcected exception not thrown' );
285 }
catch ( \UnexpectedValueException $ex ) {
287 'Provider1 returned session info for a different provider: ' .
$request->info1,
295 $this->logger->setCollect(
true );
297 'provider' => $provider1,
298 'id' => ( $id1 = $manager->generateSessionId() ),
304 'provider' => $provider2,
305 'id' => ( $id2 = $manager->generateSessionId() ),
309 $session = $manager->getSessionForRequest(
$request );
312 $this->logger->setCollect(
false );
317 $this->logger->setCollect(
true );
319 'provider' => $provider1,
320 'id' => ( $id1 = $manager->generateSessionId() ),
325 'provider' => $provider2,
326 'id' => ( $id2 = $manager->generateSessionId() ),
331 $session = $manager->getSessionForRequest(
$request );
334 $this->logger->setCollect(
false );
341 'provider' => $provider1,
342 'id' => ( $id1 = $manager->generateSessionId() ),
343 'persisted' =>
false,
348 $session = $manager->getSessionForRequest(
$request );
354 $this->
assertTrue( $session->isPersistent(),
'sanity check' );
360 $manager->getSessionById(
'bad' );
361 $this->fail(
'Expected exception not thrown' );
362 }
catch ( \InvalidArgumentException $ex ) {
363 $this->
assertSame(
'Invalid session ID', $ex->getMessage() );
367 $id = $manager->generateSessionId();
368 $session = $manager->getSessionById( $id,
true );
372 $id = $manager->generateSessionId();
373 $this->
assertNull( $manager->getSessionById( $id,
false ) );
376 $this->logger->setCollect(
true );
377 $id = $manager->generateSessionId();
378 $this->store->setSession( $id, [
'metadata' => [
380 'userToken' =>
'bad',
383 $this->
assertNull( $manager->getSessionById( $id,
true ) );
384 $this->
assertNull( $manager->getSessionById( $id,
false ) );
385 $this->logger->setCollect(
false );
388 $this->store->setSession( $id, [] );
389 $session = $manager->getSessionById( $id,
false );
394 $this->store->setSession( $id, [
'metadata' => [
396 'userToken' =>
'bad',
398 $session2 = $manager->getSessionById( $id,
false );
401 unset( $session, $session2 );
402 $this->logger->setCollect(
true );
403 $this->
assertNull( $manager->getSessionById( $id,
true ) );
404 $this->logger->setCollect(
false );
409 ->setMethods( [
'provideSessionInfo',
'newSessionInfo',
'__toString' ] )
411 $provider->expects( $this->
any() )->method(
'provideSessionInfo' )
413 $provider->expects( $this->
any() )->method(
'newSessionInfo' )
415 $provider->expects( $this->
any() )->method(
'__toString' )
417 $this->config->set(
'SessionProviders', [
420 $this->logger->setCollect(
true );
421 $this->
assertNull( $manager->getSessionById( $id,
true ) );
422 $this->logger->setCollect(
false );
424 [ LogLevel::ERROR,
'Failed to create empty session: {exception}' ]
425 ], $this->logger->getBuffer() );
430 $pmanager = TestingAccessWrapper::newFromObject( $manager );
433 $providerBuilder = $this->
getMockBuilder( \DummySessionProvider::class )
434 ->setMethods( [
'provideSessionInfo',
'newSessionInfo',
'__toString' ] );
440 $provider1 = $providerBuilder->getMock();
441 $provider1->expects( $this->
any() )->method(
'provideSessionInfo' )
443 $provider1->expects( $this->
any() )->method(
'newSessionInfo' )
444 ->with( $this->callback(
function ( $id ) use ( &$expectId ) {
450 $provider1->expects( $this->
any() )->method(
'__toString' )
453 $provider2 = $providerBuilder->getMock();
454 $provider2->expects( $this->
any() )->method(
'provideSessionInfo' )
456 $provider2->expects( $this->
any() )->method(
'newSessionInfo' )
457 ->with( $this->callback(
function ( $id ) use ( &$expectId ) {
463 $provider1->expects( $this->
any() )->method(
'__toString' )
466 $this->config->set(
'SessionProviders', [
476 $manager->getEmptySession();
477 $this->fail(
'Expected exception not thrown' );
478 }
catch ( \UnexpectedValueException $ex ) {
480 'No provider could provide an empty session!',
488 'provider' => $provider1,
489 'id' =>
'empty---------------------------',
494 $session = $manager->getEmptySession();
496 $this->
assertSame(
'empty---------------------------', $session->getId() );
499 $expectId =
'expected------------------------';
501 'provider' => $provider1,
507 $session = $pmanager->getEmptySessionInternal(
null, $expectId );
509 $this->
assertSame( $expectId, $session->getId() );
512 $expectId =
'expected-----------------------2';
514 'provider' => $provider1,
515 'id' =>
"un$expectId",
521 $pmanager->getEmptySessionInternal(
null, $expectId );
522 $this->fail(
'Expected exception not thrown' );
523 }
catch ( \UnexpectedValueException $ex ) {
525 'MockProvider1 returned empty session info with a wrong id: ' .
526 "un$expectId != $expectId",
532 $expectId =
'expected-----------------------2';
534 'provider' => $provider1,
540 $pmanager->getEmptySessionInternal(
null, $expectId );
541 $this->fail(
'Expected exception not thrown' );
542 }
catch ( \UnexpectedValueException $ex ) {
544 'MockProvider1 returned empty session info with id flagged unsafe',
552 'provider' => $provider2,
553 'id' =>
'empty---------------------------',
559 $manager->getEmptySession();
560 $this->fail(
'Expected exception not thrown' );
561 }
catch ( \UnexpectedValueException $ex ) {
563 'MockProvider1 returned an empty session info for a different provider: ' . $info1,
571 'provider' => $provider1,
572 'id' =>
'empty1--------------------------',
577 'provider' => $provider2,
578 'id' =>
'empty2--------------------------',
582 $session = $manager->getEmptySession();
584 $this->
assertSame(
'empty1--------------------------', $session->getId() );
588 'provider' => $provider1,
589 'id' =>
'empty1--------------------------',
594 'provider' => $provider2,
595 'id' =>
'empty2--------------------------',
599 $session = $manager->getEmptySession();
601 $this->
assertSame(
'empty2--------------------------', $session->getId() );
606 'provider' => $provider1,
607 'id' =>
'empty1--------------------------',
613 'provider' => $provider2,
614 'id' =>
'empty2--------------------------',
620 $manager->getEmptySession();
621 $this->fail(
'Expected exception not thrown' );
622 }
catch ( \UnexpectedValueException $ex ) {
624 'Multiple empty sessions tied for top priority: ',
631 $pmanager->getEmptySessionInternal(
null,
'bad' );
632 $this->fail(
'Expected exception not thrown' );
633 }
catch ( \InvalidArgumentException $ex ) {
634 $this->
assertSame(
'Invalid session ID', $ex->getMessage() );
638 $expectId =
'expected-----------------------3';
639 $this->store->setSessionMeta( $expectId, [
640 'provider' =>
'MockProvider2',
646 $pmanager->getEmptySessionInternal(
null, $expectId );
647 $this->fail(
'Expected exception not thrown' );
648 }
catch ( \InvalidArgumentException $ex ) {
649 $this->
assertSame(
'Session ID already exists', $ex->getMessage() );
800 $manager = TestingAccessWrapper::newFromObject( $this->
getManager() );
803 $id =
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
806 'provider' => $manager->getProvider(
'DummySessionProvider' ),
812 TestingAccessWrapper::newFromObject( $info )->idIsSafe =
true;
813 $session1 = TestingAccessWrapper::newFromObject(
814 $manager->getSessionFromInfo( $info,
$request )
816 $session2 = TestingAccessWrapper::newFromObject(
817 $manager->getSessionFromInfo( $info,
$request )
820 $this->
assertSame( $session1->backend, $session2->backend );
822 $this->
assertSame( $session1->getSessionId(), $session2->getSessionId() );
825 TestingAccessWrapper::newFromObject( $info )->idIsSafe =
false;
826 $session3 = $manager->getSessionFromInfo( $info,
$request );
833 $session = $manager->getSessionForRequest(
new \
FauxRequest );
834 $backend = TestingAccessWrapper::newFromObject( $session )->backend;
835 $sessionId = $session->getSessionId();
838 $this->
assertSame( $sessionId, $manager->getSessionById( $id,
true )->getSessionId() );
840 $manager->changeBackendId( $backend );
841 $this->
assertSame( $sessionId, $session->getSessionId() );
845 $this->
assertSame( $sessionId, $manager->getSessionById( $id,
true )->getSessionId() );
851 $manager->changeBackendId( $backend );
852 $this->fail(
'Expected exception not thrown' );
853 }
catch ( \InvalidArgumentException $ex ) {
855 'Backend was not registered with this SessionManager', $ex->getMessage()
860 $manager->deregisterSessionBackend( $backend );
861 $this->fail(
'Expected exception not thrown' );
862 }
catch ( \InvalidArgumentException $ex ) {
864 'Backend was not registered with this SessionManager', $ex->getMessage()
868 $session = $manager->getSessionById( $id,
true );
869 $this->
assertSame( $sessionId, $session->getSessionId() );
903 $manager->setLogger(
$logger );
908 $rMethod = $rClass->getMethod(
'loadSessionInfoFromStore' );
909 $rMethod->setAccessible(
true );
910 $loadSessionInfoFromStore =
function ( &$info ) use ( $rMethod, $manager,
$request ) {
911 return $rMethod->invokeArgs( $manager, [ &$info,
$request ] );
917 $id =
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
919 'userId' => $userInfo->getId(),
920 'userName' => $userInfo->getName(),
921 'userToken' => $userInfo->getToken(
true ),
922 'provider' =>
'Mock',
926 ->setMethods( [
'__toString',
'mergeMetadata',
'refreshSessionInfo' ] );
928 $provider = $builder->getMockForAbstractClass();
929 $provider->setManager( $manager );
930 $provider->expects( $this->
any() )->method(
'persistsSessionId' )
932 $provider->expects( $this->
any() )->method(
'canChangeUser' )
934 $provider->expects( $this->
any() )->method(
'refreshSessionInfo' )
936 $provider->expects( $this->
any() )->method(
'__toString' )
938 $provider->expects( $this->
any() )->method(
'mergeMetadata' )
940 if ( $b === [
'Throw' ] ) {
946 $provider2 = $builder->getMockForAbstractClass();
947 $provider2->setManager( $manager );
948 $provider2->expects( $this->
any() )->method(
'persistsSessionId' )
950 $provider2->expects( $this->
any() )->method(
'canChangeUser' )
952 $provider2->expects( $this->
any() )->method(
'__toString' )
954 $provider2->expects( $this->
any() )->method(
'refreshSessionInfo' )
956 $metadata[
'changed'] =
true;
960 $provider3 = $builder->getMockForAbstractClass();
961 $provider3->setManager( $manager );
962 $provider3->expects( $this->
any() )->method(
'persistsSessionId' )
964 $provider3->expects( $this->
any() )->method(
'canChangeUser' )
966 $provider3->expects( $this->
once() )->method(
'refreshSessionInfo' )
968 $provider3->expects( $this->
any() )->method(
'__toString' )
971 TestingAccessWrapper::newFromObject( $manager )->sessionProviders = [
972 (
string)$provider => $provider,
974 (
string)$provider3 => $provider3,
979 'provider' => $provider,
981 'userInfo' => $userInfo
983 $this->
assertFalse( $info->isIdSafe(),
'sanity check' );
989 'provider' => $provider,
990 'userInfo' => $userInfo
992 $this->
assertTrue( $info->isIdSafe(),
'sanity check' );
998 'provider' => $provider2,
1000 'userInfo' => $userInfo
1002 $this->
assertFalse( $info->isIdSafe(),
'sanity check' );
1009 'provider' => $provider,
1011 'userInfo' => $unverifiedUserInfo
1013 $this->
assertSame( $unverifiedUserInfo, $info->getUserInfo() );
1018 'Session "{session}": Unverified user provided and no metadata to auth it',
1026 'userInfo' => $userInfo
1030 [ LogLevel::WARNING,
'Session "{session}": Null provider and no metadata' ],
1035 'provider' => $provider,
1038 $this->
assertFalse( $info->isIdSafe(),
'sanity check' );
1041 $this->
assertTrue( $info->getUserInfo()->isVerified() );
1042 $this->
assertTrue( $info->getUserInfo()->isAnon() );
1047 'provider' => $provider2,
1050 $this->
assertFalse( $info->isIdSafe(),
'sanity check' );
1053 [ LogLevel::INFO,
'Session "{session}": No user provided and provider cannot set user' ]
1058 $this->store->setRawSession( $id,
true );
1061 [ LogLevel::WARNING,
'Session "{session}": Bad data' ],
1065 $this->store->setRawSession( $id, [
'data' => [] ] );
1068 [ LogLevel::WARNING,
'Session "{session}": Bad data structure' ],
1072 $this->store->deleteSession( $id );
1073 $this->store->setRawSession( $id, [
'metadata' => $metadata ] );
1076 [ LogLevel::WARNING,
'Session "{session}": Bad data structure' ],
1080 $this->store->setRawSession( $id, [
'metadata' => $metadata,
'data' =>
true ] );
1083 [ LogLevel::WARNING,
'Session "{session}": Bad data structure' ],
1087 $this->store->setRawSession( $id, [
'metadata' =>
true,
'data' => [] ] );
1090 [ LogLevel::WARNING,
'Session "{session}": Bad data structure' ],
1094 foreach ( $metadata as $key => $dummy ) {
1096 unset( $tmp[$key] );
1097 $this->store->setRawSession( $id, [
'metadata' => $tmp,
'data' => [] ] );
1100 [ LogLevel::WARNING,
'Session "{session}": Bad metadata' ],
1106 $this->store->setRawSession( $id, [
'metadata' => $metadata,
'data' => [] ] );
1108 'provider' => $provider,
1110 'userInfo' => $userInfo
1112 $this->
assertFalse( $info->isIdSafe(),
'sanity check' );
1118 $this->store->setSessionMeta( $id, [
'provider' =>
'Bad' ] + $metadata );
1120 'provider' => $provider,
1122 'userInfo' => $userInfo
1126 [ LogLevel::WARNING,
'Session "{session}": Wrong provider Bad !== Mock' ],
1131 $this->store->setSessionMeta( $id, [
'provider' =>
'Bad' ] + $metadata );
1134 'userInfo' => $userInfo
1138 [ LogLevel::WARNING,
'Session "{session}": Unknown provider Bad' ],
1143 $this->store->setSessionMeta( $id, $metadata );
1146 'userInfo' => $userInfo
1148 $this->
assertFalse( $info->isIdSafe(),
'sanity check' );
1154 $this->store->setSessionMeta( $id, [
'userId' => -1,
'userToken' =>
null ] + $metadata );
1156 'provider' => $provider,
1161 [ LogLevel::ERROR,
'Session "{session}": {exception}' ],
1165 $this->store->setSessionMeta(
1166 $id, [
'userId' => 0,
'userName' =>
'<X>',
'userToken' =>
null ] + $metadata
1169 'provider' => $provider,
1174 [ LogLevel::ERROR,
'Session "{session}": {exception}', ],
1179 $this->store->setSessionMeta(
1180 $id, [
'userId' => $userInfo->getId() + 1,
'userToken' =>
null ] + $metadata
1183 'provider' => $provider,
1185 'userInfo' => $userInfo
1189 [ LogLevel::WARNING,
'Session "{session}": User ID mismatch, {uid_a} !== {uid_b}' ],
1194 $this->store->setSessionMeta(
1195 $id, [
'userId' => 0,
'userName' =>
'X',
'userToken' =>
null ] + $metadata
1198 'provider' => $provider,
1200 'userInfo' => $userInfo
1204 [ LogLevel::WARNING,
'Session "{session}": User name mismatch, {uname_a} !== {uname_b}' ],
1209 $this->store->setSessionMeta(
1210 $id, [
'userId' => $userInfo->getId(),
'userName' =>
'X',
'userToken' =>
null ] + $metadata
1213 'provider' => $provider,
1215 'userInfo' => $userInfo
1221 'Session "{session}": User ID matched but name didn\'t (rename?), {uname_a} !== {uname_b}'
1227 $this->store->setSessionMeta(
1228 $id, [
'userId' => 0,
'userName' =>
null,
'userToken' =>
null ] + $metadata
1231 'provider' => $provider,
1233 'userInfo' => $userInfo
1239 'Session "{session}": Metadata has an anonymous user, ' .
1240 'but a non-anon user was provided',
1246 $this->store->setSessionMeta( $id, [
'userToken' =>
null ] + $metadata );
1248 'provider' => $provider,
1251 $this->
assertFalse( $info->isIdSafe(),
'sanity check' );
1253 $this->
assertSame( $userInfo->getId(), $info->getUserInfo()->getId() );
1258 $this->store->setSessionMeta(
1259 $id, [
'userId' => 0,
'userName' =>
'UTSysop',
'userToken' =>
null ] + $metadata
1262 'provider' => $provider,
1265 $this->
assertFalse( $info->isIdSafe(),
'sanity check' );
1267 $this->
assertSame( $userInfo->getId(), $info->getUserInfo()->getId() );
1272 $this->store->setSessionMeta(
1273 $id, [
'userId' => 0,
'userName' =>
null,
'userToken' =>
null ] + $metadata
1276 'provider' => $provider,
1279 $this->
assertFalse( $info->isIdSafe(),
'sanity check' );
1281 $this->
assertTrue( $info->getUserInfo()->isAnon() );
1286 $this->store->setSessionMeta( $id, $metadata );
1288 'provider' => $provider,
1290 'userInfo' => $unverifiedUserInfo
1292 $this->
assertFalse( $info->isIdSafe(),
'sanity check' );
1294 $this->
assertTrue( $info->getUserInfo()->isVerified() );
1295 $this->
assertSame( $unverifiedUserInfo->getId(), $info->getUserInfo()->getId() );
1296 $this->
assertSame( $unverifiedUserInfo->getName(), $info->getUserInfo()->getName() );
1301 $this->store->setSessionMeta( $id, $metadata );
1303 'provider' => $provider,
1305 'userInfo' => $unverifiedUserInfo
1307 $this->
assertFalse( $info->isIdSafe(),
'sanity check' );
1309 $this->
assertTrue( $info->getUserInfo()->isVerified() );
1310 $this->
assertSame( $unverifiedUserInfo->getId(), $info->getUserInfo()->getId() );
1311 $this->
assertSame( $unverifiedUserInfo->getName(), $info->getUserInfo()->getName() );
1316 $this->store->setSessionMeta( $id, [
'userToken' =>
'Bad' ] + $metadata );
1318 'provider' => $provider,
1320 'userInfo' => $userInfo
1324 [ LogLevel::WARNING,
'Session "{session}": User token mismatch' ],
1329 $this->store->setSessionMeta( $id, [
'provider' =>
'Mock2' ] + $metadata );
1331 'provider' => $provider2,
1333 'userInfo' => $userInfo,
1334 'metadata' => [
'Info' ],
1337 $this->
assertSame( [
'Info',
'changed' =>
true ], $info->getProviderMetadata() );
1340 $this->store->setSessionMeta( $id, [
'providerMetadata' => [
'Saved' ] ] + $metadata );
1342 'provider' => $provider,
1344 'userInfo' => $userInfo,
1347 $this->
assertSame( [
'Saved' ], $info->getProviderMetadata() );
1351 'provider' => $provider,
1353 'userInfo' => $userInfo,
1354 'metadata' => [
'Info' ],
1357 $this->
assertSame( [
'Merged' ], $info->getProviderMetadata() );
1361 'provider' => $provider,
1363 'userInfo' => $userInfo,
1364 'metadata' => [
'Throw' ],
1370 'Session "{session}": Metadata merge failed: {exception}',
1376 $this->store->setSessionMeta( $id, $metadata );
1378 'provider' => $provider,
1385 $this->store->setSessionMeta( $id, [
'remember' =>
true ] + $metadata );
1387 'provider' => $provider,
1394 $this->store->setSessionMeta( $id, [
'remember' =>
false ] + $metadata );
1396 'provider' => $provider,
1398 'userInfo' => $userInfo
1405 $this->store->setSessionMeta( $id, $metadata );
1407 'provider' => $provider,
1409 'userInfo' => $userInfo
1415 $this->store->setSessionMeta( $id, [
'forceHTTPS' =>
true ] + $metadata );
1417 'provider' => $provider,
1419 'userInfo' => $userInfo
1425 $this->store->setSessionMeta( $id, [
'forceHTTPS' =>
false ] + $metadata );
1427 'provider' => $provider,
1429 'userInfo' => $userInfo,
1430 'forceHTTPS' =>
true
1437 $this->store->setSessionMeta( $id, $metadata );
1439 'provider' => $provider,
1441 'userInfo' => $userInfo
1447 $this->store->setSessionMeta( $id, [
'persisted' =>
true ] + $metadata );
1449 'provider' => $provider,
1451 'userInfo' => $userInfo
1457 $this->store->setSessionMeta( $id, [
'persisted' =>
false ] + $metadata );
1459 'provider' => $provider,
1461 'userInfo' => $userInfo,
1470 'provider' => $provider3,
1477 $data = [
'foo' => 1 ];
1478 $this->store->setSession( $id, [
'metadata' => $metadata,
'data' =>
$data ] );
1480 'provider' => $provider,
1482 'userInfo' => $userInfo
1485 'SessionCheckInfo' => [
function ( &$reason, $i, $r, $m, $d ) use (
1488 $this->
assertSame( $info->getId(), $i->getId() );
1489 $this->
assertSame( $info->getProvider(), $i->getProvider() );
1490 $this->
assertSame( $info->getUserInfo(), $i->getUserInfo() );
1501 [ LogLevel::WARNING,
'Session "{session}": Hook aborted' ],
1507 $this->store->setSessionMeta( $id, [
'userToken' =>
'Bad' ] + $metadata );
1509 'provider' => $provider,
1511 'userInfo' => $userInfo,
1515 $this->
assertFalse( $this->store->getSession( $id ) );
1517 [ LogLevel::WARNING,
'Session "{session}": User token mismatch' ],