- PHP Framework upgrade 3.5.0 -> 3.5.1 (fixes some issues with CREST cURL caching, and SESSION management)

- #138 added "cookie logout" to "logout" menu entry
This commit is contained in:
Exodus4D
2016-05-06 18:09:28 +02:00
parent eb1e365020
commit dfd1e8501d
28 changed files with 575 additions and 388 deletions

View File

@@ -27,7 +27,15 @@ class Session extends Mapper {
protected
//! Session ID
$sid;
$sid,
//! Anti-CSRF token
$_csrf,
//! User agent
$_agent,
//! IP,
$_ip,
//! Suspect callback
$onsuspect;
/**
* Open session
@@ -44,6 +52,8 @@ class Session extends Mapper {
* @return TRUE
**/
function close() {
$this->reset();
$this->sid=NULL;
return TRUE;
}
@@ -53,9 +63,20 @@ class Session extends Mapper {
* @param $id string
**/
function read($id) {
if ($id!=$this->sid)
$this->load(array('session_id=?',$this->sid=$id));
return $this->dry()?FALSE:$this->get('data');
$this->load(array('session_id=?',$this->sid=$id));
if ($this->dry())
return FALSE;
if ($this->get('ip')!=$this->_ip || $this->get('agent')!=$this->_agent) {
$fw=\Base::instance();
if (!isset($this->onsuspect) || FALSE===$fw->call($this->onsuspect,array($this,$id))) {
//NB: `session_destroy` can't be called at that stage (`session_start` not completed)
$this->destroy($id);
$this->close();
$fw->clear('COOKIE.'.session_name());
$fw->error(403);
}
}
return $this->get('data');
}
/**
@@ -65,19 +86,10 @@ class Session extends Mapper {
* @param $data string
**/
function write($id,$data) {
$fw=\Base::instance();
$sent=headers_sent();
$headers=$fw->get('HEADERS');
if ($id!=$this->sid)
$this->load(array('session_id=?',$this->sid=$id));
$csrf=$fw->hash($fw->get('ROOT').$fw->get('BASE')).'.'.
$fw->hash(mt_rand());
$this->set('session_id',$id);
$this->set('data',$data);
$this->set('csrf',$sent?$this->csrf():$csrf);
$this->set('ip',$fw->get('IP'));
$this->set('agent',
isset($headers['User-Agent'])?$headers['User-Agent']:'');
$this->set('ip',$this->_ip);
$this->set('agent',$this->_agent);
$this->set('stamp',time());
$this->save();
return TRUE;
@@ -90,9 +102,6 @@ class Session extends Mapper {
**/
function destroy($id) {
$this->erase(array('session_id=?',$id));
setcookie(session_name(),'',strtotime('-1 year'));
unset($_COOKIE[session_name()]);
header_remove('Set-Cookie');
return TRUE;
}
@@ -106,20 +115,28 @@ class Session extends Mapper {
return TRUE;
}
/**
* Return session id (if session has started)
* @return string|NULL
**/
function sid() {
return $this->sid;
}
/**
* Return anti-CSRF token
* @return string|FALSE
* @return string
**/
function csrf() {
return $this->dry()?FALSE:$this->get('csrf');
return $this->_csrf;
}
/**
* Return IP address
* @return string|FALSE
* @return string
**/
function ip() {
return $this->dry()?FALSE:$this->get('ip');
return $this->_ip;
}
/**
@@ -127,25 +144,28 @@ class Session extends Mapper {
* @return string|FALSE
**/
function stamp() {
if (!$this->sid)
session_start();
return $this->dry()?FALSE:$this->get('stamp');
}
/**
* Return HTTP user agent
* @return string|FALSE
* @return string
**/
function agent() {
return $this->dry()?FALSE:$this->get('agent');
return $this->_agent;
}
/**
* Instantiate class
* @param $db object
* @param $db \DB\SQL
* @param $table string
* @param $force bool
* @param $onsuspect callback
* @param $key string
**/
function __construct(\DB\SQL $db,$table='sessions',$force=TRUE,$onsuspect=NULL) {
function __construct(\DB\SQL $db,$table='sessions',$force=TRUE,$onsuspect=NULL,$key=NULL) {
if ($force) {
$eol="\n";
$tab="\t";
@@ -160,7 +180,6 @@ class Session extends Mapper {
$table.' ('.$eol.
$tab.$db->quotekey('session_id').' VARCHAR(40),'.$eol.
$tab.$db->quotekey('data').' TEXT,'.$eol.
$tab.$db->quotekey('csrf').' TEXT,'.$eol.
$tab.$db->quotekey('ip').' VARCHAR(40),'.$eol.
$tab.$db->quotekey('agent').' VARCHAR(255),'.$eol.
$tab.$db->quotekey('stamp').' INTEGER,'.$eol.
@@ -169,6 +188,7 @@ class Session extends Mapper {
);
}
parent::__construct($db,$table);
$this->onsuspect=$onsuspect;
session_set_save_handler(
array($this,'open'),
array($this,'close'),
@@ -178,26 +198,14 @@ class Session extends Mapper {
array($this,'cleanup')
);
register_shutdown_function('session_commit');
@session_start();
$fw=\Base::instance();
$headers=$fw->get('HEADERS');
if (($ip=$this->ip()) && $ip!=$fw->get('IP') ||
($agent=$this->agent()) &&
(!isset($headers['User-Agent']) ||
$agent!=$headers['User-Agent'])) {
if (isset($onsuspect))
$fw->call($onsuspect,array($this));
else {
session_destroy();
$fw->error(403);
}
}
$csrf=$fw->hash($fw->get('ROOT').$fw->get('BASE')).'.'.
$this->_csrf=$fw->hash($fw->get('ROOT').$fw->get('BASE')).'.'.
$fw->hash(mt_rand());
if ($this->load(array('session_id=?',$this->sid=session_id()))) {
$this->set('csrf',$csrf);
$this->save();
}
if ($key)
$fw->set($key,$this->_csrf);
$this->_agent=isset($headers['User-Agent'])?$headers['User-Agent']:'';
$this->_ip=$fw->get('IP');
}
}