2014-05-27 02:47:40 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Model\RememberMe;
|
|
|
|
|
|
|
|
use PicoDb\Database;
|
|
|
|
use Model\Config;
|
|
|
|
use Model\User;
|
|
|
|
use Model\Database as DatabaseModel;
|
|
|
|
|
|
|
|
const TABLE = 'remember_me';
|
|
|
|
const COOKIE_NAME = '_R_';
|
|
|
|
const EXPIRATION = 5184000;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get a remember me record
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
* @return mixed
|
|
|
|
*/
|
|
|
|
function find($token, $sequence)
|
|
|
|
{
|
|
|
|
return Database::get('db')
|
|
|
|
->table(TABLE)
|
|
|
|
->eq('token', $token)
|
|
|
|
->eq('sequence', $sequence)
|
|
|
|
->gt('expiration', time())
|
|
|
|
->findOne();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get all sessions
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
function get_all()
|
|
|
|
{
|
|
|
|
return Database::get('db')
|
|
|
|
->table(TABLE)
|
|
|
|
->desc('date_creation')
|
|
|
|
->columns('id', 'ip', 'user_agent', 'date_creation', 'expiration')
|
|
|
|
->findAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Authenticate the user with the cookie
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
function authenticate()
|
|
|
|
{
|
|
|
|
$credentials = read_cookie();
|
|
|
|
|
|
|
|
if ($credentials !== false) {
|
|
|
|
|
|
|
|
$record = find($credentials['token'], $credentials['sequence']);
|
|
|
|
|
|
|
|
if ($record) {
|
|
|
|
|
|
|
|
// Update the sequence
|
|
|
|
write_cookie(
|
|
|
|
$record['token'],
|
|
|
|
update($record['token'], $record['sequence']),
|
|
|
|
$record['expiration']
|
|
|
|
);
|
|
|
|
|
|
|
|
// Create the session
|
|
|
|
$_SESSION['user'] = User\get($record['username']);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Update the database and the cookie with a new sequence
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
*/
|
|
|
|
function refresh()
|
|
|
|
{
|
|
|
|
$credentials = read_cookie();
|
|
|
|
|
|
|
|
if ($credentials !== false) {
|
|
|
|
|
|
|
|
$record = find($credentials['token'], $credentials['sequence']);
|
|
|
|
|
|
|
|
if ($record) {
|
|
|
|
|
|
|
|
// Update the sequence
|
|
|
|
write_cookie(
|
|
|
|
$record['token'],
|
|
|
|
update($record['token'], $record['sequence']),
|
|
|
|
$record['expiration']
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove a session record
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
* @param integer $session_id Session id
|
|
|
|
* @return mixed
|
|
|
|
*/
|
|
|
|
function remove($session_id)
|
|
|
|
{
|
|
|
|
return Database::get('db')
|
|
|
|
->table(TABLE)
|
|
|
|
->eq('id', $session_id)
|
|
|
|
->remove();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove the current RememberMe session and the cookie
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
* @param integer $user_id User id
|
|
|
|
*/
|
|
|
|
function destroy()
|
|
|
|
{
|
2015-01-17 19:35:59 +01:00
|
|
|
// delete the cookie without any conditions!
|
|
|
|
delete_cookie();
|
|
|
|
|
2014-05-27 02:47:40 +02:00
|
|
|
$credentials = read_cookie();
|
|
|
|
|
|
|
|
if ($credentials !== false) {
|
|
|
|
|
|
|
|
Database::get('db')
|
|
|
|
->table(TABLE)
|
|
|
|
->eq('token', $credentials['token'])
|
|
|
|
->remove();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a new RememberMe session
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
* @param integer $dbname Database name
|
|
|
|
* @param integer $username Username
|
|
|
|
* @param string $ip IP Address
|
|
|
|
* @param string $user_agent User Agent
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
function create($dbname, $username, $ip, $user_agent)
|
|
|
|
{
|
|
|
|
$token = hash('sha256', $dbname.$username.$user_agent.$ip.Config\generate_token());
|
|
|
|
$sequence = Config\generate_token();
|
|
|
|
$expiration = time() + EXPIRATION;
|
|
|
|
|
|
|
|
cleanup();
|
|
|
|
|
|
|
|
Database::get('db')
|
|
|
|
->table(TABLE)
|
|
|
|
->insert(array(
|
|
|
|
'username' => $username,
|
|
|
|
'ip' => $ip,
|
|
|
|
'user_agent' => $user_agent,
|
|
|
|
'token' => $token,
|
|
|
|
'sequence' => $sequence,
|
|
|
|
'expiration' => $expiration,
|
|
|
|
'date_creation' => time(),
|
|
|
|
));
|
|
|
|
|
|
|
|
return array(
|
|
|
|
'token' => $token,
|
|
|
|
'sequence' => $sequence,
|
|
|
|
'expiration' => $expiration,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove old sessions
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
function cleanup()
|
|
|
|
{
|
|
|
|
return Database::get('db')
|
|
|
|
->table(TABLE)
|
|
|
|
->lt('expiration', time())
|
|
|
|
->remove();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return a new sequence token and update the database
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
* @param string $token Session token
|
|
|
|
* @param string $sequence Sequence token
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
function update($token, $sequence)
|
|
|
|
{
|
|
|
|
$new_sequence = Config\generate_token();
|
|
|
|
|
|
|
|
Database::get('db')
|
|
|
|
->table(TABLE)
|
|
|
|
->eq('token', $token)
|
|
|
|
->eq('sequence', $sequence)
|
|
|
|
->update(array('sequence' => $new_sequence));
|
|
|
|
|
|
|
|
return $new_sequence;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Encode the cookie
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
* @param string $token Session token
|
|
|
|
* @param string $sequence Sequence token
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
function encode_cookie($token, $sequence)
|
|
|
|
{
|
|
|
|
return implode('|', array(base64_encode(DatabaseModel\select()), $token, $sequence));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Decode the value of a cookie
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
* @param string $value Raw cookie data
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
function decode_cookie($value)
|
|
|
|
{
|
|
|
|
@list($database, $token, $sequence) = explode('|', $value);
|
|
|
|
|
2015-01-17 19:35:59 +01:00
|
|
|
if (! DatabaseModel\select(base64_decode($database))) {
|
|
|
|
return false;
|
|
|
|
}
|
2014-05-27 02:47:40 +02:00
|
|
|
|
|
|
|
return array(
|
|
|
|
'token' => $token,
|
|
|
|
'sequence' => $sequence,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return true if the current user has a RememberMe cookie
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
function has_cookie()
|
|
|
|
{
|
|
|
|
return ! empty($_COOKIE[COOKIE_NAME]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Write and encode the cookie
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
* @param string $token Session token
|
|
|
|
* @param string $sequence Sequence token
|
|
|
|
* @param string $expiration Cookie expiration
|
|
|
|
*/
|
|
|
|
function write_cookie($token, $sequence, $expiration)
|
|
|
|
{
|
|
|
|
setcookie(
|
|
|
|
COOKIE_NAME,
|
|
|
|
encode_cookie($token, $sequence),
|
|
|
|
$expiration,
|
|
|
|
BASE_URL_DIRECTORY,
|
|
|
|
null,
|
|
|
|
! empty($_SERVER['HTTPS']),
|
|
|
|
true
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Read and decode the cookie
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
* @return mixed
|
|
|
|
*/
|
|
|
|
function read_cookie()
|
|
|
|
{
|
|
|
|
if (empty($_COOKIE[COOKIE_NAME])) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return decode_cookie($_COOKIE[COOKIE_NAME]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove the cookie
|
|
|
|
*
|
|
|
|
* @access public
|
|
|
|
*/
|
|
|
|
function delete_cookie()
|
|
|
|
{
|
|
|
|
setcookie(
|
|
|
|
COOKIE_NAME,
|
|
|
|
'',
|
|
|
|
time() - 3600,
|
|
|
|
BASE_URL_DIRECTORY,
|
|
|
|
null,
|
|
|
|
! empty($_SERVER['HTTPS']),
|
|
|
|
true
|
|
|
|
);
|
|
|
|
}
|