diff --git a/core/authorize.php b/core/authorize.php index e72b866..15194a8 100644 --- a/core/authorize.php +++ b/core/authorize.php @@ -46,7 +46,7 @@ * TRUE if the current user can run authorize.php, and FALSE if not. */ function authorize_access_allowed() { - \Drupal::service('session')->initialize(); + \Drupal::service('session_manager')->initialize(); return Settings::get('allow_authorize_operations', TRUE) && user_access('administer software updates'); } diff --git a/core/core.services.yml b/core/core.services.yml index 7b91ce7..d0ed6b2 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -718,8 +718,8 @@ services: arguments: ['@authentication'] calls: - [setRequest, ['@?request=']] - session: - class: Drupal\Core\Session\Session + session_manager: + class: Drupal\Core\Session\SessionManager arguments: ['@request', '@database'] tags: - { name: persist } diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index a704ebf..fa9ecef 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -2163,12 +2163,12 @@ function drupal_classloader_register($name, $path) { * * Example: * @code - * function drupal_session_started($set = NULL) { - * static $session_started = FALSE; - * if (isset($set)) { - * $session_started = $set; + * function mymodule_log_stream_handle($new_handle = NULL) { + * static $handle; + * if (isset($new_handle)) { + * $handle = $new_handle; * } - * return $session_started && session_id(); + * return $handle; * } * @endcode * diff --git a/core/includes/common.inc b/core/includes/common.inc index 9ec0e86..9ae983a 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -3048,7 +3048,7 @@ function drupal_get_private_key() { * * @see drupal_get_hash_salt() * @see \Drupal\Core\Access\CsrfTokenGenerator - * @see drupal_session_start() + * @see \Drupal\Core\Session\SessionManager::start() * * @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0. * Use \Drupal::csrfToken()->get(). diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index 88f9e0e..2db61fb 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -544,7 +544,7 @@ function install_run_task($task, &$install_state) { $response = batch_process(install_redirect_url($install_state), install_full_redirect_url($install_state)); if ($response instanceof Response) { // Save $_SESSION data from batch. - \Drupal::service('session')->save(); + \Drupal::service('session_manager')->save(); // Send the response. $response->send(); exit; @@ -1778,7 +1778,7 @@ function install_load_profile(&$install_state) { */ function install_bootstrap_full() { drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); - \Drupal::service('session')->initialize(); + \Drupal::service('session_manager')->initialize(); } /** diff --git a/core/lib/Drupal.php b/core/lib/Drupal.php index 7b9c326..3cf20c4 100644 --- a/core/lib/Drupal.php +++ b/core/lib/Drupal.php @@ -586,7 +586,7 @@ public static function languageManager() { * @return \Drupal\Core\Access\CsrfTokenGenerator * The CSRF token manager. * - * @see drupal_session_start() + * @see \Drupal\Core\Session\SessionManager::start() */ public static function csrfToken() { return static::$container->get('csrf_token'); diff --git a/core/lib/Drupal/Core/Access/CsrfTokenGenerator.php b/core/lib/Drupal/Core/Access/CsrfTokenGenerator.php index 527fffd..2e4e44d 100644 --- a/core/lib/Drupal/Core/Access/CsrfTokenGenerator.php +++ b/core/lib/Drupal/Core/Access/CsrfTokenGenerator.php @@ -69,7 +69,7 @@ public function setCurrentUser(AccountInterface $current_user = NULL) { * 'drupal_private_key' configuration variable. * * @see drupal_get_hash_salt() - * @see drupal_session_start() + * @see \Drupal\Core\Session\SessionManager::start() */ public function get($value = '') { return Crypt::hmacBase64($value, session_id() . $this->privateKey->get() . drupal_get_hash_salt()); diff --git a/core/lib/Drupal/Core/Authentication/Provider/Cookie.php b/core/lib/Drupal/Core/Authentication/Provider/Cookie.php index 308adb0..2158ecd 100644 --- a/core/lib/Drupal/Core/Authentication/Provider/Cookie.php +++ b/core/lib/Drupal/Core/Authentication/Provider/Cookie.php @@ -30,9 +30,7 @@ public function applies(Request $request) { public function authenticate(Request $request) { // Global $user is deprecated, but the session system is still based on it. global $user; - $session = \Drupal::service('session'); - $session->initialize(); - if ($session->isStarted()) { + if (\Drupal::service('session_manager')->initialize()->isStarted()) { return $user; } return NULL; @@ -42,7 +40,7 @@ public function authenticate(Request $request) { * {@inheritdoc} */ public function cleanup(Request $request) { - \Drupal::service('session')->save(); + \Drupal::service('session_manager')->save(); } /** diff --git a/core/lib/Drupal/Core/Cron.php b/core/lib/Drupal/Core/Cron.php index d481516..94cfc33 100644 --- a/core/lib/Drupal/Core/Cron.php +++ b/core/lib/Drupal/Core/Cron.php @@ -84,10 +84,9 @@ public function run() { @ignore_user_abort(TRUE); // Prevent session information from being saved while cron is running. - $session = \Drupal::service('session'); - $original_session_writing_enabled = $session->isEnabled(); - - $session->disable(); + $session_manager = \Drupal::service('session_manager'); + $original_session_saving = $session_manager->isEnabled(); + $session_manager->disable(); // Force the current user to anonymous to ensure consistent permissions on // cron runs. @@ -159,8 +158,8 @@ public function run() { // Restore the user. $this->currentUser->setAccount($original_user); - if ($original_session_writing_enabled) { - $session->enable(); + if ($original_session_saving) { + $session_manager->enable(); } return $return; diff --git a/core/lib/Drupal/Core/Session/SessionHandler.php b/core/lib/Drupal/Core/Session/SessionHandler.php index e44b1c1..3732712 100644 --- a/core/lib/Drupal/Core/Session/SessionHandler.php +++ b/core/lib/Drupal/Core/Session/SessionHandler.php @@ -19,6 +19,13 @@ class SessionHandler implements \SessionHandlerInterface { /** + * The session manager. + * + * @var \Drupal\Core\Session\SessionManager + */ + protected $sessionManager; + + /** * The request. * * @var \Symfony\Component\HttpFoundation\Request @@ -42,12 +49,15 @@ class SessionHandler implements \SessionHandlerInterface { /** * Constructs a new SessionHandler instance. * + * @param \Drupal\Core\Session\SessionManager $session_manager + * The session manager. * @param \Symfony\Component\HttpFoundation\Request $request * The current request. * @param \Drupal\Core\Database\Connection $connection * The database connection. */ - public function __construct(Request $request, Connection $connection) { + public function __construct(SessionManager $session_manager, Request $request, Connection $connection) { + $this->sessionManager = $session_manager; $this->request = $request; $this->connection = $connection; } @@ -143,7 +153,7 @@ public function write($sid, $value) { // The exception handler is not active at this point, so we need to do it // manually. try { - if (!\Drupal::service('session')->isEnabled()) { + if (!$this->sessionManager->isEnabled()) { // We don't have anything to do if we are not allowed to save the // session. return TRUE; @@ -165,8 +175,7 @@ public function write($sid, $value) { 'timestamp' => REQUEST_TIME, ); // Use the session ID as 'sid' and an empty string as 'ssid' by default. - // _drupal_session_read() does not allow empty strings so that's a safe - // default. + // read() does not allow empty strings so that's a safe default. $key = array('sid' => Crypt::hashBase64($sid), 'ssid' => ''); // On HTTPS connections, use the session ID as both 'sid' and 'ssid'. if ($this->request->isSecure()) { @@ -228,7 +237,7 @@ public function destroy($sid) { global $user; // Nothing to do if we are not allowed to change the session. - if (!\Drupal::service('session')->isEnabled()) { + if (!$this->sessionManager->isEnabled()) { return TRUE; } $is_https = $this->request->isSecure(); @@ -238,7 +247,7 @@ public function destroy($sid) { ->execute(); // Reset $_SESSION and $user to prevent a new session from being started - // in drupal_session_commit(). + // in \Drupal\Core\Session\SessionManager::save(). $_SESSION = array(); $user = new AnonymousUserSession(); diff --git a/core/lib/Drupal/Core/Session/Session.php b/core/lib/Drupal/Core/Session/SessionManager.php similarity index 96% rename from core/lib/Drupal/Core/Session/Session.php rename to core/lib/Drupal/Core/Session/SessionManager.php index b3047cc..1c357e6 100644 --- a/core/lib/Drupal/Core/Session/Session.php +++ b/core/lib/Drupal/Core/Session/SessionManager.php @@ -2,7 +2,7 @@ /** * @file - * User session handling functions. + * Contains \Drupal\Core\Session\SessionManager. */ namespace Drupal\Core\Session; @@ -14,7 +14,10 @@ use Drupal\Core\Session\SessionHandler; use Symfony\Component\HttpFoundation\Request; -class Session { +/** + * Manages user sessions. + */ +class SessionManager { /** * The master request of this process. @@ -65,13 +68,15 @@ public function __construct(Request $request, Connection $connection) { /** * Initializes the session handler, starting a session if needed. + * + * @return $this */ public function initialize() { global $user; // Register the default session handler. // @todo Extract session storage from session handler into a service. - $handler = new SessionHandler($this->request, $this->connection); + $handler = new SessionHandler($this, $this->request, $this->connection); session_set_save_handler($handler, TRUE); $is_https = $this->request->isSecure(); @@ -104,6 +109,8 @@ public function initialize() { } } date_default_timezone_set(drupal_get_user_timezone()); + + return $this; } /** @@ -234,7 +241,7 @@ public function migrate() { else { // Start the session when it doesn't exist yet. // Preserve the logged in user, as it will be reset to anonymous - // by _drupal_session_read. + // by \Drupal\Core\Session\SessionHandler::read(). $account = $user; $this->start(); $user = $account; @@ -243,6 +250,22 @@ public function migrate() { } /** + * Ends a specific user's session(s). + * + * @param int $uid + * User ID. + */ + public function delete($uid) { + // Nothing to do if we are not allowed to change the session. + if (!$this->isEnabled()) { + return; + } + $this->connection->delete('sessions') + ->condition('uid', $uid) + ->execute(); + } + + /** * Determines whether to save session data of the current request. * * @return bool @@ -289,25 +312,4 @@ protected function isCli() { return PHP_SAPI === 'cli'; } - /** - * Ends a specific user's session(s). - * - * @param $uid - * User ID. - * - * @return bool - * Returns FALSE if session wasn't ended. - */ - public function endUserSession($uid) { - // Nothing to do if we are not allowed to change the session. - if (!$this->isEnabled()) { - return FALSE; - } - $this->connection->delete('sessions') - ->condition('uid', $uid) - ->execute(); - - return TRUE; - } - } diff --git a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php index 982d0f1..e38cbfe 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php @@ -1026,7 +1026,7 @@ private function prepareEnvironment() { $this->originalUser = isset($user) ? clone $user : NULL; // Ensure that the current session is not changed by the new environment. - \Drupal::service('session')->disable(); + \Drupal::service('session_manager')->disable(); // Save and clean the shutdown callbacks array because it is static cached // and will be changed by the test run. Otherwise it will contain callbacks @@ -1255,7 +1255,7 @@ private function restoreEnvironment() { // Restore original user session. $this->container->set('current_user', $this->originalUser); - \Drupal::service('session')->enable(); + \Drupal::service('session_manager')->enable(); } /** diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php index 61c54d1..bccc5a9 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php @@ -698,8 +698,8 @@ protected function drupalUserIsLoggedIn($account) { if (!isset($account->session_id)) { return FALSE; } - // @see _drupal_session_read(). The session ID is hashed before being stored - // in the database. + // The session ID is hashed before being stored in the database. + // @see \Drupal\Core\Session\SessionHandler::read() return (bool) db_query("SELECT sid FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.sid = :sid", array(':sid' => Crypt::hashBase64($account->session_id)))->fetchField(); } diff --git a/core/modules/system/core.api.php b/core/modules/system/core.api.php index 04289c4..abfd85f 100644 --- a/core/modules/system/core.api.php +++ b/core/modules/system/core.api.php @@ -494,7 +494,6 @@ * @see mail.inc * @see php_wrappers * @see sanitization - * @see session.inc * @see transliteration * @see validation * @} diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/FormatDateTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/FormatDateTest.php index 21fa9fa..171b915 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Common/FormatDateTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Common/FormatDateTest.php @@ -128,7 +128,7 @@ function testFormatDate() { $this->drupalPostForm('user/' . $test_user->id() . '/edit', $edit, t('Save')); // Disable session saving as we are about to modify the global $user. - \Drupal::service('session')->disable(); + \Drupal::service('session_manager')->disable(); // Save the original user and language and then replace it with the test user and language. $real_user = $user; $user = user_load($test_user->id(), TRUE); @@ -158,6 +158,6 @@ function testFormatDate() { $language_interface->id = $real_language; // Restore default time zone. date_default_timezone_set(drupal_get_user_timezone()); - \Drupal::service('session')->enable(); + \Drupal::service('session_manager')->enable(); } } diff --git a/core/modules/system/lib/Drupal/system/Tests/Datetime/DrupalDateTimeTest.php b/core/modules/system/lib/Drupal/system/Tests/Datetime/DrupalDateTimeTest.php index 7d24761..8484a82 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Datetime/DrupalDateTimeTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Datetime/DrupalDateTimeTest.php @@ -100,7 +100,7 @@ public function testDateTimezone() { $this->drupalPostForm('user/' . $test_user->id() . '/edit', $edit, t('Save')); // Disable session saving as we are about to modify the global $user. - \Drupal::service('session')->disable(); + \Drupal::service('session_manager')->disable(); // Save the original user and then replace it with the test user. $real_user = $user; $user = user_load($test_user->id(), TRUE); @@ -119,7 +119,7 @@ public function testDateTimezone() { $user = $real_user; // Restore default time zone. date_default_timezone_set(drupal_get_user_timezone()); - \Drupal::service('session')->enable(); + \Drupal::service('session_manager')->enable(); } diff --git a/core/modules/system/lib/Drupal/system/Tests/Session/SessionTest.php b/core/modules/system/lib/Drupal/system/Tests/Session/SessionTest.php index 415932e..8a53800 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Session/SessionTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Session/SessionTest.php @@ -29,11 +29,13 @@ public static function getInfo() { } /** - * Tests for drupal_save_session() and drupal_session_regenerate(). + * Tests for \Drupal\Core\Session\SessionManager::isEnabled() and ::migrate(). */ function testSessionSaveRegenerate() { - $this->assertFalse(\Drupal::service('session')->isEnabled(),'\Drupal::service(\'session\')->isEnabled() correctly returns FALSE (inside of testing framework) when initially called with no arguments.', 'Session'); - $this->assertTrue(\Drupal::service('session')->disable()->isEnabled(), '\Drupal::service(\'session\')->isEnabled() correctly returns TRUE when saving has been enabled.', 'Session'); + $session_manager = $this->container->get('session_manager'); + $this->assertFalse($session_manager->isEnabled(), 'SessionManager->isEnabled() initially returns FALSE (in testing framework).'); + $this->assertFalse($session_manager->disable()->isEnabled(), 'SessionManager->isEnabled() returns FALSE after disabling.'); + $this->assertTrue($session_manager->enable()->isEnabled(), 'SessionManager->isEnabled() returns TRUE after enabling.'); // Test session hardening code from SA-2008-044. $user = $this->drupalCreateUser(); diff --git a/core/modules/system/tests/modules/session_test/lib/Drupal/session_test/Controller/SessionTestController.php b/core/modules/system/tests/modules/session_test/lib/Drupal/session_test/Controller/SessionTestController.php index 4792bfa..5fbd412 100644 --- a/core/modules/system/tests/modules/session_test/lib/Drupal/session_test/Controller/SessionTestController.php +++ b/core/modules/system/tests/modules/session_test/lib/Drupal/session_test/Controller/SessionTestController.php @@ -35,11 +35,11 @@ public function get() { * A notification message with session ID. */ public function getId() { - // Set a value in $_SESSION, so that drupal_session_commit() will start + // Set a value in $_SESSION, so that SessionManager::save() will start // a session. $_SESSION['test'] = 'test'; - \Drupal::service('session')->save(); + \Drupal::service('session_manager')->save(); return 'session_id:' . session_id() . "\n"; } @@ -83,7 +83,7 @@ public function set($test_value) { * A notification message. */ public function noSet($test_value) { - \Drupal::service('session')->disable(); + \Drupal::service('session_manager')->disable(); $this->set($test_value); return $this->t('session saving was disabled, and then %val was set', array('%val' => $test_value)); } @@ -109,7 +109,7 @@ public function setMessage() { * A notification message. */ public function setMessageButDontSave() { - \Drupal::service('session')->disable(); + \Drupal::service('session_manager')->disable(); $this->setMessage(); } diff --git a/core/modules/user/lib/Drupal/user/Entity/User.php b/core/modules/user/lib/Drupal/user/Entity/User.php index c122353..594559e 100644 --- a/core/modules/user/lib/Drupal/user/Entity/User.php +++ b/core/modules/user/lib/Drupal/user/Entity/User.php @@ -123,13 +123,13 @@ public function postSave(EntityStorageInterface $storage, $update = TRUE) { parent::postSave($storage, $update); if ($update) { + $session_manager = \Drupal::service('session_manager'); // If the password has been changed, delete all open sessions for the // user and recreate the current one. if ($this->pass->value != $this->original->pass->value) { - $session = \Drupal::service('session'); - $session->endUserSession($this->id()); + $session_manager->delete($this->id()); if ($this->id() == \Drupal::currentUser()->id()) { - drupal_session_regenerate(); + $session_manager->migrate(); } } @@ -141,7 +141,7 @@ public function postSave(EntityStorageInterface $storage, $update = TRUE) { // If the user was blocked, delete the user's sessions to force a logout. if ($this->original->status->value != $this->status->value && $this->status->value == 0) { - \Drupal::service('session')->endUserSession($this->id()); + $session_manager->delete($this->id()); } // Send emails after we have the new user object. diff --git a/core/modules/user/lib/Drupal/user/Tests/Views/ArgumentDefaultTest.php b/core/modules/user/lib/Drupal/user/Tests/Views/ArgumentDefaultTest.php index 4c61149..c8de3a3 100644 --- a/core/modules/user/lib/Drupal/user/Tests/Views/ArgumentDefaultTest.php +++ b/core/modules/user/lib/Drupal/user/Tests/Views/ArgumentDefaultTest.php @@ -37,7 +37,7 @@ public function test_plugin_argument_default_current_user() { $this->drupalLogin($account); global $user; $admin = $user; - $session = \Drupal::service('session')->disable(); + $session_manager = \Drupal::service('session_manager')->disable(); $user = $account; $view = Views::getView('test_plugin_argument_default_current_user'); @@ -46,7 +46,7 @@ public function test_plugin_argument_default_current_user() { $this->assertEqual($view->argument['null']->getDefaultArgument(), $account->id(), 'Uid of the current user is used.'); // Switch back. $user = $admin; - $session->enable(); + $session_manager->enable(); } } diff --git a/core/modules/user/user.module b/core/modules/user/user.module index 216d55d..a8096fb 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -820,7 +820,7 @@ function user_login_finalize(UserInterface $account) { // Regenerate the session ID to prevent against session fixation attacks. // This is called before hook_user in case one of those functions fails // or incorrectly does a redirect which would leave the old session in place. - \Drupal::service('session')->migrate(); + \Drupal::service('session_manager')->migrate(); \Drupal::moduleHandler()->invokeAll('user_login', array($account)); } @@ -1038,7 +1038,7 @@ function _user_cancel($edit, $account, $method) { function _user_cancel_session_regenerate() { // Regenerate the users session instead of calling session_destroy() as we // want to preserve any messages that might have been set. - drupal_session_regenerate(); + \Drupal::service('session_manager')->migrate(); } /** diff --git a/core/update.php b/core/update.php index 09f60f6..49b6aa1 100644 --- a/core/update.php +++ b/core/update.php @@ -345,7 +345,7 @@ function update_task_list($active = NULL) { // Determine if the current user has access to run update.php. drupal_bootstrap(DRUPAL_BOOTSTRAP_PAGE_CACHE); -\Drupal::service('session')->initialize(); +\Drupal::service('session_manager')->initialize(); // Ensure that URLs generated for the home and admin pages don't have 'update.php' // in them. @@ -448,7 +448,7 @@ function update_task_list($active = NULL) { } if (isset($output) && $output) { // Explicitly start a session so that the update.php token will be accepted. - \Drupal::service('session')->start(); + \Drupal::service('session_manager')->start(); // We defer the display of messages until all updates are done. $progress_page = ($batch = batch_get()) && isset($batch['running']); if ($output instanceof Response) {