Esempio n. 1
0
 /**
  * Load and verify the session info against the store
  *
  * @param SessionInfo &$info Will likely be replaced with an updated SessionInfo instance
  * @param WebRequest $request
  * @return bool Whether the session info matches the stored data (if any)
  */
 private function loadSessionInfoFromStore(SessionInfo &$info, WebRequest $request)
 {
     $key = wfMemcKey('MWSession', $info->getId());
     $blob = $this->store->get($key);
     $newParams = array();
     if ($blob !== false) {
         // Sanity check: blob must be an array, if it's saved at all
         if (!is_array($blob)) {
             $this->logger->warning("Session {$info}: Bad data");
             $this->store->delete($key);
             return false;
         }
         // Sanity check: blob has data and metadata arrays
         if (!isset($blob['data']) || !is_array($blob['data']) || !isset($blob['metadata']) || !is_array($blob['metadata'])) {
             $this->logger->warning("Session {$info}: Bad data structure");
             $this->store->delete($key);
             return false;
         }
         $data = $blob['data'];
         $metadata = $blob['metadata'];
         // Sanity check: metadata must be an array and must contain certain
         // keys, if it's saved at all
         if (!array_key_exists('userId', $metadata) || !array_key_exists('userName', $metadata) || !array_key_exists('userToken', $metadata) || !array_key_exists('provider', $metadata)) {
             $this->logger->warning("Session {$info}: Bad metadata");
             $this->store->delete($key);
             return false;
         }
         // First, load the provider from metadata, or validate it against the metadata.
         $provider = $info->getProvider();
         if ($provider === null) {
             $newParams['provider'] = $provider = $this->getProvider($metadata['provider']);
             if (!$provider) {
                 $this->logger->warning("Session {$info}: Unknown provider, " . $metadata['provider']);
                 $this->store->delete($key);
                 return false;
             }
         } elseif ($metadata['provider'] !== (string) $provider) {
             $this->logger->warning("Session {$info}: Wrong provider, " . $metadata['provider'] . ' !== ' . $provider);
             return false;
         }
         // Load provider metadata from metadata, or validate it against the metadata
         $providerMetadata = $info->getProviderMetadata();
         if (isset($metadata['providerMetadata'])) {
             if ($providerMetadata === null) {
                 $newParams['metadata'] = $metadata['providerMetadata'];
             } else {
                 try {
                     $newProviderMetadata = $provider->mergeMetadata($metadata['providerMetadata'], $providerMetadata);
                     if ($newProviderMetadata !== $providerMetadata) {
                         $newParams['metadata'] = $newProviderMetadata;
                     }
                 } catch (\UnexpectedValueException $ex) {
                     $this->logger->warning("Session {$info}: Metadata merge failed: " . $ex->getMessage());
                     return false;
                 }
             }
         }
         // Next, load the user from metadata, or validate it against the metadata.
         $userInfo = $info->getUserInfo();
         if (!$userInfo) {
             // For loading, id is preferred to name.
             try {
                 if ($metadata['userId']) {
                     $userInfo = UserInfo::newFromId($metadata['userId']);
                 } elseif ($metadata['userName'] !== null) {
                     // Shouldn't happen, but just in case
                     $userInfo = UserInfo::newFromName($metadata['userName']);
                 } else {
                     $userInfo = UserInfo::newAnonymous();
                 }
             } catch (\InvalidArgumentException $ex) {
                 $this->logger->error("Session {$info}: " . $ex->getMessage());
                 return false;
             }
             $newParams['userInfo'] = $userInfo;
         } else {
             // User validation passes if user ID matches, or if there
             // is no saved ID and the names match.
             if ($metadata['userId']) {
                 if ($metadata['userId'] !== $userInfo->getId()) {
                     $this->logger->warning("Session {$info}: User ID mismatch, " . $metadata['userId'] . ' !== ' . $userInfo->getId());
                     return false;
                 }
                 // If the user was renamed, probably best to fail here.
                 if ($metadata['userName'] !== null && $userInfo->getName() !== $metadata['userName']) {
                     $this->logger->warning("Session {$info}: User ID matched but name didn't (rename?), " . $metadata['userName'] . ' !== ' . $userInfo->getName());
                     return false;
                 }
             } elseif ($metadata['userName'] !== null) {
                 // Shouldn't happen, but just in case
                 if ($metadata['userName'] !== $userInfo->getName()) {
                     $this->logger->warning("Session {$info}: User name mismatch, " . $metadata['userName'] . ' !== ' . $userInfo->getName());
                     return false;
                 }
             } elseif (!$userInfo->isAnon()) {
                 // Metadata specifies an anonymous user, but the passed-in
                 // user isn't anonymous.
                 $this->logger->warning("Session {$info}: Metadata has an anonymous user, " . 'but a non-anon user was provided');
                 return false;
             }
         }
         // And if we have a token in the metadata, it must match the loaded/provided user.
         if ($metadata['userToken'] !== null && $userInfo->getToken() !== $metadata['userToken']) {
             $this->logger->warning("Session {$info}: User token mismatch");
             return false;
         }
         if (!$userInfo->isVerified()) {
             $newParams['userInfo'] = $userInfo->verified();
         }
         if (!empty($metadata['remember']) && !$info->wasRemembered()) {
             $newParams['remembered'] = true;
         }
         if (!empty($metadata['forceHTTPS']) && !$info->forceHTTPS()) {
             $newParams['forceHTTPS'] = true;
         }
         if (!$info->isIdSafe()) {
             $newParams['idIsSafe'] = true;
         }
     } else {
         // No metadata, so we can't load the provider if one wasn't given.
         if ($info->getProvider() === null) {
             $this->logger->warning("Session {$info}: Null provider and no metadata");
             return false;
         }
         // If no user was provided and no metadata, it must be anon.
         if (!$info->getUserInfo()) {
             if ($info->getProvider()->canChangeUser()) {
                 $newParams['userInfo'] = UserInfo::newAnonymous();
             } else {
                 $this->logger->info("Session {$info}: No user provided and provider cannot set user");
                 return false;
             }
         } elseif (!$info->getUserInfo()->isVerified()) {
             $this->logger->warning("Session {$info}: Unverified user provided and no metadata to auth it");
             return false;
         }
         $data = false;
         $metadata = false;
         if (!$info->getProvider()->persistsSessionId() && !$info->isIdSafe()) {
             // The ID doesn't come from the user, so it should be safe
             // (and if not, nothing we can do about it anyway)
             $newParams['idIsSafe'] = true;
         }
     }
     // Construct the replacement SessionInfo, if necessary
     if ($newParams) {
         $newParams['copyFrom'] = $info;
         $info = new SessionInfo($info->getPriority(), $newParams);
     }
     // Allow the provider to check the loaded SessionInfo
     $providerMetadata = $info->getProviderMetadata();
     if (!$info->getProvider()->refreshSessionInfo($info, $request, $providerMetadata)) {
         return false;
     }
     if ($providerMetadata !== $info->getProviderMetadata()) {
         $info = new SessionInfo($info->getPriority(), array('metadata' => $providerMetadata, 'copyFrom' => $info));
     }
     // Give hooks a chance to abort. Combined with the SessionMetadata
     // hook, this can allow for tying a session to an IP address or the
     // like.
     $reason = 'Hook aborted';
     if (!\Hooks::run('SessionCheckInfo', array(&$reason, $info, $request, $metadata, $data))) {
         $this->logger->warning("Session {$info}: {$reason}");
         return false;
     }
     return true;
 }
Esempio n. 2
0
 public function testBasics()
 {
     $anonInfo = UserInfo::newAnonymous();
     $userInfo = UserInfo::newFromName('UTSysop', true);
     $unverifiedUserInfo = UserInfo::newFromName('UTSysop', false);
     try {
         new SessionInfo(SessionInfo::MIN_PRIORITY - 1, array());
         $this->fail('Expected exception not thrown', 'priority < min');
     } catch (\InvalidArgumentException $ex) {
         $this->assertSame('Invalid priority', $ex->getMessage(), 'priority < min');
     }
     try {
         new SessionInfo(SessionInfo::MAX_PRIORITY + 1, array());
         $this->fail('Expected exception not thrown', 'priority > max');
     } catch (\InvalidArgumentException $ex) {
         $this->assertSame('Invalid priority', $ex->getMessage(), 'priority > max');
     }
     try {
         new SessionInfo(SessionInfo::MIN_PRIORITY, array('id' => 'ABC?'));
         $this->fail('Expected exception not thrown', 'bad session ID');
     } catch (\InvalidArgumentException $ex) {
         $this->assertSame('Invalid session ID', $ex->getMessage(), 'bad session ID');
     }
     try {
         new SessionInfo(SessionInfo::MIN_PRIORITY, array('userInfo' => new \stdClass()));
         $this->fail('Expected exception not thrown', 'bad userInfo');
     } catch (\InvalidArgumentException $ex) {
         $this->assertSame('Invalid userInfo', $ex->getMessage(), 'bad userInfo');
     }
     try {
         new SessionInfo(SessionInfo::MIN_PRIORITY, array());
         $this->fail('Expected exception not thrown', 'no provider, no id');
     } catch (\InvalidArgumentException $ex) {
         $this->assertSame('Must supply an ID when no provider is given', $ex->getMessage(), 'no provider, no id');
     }
     try {
         new SessionInfo(SessionInfo::MIN_PRIORITY, array('copyFrom' => new \stdClass()));
         $this->fail('Expected exception not thrown', 'bad copyFrom');
     } catch (\InvalidArgumentException $ex) {
         $this->assertSame('Invalid copyFrom', $ex->getMessage(), 'bad copyFrom');
     }
     $manager = new SessionManager();
     $provider = $this->getMockBuilder('MediaWiki\\Session\\SessionProvider')->setMethods(array('persistsSessionId', 'canChangeUser', '__toString'))->getMockForAbstractClass();
     $provider->setManager($manager);
     $provider->expects($this->any())->method('persistsSessionId')->will($this->returnValue(true));
     $provider->expects($this->any())->method('canChangeUser')->will($this->returnValue(true));
     $provider->expects($this->any())->method('__toString')->will($this->returnValue('Mock'));
     $provider2 = $this->getMockBuilder('MediaWiki\\Session\\SessionProvider')->setMethods(array('persistsSessionId', 'canChangeUser', '__toString'))->getMockForAbstractClass();
     $provider2->setManager($manager);
     $provider2->expects($this->any())->method('persistsSessionId')->will($this->returnValue(true));
     $provider2->expects($this->any())->method('canChangeUser')->will($this->returnValue(true));
     $provider2->expects($this->any())->method('__toString')->will($this->returnValue('Mock2'));
     try {
         new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'userInfo' => $anonInfo, 'metadata' => 'foo'));
         $this->fail('Expected exception not thrown', 'bad metadata');
     } catch (\InvalidArgumentException $ex) {
         $this->assertSame('Invalid metadata', $ex->getMessage(), 'bad metadata');
     }
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY + 5, array('provider' => $provider, 'userInfo' => $anonInfo));
     $this->assertSame($provider, $info->getProvider());
     $this->assertNotNull($info->getId());
     $this->assertSame(SessionInfo::MIN_PRIORITY + 5, $info->getPriority());
     $this->assertSame($anonInfo, $info->getUserInfo());
     $this->assertTrue($info->isIdSafe());
     $this->assertFalse($info->wasPersisted());
     $this->assertFalse($info->wasRemembered());
     $this->assertFalse($info->forceHTTPS());
     $this->assertNull($info->getProviderMetadata());
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY + 5, array('provider' => $provider, 'userInfo' => $unverifiedUserInfo, 'metadata' => array('Foo')));
     $this->assertSame($provider, $info->getProvider());
     $this->assertNotNull($info->getId());
     $this->assertSame(SessionInfo::MIN_PRIORITY + 5, $info->getPriority());
     $this->assertSame($unverifiedUserInfo, $info->getUserInfo());
     $this->assertTrue($info->isIdSafe());
     $this->assertFalse($info->wasPersisted());
     $this->assertFalse($info->wasRemembered());
     $this->assertFalse($info->forceHTTPS());
     $this->assertSame(array('Foo'), $info->getProviderMetadata());
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY + 5, array('provider' => $provider, 'userInfo' => $userInfo));
     $this->assertSame($provider, $info->getProvider());
     $this->assertNotNull($info->getId());
     $this->assertSame(SessionInfo::MIN_PRIORITY + 5, $info->getPriority());
     $this->assertSame($userInfo, $info->getUserInfo());
     $this->assertTrue($info->isIdSafe());
     $this->assertFalse($info->wasPersisted());
     $this->assertTrue($info->wasRemembered());
     $this->assertFalse($info->forceHTTPS());
     $this->assertNull($info->getProviderMetadata());
     $id = $manager->generateSessionId();
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY + 5, array('provider' => $provider, 'id' => $id, 'persisted' => true, 'userInfo' => $anonInfo));
     $this->assertSame($provider, $info->getProvider());
     $this->assertSame($id, $info->getId());
     $this->assertSame(SessionInfo::MIN_PRIORITY + 5, $info->getPriority());
     $this->assertSame($anonInfo, $info->getUserInfo());
     $this->assertFalse($info->isIdSafe());
     $this->assertTrue($info->wasPersisted());
     $this->assertFalse($info->wasRemembered());
     $this->assertFalse($info->forceHTTPS());
     $this->assertNull($info->getProviderMetadata());
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY + 5, array('provider' => $provider, 'id' => $id, 'userInfo' => $userInfo));
     $this->assertSame($provider, $info->getProvider());
     $this->assertSame($id, $info->getId());
     $this->assertSame(SessionInfo::MIN_PRIORITY + 5, $info->getPriority());
     $this->assertSame($userInfo, $info->getUserInfo());
     $this->assertFalse($info->isIdSafe());
     $this->assertFalse($info->wasPersisted());
     $this->assertTrue($info->wasRemembered());
     $this->assertFalse($info->forceHTTPS());
     $this->assertNull($info->getProviderMetadata());
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY + 5, array('id' => $id, 'persisted' => true, 'userInfo' => $userInfo, 'metadata' => array('Foo')));
     $this->assertSame($id, $info->getId());
     $this->assertSame(SessionInfo::MIN_PRIORITY + 5, $info->getPriority());
     $this->assertSame($userInfo, $info->getUserInfo());
     $this->assertFalse($info->isIdSafe());
     $this->assertTrue($info->wasPersisted());
     $this->assertFalse($info->wasRemembered());
     $this->assertFalse($info->forceHTTPS());
     $this->assertNull($info->getProviderMetadata());
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY + 5, array('id' => $id, 'remembered' => true, 'userInfo' => $userInfo));
     $this->assertFalse($info->wasRemembered(), 'no provider');
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY + 5, array('provider' => $provider, 'id' => $id, 'remembered' => true));
     $this->assertFalse($info->wasRemembered(), 'no user');
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY + 5, array('provider' => $provider, 'id' => $id, 'remembered' => true, 'userInfo' => $anonInfo));
     $this->assertFalse($info->wasRemembered(), 'anonymous user');
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY + 5, array('provider' => $provider, 'id' => $id, 'remembered' => true, 'userInfo' => $unverifiedUserInfo));
     $this->assertFalse($info->wasRemembered(), 'unverified user');
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY + 5, array('provider' => $provider, 'id' => $id, 'remembered' => false, 'userInfo' => $userInfo));
     $this->assertFalse($info->wasRemembered(), 'specific override');
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY + 5, array('id' => $id, 'idIsSafe' => true));
     $this->assertSame($id, $info->getId());
     $this->assertSame(SessionInfo::MIN_PRIORITY + 5, $info->getPriority());
     $this->assertTrue($info->isIdSafe());
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('id' => $id, 'forceHTTPS' => 1));
     $this->assertTrue($info->forceHTTPS());
     $fromInfo = new SessionInfo(SessionInfo::MIN_PRIORITY, array('id' => $id . 'A', 'provider' => $provider, 'userInfo' => $userInfo, 'idIsSafe' => true, 'persisted' => true, 'remembered' => true, 'forceHTTPS' => true, 'metadata' => array('foo!')));
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY + 4, array('copyFrom' => $fromInfo));
     $this->assertSame($id . 'A', $info->getId());
     $this->assertSame(SessionInfo::MIN_PRIORITY + 4, $info->getPriority());
     $this->assertSame($provider, $info->getProvider());
     $this->assertSame($userInfo, $info->getUserInfo());
     $this->assertTrue($info->isIdSafe());
     $this->assertTrue($info->wasPersisted());
     $this->assertTrue($info->wasRemembered());
     $this->assertTrue($info->forceHTTPS());
     $this->assertSame(array('foo!'), $info->getProviderMetadata());
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY + 4, array('id' => $id . 'X', 'provider' => $provider2, 'userInfo' => $unverifiedUserInfo, 'idIsSafe' => false, 'persisted' => false, 'remembered' => false, 'forceHTTPS' => false, 'metadata' => null, 'copyFrom' => $fromInfo));
     $this->assertSame($id . 'X', $info->getId());
     $this->assertSame(SessionInfo::MIN_PRIORITY + 4, $info->getPriority());
     $this->assertSame($provider2, $info->getProvider());
     $this->assertSame($unverifiedUserInfo, $info->getUserInfo());
     $this->assertFalse($info->isIdSafe());
     $this->assertFalse($info->wasPersisted());
     $this->assertFalse($info->wasRemembered());
     $this->assertFalse($info->forceHTTPS());
     $this->assertNull($info->getProviderMetadata());
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('id' => $id));
     $this->assertSame('[' . SessionInfo::MIN_PRIORITY . "]null<null>{$id}", (string) $info, 'toString');
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id, 'persisted' => true, 'userInfo' => $userInfo));
     $this->assertSame('[' . SessionInfo::MIN_PRIORITY . "]Mock<+:{$userInfo->getId()}:UTSysop>{$id}", (string) $info, 'toString');
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id, 'persisted' => true, 'userInfo' => $unverifiedUserInfo));
     $this->assertSame('[' . SessionInfo::MIN_PRIORITY . "]Mock<-:{$userInfo->getId()}:UTSysop>{$id}", (string) $info, 'toString');
 }
Esempio n. 3
0
 /**
  * @param SessionId $id Session ID object
  * @param SessionInfo $info Session info to populate from
  * @param CachedBagOStuff $store Backend data store
  * @param LoggerInterface $logger
  * @param int $lifetime Session data lifetime in seconds
  */
 public function __construct(SessionId $id, SessionInfo $info, CachedBagOStuff $store, LoggerInterface $logger, $lifetime)
 {
     $phpSessionHandling = \RequestContext::getMain()->getConfig()->get('PHPSessionHandling');
     $this->usePhpSessionHandling = $phpSessionHandling !== 'disable';
     if ($info->getUserInfo() && !$info->getUserInfo()->isVerified()) {
         throw new \InvalidArgumentException("Refusing to create session for unverified user {$info->getUserInfo()}");
     }
     if ($info->getProvider() === null) {
         throw new \InvalidArgumentException('Cannot create session without a provider');
     }
     if ($info->getId() !== $id->getId()) {
         throw new \InvalidArgumentException('SessionId and SessionInfo don\'t match');
     }
     $this->id = $id;
     $this->user = $info->getUserInfo() ? $info->getUserInfo()->getUser() : new User();
     $this->store = $store;
     $this->logger = $logger;
     $this->lifetime = $lifetime;
     $this->provider = $info->getProvider();
     $this->persist = $info->wasPersisted();
     $this->remember = $info->wasRemembered();
     $this->forceHTTPS = $info->forceHTTPS();
     $this->providerMetadata = $info->getProviderMetadata();
     $blob = $store->get(wfMemcKey('MWSession', (string) $this->id));
     if (!is_array($blob) || !isset($blob['metadata']) || !is_array($blob['metadata']) || !isset($blob['data']) || !is_array($blob['data'])) {
         $this->data = [];
         $this->dataDirty = true;
         $this->metaDirty = true;
         $this->logger->debug('SessionBackend "{session}" is unsaved, marking dirty in constructor', ['session' => $this->id]);
     } else {
         $this->data = $blob['data'];
         if (isset($blob['metadata']['loggedOut'])) {
             $this->loggedOut = (int) $blob['metadata']['loggedOut'];
         }
         if (isset($blob['metadata']['expires'])) {
             $this->expires = (int) $blob['metadata']['expires'];
         } else {
             $this->metaDirty = true;
             $this->logger->debug('SessionBackend "{session}" metadata dirty due to missing expiration timestamp', ['session' => $this->id]);
         }
     }
     $this->dataHash = md5(serialize($this->data));
 }
 public function testCheckSessionInfo()
 {
     $logger = new \TestLogger(true, function ($m) {
         return preg_replace('/^Session \\[\\d+\\][a-zA-Z0-9_\\\\]+<(?:null|anon|[+-]:\\d+:\\w+)>\\w+: /', 'Session X: ', $m);
     });
     $provider = $this->getProvider();
     $provider->setLogger($logger);
     $user = \User::newFromName('UTSysop');
     $request = $this->getMock('FauxRequest', array('getIP'));
     $request->expects($this->any())->method('getIP')->will($this->returnValue('127.0.0.1'));
     $bp = \BotPassword::newFromUser($user, 'BotPasswordSessionProvider');
     $data = array('provider' => $provider, 'id' => 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'userInfo' => UserInfo::newFromUser($user, true), 'persisted' => false, 'metadata' => array('centralId' => $bp->getUserCentralId(), 'appId' => $bp->getAppId(), 'token' => $bp->getToken()));
     $dataMD = $data['metadata'];
     foreach (array_keys($data['metadata']) as $key) {
         $data['metadata'] = $dataMD;
         unset($data['metadata'][$key]);
         $info = new SessionInfo(SessionInfo::MIN_PRIORITY, $data);
         $metadata = $info->getProviderMetadata();
         $this->assertFalse($provider->refreshSessionInfo($info, $request, $metadata));
         $this->assertSame(array(array(LogLevel::INFO, "Session X: Missing metadata: {$key}")), $logger->getBuffer());
         $logger->clearBuffer();
     }
     $data['metadata'] = $dataMD;
     $data['metadata']['appId'] = 'Foobar';
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, $data);
     $metadata = $info->getProviderMetadata();
     $this->assertFalse($provider->refreshSessionInfo($info, $request, $metadata));
     $this->assertSame(array(array(LogLevel::INFO, "Session X: No BotPassword for {$bp->getUserCentralId()} Foobar")), $logger->getBuffer());
     $logger->clearBuffer();
     $data['metadata'] = $dataMD;
     $data['metadata']['token'] = 'Foobar';
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, $data);
     $metadata = $info->getProviderMetadata();
     $this->assertFalse($provider->refreshSessionInfo($info, $request, $metadata));
     $this->assertSame(array(array(LogLevel::INFO, 'Session X: BotPassword token check failed')), $logger->getBuffer());
     $logger->clearBuffer();
     $request2 = $this->getMock('FauxRequest', array('getIP'));
     $request2->expects($this->any())->method('getIP')->will($this->returnValue('10.0.0.1'));
     $data['metadata'] = $dataMD;
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, $data);
     $metadata = $info->getProviderMetadata();
     $this->assertFalse($provider->refreshSessionInfo($info, $request2, $metadata));
     $this->assertSame(array(array(LogLevel::INFO, 'Session X: Restrictions check failed')), $logger->getBuffer());
     $logger->clearBuffer();
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, $data);
     $metadata = $info->getProviderMetadata();
     $this->assertTrue($provider->refreshSessionInfo($info, $request, $metadata));
     $this->assertSame(array(), $logger->getBuffer());
     $this->assertEquals($dataMD + array('rights' => array('read')), $metadata);
 }
 public function testCheckSessionInfo()
 {
     $logger = new \TestLogger(true);
     $provider = $this->getProvider();
     $provider->setLogger($logger);
     $user = static::getTestSysop()->getUser();
     $request = $this->getMock('FauxRequest', ['getIP']);
     $request->expects($this->any())->method('getIP')->will($this->returnValue('127.0.0.1'));
     $bp = \BotPassword::newFromUser($user, 'BotPasswordSessionProvider');
     $data = ['provider' => $provider, 'id' => 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'userInfo' => UserInfo::newFromUser($user, true), 'persisted' => false, 'metadata' => ['centralId' => $bp->getUserCentralId(), 'appId' => $bp->getAppId(), 'token' => $bp->getToken()]];
     $dataMD = $data['metadata'];
     foreach (array_keys($data['metadata']) as $key) {
         $data['metadata'] = $dataMD;
         unset($data['metadata'][$key]);
         $info = new SessionInfo(SessionInfo::MIN_PRIORITY, $data);
         $metadata = $info->getProviderMetadata();
         $this->assertFalse($provider->refreshSessionInfo($info, $request, $metadata));
         $this->assertSame([[LogLevel::INFO, 'Session "{session}": Missing metadata: {missing}']], $logger->getBuffer());
         $logger->clearBuffer();
     }
     $data['metadata'] = $dataMD;
     $data['metadata']['appId'] = 'Foobar';
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, $data);
     $metadata = $info->getProviderMetadata();
     $this->assertFalse($provider->refreshSessionInfo($info, $request, $metadata));
     $this->assertSame([[LogLevel::INFO, 'Session "{session}": No BotPassword for {centralId} {appId}']], $logger->getBuffer());
     $logger->clearBuffer();
     $data['metadata'] = $dataMD;
     $data['metadata']['token'] = 'Foobar';
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, $data);
     $metadata = $info->getProviderMetadata();
     $this->assertFalse($provider->refreshSessionInfo($info, $request, $metadata));
     $this->assertSame([[LogLevel::INFO, 'Session "{session}": BotPassword token check failed']], $logger->getBuffer());
     $logger->clearBuffer();
     $request2 = $this->getMock('FauxRequest', ['getIP']);
     $request2->expects($this->any())->method('getIP')->will($this->returnValue('10.0.0.1'));
     $data['metadata'] = $dataMD;
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, $data);
     $metadata = $info->getProviderMetadata();
     $this->assertFalse($provider->refreshSessionInfo($info, $request2, $metadata));
     $this->assertSame([[LogLevel::INFO, 'Session "{session}": Restrictions check failed']], $logger->getBuffer());
     $logger->clearBuffer();
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, $data);
     $metadata = $info->getProviderMetadata();
     $this->assertTrue($provider->refreshSessionInfo($info, $request, $metadata));
     $this->assertSame([], $logger->getBuffer());
     $this->assertEquals($dataMD + ['rights' => ['read']], $metadata);
 }