aboutsummaryrefslogtreecommitdiffstats
path: root/includes/session/CookieSessionProvider.php
diff options
context:
space:
mode:
authorBrad Jorsch <bjorsch@wikimedia.org>2016-02-01 12:28:29 -0500
committerBryanDavis <bdavis@wikimedia.org>2016-02-01 22:06:49 +0000
commit5083e810ebd5303bef41c2b00cafe655f9ee13eb (patch)
tree52584ee908d0f8aa714315ddb5b7bbce96ccd2f9 /includes/session/CookieSessionProvider.php
parent7489189d7c13448114963520fb383cb2c7765b1e (diff)
downloadmediawikicore-5083e810ebd5303bef41c2b00cafe655f9ee13eb.tar.gz
mediawikicore-5083e810ebd5303bef41c2b00cafe655f9ee13eb.zip
Remove SessionManager, temporarily
The plan here is to take it out of 1.27.0-wmf.12 and put it back in 1.27.0-wmf.13. Since BotPasswords depends on SessionManager, that's getting temporarily removed too. This reverts the following commits: * 6acd424e0dbc322e8b9a141bd2625453c1b9b6f1 SessionManager: Notify AuthPlugin before calling hooks * 4d1ad32d8acbd443346253d2f6a95024c833295c Close a loophole in CookieSessionProvider * fcdd643a46d87b677f6cdcc3ba9440e1472d8df7 SessionManager: Don't save non-persisted sessions to backend storage * 058aec4c76129b7ee8541692a8a48f8046e15bb6 MessageCache: Don't get a ParserOptions for $wgUser before the end of Setup.php * b5c0c03bb708f8dad6e404969df8addc123984db SessionManager: Save user name to metadata even if the user doesn't exist locally * 13f2f09a193215aa7a061d10a1955e172d06fa0a SECURITY: Fix User::setToken() call on User::newSystemUser * 305bc75b27903237a9683ec1f329bcbec0ecd266 SessionManager: Don't generate user tokens when checking the tokens * 7c4bd85d2152fd9fa975ea0fb5ffb1a0b804f99b RequestContext::exportSession() should only export persisted session IDs * 296ccfd4a9a6ad3ae412db7e2408c923aaa61f64 SessionManager: Save 'persisted' flag in session metadata * 94ba53f67731b0553a6178841d9506e384f74496 Move CSRF token handling into MediaWiki\Session\Session * 46a565d6b00174e631d2022b47677e1a78e73897 Avoid false "added in both Session and $_SESSION" when value is null * c00d0b5d94c946b8883dd7062bf7160a199aa5c2 Log backtrace for "User::loadFromSession called before the end of Setup.php" * 4eeff5b559e2ae7b8fa1f45572968ba28573a421 Use $wgSecureCookie to decide whether to actually mark secure cookies as 'secure' * 7491b52f700e220814a8190781fd794b4dd88a20 Call session_cache_limiter() before starting a session * 2c34aeea72471f9a598e67bdbf34bc5f9fb3f0c5 SessionManager: Abstract forceHTTPS cookie setting * 9aa53627a53aabec0273cecf45a86e77927ef406 Ignore auth cookies with value 'deleted' * 43f904b51a746d7f71ea2ab9951c5c98d269765b SessionManager: Kill getPersistedSessionId() * 50c52563528ba3d765c3762211f98d6f3c0e39fd SessionManager: Add SessionBackend::setProviderMetadata() * f640d403154bc0a2b4f6d399582797a9e3bc6fcb SessionManager: Notify AuthPlugin when auto-creating accounts * 70b05d1ac1e859bac2185b246e9b93ec9051e4d8 Add checks of $wgEnableBotPasswords in more places * bfed32eb78b6c720b16bc7ed60153fd2fe257a9e Do not raise a PHP warning when session write fails * 722a7331ad8d98228511f8da38adc7a3c64dd617 Only check LoggedOut timestamp on the user loaded from session * 4f5057b84b36eccd16627a6b29831dfdb4483b02 SessionManager: Change behavior of getSessionById() * 66e82e614e157e39b03d813e71ddf23f53cf640b Fix typo in [[MediaWiki:Botpasswords-editexisting/en]] * f9fd9516d922d36291037baca7205a2b0ac9f15f Add "bot passwords" * d7716f1df0b692902571bf415a0984071e3e9a60 Add missing argument for wfDebugLog * a73c5b7395a07d490f7052fd3b2491ebd656b190 Add SessionManager Change-Id: I2389a8133e25ab929e9f27f41fa9a05df8147a50
Diffstat (limited to 'includes/session/CookieSessionProvider.php')
-rw-r--r--includes/session/CookieSessionProvider.php372
1 files changed, 0 insertions, 372 deletions
diff --git a/includes/session/CookieSessionProvider.php b/includes/session/CookieSessionProvider.php
deleted file mode 100644
index f989cbc7f263..000000000000
--- a/includes/session/CookieSessionProvider.php
+++ /dev/null
@@ -1,372 +0,0 @@
-<?php
-/**
- * MediaWiki cookie-based session provider interface
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Session
- */
-
-namespace MediaWiki\Session;
-
-use Config;
-use User;
-use WebRequest;
-
-/**
- * A CookieSessionProvider persists sessions using cookies
- *
- * @ingroup Session
- * @since 1.27
- */
-class CookieSessionProvider extends SessionProvider {
-
- protected $params = array();
- protected $cookieOptions = array();
-
- /**
- * @param array $params Keys include:
- * - priority: (required) Priority of the returned sessions
- * - callUserSetCookiesHook: Whether to call the deprecated hook
- * - sessionName: Session cookie name. Doesn't honor 'prefix'. Defaults to
- * $wgSessionName, or $wgCookiePrefix . '_session' if that is unset.
- * - cookieOptions: Options to pass to WebRequest::setCookie():
- * - prefix: Cookie prefix, defaults to $wgCookiePrefix
- * - path: Cookie path, defaults to $wgCookiePath
- * - domain: Cookie domain, defaults to $wgCookieDomain
- * - secure: Cookie secure flag, defaults to $wgCookieSecure
- * - httpOnly: Cookie httpOnly flag, defaults to $wgCookieHttpOnly
- */
- public function __construct( $params = array() ) {
- parent::__construct();
-
- $params += array(
- 'cookieOptions' => array(),
- // @codeCoverageIgnoreStart
- );
- // @codeCoverageIgnoreEnd
-
- if ( !isset( $params['priority'] ) ) {
- throw new \InvalidArgumentException( __METHOD__ . ': priority must be specified' );
- }
- if ( $params['priority'] < SessionInfo::MIN_PRIORITY ||
- $params['priority'] > SessionInfo::MAX_PRIORITY
- ) {
- throw new \InvalidArgumentException( __METHOD__ . ': Invalid priority' );
- }
-
- if ( !is_array( $params['cookieOptions'] ) ) {
- throw new \InvalidArgumentException( __METHOD__ . ': cookieOptions must be an array' );
- }
-
- $this->priority = $params['priority'];
- $this->cookieOptions = $params['cookieOptions'];
- $this->params = $params;
- unset( $this->params['priority'] );
- unset( $this->params['cookieOptions'] );
- }
-
- public function setConfig( Config $config ) {
- parent::setConfig( $config );
-
- // @codeCoverageIgnoreStart
- $this->params += array(
- // @codeCoverageIgnoreEnd
- 'callUserSetCookiesHook' => false,
- 'sessionName' =>
- $config->get( 'SessionName' ) ?: $config->get( 'CookiePrefix' ) . '_session',
- );
-
- // @codeCoverageIgnoreStart
- $this->cookieOptions += array(
- // @codeCoverageIgnoreEnd
- 'prefix' => $config->get( 'CookiePrefix' ),
- 'path' => $config->get( 'CookiePath' ),
- 'domain' => $config->get( 'CookieDomain' ),
- 'secure' => $config->get( 'CookieSecure' ),
- 'httpOnly' => $config->get( 'CookieHttpOnly' ),
- );
- }
-
- public function provideSessionInfo( WebRequest $request ) {
- $info = array(
- 'id' => $this->getCookie( $request, $this->params['sessionName'], '' ),
- 'provider' => $this,
- 'forceHTTPS' => $this->getCookie( $request, 'forceHTTPS', '', false )
- );
- if ( !SessionManager::validateSessionId( $info['id'] ) ) {
- unset( $info['id'] );
- }
- $info['persisted'] = isset( $info['id'] );
-
- list( $userId, $userName, $token ) = $this->getUserInfoFromCookies( $request );
- if ( $userId !== null ) {
- try {
- $userInfo = UserInfo::newFromId( $userId );
- } catch ( \InvalidArgumentException $ex ) {
- return null;
- }
-
- // Sanity check
- if ( $userName !== null && $userInfo->getName() !== $userName ) {
- return null;
- }
-
- if ( $token !== null ) {
- if ( !hash_equals( $userInfo->getToken(), $token ) ) {
- return null;
- }
- $info['userInfo'] = $userInfo->verified();
- } elseif ( isset( $info['id'] ) ) {
- $info['userInfo'] = $userInfo;
- } else {
- // No point in returning, loadSessionInfoFromStore() will
- // reject it anyway.
- return null;
- }
- } elseif ( isset( $info['id'] ) ) {
- // No UserID cookie, so insist that the session is anonymous.
- $info['userInfo'] = UserInfo::newAnonymous();
- } else {
- // No session ID and no user is the same as an empty session, so
- // there's no point.
- return null;
- }
-
- return new SessionInfo( $this->priority, $info );
- }
-
- public function persistsSessionId() {
- return true;
- }
-
- public function canChangeUser() {
- return true;
- }
-
- public function persistSession( SessionBackend $session, WebRequest $request ) {
- $response = $request->response();
- if ( $response->headersSent() ) {
- // Can't do anything now
- $this->logger->debug( __METHOD__ . ': Headers already sent' );
- return;
- }
-
- $user = $session->getUser();
-
- $cookies = $this->cookieDataToExport( $user, $session->shouldRememberUser() );
- $sessionData = $this->sessionDataToExport( $user );
-
- // Legacy hook
- if ( $this->params['callUserSetCookiesHook'] && !$user->isAnon() ) {
- \Hooks::run( 'UserSetCookies', array( $user, &$sessionData, &$cookies ) );
- }
-
- $options = $this->cookieOptions;
-
- $forceHTTPS = $session->shouldForceHTTPS() || $user->requiresHTTPS();
- if ( $forceHTTPS ) {
- // Don't set the secure flag if the request came in
- // over "http", for backwards compat.
- // @todo Break that backwards compat properly.
- $options['secure'] = $this->config->get( 'CookieSecure' );
- }
-
- $response->setCookie( $this->params['sessionName'], $session->getId(), null,
- array( 'prefix' => '' ) + $options
- );
-
- $extendedCookies = $this->config->get( 'ExtendedLoginCookies' );
- $extendedExpiry = $this->config->get( 'ExtendedLoginCookieExpiration' );
-
- foreach ( $cookies as $key => $value ) {
- if ( $value === false ) {
- $response->clearCookie( $key, $options );
- } else {
- if ( $extendedExpiry !== null && in_array( $key, $extendedCookies ) ) {
- $expiry = time() + (int)$extendedExpiry;
- } else {
- $expiry = 0; // Default cookie expiration
- }
- $response->setCookie( $key, (string)$value, $expiry, $options );
- }
- }
-
- $this->setForceHTTPSCookie( $forceHTTPS, $session, $request );
- $this->setLoggedOutCookie( $session->getLoggedOutTimestamp(), $request );
-
- if ( $sessionData ) {
- $session->addData( $sessionData );
- }
- }
-
- public function unpersistSession( WebRequest $request ) {
- $response = $request->response();
- if ( $response->headersSent() ) {
- // Can't do anything now
- $this->logger->debug( __METHOD__ . ': Headers already sent' );
- return;
- }
-
- $cookies = array(
- 'UserID' => false,
- 'Token' => false,
- );
-
- $response->clearCookie(
- $this->params['sessionName'], array( 'prefix' => '' ) + $this->cookieOptions
- );
-
- foreach ( $cookies as $key => $value ) {
- $response->clearCookie( $key, $this->cookieOptions );
- }
-
- $this->setForceHTTPSCookie( false, null, $request );
- }
-
- /**
- * Set the "forceHTTPS" cookie
- * @param bool $set Whether the cookie should be set or not
- * @param SessionBackend|null $backend
- * @param WebRequest $request
- */
- protected function setForceHTTPSCookie(
- $set, SessionBackend $backend = null, WebRequest $request
- ) {
- $response = $request->response();
- if ( $set ) {
- $response->setCookie( 'forceHTTPS', 'true', $backend->shouldRememberUser() ? 0 : null,
- array( 'prefix' => '', 'secure' => false ) + $this->cookieOptions );
- } else {
- $response->clearCookie( 'forceHTTPS',
- array( 'prefix' => '', 'secure' => false ) + $this->cookieOptions );
- }
- }
-
- /**
- * Set the "logged out" cookie
- * @param int $loggedOut timestamp
- * @param WebRequest $request
- */
- protected function setLoggedOutCookie( $loggedOut, WebRequest $request ) {
- if ( $loggedOut + 86400 > time() &&
- $loggedOut !== (int)$this->getCookie( $request, 'LoggedOut', $this->cookieOptions['prefix'] )
- ) {
- $request->response()->setCookie( 'LoggedOut', $loggedOut, $loggedOut + 86400,
- $this->cookieOptions );
- }
- }
-
- public function getVaryCookies() {
- return array(
- // Vary on token and session because those are the real authn
- // determiners. UserID and UserName don't matter without those.
- $this->cookieOptions['prefix'] . 'Token',
- $this->cookieOptions['prefix'] . 'LoggedOut',
- $this->params['sessionName'],
- 'forceHTTPS',
- );
- }
-
- public function suggestLoginUsername( WebRequest $request ) {
- $name = $this->getCookie( $request, 'UserName', $this->cookieOptions['prefix'] );
- if ( $name !== null ) {
- $name = User::getCanonicalName( $name, 'usable' );
- }
- return $name === false ? null : $name;
- }
-
- /**
- * Fetch the user identity from cookies
- * @param \WebRequest $request
- * @return array (string|null $id, string|null $username, string|null $token)
- */
- protected function getUserInfoFromCookies( $request ) {
- $prefix = $this->cookieOptions['prefix'];
- return array(
- $this->getCookie( $request, 'UserID', $prefix ),
- $this->getCookie( $request, 'UserName', $prefix ),
- $this->getCookie( $request, 'Token', $prefix ),
- );
- }
-
- /**
- * Get a cookie. Contains an auth-specific hack.
- * @param \WebRequest $request
- * @param string $key
- * @param string $prefix
- * @param mixed $default
- * @return mixed
- */
- protected function getCookie( $request, $key, $prefix, $default = null ) {
- $value = $request->getCookie( $key, $prefix, $default );
- if ( $value === 'deleted' ) {
- // PHP uses this value when deleting cookies. A legitimate cookie will never have
- // this value (usernames start with uppercase, token is longer, other auth cookies
- // are booleans or integers). Seeing this means that in a previous request we told the
- // client to delete the cookie, but it has poor cookie handling. Pretend the cookie is
- // not there to avoid invalidating the session.
- return null;
- }
- return $value;
- }
-
- /**
- * Return the data to store in cookies
- * @param User $user
- * @param bool $remember
- * @return array $cookies Set value false to unset the cookie
- */
- protected function cookieDataToExport( $user, $remember ) {
- if ( $user->isAnon() ) {
- return array(
- 'UserID' => false,
- 'Token' => false,
- );
- } else {
- return array(
- 'UserID' => $user->getId(),
- 'UserName' => $user->getName(),
- 'Token' => $remember ? (string)$user->getToken() : false,
- );
- }
- }
-
- /**
- * Return extra data to store in the session
- * @param User $user
- * @return array $session
- */
- protected function sessionDataToExport( $user ) {
- // If we're calling the legacy hook, we should populate $session
- // like User::setCookies() did.
- if ( !$user->isAnon() && $this->params['callUserSetCookiesHook'] ) {
- return array(
- 'wsUserID' => $user->getId(),
- 'wsToken' => $user->getToken(),
- 'wsUserName' => $user->getName(),
- );
- }
-
- return array();
- }
-
- public function whyNoSession() {
- return wfMessage( 'sessionprovider-nocookies' );
- }
-
-}