MediaWiki  master
SessionBackend.php
Go to the documentation of this file.
1 <?php
24 namespace MediaWiki\Session;
25 
26 use CachedBagOStuff;
30 use Psr\Log\LoggerInterface;
31 use User;
32 use WebRequest;
33 use Wikimedia\AtEase\AtEase;
34 
53 final class SessionBackend {
55  private $id;
56 
58  private $persist = false;
59 
61  private $remember = false;
62 
64  private $forceHTTPS = false;
65 
67  private $data = null;
68 
70  private $forcePersist = false;
71 
81 
86  private $persistenceChangeData = [];
87 
89  private $metaDirty = false;
90 
92  private $dataDirty = false;
93 
95  private $dataHash = null;
96 
98  private $store;
99 
101  private $logger;
102 
104  private $hookRunner;
105 
107  private $lifetime;
108 
110  private $user;
111 
113  private $curIndex = 0;
114 
116  private $requests = [];
117 
119  private $provider;
120 
122  private $providerMetadata = null;
123 
125  private $expires = 0;
126 
128  private $loggedOut = 0;
129 
131  private $delaySave = 0;
132 
137 
139  private $shutdown = false;
140 
149  public function __construct(
150  SessionId $id, SessionInfo $info, CachedBagOStuff $store, LoggerInterface $logger,
151  HookContainer $hookContainer, $lifetime
152  ) {
153  $phpSessionHandling = \RequestContext::getMain()->getConfig()->get( 'PHPSessionHandling' );
154  $this->usePhpSessionHandling = $phpSessionHandling !== 'disable';
155 
156  if ( $info->getUserInfo() && !$info->getUserInfo()->isVerified() ) {
157  throw new \InvalidArgumentException(
158  "Refusing to create session for unverified user {$info->getUserInfo()}"
159  );
160  }
161  if ( $info->getProvider() === null ) {
162  throw new \InvalidArgumentException( 'Cannot create session without a provider' );
163  }
164  if ( $info->getId() !== $id->getId() ) {
165  throw new \InvalidArgumentException( 'SessionId and SessionInfo don\'t match' );
166  }
167 
168  $this->id = $id;
169  $this->user = $info->getUserInfo() ? $info->getUserInfo()->getUser() : new User;
170  $this->store = $store;
171  $this->logger = $logger;
172  $this->hookRunner = new HookRunner( $hookContainer );
173  $this->lifetime = $lifetime;
174  $this->provider = $info->getProvider();
175  $this->persist = $info->wasPersisted();
176  $this->remember = $info->wasRemembered();
177  $this->forceHTTPS = $info->forceHTTPS();
178  $this->providerMetadata = $info->getProviderMetadata();
179 
180  $blob = $store->get( $store->makeKey( 'MWSession', (string)$this->id ) );
181  if ( !is_array( $blob ) ||
182  !isset( $blob['metadata'] ) || !is_array( $blob['metadata'] ) ||
183  !isset( $blob['data'] ) || !is_array( $blob['data'] )
184  ) {
185  $this->data = [];
186  $this->dataDirty = true;
187  $this->metaDirty = true;
188  $this->persistenceChangeType = 'no-store';
189  $this->logger->debug(
190  'SessionBackend "{session}" is unsaved, marking dirty in constructor',
191  [
192  'session' => $this->id->__toString(),
193  ] );
194  } else {
195  $this->data = $blob['data'];
196  if ( isset( $blob['metadata']['loggedOut'] ) ) {
197  $this->loggedOut = (int)$blob['metadata']['loggedOut'];
198  }
199  if ( isset( $blob['metadata']['expires'] ) ) {
200  $this->expires = (int)$blob['metadata']['expires'];
201  } else {
202  $this->metaDirty = true;
203  $this->persistenceChangeType = 'no-expiry';
204  $this->logger->debug(
205  'SessionBackend "{session}" metadata dirty due to missing expiration timestamp',
206  [
207  'session' => $this->id->__toString(),
208  ] );
209  }
210  }
211  $this->dataHash = md5( serialize( $this->data ) );
212  }
213 
219  public function getSession( WebRequest $request ) {
220  $index = ++$this->curIndex;
221  $this->requests[$index] = $request;
222  $session = new Session( $this, $index, $this->logger );
223  return $session;
224  }
225 
231  public function deregisterSession( $index ) {
232  unset( $this->requests[$index] );
233  if ( !$this->shutdown && !count( $this->requests ) ) {
234  $this->save( true );
235  $this->provider->getManager()->deregisterSessionBackend( $this );
236  }
237  }
238 
243  public function shutdown() {
244  $this->save( true );
245  $this->shutdown = true;
246  }
247 
252  public function getId() {
253  return (string)$this->id;
254  }
255 
261  public function getSessionId() {
262  return $this->id;
263  }
264 
269  public function resetId() {
270  if ( $this->provider->persistsSessionId() ) {
271  $oldId = (string)$this->id;
272  $restart = $this->usePhpSessionHandling && $oldId === session_id() &&
274 
275  if ( $restart ) {
276  // If this session is the one behind PHP's $_SESSION, we need
277  // to close then reopen it.
278  session_write_close();
279  }
280 
281  $this->provider->getManager()->changeBackendId( $this );
282  $this->provider->sessionIdWasReset( $this, $oldId );
283  $this->metaDirty = true;
284  $this->logger->debug(
285  'SessionBackend "{session}" metadata dirty due to ID reset (formerly "{oldId}")',
286  [
287  'session' => $this->id->__toString(),
288  'oldId' => $oldId,
289  ] );
290 
291  if ( $restart ) {
292  session_id( (string)$this->id );
293  AtEase::quietCall( 'session_start' );
294  }
295 
296  $this->autosave();
297 
298  // Delete the data for the old session ID now
299  $this->store->delete( $this->store->makeKey( 'MWSession', $oldId ) );
300  }
301 
302  return $this->id;
303  }
304 
309  public function getProvider() {
310  return $this->provider;
311  }
312 
320  public function isPersistent() {
321  return $this->persist;
322  }
323 
330  public function persist() {
331  if ( !$this->persist ) {
332  $this->persist = true;
333  $this->forcePersist = true;
334  $this->metaDirty = true;
335  $this->logger->debug(
336  'SessionBackend "{session}" force-persist due to persist()',
337  [
338  'session' => $this->id->__toString(),
339  ] );
340  $this->autosave();
341  } else {
342  $this->renew();
343  }
344  }
345 
349  public function unpersist() {
350  if ( $this->persist ) {
351  // Close the PHP session, if we're the one that's open
352  if ( $this->usePhpSessionHandling && PHPSessionHandler::isEnabled() &&
353  session_id() === (string)$this->id
354  ) {
355  $this->logger->debug(
356  'SessionBackend "{session}" Closing PHP session for unpersist',
357  [ 'session' => $this->id->__toString() ]
358  );
359  session_write_close();
360  session_id( '' );
361  }
362 
363  $this->persist = false;
364  $this->forcePersist = true;
365  $this->metaDirty = true;
366 
367  // Delete the session data, so the local cache-only write in
368  // self::save() doesn't get things out of sync with the backend.
369  $this->store->delete( $this->store->makeKey( 'MWSession', (string)$this->id ) );
370 
371  $this->autosave();
372  }
373  }
374 
380  public function shouldRememberUser() {
381  return $this->remember;
382  }
383 
389  public function setRememberUser( $remember ) {
390  if ( $this->remember !== (bool)$remember ) {
391  $this->remember = (bool)$remember;
392  $this->metaDirty = true;
393  $this->logger->debug(
394  'SessionBackend "{session}" metadata dirty due to remember-user change',
395  [
396  'session' => $this->id->__toString(),
397  ] );
398  $this->autosave();
399  }
400  }
401 
407  public function getRequest( $index ) {
408  if ( !isset( $this->requests[$index] ) ) {
409  throw new \InvalidArgumentException( 'Invalid session index' );
410  }
411  return $this->requests[$index];
412  }
413 
418  public function getUser() {
419  return $this->user;
420  }
421 
426  public function getAllowedUserRights() {
427  return $this->provider->getAllowedUserRights( $this );
428  }
429 
434  public function canSetUser() {
435  return $this->provider->canChangeUser();
436  }
437 
445  public function setUser( $user ) {
446  if ( !$this->canSetUser() ) {
447  throw new \BadMethodCallException(
448  'Cannot set user on this session; check $session->canSetUser() first'
449  );
450  }
451 
452  $this->user = $user;
453  $this->metaDirty = true;
454  $this->logger->debug(
455  'SessionBackend "{session}" metadata dirty due to user change',
456  [
457  'session' => $this->id->__toString(),
458  ] );
459  $this->autosave();
460  }
461 
467  public function suggestLoginUsername( $index ) {
468  if ( !isset( $this->requests[$index] ) ) {
469  throw new \InvalidArgumentException( 'Invalid session index' );
470  }
471  return $this->provider->suggestLoginUsername( $this->requests[$index] );
472  }
473 
478  public function shouldForceHTTPS() {
479  return $this->forceHTTPS;
480  }
481 
486  public function setForceHTTPS( $force ) {
487  if ( $this->forceHTTPS !== (bool)$force ) {
488  $this->forceHTTPS = (bool)$force;
489  $this->metaDirty = true;
490  $this->logger->debug(
491  'SessionBackend "{session}" metadata dirty due to force-HTTPS change',
492  [
493  'session' => $this->id->__toString(),
494  ] );
495  $this->autosave();
496  }
497  }
498 
503  public function getLoggedOutTimestamp() {
504  return $this->loggedOut;
505  }
506 
510  public function setLoggedOutTimestamp( $ts = null ) {
511  $ts = (int)$ts;
512  if ( $this->loggedOut !== $ts ) {
513  $this->loggedOut = $ts;
514  $this->metaDirty = true;
515  $this->logger->debug(
516  'SessionBackend "{session}" metadata dirty due to logged-out-timestamp change',
517  [
518  'session' => $this->id->__toString(),
519  ] );
520  $this->autosave();
521  }
522  }
523 
529  public function getProviderMetadata() {
531  }
532 
537  public function setProviderMetadata( $metadata ) {
538  if ( $metadata !== null && !is_array( $metadata ) ) {
539  throw new \InvalidArgumentException( '$metadata must be an array or null' );
540  }
541  if ( $this->providerMetadata !== $metadata ) {
542  $this->providerMetadata = $metadata;
543  $this->metaDirty = true;
544  $this->logger->debug(
545  'SessionBackend "{session}" metadata dirty due to provider metadata change',
546  [
547  'session' => $this->id->__toString(),
548  ] );
549  $this->autosave();
550  }
551  }
552 
562  public function &getData() {
563  return $this->data;
564  }
565 
573  public function addData( array $newData ) {
574  $data = &$this->getData();
575  foreach ( $newData as $key => $value ) {
576  if ( !array_key_exists( $key, $data ) || $data[$key] !== $value ) {
577  $data[$key] = $value;
578  $this->dataDirty = true;
579  $this->logger->debug(
580  'SessionBackend "{session}" data dirty due to addData(): {callers}',
581  [
582  'session' => $this->id->__toString(),
583  'callers' => wfGetAllCallers( 5 ),
584  ] );
585  }
586  }
587  }
588 
593  public function dirty() {
594  $this->dataDirty = true;
595  $this->logger->debug(
596  'SessionBackend "{session}" data dirty due to dirty(): {callers}',
597  [
598  'session' => $this->id->__toString(),
599  'callers' => wfGetAllCallers( 5 ),
600  ] );
601  }
602 
609  public function renew() {
610  if ( time() + $this->lifetime / 2 > $this->expires ) {
611  $this->metaDirty = true;
612  $this->logger->debug(
613  'SessionBackend "{callers}" metadata dirty for renew(): {callers}',
614  [
615  'session' => $this->id->__toString(),
616  'callers' => wfGetAllCallers( 5 ),
617  ] );
618  if ( $this->persist ) {
619  $this->persistenceChangeType = 'renew';
620  $this->forcePersist = true;
621  $this->logger->debug(
622  'SessionBackend "{session}" force-persist for renew(): {callers}',
623  [
624  'session' => $this->id->__toString(),
625  'callers' => wfGetAllCallers( 5 ),
626  ] );
627  }
628  }
629  $this->autosave();
630  }
631 
639  public function delaySave() {
640  $this->delaySave++;
641  return new \Wikimedia\ScopedCallback( function () {
642  if ( --$this->delaySave <= 0 ) {
643  $this->delaySave = 0;
644  $this->save();
645  }
646  } );
647  }
648 
653  private function autosave() {
654  if ( $this->delaySave <= 0 ) {
655  $this->save();
656  }
657  }
658 
668  public function save( $closing = false ) {
669  $anon = $this->user->isAnon();
670 
671  if ( !$anon && $this->provider->getManager()->isUserSessionPrevented( $this->user->getName() ) ) {
672  $this->logger->debug(
673  'SessionBackend "{session}" not saving, user {user} was ' .
674  'passed to SessionManager::preventSessionsForUser',
675  [
676  'session' => $this->id->__toString(),
677  'user' => $this->user->__toString(),
678  ] );
679  return;
680  }
681 
682  // Ensure the user has a token
683  // @codeCoverageIgnoreStart
684  if ( !$anon && !$this->user->getToken( false ) ) {
685  $this->logger->debug(
686  'SessionBackend "{session}" creating token for user {user} on save',
687  [
688  'session' => $this->id->__toString(),
689  'user' => $this->user->__toString(),
690  ] );
691  $this->user->setToken();
692  if ( !wfReadOnly() ) {
693  // Promise that the token set here will be valid; save it at end of request
694  $user = $this->user;
695  \DeferredUpdates::addCallableUpdate( static function () use ( $user ) {
696  $user->saveSettings();
697  } );
698  }
699  $this->metaDirty = true;
700  }
701  // @codeCoverageIgnoreEnd
702 
703  if ( !$this->metaDirty && !$this->dataDirty &&
704  $this->dataHash !== md5( serialize( $this->data ) )
705  ) {
706  $this->logger->debug(
707  'SessionBackend "{session}" data dirty due to hash mismatch, {expected} !== {got}',
708  [
709  'session' => $this->id->__toString(),
710  'expected' => $this->dataHash,
711  'got' => md5( serialize( $this->data ) ),
712  ] );
713  $this->dataDirty = true;
714  }
715 
716  if ( !$this->metaDirty && !$this->dataDirty && !$this->forcePersist ) {
717  return;
718  }
719 
720  $this->logger->debug(
721  'SessionBackend "{session}" save: dataDirty={dataDirty} ' .
722  'metaDirty={metaDirty} forcePersist={forcePersist}',
723  [
724  'session' => $this->id->__toString(),
725  'dataDirty' => (int)$this->dataDirty,
726  'metaDirty' => (int)$this->metaDirty,
727  'forcePersist' => (int)$this->forcePersist,
728  ] );
729 
730  // Persist or unpersist to the provider, if necessary
731  if ( $this->metaDirty || $this->forcePersist ) {
732  if ( $this->persist ) {
733  foreach ( $this->requests as $request ) {
734  $request->setSessionId( $this->getSessionId() );
735  $this->logPersistenceChange( $request, true );
736  $this->provider->persistSession( $this, $request );
737  }
738  if ( !$closing ) {
739  $this->checkPHPSession();
740  }
741  } else {
742  foreach ( $this->requests as $request ) {
743  if ( $request->getSessionId() === $this->id ) {
744  $this->logPersistenceChange( $request, false );
745  $this->provider->unpersistSession( $request );
746  }
747  }
748  }
749  }
750 
751  $this->forcePersist = false;
752  $this->persistenceChangeType = null;
753 
754  if ( !$this->metaDirty && !$this->dataDirty ) {
755  return;
756  }
757 
758  // Save session data to store, if necessary
759  $metadata = $origMetadata = [
760  'provider' => (string)$this->provider,
761  'providerMetadata' => $this->providerMetadata,
762  'userId' => $anon ? 0 : $this->user->getId(),
763  'userName' => MediaWikiServices::getInstance()->getUserNameUtils()
764  ->isValid( $this->user->getName() ) ? $this->user->getName() : null,
765  'userToken' => $anon ? null : $this->user->getToken(),
766  'remember' => !$anon && $this->remember,
767  'forceHTTPS' => $this->forceHTTPS,
768  'expires' => time() + $this->lifetime,
769  'loggedOut' => $this->loggedOut,
770  'persisted' => $this->persist,
771  ];
772 
773  $this->hookRunner->onSessionMetadata( $this, $metadata, $this->requests );
774 
775  foreach ( $origMetadata as $k => $v ) {
776  if ( $metadata[$k] !== $v ) {
777  throw new \UnexpectedValueException( "SessionMetadata hook changed metadata key \"$k\"" );
778  }
779  }
780 
781  $flags = $this->persist ? 0 : CachedBagOStuff::WRITE_CACHE_ONLY;
782  $flags |= CachedBagOStuff::WRITE_SYNC; // write to all datacenters
783  $this->store->set(
784  $this->store->makeKey( 'MWSession', (string)$this->id ),
785  [
786  'data' => $this->data,
787  'metadata' => $metadata,
788  ],
789  $metadata['expires'],
790  $flags
791  );
792 
793  $this->metaDirty = false;
794  $this->dataDirty = false;
795  $this->dataHash = md5( serialize( $this->data ) );
796  $this->expires = $metadata['expires'];
797  }
798 
803  private function checkPHPSession() {
804  if ( !$this->checkPHPSessionRecursionGuard ) {
805  $this->checkPHPSessionRecursionGuard = true;
806  $reset = new \Wikimedia\ScopedCallback( function () {
807  $this->checkPHPSessionRecursionGuard = false;
808  } );
809 
810  if ( $this->usePhpSessionHandling && session_id() === '' && PHPSessionHandler::isEnabled() &&
811  SessionManager::getGlobalSession()->getId() === (string)$this->id
812  ) {
813  $this->logger->debug(
814  'SessionBackend "{session}" Taking over PHP session',
815  [
816  'session' => $this->id->__toString(),
817  ] );
818  session_id( (string)$this->id );
819  AtEase::quietCall( 'session_start' );
820  }
821  }
822  }
823 
829  private function logPersistenceChange( WebRequest $request, bool $persist ) {
830  if ( !$this->isPersistent() && !$persist ) {
831  // FIXME SessionManager calls unpersistSession() on anonymous requests (and the cookie
832  // filtering in WebResponse makes it a noop). Skip those.
833  return;
834  }
835 
836  $verb = $persist ? 'Persisting' : 'Unpersisting';
837  if ( $this->persistenceChangeType === 'renew' ) {
838  $message = "$verb session for renewal";
839  } elseif ( $this->persistenceChangeType === 'no-store' ) {
840  $message = "$verb session due to no pre-existing stored session";
841  } elseif ( $this->persistenceChangeType === 'no-expiry' ) {
842  $message = "$verb session due to lack of stored expiry";
843  } elseif ( $this->persistenceChangeType === null ) {
844  $message = "$verb session for unknown reason";
845  }
846 
847  // Because SessionManager repeats session loading several times in the same request,
848  // it will try to persist or unpersist several times. WebResponse deduplicates, but
849  // we want to deduplicate logging as well since the volume is already fairly large.
850  $id = $this->getId();
851  $user = $this->getUser()->isAnon() ? '<anon>' : $this->getUser()->getName();
852  if ( $this->persistenceChangeData
853  && $this->persistenceChangeData['id'] === $id
854  && $this->persistenceChangeData['user'] === $user
855  && $this->persistenceChangeData['message'] === $message
856  ) {
857  return;
858  }
859  $this->persistenceChangeData = [ 'id' => $id, 'user' => $user, 'message' => $message ];
860 
861  $this->logger->info( $message, [
862  'id' => $id,
863  'provider' => get_class( $this->getProvider() ),
864  'user' => $user,
865  'clientip' => $request->getIP(),
866  'userAgent' => $request->getHeader( 'user-agent' ),
867  ] );
868  }
869 
870 }
MediaWiki\Session\SessionInfo\forceHTTPS
forceHTTPS()
Whether this session should only be used over HTTPS.
Definition: SessionInfo.php:285
MediaWiki\Session\SessionId\getId
getId()
Definition: SessionId.php:56
MediaWiki\Session\SessionBackend\shouldRememberUser
shouldRememberUser()
Indicate whether the user should be remembered independently of the session ID.
Definition: SessionBackend.php:380
MediaWiki\Session\SessionBackend\getUser
getUser()
Returns the authenticated user for this session.
Definition: SessionBackend.php:418
MediaWiki\Session\SessionBackend\getRequest
getRequest( $index)
Returns the request associated with a Session.
Definition: SessionBackend.php:407
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:190
MediaWiki\Session\SessionBackend\getProviderMetadata
getProviderMetadata()
Fetch provider metadata.
Definition: SessionBackend.php:529
MediaWiki\Session\SessionBackend\$logger
LoggerInterface $logger
Definition: SessionBackend.php:101
MediaWiki\Session\SessionBackend\$curIndex
int $curIndex
Definition: SessionBackend.php:113
BagOStuff\WRITE_SYNC
const WRITE_SYNC
Bitfield constants for set()/merge(); these are only advisory.
Definition: BagOStuff.php:118
MediaWiki\Session\SessionBackend\getId
getId()
Returns the session ID.
Definition: SessionBackend.php:252
MediaWiki\Session\SessionBackend\$shutdown
bool $shutdown
Definition: SessionBackend.php:139
MediaWiki\Session\SessionBackend\$expires
int $expires
Definition: SessionBackend.php:125
MediaWiki\Session\SessionBackend\$id
SessionId $id
Definition: SessionBackend.php:55
MediaWiki\Session\SessionBackend\persist
persist()
Make this session persisted across requests.
Definition: SessionBackend.php:330
MediaWiki\Session\SessionBackend\setUser
setUser( $user)
Set a new user for this session.
Definition: SessionBackend.php:445
MediaWiki\Session\SessionBackend\getProvider
getProvider()
Fetch the SessionProvider for this session.
Definition: SessionBackend.php:309
MediaWiki\Session\PHPSessionHandler\isEnabled
static isEnabled()
Test whether the handler is installed and enabled.
Definition: PHPSessionHandler.php:103
MediaWiki\Session\SessionBackend\setLoggedOutTimestamp
setLoggedOutTimestamp( $ts=null)
Definition: SessionBackend.php:510
MediaWiki\Session\SessionInfo\getId
getId()
Return the session ID.
Definition: SessionInfo.php:193
MediaWiki\Session\SessionBackend\getData
& getData()
Fetch the session data array.
Definition: SessionBackend.php:562
wfReadOnly
wfReadOnly()
Check whether the wiki is in read-only mode.
Definition: GlobalFunctions.php:1099
MediaWiki\Session\SessionBackend\__construct
__construct(SessionId $id, SessionInfo $info, CachedBagOStuff $store, LoggerInterface $logger, HookContainer $hookContainer, $lifetime)
Definition: SessionBackend.php:149
MediaWiki\Session\SessionBackend\resetId
resetId()
Changes the session ID.
Definition: SessionBackend.php:269
serialize
serialize()
Definition: ApiMessageTrait.php:138
MediaWiki\Session\SessionBackend\getSession
getSession(WebRequest $request)
Return a new Session for this backend.
Definition: SessionBackend.php:219
MediaWiki\Session\SessionBackend\logPersistenceChange
logPersistenceChange(WebRequest $request, bool $persist)
Helper method for logging persistSession/unpersistSession calls.
Definition: SessionBackend.php:829
MediaWiki\Session\SessionBackend\deregisterSession
deregisterSession( $index)
Deregister a Session.
Definition: SessionBackend.php:231
CachedBagOStuff\get
get( $key, $flags=0)
Get an item with the given key.
Definition: CachedBagOStuff.php:58
MediaWiki\Session\SessionBackend\autosave
autosave()
Save the session, unless delayed.
Definition: SessionBackend.php:653
MediaWiki\MediaWikiServices\getInstance
static getInstance()
Returns the global default instance of the top level service locator.
Definition: MediaWikiServices.php:251
MediaWiki\Session\SessionBackend\$forceHTTPS
bool $forceHTTPS
Definition: SessionBackend.php:64
MediaWiki\Session\SessionBackend\shutdown
shutdown()
Shut down a session.
Definition: SessionBackend.php:243
MediaWiki\Session\SessionBackend\$dataHash
string $dataHash
Used to detect subarray modifications.
Definition: SessionBackend.php:95
MediaWiki\Session\SessionBackend\$user
User $user
Definition: SessionBackend.php:110
MediaWiki\Session\Session
Manages data for an authenticated session.
Definition: Session.php:48
MediaWiki\Session\SessionProvider
A SessionProvider provides SessionInfo and support for Session.
Definition: SessionProvider.php:81
MediaWiki\Session\SessionInfo\getProvider
getProvider()
Return the provider.
Definition: SessionInfo.php:185
$blob
$blob
Definition: testCompression.php:70
MediaWiki\Session\SessionBackend\$metaDirty
bool $metaDirty
Definition: SessionBackend.php:89
MediaWiki\Session\SessionBackend\$store
CachedBagOStuff $store
Definition: SessionBackend.php:98
MediaWiki\Session\SessionBackend\$forcePersist
bool $forcePersist
Definition: SessionBackend.php:70
MediaWiki\Session\SessionBackend\addData
addData(array $newData)
Add data to the session.
Definition: SessionBackend.php:573
MediaWiki\Session\SessionBackend\$loggedOut
int $loggedOut
Definition: SessionBackend.php:128
MediaWiki\Session\SessionBackend\dirty
dirty()
Mark data as dirty.
Definition: SessionBackend.php:593
MediaWiki\Session
Definition: BotPasswordSessionProvider.php:24
MediaWiki\Session\SessionInfo\wasPersisted
wasPersisted()
Return whether the session is persisted.
Definition: SessionInfo.php:248
User\saveSettings
saveSettings()
Save this user's settings into the database.
Definition: User.php:3296
MediaWiki\Session\SessionBackend\setForceHTTPS
setForceHTTPS( $force)
Set whether HTTPS should be forced.
Definition: SessionBackend.php:486
MediaWiki\Session\SessionBackend\$persist
bool $persist
Definition: SessionBackend.php:58
MediaWiki\Session\SessionInfo\getProviderMetadata
getProviderMetadata()
Return provider metadata.
Definition: SessionInfo.php:256
MediaWiki\Session\SessionBackend\$checkPHPSessionRecursionGuard
bool $checkPHPSessionRecursionGuard
Definition: SessionBackend.php:136
MediaWiki\Session\SessionManager\getGlobalSession
static getGlobalSession()
If PHP's session_id() has been set, returns that session.
Definition: SessionManager.php:146
MediaWiki\Session\SessionBackend\$data
array null $data
Definition: SessionBackend.php:67
MediaWiki\Session\SessionBackend\$persistenceChangeData
array $persistenceChangeData
The data from the previous logPersistenceChange() log event.
Definition: SessionBackend.php:86
MediaWiki\Session\SessionBackend\getSessionId
getSessionId()
Fetch the SessionId object.
Definition: SessionBackend.php:261
CachedBagOStuff
Wrapper around a BagOStuff that caches data in memory.
Definition: CachedBagOStuff.php:37
MediaWiki\Session\SessionBackend\shouldForceHTTPS
shouldForceHTTPS()
Whether HTTPS should be forced.
Definition: SessionBackend.php:478
RequestContext\getMain
static getMain()
Get the RequestContext object associated with the main request.
Definition: RequestContext.php:484
WebRequest
The WebRequest class encapsulates getting at data passed in the URL or via a POSTed form stripping il...
Definition: WebRequest.php:43
wfGetAllCallers
wfGetAllCallers( $limit=3)
Return a string consisting of callers in the stack.
Definition: GlobalFunctions.php:1375
WebRequest\getIP
getIP()
Work out the IP address based on various globals For trusted proxies, use the XFF client IP (first of...
Definition: WebRequest.php:1272
MediaWiki\Session\SessionBackend\getAllowedUserRights
getAllowedUserRights()
Fetch the rights allowed the user when this session is active.
Definition: SessionBackend.php:426
MediaWiki\Session\SessionInfo
Value object returned by SessionProvider.
Definition: SessionInfo.php:37
MediaWiki\Session\SessionBackend\isPersistent
isPersistent()
Indicate whether this session is persisted across requests.
Definition: SessionBackend.php:320
MediaWiki\Session\SessionBackend\$lifetime
int $lifetime
Definition: SessionBackend.php:107
CachedBagOStuff\makeKey
makeKey( $collection,... $components)
Make a cache key for the global keyspace and given components.
Definition: CachedBagOStuff.php:165
MediaWiki\Session\SessionBackend\renew
renew()
Renew the session by resaving everything.
Definition: SessionBackend.php:609
MediaWiki\Session\SessionBackend\$persistenceChangeType
string null $persistenceChangeType
The reason for the next persistSession/unpersistSession call.
Definition: SessionBackend.php:80
MediaWiki\Session\SessionBackend\getLoggedOutTimestamp
getLoggedOutTimestamp()
Fetch the "logged out" timestamp.
Definition: SessionBackend.php:503
MediaWiki\Session\SessionBackend\delaySave
delaySave()
Delay automatic saving while multiple updates are being made.
Definition: SessionBackend.php:639
MediaWiki\Session\SessionId
Value object holding the session ID in a manner that can be globally updated.
Definition: SessionId.php:40
WebRequest\getHeader
getHeader( $name, $flags=0)
Get a request header, or false if it isn't set.
Definition: WebRequest.php:1133
MediaWiki\Session\SessionBackend\$provider
SessionProvider $provider
provider
Definition: SessionBackend.php:119
MediaWiki\Session\SessionBackend\setRememberUser
setRememberUser( $remember)
Set whether the user should be remembered independently of the session ID.
Definition: SessionBackend.php:389
MediaWiki\HookContainer\HookContainer
HookContainer class.
Definition: HookContainer.php:45
MediaWiki\Session\SessionBackend\$dataDirty
bool $dataDirty
Definition: SessionBackend.php:92
MediaWiki\Session\SessionBackend\$requests
WebRequest[] $requests
Session requests.
Definition: SessionBackend.php:116
MediaWiki\HookContainer\HookRunner
This class provides an implementation of the core hook interfaces, forwarding hook calls to HookConta...
Definition: HookRunner.php:552
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:68
DeferredUpdates\addCallableUpdate
static addCallableUpdate( $callable, $stage=self::POSTSEND, $dbw=null)
Add an update to the pending update queue that invokes the specified callback when run.
Definition: DeferredUpdates.php:145
MediaWiki\Session\SessionBackend\save
save( $closing=false)
Save the session.
Definition: SessionBackend.php:668
MediaWiki\Session\SessionBackend\$hookRunner
HookRunner $hookRunner
Definition: SessionBackend.php:104
MediaWiki\Session\SessionBackend\canSetUser
canSetUser()
Indicate whether the session user info can be changed.
Definition: SessionBackend.php:434
MediaWiki\Session\SessionBackend\setProviderMetadata
setProviderMetadata( $metadata)
Definition: SessionBackend.php:537
MediaWiki\Session\SessionBackend\unpersist
unpersist()
Make this session not persisted across requests.
Definition: SessionBackend.php:349
MediaWiki\Session\SessionBackend\suggestLoginUsername
suggestLoginUsername( $index)
Get a suggested username for the login form.
Definition: SessionBackend.php:467
MediaWiki\Session\SessionBackend\$usePhpSessionHandling
bool $usePhpSessionHandling
Definition: SessionBackend.php:134
MediaWiki\Session\SessionBackend\checkPHPSession
checkPHPSession()
For backwards compatibility, open the PHP session when the global session is persisted.
Definition: SessionBackend.php:803
MediaWiki\Session\SessionBackend\$remember
bool $remember
Definition: SessionBackend.php:61
MediaWiki\Session\SessionInfo\getUserInfo
getUserInfo()
Return the user.
Definition: SessionInfo.php:240
MediaWiki\Session\SessionBackend\$providerMetadata
array null $providerMetadata
provider-specified metadata
Definition: SessionBackend.php:122
MediaWiki\Session\SessionInfo\wasRemembered
wasRemembered()
Return whether the user was remembered.
Definition: SessionInfo.php:275
MediaWiki\Session\SessionBackend\$delaySave
int $delaySave
Definition: SessionBackend.php:131
BagOStuff\WRITE_CACHE_ONLY
const WRITE_CACHE_ONLY
Definition: BagOStuff.php:119
MediaWiki\Session\SessionBackend
This is the actual workhorse for Session.
Definition: SessionBackend.php:53