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 
80 abstract class SessionProvider implements SessionProviderInterface, LoggerAwareInterface {
81 
83  protected $logger;
84 
86  protected $config;
87 
89  protected $manager;
90 
92  private $hookContainer;
93 
95  private $hookRunner;
96 
100  protected $priority;
101 
108  public function __construct() {
109  $this->priority = SessionInfo::MIN_PRIORITY + 10;
110  }
111 
112  public function setLogger( LoggerInterface $logger ) {
113  $this->logger = $logger;
114  }
115 
120  public function setConfig( Config $config ) {
121  $this->config = $config;
122  }
123 
128  public function setManager( SessionManager $manager ) {
129  $this->manager = $manager;
130  }
131 
136  public function getManager() {
137  return $this->manager;
138  }
139 
145  public function setHookContainer( $hookContainer ) {
146  $this->hookContainer = $hookContainer;
147  $this->hookRunner = new HookRunner( $hookContainer );
148  }
149 
155  protected function getHookContainer() : HookContainer {
156  return $this->hookContainer;
157  }
158 
167  protected function getHookRunner() : HookRunner {
168  return $this->hookRunner;
169  }
170 
193  abstract public function provideSessionInfo( WebRequest $request );
194 
208  public function newSessionInfo( $id = null ) {
209  if ( $this->canChangeUser() && $this->persistsSessionId() ) {
210  return new SessionInfo( $this->priority, [
211  'id' => $id,
212  'provider' => $this,
213  'persisted' => false,
214  'idIsSafe' => true,
215  ] );
216  }
217  return null;
218  }
219 
241  public function mergeMetadata( array $savedMetadata, array $providedMetadata ) {
242  foreach ( $providedMetadata as $k => $v ) {
243  if ( array_key_exists( $k, $savedMetadata ) && $savedMetadata[$k] !== $v ) {
244  $e = new MetadataMergeException( "Key \"$k\" changed" );
245  $e->setContext( [
246  'old_value' => $savedMetadata[$k],
247  'new_value' => $v,
248  ] );
249  throw $e;
250  }
251  }
252  return $providedMetadata;
253  }
254 
268  public function refreshSessionInfo( SessionInfo $info, WebRequest $request, &$metadata ) {
269  return true;
270  }
271 
298  abstract public function persistsSessionId();
299 
325  abstract public function canChangeUser();
326 
333  public function getRememberUserDuration() {
334  return null;
335  }
336 
347  public function sessionIdWasReset( SessionBackend $session, $oldId ) {
348  }
349 
377  abstract public function persistSession( SessionBackend $session, WebRequest $request );
378 
390  abstract public function unpersistSession( WebRequest $request );
391 
413  public function preventSessionsForUser( $username ) {
414  if ( !$this->canChangeUser() ) {
415  throw new \BadMethodCallException(
416  __METHOD__ . ' must be implemented when canChangeUser() is false'
417  );
418  }
419  }
420 
431  public function invalidateSessionsForUser( User $user ) {
432  }
433 
450  public function getVaryHeaders() {
451  return [];
452  }
453 
459  public function getVaryCookies() {
460  return [];
461  }
462 
469  public function suggestLoginUsername( WebRequest $request ) {
470  return null;
471  }
472 
483  public function getAllowedUserRights( SessionBackend $backend ) {
484  if ( $backend->getProvider() !== $this ) {
485  // Not that this should ever happen...
486  throw new \InvalidArgumentException( 'Backend\'s provider isn\'t $this' );
487  }
488 
489  return null;
490  }
491 
499  public function __toString() {
500  return static::class;
501  }
502 
518  protected function describeMessage() {
519  return wfMessage(
520  'sessionprovider-' . str_replace( '\\', '-', strtolower( static::class ) )
521  );
522  }
523 
524  public function describe( Language $lang ) {
525  $msg = $this->describeMessage();
526  $msg->inLanguage( $lang );
527  if ( $msg->isDisabled() ) {
528  $msg = wfMessage( 'sessionprovider-generic', (string)$this )->inLanguage( $lang );
529  }
530  return $msg->plain();
531  }
532 
533  public function whyNoSession() {
534  return null;
535  }
536 
542  public function safeAgainstCsrf() {
543  return false;
544  }
545 
559  final protected function hashToSessionId( $data, $key = null ) {
560  if ( !is_string( $data ) ) {
561  throw new \InvalidArgumentException(
562  '$data must be a string, ' . gettype( $data ) . ' was passed'
563  );
564  }
565  if ( $key !== null && !is_string( $key ) ) {
566  throw new \InvalidArgumentException(
567  '$key must be a string or null, ' . gettype( $key ) . ' was passed'
568  );
569  }
570 
571  $hash = \MWCryptHash::hmac( "$this\n$data", $key ?: $this->config->get( 'SecretKey' ), false );
572  if ( strlen( $hash ) < 32 ) {
573  // Should never happen, even md5 is 128 bits
574  // @codeCoverageIgnoreStart
575  throw new \UnexpectedValueException( 'Hash function returned less than 128 bits' );
576  // @codeCoverageIgnoreEnd
577  }
578  if ( strlen( $hash ) >= 40 ) {
579  $hash = \Wikimedia\base_convert( $hash, 16, 32, 32 );
580  }
581  return substr( $hash, -32 );
582  }
583 
584 }
MediaWiki\Session\SessionProvider\getAllowedUserRights
getAllowedUserRights(SessionBackend $backend)
Fetch the rights allowed the user when the specified session is active.
Definition: SessionProvider.php:483
MediaWiki\Session\SessionProvider\getManager
getManager()
Get the session manager.
Definition: SessionProvider.php:136
MediaWiki\Session\SessionProvider\newSessionInfo
newSessionInfo( $id=null)
Provide session info for a new, empty session.
Definition: SessionProvider.php:208
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:112
MediaWiki\Session\SessionProvider\getRememberUserDuration
getRememberUserDuration()
Returns the duration (in seconds) for which users will be remembered when Session::setRememberUser() ...
Definition: SessionProvider.php:333
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:37
MediaWiki\Session\SessionBackend\getProvider
getProvider()
Fetch the SessionProvider for this session.
Definition: SessionBackend.php:290
MediaWiki\Session\MetadataMergeException
Subclass of UnexpectedValueException that can be annotated with additional data for debug logging.
Definition: MetadataMergeException.php:35
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:1198
MediaWiki\Session\SessionProvider\describeMessage
describeMessage()
Return a Message identifying this session type.
Definition: SessionProvider.php:518
MediaWiki\Session\SessionProvider\getHookContainer
getHookContainer()
Get the HookContainer.
Definition: SessionProvider.php:155
MediaWiki\Session\SessionProvider\getVaryCookies
getVaryCookies()
Return the list of cookies that need varying on.
Definition: SessionProvider.php:459
Config
Interface for configuration instances.
Definition: Config.php:28
MediaWiki\Session\SessionProvider\provideSessionInfo
provideSessionInfo(WebRequest $request)
Provide session info for a request.
MediaWiki\Session\SessionProvider\__construct
__construct()
Definition: SessionProvider.php:108
MediaWiki\Session\SessionProvider
A SessionProvider provides SessionInfo and support for Session.
Definition: SessionProvider.php:80
MediaWiki\Session\SessionProvider\setManager
setManager(SessionManager $manager)
Set the session manager.
Definition: SessionProvider.php:128
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.
Definition: SessionProvider.php:469
MediaWiki\Session
Definition: BotPasswordSessionProvider.php:24
MediaWiki\Session\SessionProvider\whyNoSession
whyNoSession()
Return a Message for why sessions might not be being persisted.
Definition: SessionProvider.php:533
MediaWiki\Session\SessionProvider\preventSessionsForUser
preventSessionsForUser( $username)
Prevent future sessions for the user.
Definition: SessionProvider.php:413
MediaWiki\Session\SessionProvider\$logger
LoggerInterface $logger
Definition: SessionProvider.php:83
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:499
MediaWiki\Session\SessionProvider\refreshSessionInfo
refreshSessionInfo(SessionInfo $info, WebRequest $request, &$metadata)
Validate a loaded SessionInfo and refresh provider metadata.
Definition: SessionProvider.php:268
MediaWiki\Session\SessionProvider\invalidateSessionsForUser
invalidateSessionsForUser(User $user)
Invalidate existing sessions for a user.
Definition: SessionProvider.php:431
MediaWiki\Session\SessionManager
This serves as the entry point to the MediaWiki session handling system.
Definition: SessionManager.php:52
MediaWiki\Session\SessionProvider\mergeMetadata
mergeMetadata(array $savedMetadata, array $providedMetadata)
Merge saved session provider metadata.
Definition: SessionProvider.php:241
MediaWiki\Session\SessionProvider\$hookContainer
HookContainer $hookContainer
Definition: SessionProvider.php:92
MediaWiki\Session\SessionProvider\setConfig
setConfig(Config $config)
Set configuration.
Definition: SessionProvider.php:120
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:542
MediaWiki\Session\SessionProvider\$config
Config $config
Definition: SessionProvider.php:86
WebRequest
The WebRequest class encapsulates getting at data passed in the URL or via a POSTed form stripping il...
Definition: WebRequest.php:43
MediaWiki\Session\SessionInfo
Value object returned by SessionProvider.
Definition: SessionInfo.php:34
MediaWiki\Session\SessionProvider\describe
describe(Language $lang)
Return an identifier for this session type.
Definition: SessionProvider.php:524
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:100
MediaWiki\Session\SessionProvider\setHookContainer
setHookContainer( $hookContainer)
Set the hook container.
Definition: SessionProvider.php:145
MediaWiki\Session\SessionProvider\sessionIdWasReset
sessionIdWasReset(SessionBackend $session, $oldId)
Notification that the session ID was reset.
Definition: SessionProvider.php:347
MediaWiki\HookContainer\HookContainer
HookContainer class.
Definition: HookContainer.php:44
MediaWiki\HookContainer\HookRunner
This class provides an implementation of the core hook interfaces, forwarding hook calls to HookConta...
Definition: HookRunner.php:23
MediaWiki\Session\SessionProvider\$manager
SessionManager $manager
Definition: SessionProvider.php:89
MediaWiki\Session\SessionProvider\getVaryHeaders
getVaryHeaders()
Return the HTTP headers that need varying on.
Definition: SessionProvider.php:450
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:55
MediaWiki\Session\SessionInfo\MIN_PRIORITY
const MIN_PRIORITY
Minimum allowed priority.
Definition: SessionInfo.php:36
MediaWiki\Session\SessionProvider\$hookRunner
HookRunner $hookRunner
Definition: SessionProvider.php:95
Language
Internationalisation code See https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation for more...
Definition: Language.php:41
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:559
MediaWiki\Session\SessionProvider\getHookRunner
getHookRunner()
Get the HookRunner.
Definition: SessionProvider.php:167