MediaWiki  master
SessionProvider.php
Go to the documentation of this file.
1 <?php
24 namespace MediaWiki\Session;
25 
26 use Config;
27 use Language;
30 use Psr\Log\LoggerAwareInterface;
31 use Psr\Log\LoggerInterface;
32 use User;
33 use WebRequest;
34 
81 abstract class SessionProvider implements SessionProviderInterface, LoggerAwareInterface {
82 
84  protected $logger;
85 
87  protected $config;
88 
90  protected $manager;
91 
93  private $hookContainer;
94 
96  private $hookRunner;
97 
101  protected $priority;
102 
110  public function __construct() {
111  $this->priority = SessionInfo::MIN_PRIORITY + 10;
112  }
113 
114  public function setLogger( LoggerInterface $logger ) {
115  $this->logger = $logger;
116  }
117 
122  public function setConfig( Config $config ) {
123  $this->config = $config;
124  }
125 
130  public function setManager( SessionManager $manager ) {
131  $this->manager = $manager;
132  }
133 
138  public function getManager() {
139  return $this->manager;
140  }
141 
146  public function setHookContainer( $hookContainer ) {
147  $this->hookContainer = $hookContainer;
148  $this->hookRunner = new HookRunner( $hookContainer );
149  }
150 
156  protected function getHookContainer() : HookContainer {
157  return $this->hookContainer;
158  }
159 
168  protected function getHookRunner() : HookRunner {
169  return $this->hookRunner;
170  }
171 
194  abstract public function provideSessionInfo( WebRequest $request );
195 
210  public function newSessionInfo( $id = null ) {
211  if ( $this->canChangeUser() && $this->persistsSessionId() ) {
212  return new SessionInfo( $this->priority, [
213  'id' => $id,
214  'provider' => $this,
215  'persisted' => false,
216  'idIsSafe' => true,
217  ] );
218  }
219  return null;
220  }
221 
244  public function mergeMetadata( array $savedMetadata, array $providedMetadata ) {
245  foreach ( $providedMetadata as $k => $v ) {
246  if ( array_key_exists( $k, $savedMetadata ) && $savedMetadata[$k] !== $v ) {
247  $e = new MetadataMergeException( "Key \"$k\" changed" );
248  $e->setContext( [
249  'old_value' => $savedMetadata[$k],
250  'new_value' => $v,
251  ] );
252  throw $e;
253  }
254  }
255  return $providedMetadata;
256  }
257 
272  public function refreshSessionInfo( SessionInfo $info, WebRequest $request, &$metadata ) {
273  return true;
274  }
275 
302  abstract public function persistsSessionId();
303 
329  abstract public function canChangeUser();
330 
338  public function getRememberUserDuration() {
339  return null;
340  }
341 
353  public function sessionIdWasReset( SessionBackend $session, $oldId ) {
354  }
355 
383  abstract public function persistSession( SessionBackend $session, WebRequest $request );
384 
396  abstract public function unpersistSession( WebRequest $request );
397 
420  public function preventSessionsForUser( $username ) {
421  if ( !$this->canChangeUser() ) {
422  throw new \BadMethodCallException(
423  __METHOD__ . ' must be implemented when canChangeUser() is false'
424  );
425  }
426  }
427 
439  public function invalidateSessionsForUser( User $user ) {
440  }
441 
459  public function getVaryHeaders() {
460  return [];
461  }
462 
469  public function getVaryCookies() {
470  return [];
471  }
472 
480  public function suggestLoginUsername( WebRequest $request ) {
481  return null;
482  }
483 
495  public function getAllowedUserRights( SessionBackend $backend ) {
496  if ( $backend->getProvider() !== $this ) {
497  // Not that this should ever happen...
498  throw new \InvalidArgumentException( 'Backend\'s provider isn\'t $this' );
499  }
500 
501  return null;
502  }
503 
511  public function __toString() {
512  return static::class;
513  }
514 
531  protected function describeMessage() {
532  return wfMessage(
533  'sessionprovider-' . str_replace( '\\', '-', strtolower( static::class ) )
534  );
535  }
536 
541  public function describe( Language $lang ) {
542  $msg = $this->describeMessage();
543  $msg->inLanguage( $lang );
544  if ( $msg->isDisabled() ) {
545  $msg = wfMessage( 'sessionprovider-generic', (string)$this )->inLanguage( $lang );
546  }
547  return $msg->plain();
548  }
549 
554  public function whyNoSession() {
555  return null;
556  }
557 
564  public function safeAgainstCsrf() {
565  return false;
566  }
567 
581  final protected function hashToSessionId( $data, $key = null ) {
582  if ( !is_string( $data ) ) {
583  throw new \InvalidArgumentException(
584  '$data must be a string, ' . gettype( $data ) . ' was passed'
585  );
586  }
587  if ( $key !== null && !is_string( $key ) ) {
588  throw new \InvalidArgumentException(
589  '$key must be a string or null, ' . gettype( $key ) . ' was passed'
590  );
591  }
592 
593  $hash = \MWCryptHash::hmac( "$this\n$data", $key ?: $this->config->get( 'SecretKey' ), false );
594  if ( strlen( $hash ) < 32 ) {
595  // Should never happen, even md5 is 128 bits
596  // @codeCoverageIgnoreStart
597  throw new \UnexpectedValueException( 'Hash function returned less than 128 bits' );
598  // @codeCoverageIgnoreEnd
599  }
600  if ( strlen( $hash ) >= 40 ) {
601  $hash = \Wikimedia\base_convert( $hash, 16, 32, 32 );
602  }
603  return substr( $hash, -32 );
604  }
605 
606 }
MediaWiki\Session\SessionProvider\getAllowedUserRights
getAllowedUserRights(SessionBackend $backend)
Fetch the rights allowed the user when the specified session is active.
Definition: SessionProvider.php:495
MediaWiki\Session\SessionProvider\getManager
getManager()
Get the session manager.
Definition: SessionProvider.php:138
MediaWiki\Session\SessionProvider\newSessionInfo
newSessionInfo( $id=null)
Provide session info for a new, empty session.
Definition: SessionProvider.php:210
MWCryptHash\hmac
static hmac( $data, $key, $raw=true)
Generate an acceptably unstable one-way-hmac of some text making use of the best hash algorithm that ...
Definition: MWCryptHash.php:106
MediaWiki\Session\SessionProvider\setLogger
setLogger(LoggerInterface $logger)
Definition: SessionProvider.php:114
MediaWiki\Session\SessionProvider\getRememberUserDuration
getRememberUserDuration()
Returns the duration (in seconds) for which users will be remembered when Session::setRememberUser() ...
Definition: SessionProvider.php:338
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:37
MediaWiki\Session\SessionBackend\getProvider
getProvider()
Fetch the SessionProvider for this session.
Definition: SessionBackend.php:308
MediaWiki\Session\MetadataMergeException
Subclass of UnexpectedValueException that can be annotated with additional data for debug logging.
Definition: MetadataMergeException.php:36
MediaWiki\Session\SessionProvider\persistsSessionId
persistsSessionId()
Indicate whether self::persistSession() can save arbitrary session IDs.
wfMessage
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Definition: GlobalFunctions.php:1230
MediaWiki\Session\SessionProvider\describeMessage
describeMessage()
Return a Message identifying this session type.
Definition: SessionProvider.php:531
MediaWiki\Session\SessionProvider\getHookContainer
getHookContainer()
Get the HookContainer.
Definition: SessionProvider.php:156
MediaWiki\Session\SessionProvider\getVaryCookies
getVaryCookies()
Return the list of cookies that need varying on.
Definition: SessionProvider.php:469
Config
Interface for configuration instances.
Definition: Config.php:30
MediaWiki\Session\SessionProvider\provideSessionInfo
provideSessionInfo(WebRequest $request)
Provide session info for a request.
MediaWiki\Session\SessionProvider\__construct
__construct()
Stable to call.
Definition: SessionProvider.php:110
MediaWiki\Session\SessionProvider
A SessionProvider provides SessionInfo and support for Session.
Definition: SessionProvider.php:81
MediaWiki\Session\SessionProvider\setManager
setManager(SessionManager $manager)
Set the session manager.
Definition: SessionProvider.php:130
MediaWiki\Session\SessionProvider\unpersistSession
unpersistSession(WebRequest $request)
Remove any persisted session from a request/response.
MediaWiki\Session\SessionProvider\suggestLoginUsername
suggestLoginUsername(WebRequest $request)
Get a suggested username for the login form Stable to override.
Definition: SessionProvider.php:480
MediaWiki\Session
Definition: BotPasswordSessionProvider.php:24
MediaWiki\Session\SessionProvider\whyNoSession
whyNoSession()
Return a Message for why sessions might not be being persisted.For example, "check whether you're blo...
Definition: SessionProvider.php:554
MediaWiki\Session\SessionProvider\preventSessionsForUser
preventSessionsForUser( $username)
Prevent future sessions for the user.
Definition: SessionProvider.php:420
MediaWiki\Session\SessionProvider\$logger
LoggerInterface $logger
Definition: SessionProvider.php:84
MediaWiki\Session\SessionProviderInterface
This exists to make IDEs happy, so they don't see the internal-but-required-to-be-public methods on S...
Definition: SessionProviderInterface.php:36
MediaWiki\Session\SessionProvider\__toString
__toString()
Definition: SessionProvider.php:511
MediaWiki\Session\SessionProvider\refreshSessionInfo
refreshSessionInfo(SessionInfo $info, WebRequest $request, &$metadata)
Validate a loaded SessionInfo and refresh provider metadata.
Definition: SessionProvider.php:272
MediaWiki\Session\SessionProvider\invalidateSessionsForUser
invalidateSessionsForUser(User $user)
Invalidate existing sessions for a user.
Definition: SessionProvider.php:439
MediaWiki\Session\SessionManager
This serves as the entry point to the MediaWiki session handling system.
Definition: SessionManager.php:53
MediaWiki\Session\SessionProvider\mergeMetadata
mergeMetadata(array $savedMetadata, array $providedMetadata)
Merge saved session provider metadata.
Definition: SessionProvider.php:244
MediaWiki\Session\SessionProvider\$hookContainer
HookContainer $hookContainer
Definition: SessionProvider.php:93
MediaWiki\Session\SessionProvider\setConfig
setConfig(Config $config)
Set configuration.
Definition: SessionProvider.php:122
MediaWiki\Session\SessionProvider\persistSession
persistSession(SessionBackend $session, WebRequest $request)
Persist a session into a request/response.
MediaWiki\Session\SessionProvider\safeAgainstCsrf
safeAgainstCsrf()
Most session providers require protection against CSRF attacks (usually via CSRF tokens)
Definition: SessionProvider.php:564
MediaWiki\Session\SessionProvider\$config
Config $config
Definition: SessionProvider.php:87
WebRequest
The WebRequest class encapsulates getting at data passed in the URL or via a POSTed form stripping il...
Definition: WebRequest.php:42
MediaWiki\Session\SessionInfo
Value object returned by SessionProvider.
Definition: SessionInfo.php:37
MediaWiki\Session\SessionProvider\describe
describe(Language $lang)
Return an identifier for this session type.Language to use. string Stable to override
Definition: SessionProvider.php:541
MediaWiki\Session\SessionProvider\canChangeUser
canChangeUser()
Indicate whether the user associated with the request can be changed.
MediaWiki\Session\SessionProvider\$priority
int $priority
Session priority.
Definition: SessionProvider.php:101
MediaWiki\Session\SessionProvider\setHookContainer
setHookContainer( $hookContainer)
Definition: SessionProvider.php:146
MediaWiki\Session\SessionProvider\sessionIdWasReset
sessionIdWasReset(SessionBackend $session, $oldId)
Notification that the session ID was reset.
Definition: SessionProvider.php:353
MediaWiki\HookContainer\HookContainer
HookContainer class.
Definition: HookContainer.php:45
MediaWiki\HookContainer\HookRunner
This class provides an implementation of the core hook interfaces, forwarding hook calls to HookConta...
Definition: HookRunner.php:571
MediaWiki\Session\SessionProvider\$manager
SessionManager $manager
Definition: SessionProvider.php:90
MediaWiki\Session\SessionProvider\getVaryHeaders
getVaryHeaders()
Return the HTTP headers that need varying on.
Definition: SessionProvider.php:459
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:56
MediaWiki\Session\SessionInfo\MIN_PRIORITY
const MIN_PRIORITY
Minimum allowed priority.
Definition: SessionInfo.php:39
MediaWiki\Session\SessionProvider\$hookRunner
HookRunner $hookRunner
Definition: SessionProvider.php:96
Language
Internationalisation code See https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation for more...
Definition: Language.php:42
MediaWiki\Session\SessionBackend
This is the actual workhorse for Session.
Definition: SessionBackend.php:52
MediaWiki\Session\SessionProvider\hashToSessionId
hashToSessionId( $data, $key=null)
Hash data as a session ID.
Definition: SessionProvider.php:581
MediaWiki\Session\SessionProvider\getHookRunner
getHookRunner()
Get the HookRunner.
Definition: SessionProvider.php:168