Updated stay signed in system for a real (working) system

Thanks to Sbgodin for his work on Shaarli and Leed, which I adapted.

Please note that if you already have a working instance of BouffeATUlm,
you have to update manually your database. You have to set a new field
for User database (at the end of the database). This field has to be
called "stay_signed_in_token" and to be VARCHAR(32).
This commit is contained in:
Phyks 2013-12-26 00:13:54 +01:00
parent 21b7b7e64c
commit 3047a39acd
4 changed files with 69 additions and 31 deletions

View File

@ -3,7 +3,7 @@ require_once('data/config.php');
require_once('Storage.class.php'); require_once('Storage.class.php');
class User extends Storage { class User extends Storage {
protected $id = 0, $login, $email, $display_name, $password, $admin, $json_token, $notifications; protected $id = 0, $login, $email, $display_name, $password, $admin, $json_token, $notifications, $stay_signed_in_token;
protected $TABLE_NAME = "Users"; protected $TABLE_NAME = "Users";
protected $fields = array( protected $fields = array(
'id'=>'key', 'id'=>'key',
@ -13,11 +13,13 @@ class User extends Storage {
'password'=>'password', 'password'=>'password',
'admin'=>'bool', 'admin'=>'bool',
'json_token'=>'string', 'json_token'=>'string',
'notifications'=>'int' 'notifications'=>'int',
'stay_signed_in_token'=>'string'
); );
public function __construct() { public function __construct() {
parent::__construct(); parent::__construct();
$stay_signed_in_token = 0;
} }
// Getters // Getters
@ -50,6 +52,10 @@ class User extends Storage {
return $this->notifications; return $this->notifications;
} }
public function getStaySignedInToken() {
return $this->stay_signed_in_token;
}
// Setters // Setters
// ======= // =======
public function setId($id) { public function setId($id) {
@ -106,6 +112,10 @@ class User extends Storage {
} }
} }
public function setStaySignedInToken($token) {
$this->stay_signed_in_token = $token;
}
// Password functions // Password functions
// ================== // ==================
public function encrypt($text) { public function encrypt($text) {
@ -139,10 +149,10 @@ class User extends Storage {
// =============== // ===============
public function sessionStore($serialize = true) { public function sessionStore($serialize = true) {
if($serialize) { if($serialize) {
return serialize(array('id'=>$this->id, 'login'=>$this->login, 'email'=>$this->email, 'display_name'=>$this->display_name, 'password'=>$this->password, 'admin'=>$this->admin, 'json_token'=>$this->json_token, 'notifications'=>$this->notifications)); return serialize(array('id'=>$this->id, 'login'=>$this->login, 'email'=>$this->email, 'display_name'=>$this->display_name, 'password'=>$this->password, 'admin'=>$this->admin, 'json_token'=>$this->json_token, 'notifications'=>$this->notifications, 'stay_signed_in_token'=>$this->stay_signed_in_token));
} }
else { else {
return array('id'=>$this->id, 'login'=>$this->login, 'email'=>$this->email, 'display_name'=>$this->display_name, 'password'=>$this->password, 'admin'=>$this->admin, 'json_token'=>$this->json_token, 'notifications'=>$this->notifications); return array('id'=>$this->id, 'login'=>$this->login, 'email'=>$this->email, 'display_name'=>$this->display_name, 'password'=>$this->password, 'admin'=>$this->admin, 'json_token'=>$this->json_token, 'notifications'=>$this->notifications, 'stay_signed_in_token'=>$this->stay_signed_in_token);
} }
} }
@ -160,6 +170,7 @@ class User extends Storage {
$this->setAdmin($user_data['admin']); $this->setAdmin($user_data['admin']);
$this->setJsonToken($user_data['json_token']); $this->setJsonToken($user_data['json_token']);
$this->setNotifications($user_data['notifications']); $this->setNotifications($user_data['notifications']);
$this->setStaySignedInToken($user_data['stay_signed_in_token']);
} }
// Check wether a user already exists or not // Check wether a user already exists or not

View File

@ -1,4 +1,10 @@
<?php <?php
function logout() {
setcookie('bouffeatulm_staySignedIn', FALSE, 0, WEB_PATH);
setcookie('bouffeatulm_login', $_COOKIE['bouffeatulm_login'], 0, WEB_PATH);
session_destroy();
}
function getNotice() { function getNotice() {
if(!file_exists('data/notice')) { if(!file_exists('data/notice')) {
file_put_contents('data/notice'); file_put_contents('data/notice');

View File

@ -27,6 +27,13 @@
require_once('inc/functions.php'); require_once('inc/functions.php');
require_once('inc/Ban.inc.php'); require_once('inc/Ban.inc.php');
require_once('inc/CSRF.inc.php'); require_once('inc/CSRF.inc.php');
session_start();
// Long lasting session inspired by the work from sbgodin for shaarli
define('WEB_PATH', substr($_SERVER["REQUEST_URI"], 0, 1+strrpos($_SERVER["REQUEST_URI"], '/', 0)));
define('STAY_SIGNED_IN_TOKEN', sha1(SALT.$_SERVER["REMOTE_ADDR"].SALT));
if(!empty($_GET['json'])) { if(!empty($_GET['json'])) {
raintpl::$tpl_dir = 'tpl/json/'; raintpl::$tpl_dir = 'tpl/json/';
$get_redir = 'json=1'; $get_redir = 'json=1';
@ -47,28 +54,45 @@
$tpl->assign('currency', htmlspecialchars(CURRENCY)); $tpl->assign('currency', htmlspecialchars(CURRENCY));
$tpl->assign('email_webmaster', htmlspecialchars(EMAIL_WEBMASTER)); $tpl->assign('email_webmaster', htmlspecialchars(EMAIL_WEBMASTER));
// Set sessions parameters
ini_set('session.use_cookies', 1);
ini_set('session.use_only_cookies', 1);
ini_set('session.use_trans_sid', false);
session_name('bouffeatulm');
// Regenerate session if needed
$cookie = session_get_cookie_params();
$cookie_dir = ''; if(dirname($_SERVER['SCRIPT_NAME']) != '/') $cookie_dir = dirname($_SERVER['SCRIPT_NAME']);
session_set_cookie_params($cookie['lifetime'], $cookie_dir, $_SERVER['HTTP_HOST']);
session_regenerate_id(true);
// Handle current user status
if(session_id() == '') session_start();
$current_user = new User(); $current_user = new User();
if(isset($_SESSION['current_user'])) { if(isset($_SESSION['current_user'])) {
$current_user->sessionRestore($_SESSION['current_user'], true); $current_user->sessionRestore($_SESSION['current_user'], true);
} }
else {
if(!empty($_COOKIE['bouffeatulm_staySignedIn']) && !empty($_COOKIE['bouffeatulm_login'])) {
// Connect back
$user = new User();
$user->setLogin($_COOKIE['bouffeatulm_login']);
if(ban_canLogin() == false) {
setcookie('bouffeatulm_login', $_COOKIE['bouffeatulm_login'], 0, WEB_PATH);
setcookie('bouffeatulm_staySignedIn', STAY_SIGNED_IN_TOKEN, 0, WEB_PATH);
exit($errors['unknown_username_password'][LANG]);
}
else {
$user = $user->exists($_COOKIE['bouffeatulm_login']);
if($_COOKIE['bouffeatulm_staySignedIn'] === md5($user->getStaySignedInToken().$_SERVER['REMOTE_ADDR'])) {
ban_loginOk();
$_SESSION['current_user'] = $user->sessionStore();
$_SESSION['ip'] = user_ip();
setcookie('bouffeatulm_login', $_COOKIE['bouffeatulm_login'], time()+31536000, WEB_PATH);
setcookie('bouffeatulm_staySignedIn', STAY_SIGNED_IN_TOKEN, time()+31536000, WEB_PATH);
header('location: index.php?'.$get_redir);
exit();
}
else {
ban_loginFailed();
setcookie('bouffeatulm_login', $_COOKIE['bouffeatulm_login'], 0, WEB_PATH);
setcookie('bouffeatulm_staySignedIn', STAY_SIGNED_IN_TOKEN, 0, WEB_PATH);
exit($errors['unknown_username_password'][LANG]);
}
}
}
else { else {
$current_user = false; $current_user = false;
} }
}
$tpl->assign('current_user', secureDisplay($current_user)); $tpl->assign('current_user', secureDisplay($current_user));
if(!empty($_GET['json_token'])) { if(!empty($_GET['json_token'])) {
@ -96,7 +120,7 @@
// If IP has changed, logout // If IP has changed, logout
if($current_user !== false && user_ip() != $_SESSION['ip']) { if($current_user !== false && user_ip() != $_SESSION['ip']) {
session_destroy(); logout();
header('location: index.php?do=connect&'.$get_redir); header('location: index.php?do=connect&'.$get_redir);
exit(); exit();
} }
@ -128,15 +152,12 @@
$_SESSION['ip'] = user_ip(); $_SESSION['ip'] = user_ip();
if(!empty($_POST['remember_me'])) { // Handle remember me cookie if(!empty($_POST['remember_me'])) { // Handle remember me cookie
$_SESSION['remember_me'] = 31536000; $token = md5(uniqid(mt_rand(), true));
$user->setStaySignedInToken($token);
$user->save();
setcookie('bouffeatulm_login', $_POST['login'], time()+31536000, WEB_PATH);
setcookie('bouffeatulm_staySignedIn', md5($token.$_SERVER['REMOTE_ADDR']), time()+31536000, WEB_PATH);
} }
else {
$_SESSION['remember_me'] = 0;
}
$cookie_dir = ''; if(dirname($_SERVER['SCRIPT_NAME']) != '/') $cookie_dir = dirname($_SERVER['SCRIPT_NAME']);
session_set_cookie_params($_SESSION['remember_me'], $cookie_dir, $_SERVER['HTTP_HOST']);
session_regenerate_id(true);
header('location: index.php?'.$get_redir); header('location: index.php?'.$get_redir);
exit(); exit();
@ -157,7 +178,7 @@
case 'disconnect': case 'disconnect':
$current_user = false; $current_user = false;
session_destroy(); logout();
header('location: index.php?do=connect&'.$get_redir); header('location: index.php?do=connect&'.$get_redir);
exit(); exit();
break; break;

View File

@ -29,7 +29,7 @@
$db = new PDO('mysql:host='.$mysql_host.';dbname='.$mysql_db, $mysql_login, $mysql_password); $db = new PDO('mysql:host='.$mysql_host.';dbname='.$mysql_db, $mysql_login, $mysql_password);
//Create table "Users" //Create table "Users"
$db->query('CREATE TABLE IF NOT EXISTS '.$mysql_prefix.'Users (id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, login VARCHAR(255), email VARCHAR(255), display_name VARCHAR(255), password VARCHAR(130), admin TINYINT(1), json_token VARCHAR(32), notifications TINYINT(1)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci'); $db->query('CREATE TABLE IF NOT EXISTS '.$mysql_prefix.'Users (id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, login VARCHAR(255), email VARCHAR(255), display_name VARCHAR(255), password VARCHAR(130), admin TINYINT(1), json_token VARCHAR(32), notifications TINYINT(1), stay_signed_in_token VARCHAR(32)) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci');
//Create table "Invoices" //Create table "Invoices"
$db->query('CREATE TABLE IF NOT EXISTS '.$mysql_prefix.'Invoices (id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, date DATETIME, buyer INT(11), amount INT(11), what TEXT) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci'); $db->query('CREATE TABLE IF NOT EXISTS '.$mysql_prefix.'Invoices (id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, date DATETIME, buyer INT(11), amount INT(11), what TEXT) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci');