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');
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 $fields = array(
'id'=>'key',
@ -13,11 +13,13 @@ class User extends Storage {
'password'=>'password',
'admin'=>'bool',
'json_token'=>'string',
'notifications'=>'int'
'notifications'=>'int',
'stay_signed_in_token'=>'string'
);
public function __construct() {
parent::__construct();
$stay_signed_in_token = 0;
}
// Getters
@ -50,6 +52,10 @@ class User extends Storage {
return $this->notifications;
}
public function getStaySignedInToken() {
return $this->stay_signed_in_token;
}
// Setters
// =======
public function setId($id) {
@ -106,6 +112,10 @@ class User extends Storage {
}
}
public function setStaySignedInToken($token) {
$this->stay_signed_in_token = $token;
}
// Password functions
// ==================
public function encrypt($text) {
@ -139,10 +149,10 @@ class User extends Storage {
// ===============
public function sessionStore($serialize = true) {
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 {
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->setJsonToken($user_data['json_token']);
$this->setNotifications($user_data['notifications']);
$this->setStaySignedInToken($user_data['stay_signed_in_token']);
}
// Check wether a user already exists or not

View File

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

View File

@ -27,6 +27,13 @@
require_once('inc/functions.php');
require_once('inc/Ban.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'])) {
raintpl::$tpl_dir = 'tpl/json/';
$get_redir = 'json=1';
@ -47,28 +54,45 @@
$tpl->assign('currency', htmlspecialchars(CURRENCY));
$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();
if(isset($_SESSION['current_user'])) {
$current_user->sessionRestore($_SESSION['current_user'], true);
}
else {
$current_user = false;
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 {
$current_user = false;
}
}
$tpl->assign('current_user', secureDisplay($current_user));
if(!empty($_GET['json_token'])) {
@ -96,7 +120,7 @@
// If IP has changed, logout
if($current_user !== false && user_ip() != $_SESSION['ip']) {
session_destroy();
logout();
header('location: index.php?do=connect&'.$get_redir);
exit();
}
@ -128,15 +152,12 @@
$_SESSION['ip'] = user_ip();
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);
exit();
@ -157,7 +178,7 @@
case 'disconnect':
$current_user = false;
session_destroy();
logout();
header('location: index.php?do=connect&'.$get_redir);
exit();
break;

View File

@ -29,7 +29,7 @@
$db = new PDO('mysql:host='.$mysql_host.';dbname='.$mysql_db, $mysql_login, $mysql_password);
//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"
$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');