Skip to content
This repository has been archived by the owner on Feb 4, 2021. It is now read-only.

Commit

Permalink
#251 - Add session_autostart option
Browse files Browse the repository at this point in the history
If auto_start is disabled a session will only start when a session cookie is found.
  • Loading branch information
Steven Rombauts committed Oct 27, 2015
1 parent 74d6afb commit 7b51eb7
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 73 deletions.
3 changes: 3 additions & 0 deletions config/environment.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,7 @@
/* Feed */
'feed_limit' => 10,
'feed_email' => 'author',

/* Session autostart */
'session_autostart' => false
];
93 changes: 58 additions & 35 deletions lib/libraries/cms/application/cms.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ public function __construct(JInput $input = null, JRegistry $config = null, JApp
// Create the session if a session name is passed.
if ($this->config->get('session') !== false)
{
$this->loadSession();
$this->loadSession(null, $this->config->get('session_autostart'));
}
}

Expand Down Expand Up @@ -620,7 +620,7 @@ public function isSite()
*
* @since 3.2
*/
public function loadSession(JSession $session = null)
public function loadSession(JSession $session = null, $auto_start = true)
{
if ($session !== null)
{
Expand Down Expand Up @@ -664,35 +664,49 @@ public function loadSession(JSession $session = null)

// There's an internal coupling to the session object being present in JFactory, need to deal with this at some point
$session = JFactory::getSession($options);
$session->initialise($this->input, $this->dispatcher);
$session->start();

// TODO: At some point we need to get away from having session data always in the db.
$db = JFactory::getDbo();

// Remove expired sessions from the database.
$time = time();

if ($time % 2)
{
// The modulus introduces a little entropy, making the flushing less accurate
// but fires the query less than half the time.
$query = $db->getQuery(true)
->delete($db->quoteName('#__users_sessions'))
->where($db->quoteName('time') . ' < ' . $db->quote((int) ($time - $session->getExpire())));

$db->setQuery($query);
$db->execute();
}

// Get the session handler from the configuration.
$handler = $this->get('session_handler', 'none');

if (($handler != 'database' && ($time % 2 || $session->isNew()))
|| ($handler == 'database' && $session->isNew()))
{
$this->checkSession();
}
$session->initialise($this->input, $this->dispatcher);

if ($session->getState() != 'active')
{
if ($auto_start || $this->input->cookie->get($session->getName())) {
$session->start();
}
}

// Only update the session table if the session is active
if ($session->getState() == 'active')
{
// TODO: At some point we need to get away from having session data always in the db.
$db = JFactory::getDbo();

// Remove expired sessions from the database.
$time = time();

if ($time % 2) {
// The modulus introduces a little entropy, making the flushing less accurate
// but fires the query less than half the time.
$query = $db->getQuery(true)
->delete($db->quoteName('#__users_sessions'))
->where($db->quoteName('time') . ' < ' . $db->quote((int)($time - $session->getExpire())));

$db->setQuery($query);
$db->execute();
}

// Get the session handler from the configuration.
$handler = $this->get('session_handler', 'none');

if (($handler != 'database' && ($time % 2 || $session->isNew()))
|| ($handler == 'database' && $session->isNew())
) {
$this->checkSession();
}
}
else
{
$session->set('registry', new JRegistry('session'));
$session->set('user', new JUser());
}

// Set the session object.
$this->session = $session;
Expand Down Expand Up @@ -732,10 +746,19 @@ public function login($credentials, $options = array())

if ($response->status === JAuthentication::STATUS_SUCCESS)
{
/*
* Validate that the user should be able to login (different to being authenticated).
* This permits authentication plugins blocking the user.
*/
$session = JFactory::getSession($options);

// Fork the session to prevent session fixation issues if it's active
if($session->getState() != 'active') {
$session->start();
} else {
$session->fork();
}

/*
* Validate that the user should be able to login (different to being authenticated).
* This permits authentication plugins blocking the user.
*/
$authorisations = $authenticate->authorise($response, $options);

foreach ($authorisations as $authorisation)
Expand Down
18 changes: 12 additions & 6 deletions lib/libraries/joomla/application/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,10 @@ public function __construct(JInput $input = null, JRegistry $config = null, JApp
// Load the configuration object.
$this->loadConfiguration($this->fetchConfigurationData());

if (is_null($this->config->get('session_autostart'))) {
$this->config->set('session_autostart', true);
}

// Set the execution datetime and timestamp;
$this->set('execution.datetime', gmdate('Y-m-d H:i:s'));
$this->set('execution.timestamp', time());
Expand Down Expand Up @@ -213,7 +217,7 @@ public function initialise($session = null, $document = null, $language = null,
// Create the session based on the application logic.
if ($session !== false)
{
$this->loadSession($session);
$this->loadSession($session, $this->config->get('session_autostart'));
}

// Create the document based on the application logic.
Expand Down Expand Up @@ -1030,7 +1034,7 @@ public function loadLanguage(JLanguage $language = null)
*
* @since 11.3
*/
public function loadSession(JSession $session = null)
public function loadSession(JSession $session = null, $auto_start = true)
{
if ($session !== null)
{
Expand Down Expand Up @@ -1065,10 +1069,12 @@ public function loadSession(JSession $session = null)
{
$session->restart();
}
else
{
$session->start();
}
elseif ($session->getState() != 'active')
{
if ($auto_start || $this->input->cookie->get($session->getName())) {
$session->start();
}
}

// Set the session object.
$this->session = $session;
Expand Down
83 changes: 51 additions & 32 deletions lib/libraries/legacy/application/application.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,15 @@ public function __construct($config = array())
$this->_createConfiguration(JPATH_CONFIGURATION . '/' . $config['config_file']);
}

// Set the session autostart
if(!isset($config['session_autostart'])) {
$config['session_autostart'] = !is_null($this->getCfg('session_autostart')) ? $this->getCfg('session_autostart') : true;
}

// Create the session if a session name is passed.
if ($config['session'] !== false)
{
$this->_createSession(self::getHash($config['session_name']));
$this->_createSession(self::getHash($config['session_name']), false, $config['session_autostart']);
}

$this->requestTime = gmdate('Y-m-d H:i');
Expand Down Expand Up @@ -962,7 +967,7 @@ protected function _createConfiguration($file)
* @since 11.1
* @deprecated 4.0
*/
protected function _createSession($name)
protected function _createSession($name, $auto_start = true)
{
$options = array();
$options['name'] = $name;
Expand All @@ -987,36 +992,50 @@ protected function _createSession($name)
$this->registerEvent('onAfterSessionStart', array($this, 'afterSessionStart'));

$session = JFactory::getSession($options);
$session->initialise($this->input, $this->dispatcher);
$session->start();

// TODO: At some point we need to get away from having session data always in the db.

$db = JFactory::getDbo();

// Remove expired sessions from the database.
$time = time();

if ($time % 2)
{
// The modulus introduces a little entropy, making the flushing less accurate
// but fires the query less than half the time.
$query = $db->getQuery(true)
->delete($db->quoteName('#__users_sessions'))
->where($db->quoteName('time') . ' < ' . $db->quote((int) ($time - $session->getExpire())));

$db->setQuery($query);
$db->execute();
}

// Check to see the the session already exists.
$handler = $this->getCfg('session_handler');

if (($handler != 'database' && ($time % 2 || $session->isNew()))
|| ($handler == 'database' && $session->isNew()))
{
$this->checkSession();
}
$session->initialise($this->input, $this->dispatcher);

if($session->getState() != 'active')
{
if ($auto_start || JRequest::getCmd($session->getName(), null, 'cookie')) {
$session->start();
}
}

// Only update the session table if the session is active
if($session->getState() == 'active')
{
// TODO: At some point we need to get away from having session data always in the db.
$db = JFactory::getDbo();

// Remove expired sessions from the database.
$time = time();

if ($time % 2)
{
// The modulus introduces a little entropy, making the flushing less accurate
// but fires the query less than half the time.
$query = $db->getQuery(true)
->delete($db->quoteName('#__users_sessions'))
->where($db->quoteName('time') . ' < ' . $db->quote((int) ($time - $session->getExpire())));

$db->setQuery($query);
$db->execute();
}

// Check to see the the session already exists.
$handler = $this->getCfg('session_handler');

if (($handler != 'database' && ($time % 2 || $session->isNew()))
|| ($handler == 'database' && $session->isNew()))
{
$this->checkSession();
}
}
else
{
$session->set('registry', new JRegistry('session'));
$session->set('user', new JUser());
}

return $session;
}
Expand Down

0 comments on commit 7b51eb7

Please sign in to comment.