* use database table for session handling

This commit is contained in:
Max Pozdeev 2021-07-29 16:52:44 +03:00
parent b657cc490f
commit 73ab4ac10f
10 changed files with 147 additions and 27 deletions

1
.gitignore vendored
View file

@ -1,4 +1,3 @@
src/db/todolist.db
src/tmp/sessions/sess*
src/db/config.php
src/db/config-*

View file

@ -145,9 +145,6 @@
"set_timezone": "Time zone",
"set_autotag": "Autotagging",
"set_autotag_descr": "(automatically adds tag of current tag filter to newly created task)",
"set_sessions": "Session handling mechanism",
"set_sessions_php": "PHP",
"set_sessions_files": "Files",
"set_firstdayofweek": "First day of week",
"set_custom": "Custom",
"set_date": "Date format",

View file

@ -145,9 +145,6 @@
"set_timezone": "Часовой пояс",
"set_autotag": "Autotagging",
"set_autotag_descr": "(автодобавление текущего тега из фильтра в новую задачу)",
"set_sessions": "Хранилище сессий",
"set_sessions_php": "PHP",
"set_sessions_files": "Файлы",
"set_firstdayofweek": "Первый день недели",
"set_custom": "другой",
"set_date": "Формат даты",

View file

@ -0,0 +1,97 @@
<?php
class MTTSessionHandler implements SessionHandlerInterface
{
/**
* @var Database_Abstract
*/
private $db;
/**
* @param string $path
* @param string $name
* @return bool
* @throws Exception
*/
public function open($path, $name)
{
$this->db = DBConnection::instance();
return true;
}
/** @return bool */
public function close()
{
return true;
}
/**
* @param string $id
* @return string
* @throws Exception
*/
public function read($id)
{
// read session data if not expired
$expire = time();
$r = $this->db->sq("SELECT data,last_access FROM {$this->db->prefix}sessions WHERE id = ? AND expires >= $expire", $id);
if ( is_null($r) ) return '';
// update last access time and set expires in 14 days
// refresh once in a second
if ( $r[1] < time() ) {
$expire = time() + 14 * 86400;
$this->db->ex("UPDATE {$this->db->prefix}sessions SET last_access=?,expires=? WHERE id = ?",
array(time(), $expire, $id) );
}
return $r[0];
}
/**
* @param string $id
* @param string $data
* @return bool
* @throws Exception
*/
public function write($id, $data)
{
$exists = $this->db->sq("SELECT COUNT(*) FROM {$this->db->prefix}sessions WHERE id = ?", $id);
if (!$exists) {
// Create new session with 14 days lifetime
$expire = time() + 14 * 86400;
$this->db->ex("INSERT INTO {$this->db->prefix}sessions (id,data,expires) VALUES (?,?,?)",
array($id, $data, $expire) );
}
else {
// Update existing session
$this->db->ex("UPDATE {$this->db->prefix}sessions SET data = ? WHERE id = ?",
array($data, $id) );
}
return true;
}
/**
* @param string $id
* @return bool
* @throws Exception
*/
public function destroy($id)
{
$this->db->ex("DELETE FROM {$this->db->prefix}sessions WHERE id = ?", $id);
return true;
}
/**
* @param int $max_lifetime
* @return int|false
*/
public function gc($max_lifetime)
{
// We ignore php runtime 'session.gc_maxlifetime'
$expire = time();
$affected = $this->db->ex("DELETE FROM {$this->db->prefix}sessions WHERE expires < $expire");
return $affected;
}
}
?>

View file

@ -92,14 +92,8 @@ $_mttinfo = array();
if (need_auth() && !isset($dontStartSession))
{
if(Config::get('session') == 'files')
{
session_save_path(MTTPATH. 'tmp/sessions');
ini_set('session.gc_maxlifetime', '1209600'); # 14 days session file minimum lifetime
ini_set('session.gc_probability', 1);
ini_set('session.gc_divisor', 10);
}
require_once(MTTINC. 'class.sessionhandler.php');
session_set_save_handler(new MTTSessionHandler());
ini_set('session.use_cookies', true);
ini_set('session.use_only_cookies', true);
session_set_cookie_params(1209600, url_dir(Config::get('url')=='' ? getRequestUri() : Config::getUrl('url'))); # 14 days session cookie lifetime

View file

@ -146,9 +146,6 @@ class DefaultLang
'set_timezone' => "Time zone",
'set_autotag' => "Autotagging",
'set_autotag_descr' => "(automatically adds tag of current tag filter to newly created task)",
'set_sessions' => "Session handling mechanism",
'set_sessions_php' => "PHP",
'set_sessions_files' => "Files",
'set_firstdayofweek' => "First day of week",
'set_custom' => "Custom",
'set_date' => "Date format",

View file

@ -41,7 +41,6 @@ if(isset($_POST['save']))
catch (Exception $e) {
}
Config::set('autotag', (int)_post('autotag'));
Config::set('session', _post('session'));
Config::set('firstdayofweek', (int)_post('firstdayofweek'));
Config::set('clock', (int)_post('clock'));
Config::set('dateformat', _post('dateformat'));
@ -231,13 +230,6 @@ header('Content-type:text/html; charset=utf-8');
<label><input type="radio" name="autotag" value="0" <?php if(!_c('autotag')) echo 'checked="checked"'; ?> /><?php _e('set_disabled');?></label>
</div></div>
<div class="tr">
<div class="th"><?php _e('set_sessions');?>:</div>
<div class="td">
<label><input type="radio" name="session" value="default" <?php if(_c('session')=='default') echo 'checked="checked"'; ?> /><?php _e('set_sessions_php');?></label> <br/>
<label><input type="radio" name="session" value="files" <?php if(_c('session')=='files') echo 'checked="checked"'; ?> /><?php _e('set_sessions_files');?></label> <span class="descr">(&lt;mytinytodo_dir&gt;/tmp/sessions)</span>
</div></div>
<div class="tr">
<div class="th"><?php _e('set_timezone');?>:</div>
<div class="td">

View file

@ -167,6 +167,17 @@ if (!$ver)
UNIQUE KEY `param_key` (`param_key`)
) CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ");
$db->ex(
"CREATE TABLE {$db->prefix}sessions (
`id` VARCHAR(64) NOT NULL default '', /* upto 64 bytes for sha256 */
`data` TEXT,
`last_access` INT UNSIGNED NOT NULL default 0, /* time() timestamp */
`expires` INT UNSIGNED NOT NULL default 0, /* time() timestamp */
UNIQUE KEY `id` (`id`)
) CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ");
} catch (Exception $e) {
exitMessage("<b>Error:</b> ". htmlarray($e->getMessage()));
}
@ -239,6 +250,17 @@ UNIQUE KEY `param_key` (`param_key`)
$db->ex("CREATE UNIQUE INDEX settings_key ON {$db->prefix}settings (param_key COLLATE NOCASE)");
$db->ex(
"CREATE TABLE {$db->prefix}sessions (
id VARCHAR(64) NOT NULL default '',
data TEXT,
last_access INTEGER UNSIGNED NOT NULL default 0,
expires INTEGER UNSIGNED NOT NULL default 0
) ");
$db->ex("CREATE UNIQUE INDEX sessions_id ON {$db->prefix}sessions (id COLLATE NOCASE)");
} catch (Exception $e) {
exitMessage("<b>Error:</b> ". htmlarray($e->getMessage()));
}
@ -390,6 +412,7 @@ function myExceptionHandler($e)
function update_14_17(Database_Abstract $db, $dbtype)
{
$db->ex("BEGIN");
if($dbtype=='mysql')
{
# convert charset to utf8mb4
@ -407,6 +430,18 @@ function update_14_17(Database_Abstract $db, $dbtype)
`param_value` TEXT,
UNIQUE KEY `param_key` (`param_key`)
) CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ");
# create sessions table
$db->ex(
"CREATE TABLE {$db->prefix}sessions (
`id` VARCHAR(64) NOT NULL default '',
`data` TEXT,
`last_access` INT UNSIGNED NOT NULL default 0,
`expires` INT UNSIGNED NOT NULL default 0,
UNIQUE KEY `id` (`id`)
) CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ");
}
else #sqlite
@ -417,7 +452,20 @@ UNIQUE KEY `param_key` (`param_key`)
param_value TEXT
) ");
$db->ex("CREATE UNIQUE INDEX settings_key ON {$db->prefix}settings (param_key COLLATE NOCASE)");
# sessions
$db->ex(
"CREATE TABLE {$db->prefix}sessions (
id VARCHAR(100) NOT NULL default '',
data TEXT,
last_access INTEGER UNSIGNED NOT NULL default 0,
expires INTEGER UNSIGNED NOT NULL default 0
) ");
$db->ex("CREATE UNIQUE INDEX sessions_id ON {$db->prefix}sessions (id COLLATE NOCASE)");
}
$db->ex("COMMIT");
Config::save();

View file

@ -1 +0,0 @@
deny from all

View file