private $dataHash = null;
/** @var BagOStuff */
- private $store;
+ private $tempStore;
+ /** @var BagOStuff */
+ private $permStore;
/** @var LoggerInterface */
private $logger;
/**
* @param SessionId $id Session ID object
* @param SessionInfo $info Session info to populate from
- * @param BagOStuff $store Backend data store
+ * @param BagOStuff $tempStore In-process data store
+ * @param BagOStuff $permstore Backend data store for persisted sessions
* @param LoggerInterface $logger
* @param int $lifetime Session data lifetime in seconds
*/
public function __construct(
- SessionId $id, SessionInfo $info, BagOStuff $store, LoggerInterface $logger, $lifetime
+ SessionId $id, SessionInfo $info, BagOStuff $tempStore, BagOStuff $permStore,
+ LoggerInterface $logger, $lifetime
) {
$phpSessionHandling = \RequestContext::getMain()->getConfig()->get( 'PHPSessionHandling' );
$this->usePhpSessionHandling = $phpSessionHandling !== 'disable';
$this->id = $id;
$this->user = $info->getUserInfo() ? $info->getUserInfo()->getUser() : new User;
- $this->store = $store;
+ $this->tempStore = $tempStore;
+ $this->permStore = $permStore;
$this->logger = $logger;
$this->lifetime = $lifetime;
$this->provider = $info->getProvider();
$this->forceHTTPS = $info->forceHTTPS();
$this->providerMetadata = $info->getProviderMetadata();
- $blob = $store->get( wfMemcKey( 'MWSession', (string)$this->id ) );
+ $key = wfMemcKey( 'MWSession', (string)$this->id );
+ $blob = $tempStore->get( $key );
+ if ( $blob === false ) {
+ $blob = $permStore->get( $key );
+ if ( $blob !== false ) {
+ $tempStore->set( $key, $blob );
+ }
+ }
if ( !is_array( $blob ) ||
!isset( $blob['metadata'] ) || !is_array( $blob['metadata'] ) ||
!isset( $blob['data'] ) || !is_array( $blob['data'] )
$this->autosave();
// Delete the data for the old session ID now
- $this->store->delete( wfMemcKey( 'MWSession', $oldId ) );
+ $this->tempStore->delete( wfMemcKey( 'MWSession', $oldId ) );
+ $this->permStore->delete( wfMemcKey( 'MWSession', $oldId ) );
}
}
if ( !$this->persist ) {
$this->persist = true;
$this->forcePersist = true;
+ $this->metaDirty = true;
$this->logger->debug( "SessionBackend $this->id force-persist due to persist()" );
$this->autosave();
} else {
/**
* Fetch provider metadata
* @protected For use by SessionProvider subclasses only
- * @return mixed
+ * @return array|null
*/
public function getProviderMetadata() {
return $this->providerMetadata;
}
+ /**
+ * Set provider metadata
+ * @protected For use by SessionProvider subclasses only
+ * @param array|null $metadata
+ */
+ public function setProviderMetadata( $metadata ) {
+ if ( $metadata !== null && !is_array( $metadata ) ) {
+ throw new \InvalidArgumentException( '$metadata must be an array or null' );
+ }
+ if ( $this->providerMetadata !== $metadata ) {
+ $this->providerMetadata = $metadata;
+ $this->metaDirty = true;
+ $this->logger->debug(
+ "SessionBackend $this->id metadata dirty due to provider metadata change"
+ );
+ $this->autosave();
+ }
+ }
+
/**
* Fetch the session data array
*
// Ensure the user has a token
// @codeCoverageIgnoreStart
$anon = $this->user->isAnon();
- if ( !$anon && !$this->user->getToken() ) {
+ if ( !$anon && !$this->user->getToken( false ) ) {
$this->logger->debug(
"SessionBackend $this->id creating token for user {$this->user} on save"
);
'provider' => (string)$this->provider,
'providerMetadata' => $this->providerMetadata,
'userId' => $anon ? 0 : $this->user->getId(),
- 'userName' => $anon ? null : $this->user->getName(),
+ 'userName' => User::isValidUserName( $this->user->getName() ) ? $this->user->getName() : null,
'userToken' => $anon ? null : $this->user->getToken(),
'remember' => !$anon && $this->remember,
'forceHTTPS' => $this->forceHTTPS,
'expires' => time() + $this->lifetime,
'loggedOut' => $this->loggedOut,
+ 'persisted' => $this->persist,
);
\Hooks::run( 'SessionMetadata', array( $this, &$metadata, $this->requests ) );
}
}
- $this->store->set(
+ $this->tempStore->set(
wfMemcKey( 'MWSession', (string)$this->id ),
array(
'data' => $this->data,
),
$metadata['expires']
);
+ if ( $this->persist ) {
+ $this->permStore->set(
+ wfMemcKey( 'MWSession', (string)$this->id ),
+ array(
+ 'data' => $this->data,
+ 'metadata' => $metadata,
+ ),
+ $metadata['expires']
+ );
+ }
$this->metaDirty = false;
$this->dataDirty = false;
) {
$this->logger->debug( "SessionBackend $this->id: Taking over PHP session" );
session_id( (string)$this->id );
+ \MediaWiki\quietCall( 'session_cache_limiter', 'private, must-revalidate' );
\MediaWiki\quietCall( 'session_start' );
}
}