Example #1
0
 /**
  * Create a session corresponding to the passed SessionInfo
  * @private For use by a SessionProvider that needs to specially create its
  *  own session.
  * @param SessionInfo $info
  * @param WebRequest $request
  * @return Session
  */
 public function getSessionFromInfo(SessionInfo $info, WebRequest $request)
 {
     $id = $info->getId();
     if (!isset($this->allSessionBackends[$id])) {
         if (!isset($this->allSessionIds[$id])) {
             $this->allSessionIds[$id] = new SessionId($id);
         }
         $backend = new SessionBackend($this->allSessionIds[$id], $info, $this->store, $this->logger, $this->config->get('ObjectCacheSessionExpiry'));
         $this->allSessionBackends[$id] = $backend;
         $delay = $backend->delaySave();
     } else {
         $backend = $this->allSessionBackends[$id];
         $delay = $backend->delaySave();
         if ($info->wasPersisted()) {
             $backend->persist();
         }
         if ($info->wasRemembered()) {
             $backend->setRememberUser(true);
         }
     }
     $request->setSessionId($backend->getSessionId());
     $session = $backend->getSession($request);
     if (!$info->isIdSafe()) {
         $session->resetId();
     }
     \ScopedCallback::consume($delay);
     return $session;
 }
Example #2
0
 public function testBasics()
 {
     $anonInfo = UserInfo::newAnonymous();
     $userInfo = UserInfo::newFromName('UTSysop', true);
     $unverifiedUserInfo = UserInfo::newFromName('UTSysop', false);
     try {
         new SessionInfo(SessionInfo::MIN_PRIORITY - 1, array());
         $this->fail('Expected exception not thrown', 'priority < min');
     } catch (\InvalidArgumentException $ex) {
         $this->assertSame('Invalid priority', $ex->getMessage(), 'priority < min');
     }
     try {
         new SessionInfo(SessionInfo::MAX_PRIORITY + 1, array());
         $this->fail('Expected exception not thrown', 'priority > max');
     } catch (\InvalidArgumentException $ex) {
         $this->assertSame('Invalid priority', $ex->getMessage(), 'priority > max');
     }
     try {
         new SessionInfo(SessionInfo::MIN_PRIORITY, array('id' => 'ABC?'));
         $this->fail('Expected exception not thrown', 'bad session ID');
     } catch (\InvalidArgumentException $ex) {
         $this->assertSame('Invalid session ID', $ex->getMessage(), 'bad session ID');
     }
     try {
         new SessionInfo(SessionInfo::MIN_PRIORITY, array('userInfo' => new \stdClass()));
         $this->fail('Expected exception not thrown', 'bad userInfo');
     } catch (\InvalidArgumentException $ex) {
         $this->assertSame('Invalid userInfo', $ex->getMessage(), 'bad userInfo');
     }
     try {
         new SessionInfo(SessionInfo::MIN_PRIORITY, array());
         $this->fail('Expected exception not thrown', 'no provider, no id');
     } catch (\InvalidArgumentException $ex) {
         $this->assertSame('Must supply an ID when no provider is given', $ex->getMessage(), 'no provider, no id');
     }
     try {
         new SessionInfo(SessionInfo::MIN_PRIORITY, array('copyFrom' => new \stdClass()));
         $this->fail('Expected exception not thrown', 'bad copyFrom');
     } catch (\InvalidArgumentException $ex) {
         $this->assertSame('Invalid copyFrom', $ex->getMessage(), 'bad copyFrom');
     }
     $manager = new SessionManager();
     $provider = $this->getMockBuilder('MediaWiki\\Session\\SessionProvider')->setMethods(array('persistsSessionId', 'canChangeUser', '__toString'))->getMockForAbstractClass();
     $provider->setManager($manager);
     $provider->expects($this->any())->method('persistsSessionId')->will($this->returnValue(true));
     $provider->expects($this->any())->method('canChangeUser')->will($this->returnValue(true));
     $provider->expects($this->any())->method('__toString')->will($this->returnValue('Mock'));
     $provider2 = $this->getMockBuilder('MediaWiki\\Session\\SessionProvider')->setMethods(array('persistsSessionId', 'canChangeUser', '__toString'))->getMockForAbstractClass();
     $provider2->setManager($manager);
     $provider2->expects($this->any())->method('persistsSessionId')->will($this->returnValue(true));
     $provider2->expects($this->any())->method('canChangeUser')->will($this->returnValue(true));
     $provider2->expects($this->any())->method('__toString')->will($this->returnValue('Mock2'));
     try {
         new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'userInfo' => $anonInfo, 'metadata' => 'foo'));
         $this->fail('Expected exception not thrown', 'bad metadata');
     } catch (\InvalidArgumentException $ex) {
         $this->assertSame('Invalid metadata', $ex->getMessage(), 'bad metadata');
     }
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY + 5, array('provider' => $provider, 'userInfo' => $anonInfo));
     $this->assertSame($provider, $info->getProvider());
     $this->assertNotNull($info->getId());
     $this->assertSame(SessionInfo::MIN_PRIORITY + 5, $info->getPriority());
     $this->assertSame($anonInfo, $info->getUserInfo());
     $this->assertTrue($info->isIdSafe());
     $this->assertFalse($info->wasPersisted());
     $this->assertFalse($info->wasRemembered());
     $this->assertFalse($info->forceHTTPS());
     $this->assertNull($info->getProviderMetadata());
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY + 5, array('provider' => $provider, 'userInfo' => $unverifiedUserInfo, 'metadata' => array('Foo')));
     $this->assertSame($provider, $info->getProvider());
     $this->assertNotNull($info->getId());
     $this->assertSame(SessionInfo::MIN_PRIORITY + 5, $info->getPriority());
     $this->assertSame($unverifiedUserInfo, $info->getUserInfo());
     $this->assertTrue($info->isIdSafe());
     $this->assertFalse($info->wasPersisted());
     $this->assertFalse($info->wasRemembered());
     $this->assertFalse($info->forceHTTPS());
     $this->assertSame(array('Foo'), $info->getProviderMetadata());
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY + 5, array('provider' => $provider, 'userInfo' => $userInfo));
     $this->assertSame($provider, $info->getProvider());
     $this->assertNotNull($info->getId());
     $this->assertSame(SessionInfo::MIN_PRIORITY + 5, $info->getPriority());
     $this->assertSame($userInfo, $info->getUserInfo());
     $this->assertTrue($info->isIdSafe());
     $this->assertFalse($info->wasPersisted());
     $this->assertTrue($info->wasRemembered());
     $this->assertFalse($info->forceHTTPS());
     $this->assertNull($info->getProviderMetadata());
     $id = $manager->generateSessionId();
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY + 5, array('provider' => $provider, 'id' => $id, 'persisted' => true, 'userInfo' => $anonInfo));
     $this->assertSame($provider, $info->getProvider());
     $this->assertSame($id, $info->getId());
     $this->assertSame(SessionInfo::MIN_PRIORITY + 5, $info->getPriority());
     $this->assertSame($anonInfo, $info->getUserInfo());
     $this->assertFalse($info->isIdSafe());
     $this->assertTrue($info->wasPersisted());
     $this->assertFalse($info->wasRemembered());
     $this->assertFalse($info->forceHTTPS());
     $this->assertNull($info->getProviderMetadata());
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY + 5, array('provider' => $provider, 'id' => $id, 'userInfo' => $userInfo));
     $this->assertSame($provider, $info->getProvider());
     $this->assertSame($id, $info->getId());
     $this->assertSame(SessionInfo::MIN_PRIORITY + 5, $info->getPriority());
     $this->assertSame($userInfo, $info->getUserInfo());
     $this->assertFalse($info->isIdSafe());
     $this->assertFalse($info->wasPersisted());
     $this->assertTrue($info->wasRemembered());
     $this->assertFalse($info->forceHTTPS());
     $this->assertNull($info->getProviderMetadata());
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY + 5, array('id' => $id, 'persisted' => true, 'userInfo' => $userInfo, 'metadata' => array('Foo')));
     $this->assertSame($id, $info->getId());
     $this->assertSame(SessionInfo::MIN_PRIORITY + 5, $info->getPriority());
     $this->assertSame($userInfo, $info->getUserInfo());
     $this->assertFalse($info->isIdSafe());
     $this->assertTrue($info->wasPersisted());
     $this->assertFalse($info->wasRemembered());
     $this->assertFalse($info->forceHTTPS());
     $this->assertNull($info->getProviderMetadata());
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY + 5, array('id' => $id, 'remembered' => true, 'userInfo' => $userInfo));
     $this->assertFalse($info->wasRemembered(), 'no provider');
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY + 5, array('provider' => $provider, 'id' => $id, 'remembered' => true));
     $this->assertFalse($info->wasRemembered(), 'no user');
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY + 5, array('provider' => $provider, 'id' => $id, 'remembered' => true, 'userInfo' => $anonInfo));
     $this->assertFalse($info->wasRemembered(), 'anonymous user');
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY + 5, array('provider' => $provider, 'id' => $id, 'remembered' => true, 'userInfo' => $unverifiedUserInfo));
     $this->assertFalse($info->wasRemembered(), 'unverified user');
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY + 5, array('provider' => $provider, 'id' => $id, 'remembered' => false, 'userInfo' => $userInfo));
     $this->assertFalse($info->wasRemembered(), 'specific override');
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY + 5, array('id' => $id, 'idIsSafe' => true));
     $this->assertSame($id, $info->getId());
     $this->assertSame(SessionInfo::MIN_PRIORITY + 5, $info->getPriority());
     $this->assertTrue($info->isIdSafe());
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('id' => $id, 'forceHTTPS' => 1));
     $this->assertTrue($info->forceHTTPS());
     $fromInfo = new SessionInfo(SessionInfo::MIN_PRIORITY, array('id' => $id . 'A', 'provider' => $provider, 'userInfo' => $userInfo, 'idIsSafe' => true, 'persisted' => true, 'remembered' => true, 'forceHTTPS' => true, 'metadata' => array('foo!')));
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY + 4, array('copyFrom' => $fromInfo));
     $this->assertSame($id . 'A', $info->getId());
     $this->assertSame(SessionInfo::MIN_PRIORITY + 4, $info->getPriority());
     $this->assertSame($provider, $info->getProvider());
     $this->assertSame($userInfo, $info->getUserInfo());
     $this->assertTrue($info->isIdSafe());
     $this->assertTrue($info->wasPersisted());
     $this->assertTrue($info->wasRemembered());
     $this->assertTrue($info->forceHTTPS());
     $this->assertSame(array('foo!'), $info->getProviderMetadata());
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY + 4, array('id' => $id . 'X', 'provider' => $provider2, 'userInfo' => $unverifiedUserInfo, 'idIsSafe' => false, 'persisted' => false, 'remembered' => false, 'forceHTTPS' => false, 'metadata' => null, 'copyFrom' => $fromInfo));
     $this->assertSame($id . 'X', $info->getId());
     $this->assertSame(SessionInfo::MIN_PRIORITY + 4, $info->getPriority());
     $this->assertSame($provider2, $info->getProvider());
     $this->assertSame($unverifiedUserInfo, $info->getUserInfo());
     $this->assertFalse($info->isIdSafe());
     $this->assertFalse($info->wasPersisted());
     $this->assertFalse($info->wasRemembered());
     $this->assertFalse($info->forceHTTPS());
     $this->assertNull($info->getProviderMetadata());
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('id' => $id));
     $this->assertSame('[' . SessionInfo::MIN_PRIORITY . "]null<null>{$id}", (string) $info, 'toString');
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id, 'persisted' => true, 'userInfo' => $userInfo));
     $this->assertSame('[' . SessionInfo::MIN_PRIORITY . "]Mock<+:{$userInfo->getId()}:UTSysop>{$id}", (string) $info, 'toString');
     $info = new SessionInfo(SessionInfo::MIN_PRIORITY, array('provider' => $provider, 'id' => $id, 'persisted' => true, 'userInfo' => $unverifiedUserInfo));
     $this->assertSame('[' . SessionInfo::MIN_PRIORITY . "]Mock<-:{$userInfo->getId()}:UTSysop>{$id}", (string) $info, 'toString');
 }
Example #3
0
 /**
  * @param SessionId $id Session ID object
  * @param SessionInfo $info Session info to populate from
  * @param CachedBagOStuff $store Backend data store
  * @param LoggerInterface $logger
  * @param int $lifetime Session data lifetime in seconds
  */
 public function __construct(SessionId $id, SessionInfo $info, CachedBagOStuff $store, LoggerInterface $logger, $lifetime)
 {
     $phpSessionHandling = \RequestContext::getMain()->getConfig()->get('PHPSessionHandling');
     $this->usePhpSessionHandling = $phpSessionHandling !== 'disable';
     if ($info->getUserInfo() && !$info->getUserInfo()->isVerified()) {
         throw new \InvalidArgumentException("Refusing to create session for unverified user {$info->getUserInfo()}");
     }
     if ($info->getProvider() === null) {
         throw new \InvalidArgumentException('Cannot create session without a provider');
     }
     if ($info->getId() !== $id->getId()) {
         throw new \InvalidArgumentException('SessionId and SessionInfo don\'t match');
     }
     $this->id = $id;
     $this->user = $info->getUserInfo() ? $info->getUserInfo()->getUser() : new User();
     $this->store = $store;
     $this->logger = $logger;
     $this->lifetime = $lifetime;
     $this->provider = $info->getProvider();
     $this->persist = $info->wasPersisted();
     $this->remember = $info->wasRemembered();
     $this->forceHTTPS = $info->forceHTTPS();
     $this->providerMetadata = $info->getProviderMetadata();
     $blob = $store->get(wfMemcKey('MWSession', (string) $this->id));
     if (!is_array($blob) || !isset($blob['metadata']) || !is_array($blob['metadata']) || !isset($blob['data']) || !is_array($blob['data'])) {
         $this->data = [];
         $this->dataDirty = true;
         $this->metaDirty = true;
         $this->logger->debug('SessionBackend "{session}" is unsaved, marking dirty in constructor', ['session' => $this->id]);
     } else {
         $this->data = $blob['data'];
         if (isset($blob['metadata']['loggedOut'])) {
             $this->loggedOut = (int) $blob['metadata']['loggedOut'];
         }
         if (isset($blob['metadata']['expires'])) {
             $this->expires = (int) $blob['metadata']['expires'];
         } else {
             $this->metaDirty = true;
             $this->logger->debug('SessionBackend "{session}" metadata dirty due to missing expiration timestamp', ['session' => $this->id]);
         }
     }
     $this->dataHash = md5(serialize($this->data));
 }
 public function 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());
 }
Example #5
0
 /**
  * Create a Session corresponding to the passed SessionInfo
  * @private For use by a SessionProvider that needs to specially create its
  *  own Session. Most session providers won't need this.
  * @param SessionInfo $info
  * @param WebRequest $request
  * @return Session
  */
 public function getSessionFromInfo(SessionInfo $info, WebRequest $request)
 {
     // @codeCoverageIgnoreStart
     if (defined('MW_NO_SESSION')) {
         if (MW_NO_SESSION === 'warn') {
             // Undocumented safety case for converting existing entry points
             $this->logger->error('Sessions are supposed to be disabled for this entry point', ['exception' => new \BadMethodCallException('Sessions are disabled for this entry point')]);
         } else {
             throw new \BadMethodCallException('Sessions are disabled for this entry point');
         }
     }
     // @codeCoverageIgnoreEnd
     $id = $info->getId();
     if (!isset($this->allSessionBackends[$id])) {
         if (!isset($this->allSessionIds[$id])) {
             $this->allSessionIds[$id] = new SessionId($id);
         }
         $backend = new SessionBackend($this->allSessionIds[$id], $info, $this->store, $this->logger, $this->config->get('ObjectCacheSessionExpiry'));
         $this->allSessionBackends[$id] = $backend;
         $delay = $backend->delaySave();
     } else {
         $backend = $this->allSessionBackends[$id];
         $delay = $backend->delaySave();
         if ($info->wasPersisted()) {
             $backend->persist();
         }
         if ($info->wasRemembered()) {
             $backend->setRememberUser(true);
         }
     }
     $request->setSessionId($backend->getSessionId());
     $session = $backend->getSession($request);
     if (!$info->isIdSafe()) {
         $session->resetId();
     }
     \Wikimedia\ScopedCallback::consume($delay);
     return $session;
 }