コード例 #1
0
 public function testConstructor()
 {
     // Set variables
     $this->getBackend();
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $this->provider, 'id' => self::SESSIONID, 'persisted' => true, 'userInfo' => UserInfo::newFromName('UTSysop', false), 'idIsSafe' => true));
     $id = new SessionId($info->getId());
     $logger = new \Psr\Log\NullLogger();
     try {
         new SessionBackend($id, $info, $this->store, $this->store, $logger, 10);
         $this->fail('Expected exception not thrown');
     } catch (\InvalidArgumentException $ex) {
         $this->assertSame("Refusing to create session for unverified user {$info->getUserInfo()}", $ex->getMessage());
     }
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('id' => self::SESSIONID, 'userInfo' => UserInfo::newFromName('UTSysop', true), 'idIsSafe' => true));
     $id = new SessionId($info->getId());
     try {
         new SessionBackend($id, $info, $this->store, $this->store, $logger, 10);
         $this->fail('Expected exception not thrown');
     } catch (\InvalidArgumentException $ex) {
         $this->assertSame('Cannot create session without a provider', $ex->getMessage());
     }
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $this->provider, 'id' => self::SESSIONID, 'persisted' => true, 'userInfo' => UserInfo::newFromName('UTSysop', true), 'idIsSafe' => true));
     $id = new SessionId('!' . $info->getId());
     try {
         new SessionBackend($id, $info, $this->store, $this->store, $logger, 10);
         $this->fail('Expected exception not thrown');
     } catch (\InvalidArgumentException $ex) {
         $this->assertSame('SessionId and SessionInfo don\'t match', $ex->getMessage());
     }
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $this->provider, 'id' => self::SESSIONID, 'persisted' => true, 'userInfo' => UserInfo::newFromName('UTSysop', true), 'idIsSafe' => true));
     $id = new SessionId($info->getId());
     $backend = new SessionBackend($id, $info, $this->store, $this->store, $logger, 10);
     $this->assertSame(self::SESSIONID, $backend->getId());
     $this->assertSame($id, $backend->getSessionId());
     $this->assertSame($this->provider, $backend->getProvider());
     $this->assertInstanceOf('User', $backend->getUser());
     $this->assertSame('UTSysop', $backend->getUser()->getName());
     $this->assertSame($info->wasPersisted(), $backend->isPersistent());
     $this->assertSame($info->wasRemembered(), $backend->shouldRememberUser());
     $this->assertSame($info->forceHTTPS(), $backend->shouldForceHTTPS());
     $expire = time() + 100;
     $this->store->setSessionMeta(self::SESSIONID, array('expires' => $expire), 2);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $this->provider, 'id' => self::SESSIONID, 'persisted' => true, 'forceHTTPS' => true, 'metadata' => array('foo'), 'idIsSafe' => true));
     $id = new SessionId($info->getId());
     $backend = new SessionBackend($id, $info, $this->store, $this->store, $logger, 10);
     $this->assertSame(self::SESSIONID, $backend->getId());
     $this->assertSame($id, $backend->getSessionId());
     $this->assertSame($this->provider, $backend->getProvider());
     $this->assertInstanceOf('User', $backend->getUser());
     $this->assertTrue($backend->getUser()->isAnon());
     $this->assertSame($info->wasPersisted(), $backend->isPersistent());
     $this->assertSame($info->wasRemembered(), $backend->shouldRememberUser());
     $this->assertSame($info->forceHTTPS(), $backend->shouldForceHTTPS());
     $this->assertSame($expire, \TestingAccessWrapper::newFromObject($backend)->expires);
     $this->assertSame(array('foo'), $backend->getProviderMetadata());
 }
コード例 #2
0
ファイル: SessionInfo.php プロジェクト: Gomyul/mediawiki
 /**
  * @param int $priority Session priority
  * @param array $data
  *  - provider: (SessionProvider|null) If not given, the provider will be
  *    determined from the saved session data.
  *  - id: (string|null) Session ID
  *  - userInfo: (UserInfo|null) User known from the request. If
  *    $provider->canChangeUser() is false, a verified user
  *    must be provided.
  *  - persisted: (bool) Whether this session was persisted
  *  - remembered: (bool) Whether the verified user was remembered.
  *    Defaults to true.
  *  - forceHTTPS: (bool) Whether to force HTTPS for this session
  *  - metadata: (array) Provider metadata, to be returned by
  *    Session::getProviderMetadata().
  *  - idIsSafe: (bool) Set true if the 'id' did not come from the user.
  *    Generally you'll use this from SessionProvider::newEmptySession(),
  *    and not from any other method.
  *  - copyFrom: (SessionInfo) SessionInfo to copy other data items from.
  */
 public function __construct($priority, array $data)
 {
     if ($priority < self::MIN_PRIORITY || $priority > self::MAX_PRIORITY) {
         throw new \InvalidArgumentException('Invalid priority');
     }
     if (isset($data['copyFrom'])) {
         $from = $data['copyFrom'];
         if (!$from instanceof SessionInfo) {
             throw new \InvalidArgumentException('Invalid copyFrom');
         }
         $data += array('provider' => $from->provider, 'id' => $from->id, 'userInfo' => $from->userInfo, 'persisted' => $from->persisted, 'remembered' => $from->remembered, 'forceHTTPS' => $from->forceHTTPS, 'metadata' => $from->providerMetadata, 'idIsSafe' => $from->idIsSafe);
         // @codeCoverageIgnoreEnd
     } else {
         $data += array('provider' => null, 'id' => null, 'userInfo' => null, 'persisted' => false, 'remembered' => true, 'forceHTTPS' => false, 'metadata' => null, 'idIsSafe' => false);
         // @codeCoverageIgnoreEnd
     }
     if ($data['id'] !== null && !SessionManager::validateSessionId($data['id'])) {
         throw new \InvalidArgumentException('Invalid session ID');
     }
     if ($data['userInfo'] !== null && !$data['userInfo'] instanceof UserInfo) {
         throw new \InvalidArgumentException('Invalid userInfo');
     }
     if (!$data['provider'] && $data['id'] === null) {
         throw new \InvalidArgumentException('Must supply an ID when no provider is given');
     }
     if ($data['metadata'] !== null && !is_array($data['metadata'])) {
         throw new \InvalidArgumentException('Invalid metadata');
     }
     $this->provider = $data['provider'];
     if ($data['id'] !== null) {
         $this->id = $data['id'];
         $this->idIsSafe = $data['idIsSafe'];
     } else {
         $this->id = $this->provider->getManager()->generateSessionId();
         $this->idIsSafe = true;
     }
     $this->priority = (int) $priority;
     $this->userInfo = $data['userInfo'];
     $this->persisted = (bool) $data['persisted'];
     if ($data['provider'] !== null) {
         if ($this->userInfo !== null && !$this->userInfo->isAnon() && $this->userInfo->isVerified()) {
             $this->remembered = (bool) $data['remembered'];
         }
         $this->providerMetadata = $data['metadata'];
     }
     $this->forceHTTPS = (bool) $data['forceHTTPS'];
 }
コード例 #3
0
ファイル: SessionManager.php プロジェクト: paladox/2
 /**
  * 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;
 }
コード例 #4
0
 public function provideSessionInfo(WebRequest $request)
 {
     $sessionId = $this->getCookie($request, $this->params['sessionName'], '');
     $info = array('provider' => $this, 'forceHTTPS' => $this->getCookie($request, 'forceHTTPS', '', false));
     if (SessionManager::validateSessionId($sessionId)) {
         $info['id'] = $sessionId;
         $info['persisted'] = true;
     }
     list($userId, $userName, $token) = $this->getUserInfoFromCookies($request);
     if ($userId !== null) {
         try {
             $userInfo = UserInfo::newFromId($userId);
         } catch (\InvalidArgumentException $ex) {
             return null;
         }
         // Sanity check
         if ($userName !== null && $userInfo->getName() !== $userName) {
             $this->logger->warning('Session "{session}" requested with mismatched UserID and UserName cookies.', array('session' => $sessionId, 'mismatch' => array('userid' => $userId, 'cookie_username' => $userName, 'username' => $userInfo->getName())));
             return null;
         }
         if ($token !== null) {
             if (!hash_equals($userInfo->getToken(), $token)) {
                 $this->logger->warning('Session "{session}" requested with invalid Token cookie.', array('session' => $sessionId, 'userid' => $userId, 'username' => $userInfo->getName()));
                 return null;
             }
             $info['userInfo'] = $userInfo->verified();
         } elseif (isset($info['id'])) {
             $info['userInfo'] = $userInfo;
         } else {
             // No point in returning, loadSessionInfoFromStore() will
             // reject it anyway.
             return null;
         }
     } elseif (isset($info['id'])) {
         // No UserID cookie, so insist that the session is anonymous.
         // Note: this event occurs for several normal activities:
         // * anon visits Special:UserLogin
         // * anon browsing after seeing Special:UserLogin
         // * anon browsing after edit or preview
         $this->logger->debug('Session "{session}" requested without UserID cookie', array('session' => $info['id']));
         $info['userInfo'] = UserInfo::newAnonymous();
     } else {
         // No session ID and no user is the same as an empty session, so
         // there's no point.
         return null;
     }
     return new SessionInfo($this->priority, $info);
 }
コード例 #5
0
ファイル: SessionInfoTest.php プロジェクト: Gomyul/mediawiki
 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');
 }
コード例 #6
0
 /**
  * @dataProvider provideSecuritySensitiveOperationStatus
  * @param bool $mutableSession
  */
 public function testSecuritySensitiveOperationStatus($mutableSession)
 {
     $this->logger = new \Psr\Log\NullLogger();
     $user = \User::newFromName('UTSysop');
     $provideUser = null;
     $reauth = $mutableSession ? AuthManager::SEC_REAUTH : AuthManager::SEC_FAIL;
     list($provider, $reset) = $this->getMockSessionProvider($mutableSession, ['provideSessionInfo']);
     $provider->expects($this->any())->method('provideSessionInfo')->will($this->returnCallback(function () use($provider, &$provideUser) {
         return new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => \DummySessionProvider::ID, 'persisted' => true, 'userInfo' => UserInfo::newFromUser($provideUser, true)]);
     }));
     $this->initializeManager();
     $this->config->set('ReauthenticateTime', []);
     $this->config->set('AllowSecuritySensitiveOperationIfCannotReauthenticate', []);
     $provideUser = new \User();
     $session = $provider->getManager()->getSessionForRequest($this->request);
     $this->assertSame(0, $session->getUser()->getId(), 'sanity check');
     // Anonymous user => reauth
     $session->set('AuthManager:lastAuthId', 0);
     $session->set('AuthManager:lastAuthTimestamp', time() - 5);
     $this->assertSame($reauth, $this->manager->securitySensitiveOperationStatus('foo'));
     $provideUser = $user;
     $session = $provider->getManager()->getSessionForRequest($this->request);
     $this->assertSame($user->getId(), $session->getUser()->getId(), 'sanity check');
     // Error for no default (only gets thrown for non-anonymous user)
     $session->set('AuthManager:lastAuthId', $user->getId() + 1);
     $session->set('AuthManager:lastAuthTimestamp', time() - 5);
     try {
         $this->manager->securitySensitiveOperationStatus('foo');
         $this->fail('Expected exception not thrown');
     } catch (\UnexpectedValueException $ex) {
         $this->assertSame($mutableSession ? '$wgReauthenticateTime lacks a default' : '$wgAllowSecuritySensitiveOperationIfCannotReauthenticate lacks a default', $ex->getMessage());
     }
     if ($mutableSession) {
         $this->config->set('ReauthenticateTime', ['test' => 100, 'test2' => -1, 'default' => 10]);
         // Mismatched user ID
         $session->set('AuthManager:lastAuthId', $user->getId() + 1);
         $session->set('AuthManager:lastAuthTimestamp', time() - 5);
         $this->assertSame(AuthManager::SEC_REAUTH, $this->manager->securitySensitiveOperationStatus('foo'));
         $this->assertSame(AuthManager::SEC_REAUTH, $this->manager->securitySensitiveOperationStatus('test'));
         $this->assertSame(AuthManager::SEC_OK, $this->manager->securitySensitiveOperationStatus('test2'));
         // Missing time
         $session->set('AuthManager:lastAuthId', $user->getId());
         $session->set('AuthManager:lastAuthTimestamp', null);
         $this->assertSame(AuthManager::SEC_REAUTH, $this->manager->securitySensitiveOperationStatus('foo'));
         $this->assertSame(AuthManager::SEC_REAUTH, $this->manager->securitySensitiveOperationStatus('test'));
         $this->assertSame(AuthManager::SEC_OK, $this->manager->securitySensitiveOperationStatus('test2'));
         // Recent enough to pass
         $session->set('AuthManager:lastAuthTimestamp', time() - 5);
         $this->assertSame(AuthManager::SEC_OK, $this->manager->securitySensitiveOperationStatus('foo'));
         // Not recent enough to pass
         $session->set('AuthManager:lastAuthTimestamp', time() - 20);
         $this->assertSame(AuthManager::SEC_REAUTH, $this->manager->securitySensitiveOperationStatus('foo'));
         // But recent enough for the 'test' operation
         $this->assertSame(AuthManager::SEC_OK, $this->manager->securitySensitiveOperationStatus('test'));
     } else {
         $this->config->set('AllowSecuritySensitiveOperationIfCannotReauthenticate', ['test' => false, 'default' => true]);
         $this->assertEquals(AuthManager::SEC_OK, $this->manager->securitySensitiveOperationStatus('foo'));
         $this->assertEquals(AuthManager::SEC_FAIL, $this->manager->securitySensitiveOperationStatus('test'));
     }
     // Test hook, all three possible values
     foreach ([AuthManager::SEC_OK => AuthManager::SEC_OK, AuthManager::SEC_REAUTH => $reauth, AuthManager::SEC_FAIL => AuthManager::SEC_FAIL] as $hook => $expect) {
         $this->hook('SecuritySensitiveOperationStatus', $this->exactly(2))->with($this->anything(), $this->anything(), $this->callback(function ($s) use($session) {
             return $s->getId() === $session->getId();
         }), $mutableSession ? $this->equalTo(500, 1) : $this->equalTo(-1))->will($this->returnCallback(function (&$v) use($hook) {
             $v = $hook;
             return true;
         }));
         $session->set('AuthManager:lastAuthTimestamp', time() - 500);
         $this->assertEquals($expect, $this->manager->securitySensitiveOperationStatus('test'), "hook {$hook}");
         $this->assertEquals($expect, $this->manager->securitySensitiveOperationStatus('test2'), "hook {$hook}");
         $this->unhook('SecuritySensitiveOperationStatus');
     }
     \ScopedCallback::consume($reset);
 }
コード例 #7
0
ファイル: CookieSessionProvider.php プロジェクト: paladox/2
 public function provideSessionInfo(WebRequest $request)
 {
     $info = array('id' => $this->getCookie($request, $this->params['sessionName'], ''));
     if (!SessionManager::validateSessionId($info['id'])) {
         unset($info['id']);
     }
     list($userId, $userName, $token) = $this->getUserInfoFromCookies($request);
     if ($userId !== null) {
         try {
             $userInfo = UserInfo::newFromId($userId);
         } catch (\InvalidArgumentException $ex) {
             return null;
         }
         // Sanity check
         if ($userName !== null && $userInfo->getName() !== $userName) {
             return null;
         }
         if ($token !== null) {
             if (!hash_equals($userInfo->getToken(), $token)) {
                 return null;
             }
             $info['userInfo'] = $userInfo->verified();
         } elseif (isset($info['id'])) {
             // No point if no session ID
             $info['userInfo'] = $userInfo;
         }
     }
     if (!$info) {
         return null;
     }
     $info += array('provider' => $this, 'persisted' => isset($info['id']), 'forceHTTPS' => $this->getCookie($request, 'forceHTTPS', '', false));
     return new SessionInfo($this->priority, $info);
 }
コード例 #8
0
 /**
  * @dataProvider providePersistSession
  * @param bool $secure
  * @param bool $remember
  */
 public function testPersistSession($secure, $remember)
 {
     $this->setMwGlobals(array('wgCookieExpiration' => 100, 'wgSecureLogin' => false));
     $provider = $this->getProvider('session');
     $provider->setLogger(new \Psr\Log\NullLogger());
     $priv = \TestingAccessWrapper::newFromObject($provider);
     $priv->sessionCookieOptions = array('prefix' => 'x', 'path' => 'CookiePath', 'domain' => 'CookieDomain', 'secure' => false, 'httpOnly' => true);
     $sessionId = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
     $user = User::newFromName('UTSysop');
     $this->assertFalse($user->requiresHTTPS(), 'sanity check');
     $backend = new SessionBackend(new SessionId($sessionId), new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $sessionId, 'persisted' => true, 'userInfo' => UserInfo::newFromUser($user, true), 'idIsSafe' => true)), new \EmptyBagOStuff(), new \EmptyBagOStuff(), new \Psr\Log\NullLogger(), 10);
     \TestingAccessWrapper::newFromObject($backend)->usePhpSessionHandling = false;
     $backend->setRememberUser($remember);
     $backend->setForceHTTPS($secure);
     // No cookie
     $priv->sessionCookieName = null;
     $request = new \FauxRequest();
     $provider->persistSession($backend, $request);
     $this->assertSame(array(), $request->response()->getCookies());
     // Cookie
     $priv->sessionCookieName = 'session';
     $request = new \FauxRequest();
     $time = time();
     $provider->persistSession($backend, $request);
     $cookie = $request->response()->getCookieData('xsession');
     $this->assertInternalType('array', $cookie);
     if (isset($cookie['expire']) && $cookie['expire'] > 0) {
         // Round expiry so we don't randomly fail if the seconds ticked during the test.
         $cookie['expire'] = round($cookie['expire'] - $time, -2);
     }
     $this->assertEquals(array('value' => $sessionId, 'expire' => null, 'path' => 'CookiePath', 'domain' => 'CookieDomain', 'secure' => $secure, 'httpOnly' => true, 'raw' => false), $cookie);
     $cookie = $request->response()->getCookieData('forceHTTPS');
     if ($secure) {
         $this->assertInternalType('array', $cookie);
         if (isset($cookie['expire']) && $cookie['expire'] > 0) {
             // Round expiry so we don't randomly fail if the seconds ticked during the test.
             $cookie['expire'] = round($cookie['expire'] - $time, -2);
         }
         $this->assertEquals(array('value' => 'true', 'expire' => $remember ? 100 : null, 'path' => 'CookiePath', 'domain' => 'CookieDomain', 'secure' => false, 'httpOnly' => true, 'raw' => false), $cookie);
     } else {
         $this->assertNull($cookie);
     }
     // Headers sent
     $request = $this->getSentRequest();
     $provider->persistSession($backend, $request);
     $this->assertSame(array(), $request->response()->getCookies());
 }
コード例 #9
0
 public function testLoadSessionInfoFromStore()
 {
     $manager = $this->getManager();
     $logger = new \TestLogger(true, function ($m) {
         return preg_replace('/^Session \\[\\d+\\]\\w+<(?:null|anon|[+-]:\\d+:\\w+)>\\w+: /', 'Session X: ', $m);
     });
     $manager->setLogger($logger);
     $request = new \FauxRequest();
     // TestingAccessWrapper can't handle methods with reference arguments, sigh.
     $rClass = new \ReflectionClass($manager);
     $rMethod = $rClass->getMethod('loadSessionInfoFromStore');
     $rMethod->setAccessible(true);
     $loadSessionInfoFromStore = function (&$info) use($rMethod, $manager, $request) {
         return $rMethod->invokeArgs($manager, array(&$info, $request));
     };
     $userInfo = UserInfo::newFromName('UTSysop', true);
     $unverifiedUserInfo = UserInfo::newFromName('UTSysop', false);
     $id = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
     $metadata = array('userId' => $userInfo->getId(), 'userName' => $userInfo->getName(), 'userToken' => $userInfo->getToken(true), 'provider' => 'Mock');
     $builder = $this->getMockBuilder('MediaWiki\\Session\\SessionProvider')->setMethods(array('__toString', 'mergeMetadata', 'refreshSessionInfo'));
     $provider = $builder->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('refreshSessionInfo')->will($this->returnValue(true));
     $provider->expects($this->any())->method('__toString')->will($this->returnValue('Mock'));
     $provider->expects($this->any())->method('mergeMetadata')->will($this->returnCallback(function ($a, $b) {
         if ($b === array('Throw')) {
             throw new \UnexpectedValueException('no merge!');
         }
         return array('Merged');
     }));
     $provider2 = $builder->getMockForAbstractClass();
     $provider2->setManager($manager);
     $provider2->expects($this->any())->method('persistsSessionId')->will($this->returnValue(false));
     $provider2->expects($this->any())->method('canChangeUser')->will($this->returnValue(false));
     $provider2->expects($this->any())->method('__toString')->will($this->returnValue('Mock2'));
     $provider2->expects($this->any())->method('refreshSessionInfo')->will($this->returnCallback(function ($info, $request, &$metadata) {
         $metadata['changed'] = true;
         return true;
     }));
     $provider3 = $builder->getMockForAbstractClass();
     $provider3->setManager($manager);
     $provider3->expects($this->any())->method('persistsSessionId')->will($this->returnValue(true));
     $provider3->expects($this->any())->method('canChangeUser')->will($this->returnValue(true));
     $provider3->expects($this->once())->method('refreshSessionInfo')->will($this->returnValue(false));
     $provider3->expects($this->any())->method('__toString')->will($this->returnValue('Mock3'));
     \TestingAccessWrapper::newFromObject($manager)->sessionProviders = array((string) $provider => $provider, (string) $provider2 => $provider2, (string) $provider3 => $provider3);
     // No metadata, basic usage
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id, 'userInfo' => $userInfo));
     $this->assertFalse($info->isIdSafe(), 'sanity check');
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertFalse($info->isIdSafe());
     $this->assertSame(array(), $logger->getBuffer());
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'userInfo' => $userInfo));
     $this->assertTrue($info->isIdSafe(), 'sanity check');
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertTrue($info->isIdSafe());
     $this->assertSame(array(), $logger->getBuffer());
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider2, 'id' => $id, 'userInfo' => $userInfo));
     $this->assertFalse($info->isIdSafe(), 'sanity check');
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertTrue($info->isIdSafe());
     $this->assertSame(array(), $logger->getBuffer());
     // Unverified user, no metadata
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id, 'userInfo' => $unverifiedUserInfo));
     $this->assertSame($unverifiedUserInfo, $info->getUserInfo());
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame(array(array(LogLevel::WARNING, 'Session X: Unverified user provided and no metadata to auth it')), $logger->getBuffer());
     $logger->clearBuffer();
     // No metadata, missing data
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('id' => $id, 'userInfo' => $userInfo));
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame(array(array(LogLevel::WARNING, 'Session X: Null provider and no metadata')), $logger->getBuffer());
     $logger->clearBuffer();
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id));
     $this->assertFalse($info->isIdSafe(), 'sanity check');
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertInstanceOf('MediaWiki\\Session\\UserInfo', $info->getUserInfo());
     $this->assertTrue($info->getUserInfo()->isVerified());
     $this->assertTrue($info->getUserInfo()->isAnon());
     $this->assertFalse($info->isIdSafe());
     $this->assertSame(array(), $logger->getBuffer());
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider2, 'id' => $id));
     $this->assertFalse($info->isIdSafe(), 'sanity check');
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame(array(array(LogLevel::INFO, 'Session X: No user provided and provider cannot set user')), $logger->getBuffer());
     $logger->clearBuffer();
     // Incomplete/bad metadata
     $this->store->setRawSession($id, true);
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame(array(array(LogLevel::WARNING, 'Session X: Bad data')), $logger->getBuffer());
     $logger->clearBuffer();
     $this->store->setRawSession($id, array('data' => array()));
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame(array(array(LogLevel::WARNING, 'Session X: Bad data structure')), $logger->getBuffer());
     $logger->clearBuffer();
     $this->store->deleteSession($id);
     $this->store->setRawSession($id, array('metadata' => $metadata));
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame(array(array(LogLevel::WARNING, 'Session X: Bad data structure')), $logger->getBuffer());
     $logger->clearBuffer();
     $this->store->setRawSession($id, array('metadata' => $metadata, 'data' => true));
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame(array(array(LogLevel::WARNING, 'Session X: Bad data structure')), $logger->getBuffer());
     $logger->clearBuffer();
     $this->store->setRawSession($id, array('metadata' => true, 'data' => array()));
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame(array(array(LogLevel::WARNING, 'Session X: Bad data structure')), $logger->getBuffer());
     $logger->clearBuffer();
     foreach ($metadata as $key => $dummy) {
         $tmp = $metadata;
         unset($tmp[$key]);
         $this->store->setRawSession($id, array('metadata' => $tmp, 'data' => array()));
         $this->assertFalse($loadSessionInfoFromStore($info));
         $this->assertSame(array(array(LogLevel::WARNING, 'Session X: Bad metadata')), $logger->getBuffer());
         $logger->clearBuffer();
     }
     // Basic usage with metadata
     $this->store->setRawSession($id, array('metadata' => $metadata, 'data' => array()));
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id, 'userInfo' => $userInfo));
     $this->assertFalse($info->isIdSafe(), 'sanity check');
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertTrue($info->isIdSafe());
     $this->assertSame(array(), $logger->getBuffer());
     // Mismatched provider
     $this->store->setSessionMeta($id, array('provider' => 'Bad') + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id, 'userInfo' => $userInfo));
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame(array(array(LogLevel::WARNING, 'Session X: Wrong provider, Bad !== Mock')), $logger->getBuffer());
     $logger->clearBuffer();
     // Unknown provider
     $this->store->setSessionMeta($id, array('provider' => 'Bad') + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('id' => $id, 'userInfo' => $userInfo));
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame(array(array(LogLevel::WARNING, 'Session X: Unknown provider, Bad')), $logger->getBuffer());
     $logger->clearBuffer();
     // Fill in provider
     $this->store->setSessionMeta($id, $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('id' => $id, 'userInfo' => $userInfo));
     $this->assertFalse($info->isIdSafe(), 'sanity check');
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertTrue($info->isIdSafe());
     $this->assertSame(array(), $logger->getBuffer());
     // Bad user metadata
     $this->store->setSessionMeta($id, array('userId' => -1, 'userToken' => null) + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id));
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame(array(array(LogLevel::ERROR, 'Session X: Invalid ID')), $logger->getBuffer());
     $logger->clearBuffer();
     $this->store->setSessionMeta($id, array('userId' => 0, 'userName' => '<X>', 'userToken' => null) + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id));
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame(array(array(LogLevel::ERROR, 'Session X: Invalid user name')), $logger->getBuffer());
     $logger->clearBuffer();
     // Mismatched user by ID
     $this->store->setSessionMeta($id, array('userId' => $userInfo->getId() + 1, 'userToken' => null) + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id, 'userInfo' => $userInfo));
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame(array(array(LogLevel::WARNING, 'Session X: User ID mismatch, 2 !== 1')), $logger->getBuffer());
     $logger->clearBuffer();
     // Mismatched user by name
     $this->store->setSessionMeta($id, array('userId' => 0, 'userName' => 'X', 'userToken' => null) + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id, 'userInfo' => $userInfo));
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame(array(array(LogLevel::WARNING, 'Session X: User name mismatch, X !== UTSysop')), $logger->getBuffer());
     $logger->clearBuffer();
     // ID matches, name doesn't
     $this->store->setSessionMeta($id, array('userId' => $userInfo->getId(), 'userName' => 'X', 'userToken' => null) + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id, 'userInfo' => $userInfo));
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame(array(array(LogLevel::WARNING, 'Session X: User ID matched but name didn\'t (rename?), X !== UTSysop')), $logger->getBuffer());
     $logger->clearBuffer();
     // Mismatched anon user
     $this->store->setSessionMeta($id, array('userId' => 0, 'userName' => null, 'userToken' => null) + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id, 'userInfo' => $userInfo));
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame(array(array(LogLevel::WARNING, 'Session X: Metadata has an anonymous user, but a non-anon user was provided')), $logger->getBuffer());
     $logger->clearBuffer();
     // Lookup user by ID
     $this->store->setSessionMeta($id, array('userToken' => null) + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id));
     $this->assertFalse($info->isIdSafe(), 'sanity check');
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertSame($userInfo->getId(), $info->getUserInfo()->getId());
     $this->assertTrue($info->isIdSafe());
     $this->assertSame(array(), $logger->getBuffer());
     // Lookup user by name
     $this->store->setSessionMeta($id, array('userId' => 0, 'userName' => 'UTSysop', 'userToken' => null) + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id));
     $this->assertFalse($info->isIdSafe(), 'sanity check');
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertSame($userInfo->getId(), $info->getUserInfo()->getId());
     $this->assertTrue($info->isIdSafe());
     $this->assertSame(array(), $logger->getBuffer());
     // Lookup anonymous user
     $this->store->setSessionMeta($id, array('userId' => 0, 'userName' => null, 'userToken' => null) + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id));
     $this->assertFalse($info->isIdSafe(), 'sanity check');
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertTrue($info->getUserInfo()->isAnon());
     $this->assertTrue($info->isIdSafe());
     $this->assertSame(array(), $logger->getBuffer());
     // Unverified user with metadata
     $this->store->setSessionMeta($id, $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id, 'userInfo' => $unverifiedUserInfo));
     $this->assertFalse($info->isIdSafe(), 'sanity check');
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertTrue($info->getUserInfo()->isVerified());
     $this->assertSame($unverifiedUserInfo->getId(), $info->getUserInfo()->getId());
     $this->assertSame($unverifiedUserInfo->getName(), $info->getUserInfo()->getName());
     $this->assertTrue($info->isIdSafe());
     $this->assertSame(array(), $logger->getBuffer());
     // Unverified user with metadata
     $this->store->setSessionMeta($id, $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id, 'userInfo' => $unverifiedUserInfo));
     $this->assertFalse($info->isIdSafe(), 'sanity check');
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertTrue($info->getUserInfo()->isVerified());
     $this->assertSame($unverifiedUserInfo->getId(), $info->getUserInfo()->getId());
     $this->assertSame($unverifiedUserInfo->getName(), $info->getUserInfo()->getName());
     $this->assertTrue($info->isIdSafe());
     $this->assertSame(array(), $logger->getBuffer());
     // Wrong token
     $this->store->setSessionMeta($id, array('userToken' => 'Bad') + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id, 'userInfo' => $userInfo));
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame(array(array(LogLevel::WARNING, 'Session X: User token mismatch')), $logger->getBuffer());
     $logger->clearBuffer();
     // Provider metadata
     $this->store->setSessionMeta($id, array('provider' => 'Mock2') + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider2, 'id' => $id, 'userInfo' => $userInfo, 'metadata' => array('Info')));
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertSame(array('Info', 'changed' => true), $info->getProviderMetadata());
     $this->assertSame(array(), $logger->getBuffer());
     $this->store->setSessionMeta($id, array('providerMetadata' => array('Saved')) + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id, 'userInfo' => $userInfo));
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertSame(array('Saved'), $info->getProviderMetadata());
     $this->assertSame(array(), $logger->getBuffer());
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id, 'userInfo' => $userInfo, 'metadata' => array('Info')));
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertSame(array('Merged'), $info->getProviderMetadata());
     $this->assertSame(array(), $logger->getBuffer());
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id, 'userInfo' => $userInfo, 'metadata' => array('Throw')));
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame(array(array(LogLevel::WARNING, 'Session X: Metadata merge failed: no merge!')), $logger->getBuffer());
     $logger->clearBuffer();
     // Remember from session
     $this->store->setSessionMeta($id, $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id));
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertFalse($info->wasRemembered());
     $this->assertSame(array(), $logger->getBuffer());
     $this->store->setSessionMeta($id, array('remember' => true) + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id));
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertTrue($info->wasRemembered());
     $this->assertSame(array(), $logger->getBuffer());
     $this->store->setSessionMeta($id, array('remember' => false) + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id, 'userInfo' => $userInfo));
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertTrue($info->wasRemembered());
     $this->assertSame(array(), $logger->getBuffer());
     // forceHTTPS from session
     $this->store->setSessionMeta($id, $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id, 'userInfo' => $userInfo));
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertFalse($info->forceHTTPS());
     $this->assertSame(array(), $logger->getBuffer());
     $this->store->setSessionMeta($id, array('forceHTTPS' => true) + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id, 'userInfo' => $userInfo));
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertTrue($info->forceHTTPS());
     $this->assertSame(array(), $logger->getBuffer());
     $this->store->setSessionMeta($id, array('forceHTTPS' => false) + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id, 'userInfo' => $userInfo, 'forceHTTPS' => true));
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertTrue($info->forceHTTPS());
     $this->assertSame(array(), $logger->getBuffer());
     // "Persist" flag from session
     $this->store->setSessionMeta($id, $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id, 'userInfo' => $userInfo));
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertFalse($info->wasPersisted());
     $this->assertSame(array(), $logger->getBuffer());
     $this->store->setSessionMeta($id, array('persisted' => true) + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id, 'userInfo' => $userInfo));
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertTrue($info->wasPersisted());
     $this->assertSame(array(), $logger->getBuffer());
     $this->store->setSessionMeta($id, array('persisted' => false) + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id, 'userInfo' => $userInfo, 'persisted' => true));
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertTrue($info->wasPersisted());
     $this->assertSame(array(), $logger->getBuffer());
     // Provider refreshSessionInfo() returning false
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider3));
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame(array(), $logger->getBuffer());
     // Hook
     $that = $this;
     $called = false;
     $data = array('foo' => 1);
     $this->store->setSession($id, array('metadata' => $metadata, 'data' => $data));
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id, 'userInfo' => $userInfo));
     $this->mergeMwGlobalArrayValue('wgHooks', array('SessionCheckInfo' => array(function (&$reason, $i, $r, $m, $d) use($that, $info, $metadata, $data, $request, &$called) {
         $that->assertSame($info->getId(), $i->getId());
         $that->assertSame($info->getProvider(), $i->getProvider());
         $that->assertSame($info->getUserInfo(), $i->getUserInfo());
         $that->assertSame($request, $r);
         $that->assertEquals($metadata, $m);
         $that->assertEquals($data, $d);
         $called = true;
         return false;
     })));
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertTrue($called);
     $this->assertSame(array(array(LogLevel::WARNING, 'Session X: Hook aborted')), $logger->getBuffer());
     $logger->clearBuffer();
 }
コード例 #10
0
 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);
 }
コード例 #11
0
ファイル: UserInfoTest.php プロジェクト: claudinec/galan-wiki
 public function testNewFromUser()
 {
     // User that exists
     $user = User::newFromName('UTSysop');
     $userinfo = UserInfo::newFromUser($user);
     $this->assertFalse($userinfo->isAnon());
     $this->assertFalse($userinfo->isVerified());
     $this->assertSame($user->getId(), $userinfo->getId());
     $this->assertSame($user->getName(), $userinfo->getName());
     $this->assertSame($user->getToken(true), $userinfo->getToken());
     $this->assertSame($user, $userinfo->getUser());
     $userinfo2 = $userinfo->verified();
     $this->assertNotSame($userinfo2, $userinfo);
     $this->assertSame("<-:{$user->getId()}:{$user->getName()}>", (string) $userinfo);
     $this->assertFalse($userinfo2->isAnon());
     $this->assertTrue($userinfo2->isVerified());
     $this->assertSame($user->getId(), $userinfo2->getId());
     $this->assertSame($user->getName(), $userinfo2->getName());
     $this->assertSame($user->getToken(true), $userinfo2->getToken());
     $this->assertSame($user, $userinfo2->getUser());
     $this->assertSame($userinfo2, $userinfo2->verified());
     $this->assertSame("<+:{$user->getId()}:{$user->getName()}>", (string) $userinfo2);
     $userinfo = UserInfo::newFromUser($user, true);
     $this->assertTrue($userinfo->isVerified());
     $this->assertSame($userinfo, $userinfo->verified());
     // User name that does not exist should still be non-anon
     $user = User::newFromName('DoesNotExist');
     $this->assertSame(0, $user->getId(), 'sanity check');
     $userinfo = UserInfo::newFromUser($user);
     $this->assertFalse($userinfo->isAnon());
     $this->assertFalse($userinfo->isVerified());
     $this->assertSame($user->getId(), $userinfo->getId());
     $this->assertSame($user->getName(), $userinfo->getName());
     $this->assertSame('', $userinfo->getToken());
     $this->assertSame($user, $userinfo->getUser());
     $userinfo2 = $userinfo->verified();
     $this->assertNotSame($userinfo2, $userinfo);
     $this->assertSame("<-:{$user->getId()}:{$user->getName()}>", (string) $userinfo);
     $this->assertFalse($userinfo2->isAnon());
     $this->assertTrue($userinfo2->isVerified());
     $this->assertSame($user->getId(), $userinfo2->getId());
     $this->assertSame($user->getName(), $userinfo2->getName());
     $this->assertSame('', $userinfo2->getToken());
     $this->assertSame($user, $userinfo2->getUser());
     $this->assertSame($userinfo2, $userinfo2->verified());
     $this->assertSame("<+:{$user->getId()}:{$user->getName()}>", (string) $userinfo2);
     $userinfo = UserInfo::newFromUser($user, true);
     $this->assertTrue($userinfo->isVerified());
     $this->assertSame($userinfo, $userinfo->verified());
     // Anonymous user gives anon
     $userinfo = UserInfo::newFromUser(new User(), false);
     $this->assertTrue($userinfo->isVerified());
     $this->assertSame(0, $userinfo->getId());
     $this->assertSame(null, $userinfo->getName());
 }
コード例 #12
0
 /**
  * Create a new session for a request
  * @param User $user
  * @param BotPassword $bp
  * @param WebRequest $request
  * @return Session
  */
 public function newSessionForRequest(User $user, BotPassword $bp, WebRequest $request)
 {
     $id = $this->getSessionIdFromCookie($request);
     $info = new SessionInfo(SessionInfo::MAX_PRIORITY, ['provider' => $this, 'id' => $id, 'userInfo' => UserInfo::newFromUser($user, true), 'persisted' => $id !== null, 'metadata' => ['centralId' => $bp->getUserCentralId(), 'appId' => $bp->getAppId(), 'token' => $bp->getToken(), 'rights' => \MWGrants::getGrantRights($bp->getGrants())]]);
     $session = $this->getManager()->getSessionFromInfo($info, $request);
     $session->persist();
     return $session;
 }
コード例 #13
0
 public function testLoadSessionInfoFromStore()
 {
     $manager = $this->getManager();
     $logger = new \TestLogger(true);
     $manager->setLogger($logger);
     $request = new \FauxRequest();
     // TestingAccessWrapper can't handle methods with reference arguments, sigh.
     $rClass = new \ReflectionClass($manager);
     $rMethod = $rClass->getMethod('loadSessionInfoFromStore');
     $rMethod->setAccessible(true);
     $loadSessionInfoFromStore = function (&$info) use($rMethod, $manager, $request) {
         return $rMethod->invokeArgs($manager, [&$info, $request]);
     };
     $userInfo = UserInfo::newFromName('UTSysop', true);
     $unverifiedUserInfo = UserInfo::newFromName('UTSysop', false);
     $id = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
     $metadata = ['userId' => $userInfo->getId(), 'userName' => $userInfo->getName(), 'userToken' => $userInfo->getToken(true), 'provider' => 'Mock'];
     $builder = $this->getMockBuilder(SessionProvider::class)->setMethods(['__toString', 'mergeMetadata', 'refreshSessionInfo']);
     $provider = $builder->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('refreshSessionInfo')->will($this->returnValue(true));
     $provider->expects($this->any())->method('__toString')->will($this->returnValue('Mock'));
     $provider->expects($this->any())->method('mergeMetadata')->will($this->returnCallback(function ($a, $b) {
         if ($b === ['Throw']) {
             throw new MetadataMergeException('no merge!');
         }
         return ['Merged'];
     }));
     $provider2 = $builder->getMockForAbstractClass();
     $provider2->setManager($manager);
     $provider2->expects($this->any())->method('persistsSessionId')->will($this->returnValue(false));
     $provider2->expects($this->any())->method('canChangeUser')->will($this->returnValue(false));
     $provider2->expects($this->any())->method('__toString')->will($this->returnValue('Mock2'));
     $provider2->expects($this->any())->method('refreshSessionInfo')->will($this->returnCallback(function ($info, $request, &$metadata) {
         $metadata['changed'] = true;
         return true;
     }));
     $provider3 = $builder->getMockForAbstractClass();
     $provider3->setManager($manager);
     $provider3->expects($this->any())->method('persistsSessionId')->will($this->returnValue(true));
     $provider3->expects($this->any())->method('canChangeUser')->will($this->returnValue(true));
     $provider3->expects($this->once())->method('refreshSessionInfo')->will($this->returnValue(false));
     $provider3->expects($this->any())->method('__toString')->will($this->returnValue('Mock3'));
     \TestingAccessWrapper::newFromObject($manager)->sessionProviders = [(string) $provider => $provider, (string) $provider2 => $provider2, (string) $provider3 => $provider3];
     // No metadata, basic usage
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id, 'userInfo' => $userInfo]);
     $this->assertFalse($info->isIdSafe(), 'sanity check');
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertFalse($info->isIdSafe());
     $this->assertSame([], $logger->getBuffer());
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'userInfo' => $userInfo]);
     $this->assertTrue($info->isIdSafe(), 'sanity check');
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertTrue($info->isIdSafe());
     $this->assertSame([], $logger->getBuffer());
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider2, 'id' => $id, 'userInfo' => $userInfo]);
     $this->assertFalse($info->isIdSafe(), 'sanity check');
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertTrue($info->isIdSafe());
     $this->assertSame([], $logger->getBuffer());
     // Unverified user, no metadata
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id, 'userInfo' => $unverifiedUserInfo]);
     $this->assertSame($unverifiedUserInfo, $info->getUserInfo());
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame([[LogLevel::WARNING, 'Session "{session}": Unverified user provided and no metadata to auth it']], $logger->getBuffer());
     $logger->clearBuffer();
     // No metadata, missing data
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['id' => $id, 'userInfo' => $userInfo]);
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame([[LogLevel::WARNING, 'Session "{session}": Null provider and no metadata']], $logger->getBuffer());
     $logger->clearBuffer();
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id]);
     $this->assertFalse($info->isIdSafe(), 'sanity check');
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertInstanceOf(UserInfo::class, $info->getUserInfo());
     $this->assertTrue($info->getUserInfo()->isVerified());
     $this->assertTrue($info->getUserInfo()->isAnon());
     $this->assertFalse($info->isIdSafe());
     $this->assertSame([], $logger->getBuffer());
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider2, 'id' => $id]);
     $this->assertFalse($info->isIdSafe(), 'sanity check');
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame([[LogLevel::INFO, 'Session "{session}": No user provided and provider cannot set user']], $logger->getBuffer());
     $logger->clearBuffer();
     // Incomplete/bad metadata
     $this->store->setRawSession($id, true);
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame([[LogLevel::WARNING, 'Session "{session}": Bad data']], $logger->getBuffer());
     $logger->clearBuffer();
     $this->store->setRawSession($id, ['data' => []]);
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame([[LogLevel::WARNING, 'Session "{session}": Bad data structure']], $logger->getBuffer());
     $logger->clearBuffer();
     $this->store->deleteSession($id);
     $this->store->setRawSession($id, ['metadata' => $metadata]);
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame([[LogLevel::WARNING, 'Session "{session}": Bad data structure']], $logger->getBuffer());
     $logger->clearBuffer();
     $this->store->setRawSession($id, ['metadata' => $metadata, 'data' => true]);
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame([[LogLevel::WARNING, 'Session "{session}": Bad data structure']], $logger->getBuffer());
     $logger->clearBuffer();
     $this->store->setRawSession($id, ['metadata' => true, 'data' => []]);
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame([[LogLevel::WARNING, 'Session "{session}": Bad data structure']], $logger->getBuffer());
     $logger->clearBuffer();
     foreach ($metadata as $key => $dummy) {
         $tmp = $metadata;
         unset($tmp[$key]);
         $this->store->setRawSession($id, ['metadata' => $tmp, 'data' => []]);
         $this->assertFalse($loadSessionInfoFromStore($info));
         $this->assertSame([[LogLevel::WARNING, 'Session "{session}": Bad metadata']], $logger->getBuffer());
         $logger->clearBuffer();
     }
     // Basic usage with metadata
     $this->store->setRawSession($id, ['metadata' => $metadata, 'data' => []]);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id, 'userInfo' => $userInfo]);
     $this->assertFalse($info->isIdSafe(), 'sanity check');
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertTrue($info->isIdSafe());
     $this->assertSame([], $logger->getBuffer());
     // Mismatched provider
     $this->store->setSessionMeta($id, ['provider' => 'Bad'] + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id, 'userInfo' => $userInfo]);
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame([[LogLevel::WARNING, 'Session "{session}": Wrong provider Bad !== Mock']], $logger->getBuffer());
     $logger->clearBuffer();
     // Unknown provider
     $this->store->setSessionMeta($id, ['provider' => 'Bad'] + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['id' => $id, 'userInfo' => $userInfo]);
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame([[LogLevel::WARNING, 'Session "{session}": Unknown provider Bad']], $logger->getBuffer());
     $logger->clearBuffer();
     // Fill in provider
     $this->store->setSessionMeta($id, $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['id' => $id, 'userInfo' => $userInfo]);
     $this->assertFalse($info->isIdSafe(), 'sanity check');
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertTrue($info->isIdSafe());
     $this->assertSame([], $logger->getBuffer());
     // Bad user metadata
     $this->store->setSessionMeta($id, ['userId' => -1, 'userToken' => null] + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id]);
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame([[LogLevel::ERROR, 'Session "{session}": {exception}']], $logger->getBuffer());
     $logger->clearBuffer();
     $this->store->setSessionMeta($id, ['userId' => 0, 'userName' => '<X>', 'userToken' => null] + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id]);
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame([[LogLevel::ERROR, 'Session "{session}": {exception}']], $logger->getBuffer());
     $logger->clearBuffer();
     // Mismatched user by ID
     $this->store->setSessionMeta($id, ['userId' => $userInfo->getId() + 1, 'userToken' => null] + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id, 'userInfo' => $userInfo]);
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame([[LogLevel::WARNING, 'Session "{session}": User ID mismatch, {uid_a} !== {uid_b}']], $logger->getBuffer());
     $logger->clearBuffer();
     // Mismatched user by name
     $this->store->setSessionMeta($id, ['userId' => 0, 'userName' => 'X', 'userToken' => null] + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id, 'userInfo' => $userInfo]);
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame([[LogLevel::WARNING, 'Session "{session}": User name mismatch, {uname_a} !== {uname_b}']], $logger->getBuffer());
     $logger->clearBuffer();
     // ID matches, name doesn't
     $this->store->setSessionMeta($id, ['userId' => $userInfo->getId(), 'userName' => 'X', 'userToken' => null] + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id, 'userInfo' => $userInfo]);
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame([[LogLevel::WARNING, 'Session "{session}": User ID matched but name didn\'t (rename?), {uname_a} !== {uname_b}']], $logger->getBuffer());
     $logger->clearBuffer();
     // Mismatched anon user
     $this->store->setSessionMeta($id, ['userId' => 0, 'userName' => null, 'userToken' => null] + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id, 'userInfo' => $userInfo]);
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame([[LogLevel::WARNING, 'Session "{session}": Metadata has an anonymous user, ' . 'but a non-anon user was provided']], $logger->getBuffer());
     $logger->clearBuffer();
     // Lookup user by ID
     $this->store->setSessionMeta($id, ['userToken' => null] + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id]);
     $this->assertFalse($info->isIdSafe(), 'sanity check');
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertSame($userInfo->getId(), $info->getUserInfo()->getId());
     $this->assertTrue($info->isIdSafe());
     $this->assertSame([], $logger->getBuffer());
     // Lookup user by name
     $this->store->setSessionMeta($id, ['userId' => 0, 'userName' => 'UTSysop', 'userToken' => null] + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id]);
     $this->assertFalse($info->isIdSafe(), 'sanity check');
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertSame($userInfo->getId(), $info->getUserInfo()->getId());
     $this->assertTrue($info->isIdSafe());
     $this->assertSame([], $logger->getBuffer());
     // Lookup anonymous user
     $this->store->setSessionMeta($id, ['userId' => 0, 'userName' => null, 'userToken' => null] + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id]);
     $this->assertFalse($info->isIdSafe(), 'sanity check');
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertTrue($info->getUserInfo()->isAnon());
     $this->assertTrue($info->isIdSafe());
     $this->assertSame([], $logger->getBuffer());
     // Unverified user with metadata
     $this->store->setSessionMeta($id, $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id, 'userInfo' => $unverifiedUserInfo]);
     $this->assertFalse($info->isIdSafe(), 'sanity check');
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertTrue($info->getUserInfo()->isVerified());
     $this->assertSame($unverifiedUserInfo->getId(), $info->getUserInfo()->getId());
     $this->assertSame($unverifiedUserInfo->getName(), $info->getUserInfo()->getName());
     $this->assertTrue($info->isIdSafe());
     $this->assertSame([], $logger->getBuffer());
     // Unverified user with metadata
     $this->store->setSessionMeta($id, $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id, 'userInfo' => $unverifiedUserInfo]);
     $this->assertFalse($info->isIdSafe(), 'sanity check');
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertTrue($info->getUserInfo()->isVerified());
     $this->assertSame($unverifiedUserInfo->getId(), $info->getUserInfo()->getId());
     $this->assertSame($unverifiedUserInfo->getName(), $info->getUserInfo()->getName());
     $this->assertTrue($info->isIdSafe());
     $this->assertSame([], $logger->getBuffer());
     // Wrong token
     $this->store->setSessionMeta($id, ['userToken' => 'Bad'] + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id, 'userInfo' => $userInfo]);
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame([[LogLevel::WARNING, 'Session "{session}": User token mismatch']], $logger->getBuffer());
     $logger->clearBuffer();
     // Provider metadata
     $this->store->setSessionMeta($id, ['provider' => 'Mock2'] + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider2, 'id' => $id, 'userInfo' => $userInfo, 'metadata' => ['Info']]);
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertSame(['Info', 'changed' => true], $info->getProviderMetadata());
     $this->assertSame([], $logger->getBuffer());
     $this->store->setSessionMeta($id, ['providerMetadata' => ['Saved']] + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id, 'userInfo' => $userInfo]);
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertSame(['Saved'], $info->getProviderMetadata());
     $this->assertSame([], $logger->getBuffer());
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id, 'userInfo' => $userInfo, 'metadata' => ['Info']]);
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertSame(['Merged'], $info->getProviderMetadata());
     $this->assertSame([], $logger->getBuffer());
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id, 'userInfo' => $userInfo, 'metadata' => ['Throw']]);
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame([[LogLevel::WARNING, 'Session "{session}": Metadata merge failed: {exception}']], $logger->getBuffer());
     $logger->clearBuffer();
     // Remember from session
     $this->store->setSessionMeta($id, $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id]);
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertFalse($info->wasRemembered());
     $this->assertSame([], $logger->getBuffer());
     $this->store->setSessionMeta($id, ['remember' => true] + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id]);
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertTrue($info->wasRemembered());
     $this->assertSame([], $logger->getBuffer());
     $this->store->setSessionMeta($id, ['remember' => false] + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id, 'userInfo' => $userInfo]);
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertTrue($info->wasRemembered());
     $this->assertSame([], $logger->getBuffer());
     // forceHTTPS from session
     $this->store->setSessionMeta($id, $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id, 'userInfo' => $userInfo]);
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertFalse($info->forceHTTPS());
     $this->assertSame([], $logger->getBuffer());
     $this->store->setSessionMeta($id, ['forceHTTPS' => true] + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id, 'userInfo' => $userInfo]);
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertTrue($info->forceHTTPS());
     $this->assertSame([], $logger->getBuffer());
     $this->store->setSessionMeta($id, ['forceHTTPS' => false] + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id, 'userInfo' => $userInfo, 'forceHTTPS' => true]);
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertTrue($info->forceHTTPS());
     $this->assertSame([], $logger->getBuffer());
     // "Persist" flag from session
     $this->store->setSessionMeta($id, $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id, 'userInfo' => $userInfo]);
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertFalse($info->wasPersisted());
     $this->assertSame([], $logger->getBuffer());
     $this->store->setSessionMeta($id, ['persisted' => true] + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id, 'userInfo' => $userInfo]);
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertTrue($info->wasPersisted());
     $this->assertSame([], $logger->getBuffer());
     $this->store->setSessionMeta($id, ['persisted' => false] + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id, 'userInfo' => $userInfo, 'persisted' => true]);
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertTrue($info->wasPersisted());
     $this->assertSame([], $logger->getBuffer());
     // Provider refreshSessionInfo() returning false
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider3]);
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertSame([], $logger->getBuffer());
     // Hook
     $called = false;
     $data = ['foo' => 1];
     $this->store->setSession($id, ['metadata' => $metadata, 'data' => $data]);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id, 'userInfo' => $userInfo]);
     $this->mergeMwGlobalArrayValue('wgHooks', ['SessionCheckInfo' => [function (&$reason, $i, $r, $m, $d) use($info, $metadata, $data, $request, &$called) {
         $this->assertSame($info->getId(), $i->getId());
         $this->assertSame($info->getProvider(), $i->getProvider());
         $this->assertSame($info->getUserInfo(), $i->getUserInfo());
         $this->assertSame($request, $r);
         $this->assertEquals($metadata, $m);
         $this->assertEquals($data, $d);
         $called = true;
         return false;
     }]]);
     $this->assertFalse($loadSessionInfoFromStore($info));
     $this->assertTrue($called);
     $this->assertSame([[LogLevel::WARNING, 'Session "{session}": Hook aborted']], $logger->getBuffer());
     $logger->clearBuffer();
     $this->mergeMwGlobalArrayValue('wgHooks', ['SessionCheckInfo' => []]);
     // forceUse deletes bad backend data
     $this->store->setSessionMeta($id, ['userToken' => 'Bad'] + $metadata);
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, ['provider' => $provider, 'id' => $id, 'userInfo' => $userInfo, 'forceUse' => true]);
     $this->assertTrue($loadSessionInfoFromStore($info));
     $this->assertFalse($this->store->getSession($id));
     $this->assertSame([[LogLevel::WARNING, 'Session "{session}": User token mismatch']], $logger->getBuffer());
     $logger->clearBuffer();
 }
コード例 #14
0
 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);
 }
コード例 #15
0
 public function provideSessionInfo(WebRequest $request)
 {
     $info = array('id' => $this->getCookie($request, $this->params['sessionName'], ''), 'provider' => $this, 'forceHTTPS' => $this->getCookie($request, 'forceHTTPS', '', false));
     if (!SessionManager::validateSessionId($info['id'])) {
         unset($info['id']);
     }
     $info['persisted'] = isset($info['id']);
     list($userId, $userName, $token) = $this->getUserInfoFromCookies($request);
     if ($userId !== null) {
         try {
             $userInfo = UserInfo::newFromId($userId);
         } catch (\InvalidArgumentException $ex) {
             return null;
         }
         // Sanity check
         if ($userName !== null && $userInfo->getName() !== $userName) {
             return null;
         }
         if ($token !== null) {
             if (!hash_equals($userInfo->getToken(), $token)) {
                 return null;
             }
             $info['userInfo'] = $userInfo->verified();
         } elseif (isset($info['id'])) {
             $info['userInfo'] = $userInfo;
         } else {
             // No point in returning, loadSessionInfoFromStore() will
             // reject it anyway.
             return null;
         }
     } elseif (isset($info['id'])) {
         // No UserID cookie, so insist that the session is anonymous.
         $info['userInfo'] = UserInfo::newAnonymous();
     } else {
         // No session ID and no user is the same as an empty session, so
         // there's no point.
         return null;
     }
     return new SessionInfo($this->priority, $info);
 }
コード例 #16
0
 public function newSessionInfo($id = null)
 {
     return new SessionInfo(SessionInfo::MIN_PRIORITY, array('id' => $id, 'idIsSafe' => true, 'provider' => $this, 'persisted' => false, 'userInfo' => UserInfo::newAnonymous()));
 }