From 2641b7a9ecddc322a79c56a5f678fcebb4a1c8cb Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Wed, 14 Feb 2018 18:14:13 -0600 Subject: [PATCH 1/7] Session garbage collection plugin --- .../sql/updates/mysql/3.8.6-2018-02-14.sql | 2 + .../updates/postgresql/3.8.6-2018-02-14.sql | 2 + .../sql/updates/sqlazure/3.8.6-2018-02-14.sql | 2 + .../en-GB/en-GB.plg_system_sessiongc.ini | 13 ++++ .../en-GB/en-GB.plg_system_sessiongc.sys.ini | 7 +++ installation/sql/mysql/joomla.sql | 1 + installation/sql/postgresql/joomla.sql | 1 + installation/sql/sqlazure/joomla.sql | 1 + plugins/system/sessiongc/sessiongc.php | 43 +++++++++++++ plugins/system/sessiongc/sessiongc.xml | 61 +++++++++++++++++++ 10 files changed, 133 insertions(+) create mode 100644 administrator/components/com_admin/sql/updates/mysql/3.8.6-2018-02-14.sql create mode 100644 administrator/components/com_admin/sql/updates/postgresql/3.8.6-2018-02-14.sql create mode 100644 administrator/components/com_admin/sql/updates/sqlazure/3.8.6-2018-02-14.sql create mode 100644 administrator/language/en-GB/en-GB.plg_system_sessiongc.ini create mode 100644 administrator/language/en-GB/en-GB.plg_system_sessiongc.sys.ini create mode 100644 plugins/system/sessiongc/sessiongc.php create mode 100644 plugins/system/sessiongc/sessiongc.xml diff --git a/administrator/components/com_admin/sql/updates/mysql/3.8.6-2018-02-14.sql b/administrator/components/com_admin/sql/updates/mysql/3.8.6-2018-02-14.sql new file mode 100644 index 0000000000000..20749c6bcc0c1 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/3.8.6-2018-02-14.sql @@ -0,0 +1,2 @@ +INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `manifest_cache`, `params`, `custom_data`, `system_data`, `checked_out`, `checked_out_time`, `ordering`, `state`) VALUES +(480, 0, 'plg_system_sessiongc', 'plugin', 'sessiongc', 'system', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/3.8.6-2018-02-14.sql b/administrator/components/com_admin/sql/updates/postgresql/3.8.6-2018-02-14.sql new file mode 100644 index 0000000000000..76d9539bb0c41 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/3.8.6-2018-02-14.sql @@ -0,0 +1,2 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(480, 0, 'plg_system_sessiongc', 'plugin', 'sessiongc', 'system', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/sqlazure/3.8.6-2018-02-14.sql b/administrator/components/com_admin/sql/updates/sqlazure/3.8.6-2018-02-14.sql new file mode 100644 index 0000000000000..2fb39894e3108 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/sqlazure/3.8.6-2018-02-14.sql @@ -0,0 +1,2 @@ +INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "manifest_cache", "params", "custom_data", "system_data", "checked_out", "checked_out_time", "ordering", "state") VALUES +(480, 0, 'plg_system_sessiongc', 'plugin', 'sessiongc', 'system', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0); diff --git a/administrator/language/en-GB/en-GB.plg_system_sessiongc.ini b/administrator/language/en-GB/en-GB.plg_system_sessiongc.ini new file mode 100644 index 0000000000000..f53d1e20be38a --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_system_sessiongc.ini @@ -0,0 +1,13 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_SESSIONGC="System - Session Garbage Collection" +PLG_SYSTEM_SESSIONGC_ENABLE_SESSION_GC_DESC="When enabled, this plugin will attempt to perform session garbage collection based on the odds calculated by the probability and divisor." +PLG_SYSTEM_SESSIONGC_ENABLE_SESSION_GC_LABEL="Enable Session Garbage Collection" +PLG_SYSTEM_SESSIONGC_GC_DIVISOR_DESC="Used in combination with the probability field, these two fields are used to determine the odds of the garbage collection operation being triggered on a request. The probability is calculated by using probability/divisor, e.g. 1/100 means there is a 1% chance that the process runs on each request." +PLG_SYSTEM_SESSIONGC_GC_DIVISOR_LABEL="Divisor" +PLG_SYSTEM_SESSIONGC_GC_PROBABILITY_DESC="Used in combination with the divisor field, these two fields are used to determine the odds of the garbage collection operation being triggered on a request." +PLG_SYSTEM_SESSIONGC_GC_PROBABILITY_LABEL="Probability" +PLG_SYSTEM_SESSIONGC_XML_DESCRIPTION="System Plugin that handles session garbage collection tasks." diff --git a/administrator/language/en-GB/en-GB.plg_system_sessiongc.sys.ini b/administrator/language/en-GB/en-GB.plg_system_sessiongc.sys.ini new file mode 100644 index 0000000000000..d33c6c3c5d031 --- /dev/null +++ b/administrator/language/en-GB/en-GB.plg_system_sessiongc.sys.ini @@ -0,0 +1,7 @@ +; Joomla! Project +; Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. +; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php +; Note : All ini files need to be saved as UTF-8 + +PLG_SYSTEM_SESSIONGC="System - Session Garbage Collection" +PLG_SYSTEM_SESSIONGC_XML_DESCRIPTION="System Plugin that handles session garbage collection tasks." diff --git a/installation/sql/mysql/joomla.sql b/installation/sql/mysql/joomla.sql index 32d131a542bf0..6b5173c4946a3 100644 --- a/installation/sql/mysql/joomla.sql +++ b/installation/sql/mysql/joomla.sql @@ -642,6 +642,7 @@ INSERT INTO `#__extensions` (`extension_id`, `package_id`, `name`, `type`, `elem (477, 0, 'plg_content_fields', 'plugin', 'fields', 'content', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), (478, 0, 'plg_editors-xtd_fields', 'plugin', 'fields', 'editors-xtd', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), (479, 0, 'plg_sampledata_blog', 'plugin', 'blog', 'sampledata', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), +(480, 0, 'plg_system_sessiongc', 'plugin', 'sessiongc', 'system', 0, 1, 1, 0, '', '', '', '', 0, '0000-00-00 00:00:00', 0, 0), (503, 0, 'beez3', 'template', 'beez3', '', 0, 1, 1, 0, '', '{"wrapperSmall":"53","wrapperLarge":"72","sitetitle":"","sitedescription":"","navposition":"center","templatecolor":"nature"}', '', '', 0, '0000-00-00 00:00:00', 0, 0), (504, 0, 'hathor', 'template', 'hathor', '', 1, 1, 1, 0, '', '{"showSiteName":"0","colourChoice":"0","boldText":"0"}', '', '', 0, '0000-00-00 00:00:00', 0, 0), (506, 0, 'protostar', 'template', 'protostar', '', 0, 1, 1, 0, '', '{"templateColor":"","logoFile":"","googleFont":"1","googleFontName":"Open+Sans","fluidContainer":"0"}', '', '', 0, '0000-00-00 00:00:00', 0, 0), diff --git a/installation/sql/postgresql/joomla.sql b/installation/sql/postgresql/joomla.sql index abfa4e5ce739f..74ad9ba46863f 100644 --- a/installation/sql/postgresql/joomla.sql +++ b/installation/sql/postgresql/joomla.sql @@ -656,6 +656,7 @@ INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "elem (477, 0, 'plg_content_fields', 'plugin', 'fields', 'content', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), (478, 0, 'plg_editors-xtd_fields', 'plugin', 'fields', 'editors-xtd', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), (479, 0, 'plg_sampledata_blog', 'plugin', 'blog', 'sampledata', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), +(480, 0, 'plg_system_sessiongc', 'plugin', 'sessiongc', 'system', 0, 1, 1, 0, '', '', '', '', 0, '1970-01-01 00:00:00', 0, 0), (503, 0, 'beez3', 'template', 'beez3', '', 0, 1, 1, 0, '', '{"wrapperSmall":"53","wrapperLarge":"72","sitetitle":"","sitedescription":"","navposition":"center","templatecolor":"nature"}', '', '', 0, '1970-01-01 00:00:00', 0, 0), (504, 0, 'hathor', 'template', 'hathor', '', 1, 1, 1, 0, '', '{"showSiteName":"0","colourChoice":"0","boldText":"0"}', '', '', 0, '1970-01-01 00:00:00', 0, 0), (506, 0, 'protostar', 'template', 'protostar', '', 0, 1, 1, 0, '', '{"templateColor":"","logoFile":"","googleFont":"1","googleFontName":"Open+Sans","fluidContainer":"0"}', '', '', 0, '1970-01-01 00:00:00', 0, 0), diff --git a/installation/sql/sqlazure/joomla.sql b/installation/sql/sqlazure/joomla.sql index a7d4a96fbbe91..99e73fe5afc7d 100644 --- a/installation/sql/sqlazure/joomla.sql +++ b/installation/sql/sqlazure/joomla.sql @@ -871,6 +871,7 @@ INSERT INTO "#__extensions" ("extension_id", "package_id", "name", "type", "elem (477, 0, 'plg_content_fields', 'plugin', 'fields', 'content', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0), (478, 0, 'plg_editors-xtd_fields', 'plugin', 'fields', 'editors-xtd', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0), (479, 0, 'plg_sampledata_blog', 'plugin', 'blog', 'sampledata', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0), +(480, 0, 'plg_system_sessiongc', 'plugin', 'sessiongc', 'system', 0, 1, 1, 0, '', '', '', '', 0, '1900-01-01 00:00:00', 0, 0), (503, 0, 'beez3', 'template', 'beez3', '', 0, 1, 1, 0, '', '{"wrapperSmall":"53","wrapperLarge":"72","sitetitle":"","sitedescription":"","navposition":"center","templatecolor":"nature"}', '', '', 0, '1900-01-01 00:00:00', 0, 0), (504, 0, 'hathor', 'template', 'hathor', '', 1, 1, 1, 0, '', '{"showSiteName":"0","colourChoice":"0","boldText":"0"}', '', '', 0, '1900-01-01 00:00:00', 0, 0), (506, 0, 'protostar', 'template', 'protostar', '', 0, 1, 1, 0, '', '{"templateColor":"","logoFile":"","googleFont":"1","googleFontName":"Open+Sans","fluidContainer":"0"}', '', '', 0, '1900-01-01 00:00:00', 0, 0), diff --git a/plugins/system/sessiongc/sessiongc.php b/plugins/system/sessiongc/sessiongc.php new file mode 100644 index 0000000000000..fa6dd01de3eb5 --- /dev/null +++ b/plugins/system/sessiongc/sessiongc.php @@ -0,0 +1,43 @@ +params->get('enable_session_gc', true)) + { + $probability = $this->params->get('gc_probability', 1); + $divisor = $this->params->get('gc_divisor', 100); + + $random = $divisor * lcg_value(); + + if ($probability > 0 && $random < $probability) + { + JFactory::getSession()->gc(); + } + } + } +} diff --git a/plugins/system/sessiongc/sessiongc.xml b/plugins/system/sessiongc/sessiongc.xml new file mode 100644 index 0000000000000..17140fa304700 --- /dev/null +++ b/plugins/system/sessiongc/sessiongc.xml @@ -0,0 +1,61 @@ + + + plg_system_sessiongc + Joomla! Project + February 2018 + Copyright (C) 2005 - 2018 Open Source Matters. All rights reserved. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + __DEPLOY_VERSION__ + PLG_SYSTEM_SESSIONGC_XML_DESCRIPTION + + sessiongc.php + + + en-GB/en-GB.plg_system_sessiongc.ini + en-GB/en-GB.plg_system_sessiongc.sys.ini + + + +
+ + + + + + + + +
+
+
+
From 83fabd141089a310c437a97d79e0ab283a5cad4b Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Wed, 14 Feb 2018 18:17:40 -0600 Subject: [PATCH 2/7] Session metadata manager --- libraries/src/Application/CMSApplication.php | 94 ++--------- libraries/src/Session/MetadataManager.php | 159 +++++++++++++++++++ 2 files changed, 175 insertions(+), 78 deletions(-) create mode 100644 libraries/src/Session/MetadataManager.php diff --git a/libraries/src/Application/CMSApplication.php b/libraries/src/Application/CMSApplication.php index 4989bac2e5fe3..281833322d307 100644 --- a/libraries/src/Application/CMSApplication.php +++ b/libraries/src/Application/CMSApplication.php @@ -11,6 +11,7 @@ defined('JPATH_PLATFORM') or die; use Joomla\CMS\Input\Input; +use Joomla\CMS\Session\MetadataManager; use Joomla\Registry\Registry; /** @@ -62,6 +63,14 @@ class CMSApplication extends WebApplication */ protected $_messageQueue = array(); + /** + * The session metadata manager + * + * @var MetadataManager + * @since __DEPLOY_VERSION__ + */ + protected $metadataManager = null; + /** * The name of the application. * @@ -106,6 +115,8 @@ public function __construct(Input $input = null, Registry $config = null, \JAppl { parent::__construct($input, $config, $client); + $this->metadataManager = new MetadataManager($this, \JFactory::getDbo()); + // Load and set the dispatcher $this->loadDispatcher(); @@ -159,30 +170,13 @@ public function afterSessionStart() // If the database session handler is not in use and the current time is a divisor of 5, purge session metadata after the response is sent if ($handler !== 'database' && $time % 5 === 0) { + $manager = $this->metadataManager; + $this->registerEvent( 'onAfterRespond', - function () use ($session, $time) + function () use ($session, $time, $manager) { - // TODO: At some point we need to get away from having session data always in the db. - $db = \JFactory::getDbo(); - - $query = $db->getQuery(true) - ->delete($db->quoteName('#__session')) - ->where($db->quoteName('time') . ' < ' . $db->quote((int) ($time - $session->getExpire()))); - - $db->setQuery($query); - - try - { - $db->execute(); - } - catch (\JDatabaseExceptionExecuting $exception) - { - /* - * The database API logs errors on failures so we don't need to add any error handling mechanisms here. - * Since garbage collection does not result in a fatal error when run in the session API, we don't allow it here either. - */ - } + $manager->deletePriorTo((int) ($time - $session->getExpire())); } ); } @@ -201,63 +195,7 @@ function () use ($session, $time) */ public function checkSession() { - $db = \JFactory::getDbo(); - $session = \JFactory::getSession(); - $user = \JFactory::getUser(); - - $query = $db->getQuery(true) - ->select($db->quoteName('session_id')) - ->from($db->quoteName('#__session')) - ->where($db->quoteName('session_id') . ' = ' . $db->quote($session->getId())); - - $db->setQuery($query, 0, 1); - $exists = $db->loadResult(); - - // If the session record doesn't exist initialise it. - if (!$exists) - { - $query->clear(); - - $time = $session->isNew() ? time() : $session->get('session.timer.start'); - - $columns = array( - $db->quoteName('session_id'), - $db->quoteName('guest'), - $db->quoteName('time'), - $db->quoteName('userid'), - $db->quoteName('username'), - ); - - $values = array( - $db->quote($session->getId()), - (int) $user->guest, - $db->quote((int) $time), - (int) $user->id, - $db->quote($user->username), - ); - - if (!$this->get('shared_session', '0')) - { - $columns[] = $db->quoteName('client_id'); - $values[] = (int) $this->getClientId(); - } - - $query->insert($db->quoteName('#__session')) - ->columns($columns) - ->values(implode(', ', $values)); - - $db->setQuery($query); - - // If the insert failed, exit the application. - try - { - $db->execute(); - } - catch (\RuntimeException $e) - { - throw new \RuntimeException(\JText::_('JERROR_SESSION_STARTUP'), $e->getCode(), $e); - } - } + $this->metadataManager->createRecordIfNonExisting(\JFactory::getSession(), \JFactory::getUser()); } /** diff --git a/libraries/src/Session/MetadataManager.php b/libraries/src/Session/MetadataManager.php new file mode 100644 index 0000000000000..ee358e4b48852 --- /dev/null +++ b/libraries/src/Session/MetadataManager.php @@ -0,0 +1,159 @@ +app = $app; + $this->db = $db; + } + + /** + * Create the metadata record if it does not exist. + * + * @param Session $session The session to create the metadata record for. + * @param User $user The user to associate with the record. + * + * @return void + * + * @since __DEPLOY_VERSION__ + * @throws \RuntimeException + */ + public function createRecordIfNonExisting(Session $session, User $user) + { + $query = $this->db->getQuery(true) + ->select($this->db->quoteName('session_id')) + ->from($this->db->quoteName('#__session')) + ->where($this->db->quoteName('session_id') . ' = ' . $this->db->quote($session->getId())); + + $this->db->setQuery($query, 0, 1); + $exists = $this->db->loadResult(); + + // If the session record doesn't exist initialise it. + if ($exists) + { + return; + } + + $query->clear(); + + $time = $session->isNew() ? time() : $session->get('session.timer.start'); + + $columns = array( + $this->db->quoteName('session_id'), + $this->db->quoteName('guest'), + $this->db->quoteName('time'), + $this->db->quoteName('userid'), + $this->db->quoteName('username'), + ); + + $values = array( + $this->db->quote($session->getId()), + (int) $user->guest, + $this->db->quote((int) $time), + (int) $user->id, + $this->db->quote($user->username), + ); + + if (!$this->app->get('shared_session', '0')) + { + $columns[] = $this->db->quoteName('client_id'); + $values[] = (int) $this->app->getClientId(); + } + + $query->insert($this->db->quoteName('#__session')) + ->columns($columns) + ->values(implode(', ', $values)); + + $this->db->setQuery($query); + + try + { + $this->db->execute(); + } + catch (\RuntimeException $e) + { + /* + * Because of how our session handlers are structured, we must abort the request if this insert query fails, + * especially in the case of the database handler which does not support "INSERT or UPDATE" logic. With the + * change to the `joomla/session` Framework package in 4.0, where the required logic is implemented in the + * handlers, we can change this catch block so that the error is gracefully handled and does not result + * in a fatal error for the request. + */ + throw new \RuntimeException(\JText::_('JERROR_SESSION_STARTUP'), $e->getCode(), $e); + } + } + + /** + * Delete records with a timestamp prior to the given time. + * + * @param integer $time The time records should be deleted if expired before. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function deletePriorTo($time) + { + $query = $this->db->getQuery(true) + ->delete($this->db->quoteName('#__session')) + ->where($this->db->quoteName('time') . ' < ' . $this->db->quote($time)); + + $this->db->setQuery($query); + + try + { + $this->db->execute(); + } + catch (\JDatabaseExceptionExecuting $exception) + { + /* + * The database API logs errors on failures so we don't need to add any error handling mechanisms here. + * Since garbage collection does not result in a fatal error when run in the session API, we don't allow it here either. + */ + } + } +} From 2dd4f659faa6b5df4248f36f740c03698e9d4b10 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Wed, 14 Feb 2018 18:21:29 -0600 Subject: [PATCH 3/7] Expand metadata manager to allow all apps, CLI for metadata cleaner --- cli/sessionMetadataGc.php | 59 +++++++++++++++++++++++ libraries/src/Session/MetadataManager.php | 11 +++-- 2 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 cli/sessionMetadataGc.php diff --git a/cli/sessionMetadataGc.php b/cli/sessionMetadataGc.php new file mode 100644 index 0000000000000..4b51fdb28c72c --- /dev/null +++ b/cli/sessionMetadataGc.php @@ -0,0 +1,59 @@ +getExpire(); + + $metadataManager->deletePriorTo(time() - $sessionExpire); + } +} + +JApplicationCli::getInstance('SessionMetadataGc')->execute(); diff --git a/libraries/src/Session/MetadataManager.php b/libraries/src/Session/MetadataManager.php index ee358e4b48852..4ca837bc07d22 100644 --- a/libraries/src/Session/MetadataManager.php +++ b/libraries/src/Session/MetadataManager.php @@ -10,6 +10,7 @@ defined('JPATH_PLATFORM') or die; +use Joomla\Application\AbstractApplication; use Joomla\CMS\Application\CMSApplication; use Joomla\CMS\User\User; @@ -24,7 +25,7 @@ final class MetadataManager /** * Application object. * - * @var CMSApplication + * @var AbstractApplication * @since __DEPLOY_VERSION__ */ private $app; @@ -40,12 +41,12 @@ final class MetadataManager /** * MetadataManager constructor. * - * @param CMSApplication $app Application object. - * @param \JDatabaseDriver $db Database driver. + * @param AbstractApplication $app Application object. + * @param \JDatabaseDriver $db Database driver. * * @since __DEPLOY_VERSION__ */ - public function __construct(CMSApplication $app, \JDatabaseDriver $db) + public function __construct(AbstractApplication $app, \JDatabaseDriver $db) { $this->app = $app; $this->db = $db; @@ -98,7 +99,7 @@ public function createRecordIfNonExisting(Session $session, User $user) $this->db->quote($user->username), ); - if (!$this->app->get('shared_session', '0')) + if ($this->app instanceof CMSApplication && !$this->app->get('shared_session', '0')) { $columns[] = $this->db->quoteName('client_id'); $values[] = (int) $this->app->getClientId(); From a93b027bec80d7aedc49a03e3b708b5ad073268e Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Wed, 14 Feb 2018 18:31:39 -0600 Subject: [PATCH 4/7] Move metadata cleanup to the plugin --- .../en-GB/en-GB.plg_system_sessiongc.ini | 2 + libraries/src/Application/CMSApplication.php | 37 ------------------- plugins/system/sessiongc/sessiongc.php | 37 ++++++++++++++++++- plugins/system/sessiongc/sessiongc.xml | 17 ++++++++- 4 files changed, 53 insertions(+), 40 deletions(-) diff --git a/administrator/language/en-GB/en-GB.plg_system_sessiongc.ini b/administrator/language/en-GB/en-GB.plg_system_sessiongc.ini index f53d1e20be38a..e147deedddd41 100644 --- a/administrator/language/en-GB/en-GB.plg_system_sessiongc.ini +++ b/administrator/language/en-GB/en-GB.plg_system_sessiongc.ini @@ -6,6 +6,8 @@ PLG_SYSTEM_SESSIONGC="System - Session Garbage Collection" PLG_SYSTEM_SESSIONGC_ENABLE_SESSION_GC_DESC="When enabled, this plugin will attempt to perform session garbage collection based on the odds calculated by the probability and divisor." PLG_SYSTEM_SESSIONGC_ENABLE_SESSION_GC_LABEL="Enable Session Garbage Collection" +PLG_SYSTEM_SESSIONGC_ENABLE_SESSION_METADATA_GC_DESC="When enabled, this plugin will clean optional session metadata from the database. Note that this operation will not run when the database handler is in use as that data is cleared as part of the garbage collection operation." +PLG_SYSTEM_SESSIONGC_ENABLE_SESSION_METADATA_GC_LABEL="Enable Session Metadata Cleanup" PLG_SYSTEM_SESSIONGC_GC_DIVISOR_DESC="Used in combination with the probability field, these two fields are used to determine the odds of the garbage collection operation being triggered on a request. The probability is calculated by using probability/divisor, e.g. 1/100 means there is a 1% chance that the process runs on each request." PLG_SYSTEM_SESSIONGC_GC_DIVISOR_LABEL="Divisor" PLG_SYSTEM_SESSIONGC_GC_PROBABILITY_DESC="Used in combination with the divisor field, these two fields are used to determine the odds of the garbage collection operation being triggered on a request." diff --git a/libraries/src/Application/CMSApplication.php b/libraries/src/Application/CMSApplication.php index 281833322d307..f442cb7b38b12 100644 --- a/libraries/src/Application/CMSApplication.php +++ b/libraries/src/Application/CMSApplication.php @@ -145,43 +145,6 @@ public function __construct(Input $input = null, Registry $config = null, \JAppl } } - /** - * After the session has been started we need to populate it with some default values. - * - * @return void - * - * @since 3.2 - */ - public function afterSessionStart() - { - $session = \JFactory::getSession(); - - if ($session->isNew()) - { - $session->set('registry', new Registry); - $session->set('user', new \JUser); - } - - // Get the session handler from the configuration. - $handler = $this->get('session_handler', 'none'); - - $time = time(); - - // If the database session handler is not in use and the current time is a divisor of 5, purge session metadata after the response is sent - if ($handler !== 'database' && $time % 5 === 0) - { - $manager = $this->metadataManager; - - $this->registerEvent( - 'onAfterRespond', - function () use ($session, $time, $manager) - { - $manager->deletePriorTo((int) ($time - $session->getExpire())); - } - ); - } - } - /** * Checks the user session. * diff --git a/plugins/system/sessiongc/sessiongc.php b/plugins/system/sessiongc/sessiongc.php index fa6dd01de3eb5..329154411ebfe 100644 --- a/plugins/system/sessiongc/sessiongc.php +++ b/plugins/system/sessiongc/sessiongc.php @@ -9,7 +9,10 @@ defined('_JEXEC') or die; +use Joomla\CMS\Application\CMSApplication; +use Joomla\CMS\Factory; use Joomla\CMS\Plugin\CMSPlugin; +use Joomla\CMS\Session\MetadataManager; /** * Garbage collection handler for session related data @@ -18,6 +21,22 @@ */ class PlgSystemSessionGc extends CMSPlugin { + /** + * Application object + * + * @var CMSApplication + * @since __DEPLOY_VERSION__ + */ + protected $app; + + /** + * Database driver + * + * @var JDatabaseDriver + * @since __DEPLOY_VERSION__ + */ + protected $db; + /** * Runs after the HTTP response has been sent to the client and performs garbage collection tasks * @@ -27,6 +46,8 @@ class PlgSystemSessionGc extends CMSPlugin */ public function onAfterRespond() { + $session = Factory::getSession(); + if ($this->params->get('enable_session_gc', true)) { $probability = $this->params->get('gc_probability', 1); @@ -36,7 +57,21 @@ public function onAfterRespond() if ($probability > 0 && $random < $probability) { - JFactory::getSession()->gc(); + $session->gc(); + } + } + + if ($this->app->get('session_handler', 'none') !== 'database' && $this->params->get('enable_session_metadata_gc', true)) + { + $probability = $this->params->get('gc_probability', 1); + $divisor = $this->params->get('gc_divisor', 100); + + $random = $divisor * lcg_value(); + + if ($probability > 0 && $random < $probability) + { + $metadataManager = new MetadataManager($this->app, $this->db); + $metadataManager->deletePriorTo(time() - $session->getExpire()); } } } diff --git a/plugins/system/sessiongc/sessiongc.xml b/plugins/system/sessiongc/sessiongc.xml index 17140fa304700..76cb22b0c207f 100644 --- a/plugins/system/sessiongc/sessiongc.xml +++ b/plugins/system/sessiongc/sessiongc.xml @@ -32,6 +32,19 @@ + + + + + From 36c92deed10b32bf610975d26bb1becec3281caf Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Tue, 20 Feb 2018 18:01:53 -0600 Subject: [PATCH 5/7] Misc fixes from feedback --- administrator/language/en-GB/en-GB.plg_system_sessiongc.ini | 4 ++-- cli/sessionMetadataGc.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/administrator/language/en-GB/en-GB.plg_system_sessiongc.ini b/administrator/language/en-GB/en-GB.plg_system_sessiongc.ini index e147deedddd41..6f843ba725b99 100644 --- a/administrator/language/en-GB/en-GB.plg_system_sessiongc.ini +++ b/administrator/language/en-GB/en-GB.plg_system_sessiongc.ini @@ -8,8 +8,8 @@ PLG_SYSTEM_SESSIONGC_ENABLE_SESSION_GC_DESC="When enabled, this plugin will atte PLG_SYSTEM_SESSIONGC_ENABLE_SESSION_GC_LABEL="Enable Session Garbage Collection" PLG_SYSTEM_SESSIONGC_ENABLE_SESSION_METADATA_GC_DESC="When enabled, this plugin will clean optional session metadata from the database. Note that this operation will not run when the database handler is in use as that data is cleared as part of the garbage collection operation." PLG_SYSTEM_SESSIONGC_ENABLE_SESSION_METADATA_GC_LABEL="Enable Session Metadata Cleanup" -PLG_SYSTEM_SESSIONGC_GC_DIVISOR_DESC="Used in combination with the probability field, these two fields are used to determine the odds of the garbage collection operation being triggered on a request. The probability is calculated by using probability/divisor, e.g. 1/100 means there is a 1% chance that the process runs on each request." +PLG_SYSTEM_SESSIONGC_GC_DIVISOR_DESC="In combination with the probability field, these two fields are used to determine the odds of the garbage collection operation being triggered on a request. The probability is calculated by using probability/divisor, e.g. 1/100 means there is a 1% chance that the process runs on each request." PLG_SYSTEM_SESSIONGC_GC_DIVISOR_LABEL="Divisor" -PLG_SYSTEM_SESSIONGC_GC_PROBABILITY_DESC="Used in combination with the divisor field, these two fields are used to determine the odds of the garbage collection operation being triggered on a request." +PLG_SYSTEM_SESSIONGC_GC_PROBABILITY_DESC="In combination with the divisor field, these two fields are used to determine the odds of the garbage collection operation being triggered on a request." PLG_SYSTEM_SESSIONGC_GC_PROBABILITY_LABEL="Probability" PLG_SYSTEM_SESSIONGC_XML_DESCRIPTION="System Plugin that handles session garbage collection tasks." diff --git a/cli/sessionMetadataGc.php b/cli/sessionMetadataGc.php index 4b51fdb28c72c..aa2007b9dea72 100644 --- a/cli/sessionMetadataGc.php +++ b/cli/sessionMetadataGc.php @@ -9,7 +9,7 @@ /** * This is a CRON script to delete expired optional session metadata which should be called from the command-line, not the * web. For example something like: - * /usr/bin/php /path/to/site/cli/sessionGc.php + * /usr/bin/php /path/to/site/cli/sessionMetadataGc.php */ // Initialize Joomla framework From 723f8251ae3738a64ae6cf45f83f01f8a30b7bac Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Thu, 22 Feb 2018 12:18:00 -0600 Subject: [PATCH 6/7] Language tweaks --- .../language/en-GB/en-GB.plg_system_sessiongc.ini | 14 +++++++------- .../en-GB/en-GB.plg_system_sessiongc.sys.ini | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/administrator/language/en-GB/en-GB.plg_system_sessiongc.ini b/administrator/language/en-GB/en-GB.plg_system_sessiongc.ini index 6f843ba725b99..6f8879115a291 100644 --- a/administrator/language/en-GB/en-GB.plg_system_sessiongc.ini +++ b/administrator/language/en-GB/en-GB.plg_system_sessiongc.ini @@ -3,13 +3,13 @@ ; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php ; Note : All ini files need to be saved as UTF-8 -PLG_SYSTEM_SESSIONGC="System - Session Garbage Collection" -PLG_SYSTEM_SESSIONGC_ENABLE_SESSION_GC_DESC="When enabled, this plugin will attempt to perform session garbage collection based on the odds calculated by the probability and divisor." -PLG_SYSTEM_SESSIONGC_ENABLE_SESSION_GC_LABEL="Enable Session Garbage Collection" -PLG_SYSTEM_SESSIONGC_ENABLE_SESSION_METADATA_GC_DESC="When enabled, this plugin will clean optional session metadata from the database. Note that this operation will not run when the database handler is in use as that data is cleared as part of the garbage collection operation." +PLG_SYSTEM_SESSIONGC="System - Session Data Purge" +PLG_SYSTEM_SESSIONGC_ENABLE_SESSION_GC_DESC="When enabled, this plugin will attempt to purge expired data based on the frequency calculated by the probability and divisor." +PLG_SYSTEM_SESSIONGC_ENABLE_SESSION_GC_LABEL="Enable Session Data Cleanup" +PLG_SYSTEM_SESSIONGC_ENABLE_SESSION_METADATA_GC_DESC="When enabled, this plugin will clean optional session metadata from the database. Note that this operation will not run when the database handler is in use as that data is cleared as part of the Session Data Cleanup operation." PLG_SYSTEM_SESSIONGC_ENABLE_SESSION_METADATA_GC_LABEL="Enable Session Metadata Cleanup" -PLG_SYSTEM_SESSIONGC_GC_DIVISOR_DESC="In combination with the probability field, these two fields are used to determine the odds of the garbage collection operation being triggered on a request. The probability is calculated by using probability/divisor, e.g. 1/100 means there is a 1% chance that the process runs on each request." +PLG_SYSTEM_SESSIONGC_GC_DIVISOR_DESC="In combination with the probability field, these two fields are used to determine the frequency of the session data cleanup operation being triggered on a request. The probability is calculated by using probability/divisor, e.g. 1/100 means there is a 1% chance that the process runs on each request." PLG_SYSTEM_SESSIONGC_GC_DIVISOR_LABEL="Divisor" -PLG_SYSTEM_SESSIONGC_GC_PROBABILITY_DESC="In combination with the divisor field, these two fields are used to determine the odds of the garbage collection operation being triggered on a request." +PLG_SYSTEM_SESSIONGC_GC_PROBABILITY_DESC="In combination with the divisor field, these two fields are used to determine the frequency of the session data cleanup operation being triggered on a request." PLG_SYSTEM_SESSIONGC_GC_PROBABILITY_LABEL="Probability" -PLG_SYSTEM_SESSIONGC_XML_DESCRIPTION="System Plugin that handles session garbage collection tasks." +PLG_SYSTEM_SESSIONGC_XML_DESCRIPTION="System Plugin that purges expired data and metadata depending on the session handler set in Global Configuration." diff --git a/administrator/language/en-GB/en-GB.plg_system_sessiongc.sys.ini b/administrator/language/en-GB/en-GB.plg_system_sessiongc.sys.ini index d33c6c3c5d031..415d42e49971b 100644 --- a/administrator/language/en-GB/en-GB.plg_system_sessiongc.sys.ini +++ b/administrator/language/en-GB/en-GB.plg_system_sessiongc.sys.ini @@ -3,5 +3,5 @@ ; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php ; Note : All ini files need to be saved as UTF-8 -PLG_SYSTEM_SESSIONGC="System - Session Garbage Collection" -PLG_SYSTEM_SESSIONGC_XML_DESCRIPTION="System Plugin that handles session garbage collection tasks." +PLG_SYSTEM_SESSIONGC="System - Session Data Purge" +PLG_SYSTEM_SESSIONGC_XML_DESCRIPTION="System Plugin that purges expired data and metadata depending on the session handler set in Global Configuration." From 79a6308329c4544a16bfc94557404190e0b56fe6 Mon Sep 17 00:00:00 2001 From: Michael Babker Date: Thu, 22 Feb 2018 12:29:03 -0600 Subject: [PATCH 7/7] Change to uint filter, if it'll get people to review and accept the damn PR... --- plugins/system/sessiongc/sessiongc.php | 4 ++-- plugins/system/sessiongc/sessiongc.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/system/sessiongc/sessiongc.php b/plugins/system/sessiongc/sessiongc.php index 329154411ebfe..3693fb4daa286 100644 --- a/plugins/system/sessiongc/sessiongc.php +++ b/plugins/system/sessiongc/sessiongc.php @@ -48,7 +48,7 @@ public function onAfterRespond() { $session = Factory::getSession(); - if ($this->params->get('enable_session_gc', true)) + if ($this->params->get('enable_session_gc', 1)) { $probability = $this->params->get('gc_probability', 1); $divisor = $this->params->get('gc_divisor', 100); @@ -61,7 +61,7 @@ public function onAfterRespond() } } - if ($this->app->get('session_handler', 'none') !== 'database' && $this->params->get('enable_session_metadata_gc', true)) + if ($this->app->get('session_handler', 'none') !== 'database' && $this->params->get('enable_session_metadata_gc', 1)) { $probability = $this->params->get('gc_probability', 1); $divisor = $this->params->get('gc_divisor', 100); diff --git a/plugins/system/sessiongc/sessiongc.xml b/plugins/system/sessiongc/sessiongc.xml index 76cb22b0c207f..f9d9886169158 100644 --- a/plugins/system/sessiongc/sessiongc.xml +++ b/plugins/system/sessiongc/sessiongc.xml @@ -26,7 +26,7 @@ description="PLG_SYSTEM_SESSIONGC_ENABLE_SESSION_GC_DESC" class="btn-group btn-group-yesno" default="1" - filter="boolean" + filter="uint" > @@ -39,7 +39,7 @@ description="PLG_SYSTEM_SESSIONGC_ENABLE_SESSION_METADATA_GC_DESC" class="btn-group btn-group-yesno" default="1" - filter="boolean" + filter="uint" >