From de02569e6b953befd9e068139751d7d21c8bfd18 Mon Sep 17 00:00:00 2001
From: Marius Cramer <m.cramer@pixcept.de>
Date: Wed, 20 Nov 2013 19:13:53 +0100
Subject: [PATCH] Allow "keep me logged in" on session timeouts > 0 (setting)
 Fixed login as

---
 install/sql/ispconfig3.sql                    |  1 +
 install/tpl/system.ini.master                 |  1 +
 interface/lib/app.inc.php                     | 21 +++++++++++++++++--
 interface/lib/classes/session.inc.php         | 18 +++++++++++++---
 .../web/admin/form/system_config.tform.php    |  6 ++++++
 .../web/admin/lib/lang/de_system_config.lng   |  1 +
 .../web/admin/lib/lang/en_system_config.lng   |  1 +
 .../templates/system_config_misc_edit.htm     |  6 ++++++
 interface/web/login/index.php                 |  8 ++++---
 interface/web/login/lib/lang/de.lng           |  1 +
 interface/web/login/lib/lang/en.lng           |  1 +
 interface/web/login/templates/index.htm       | 10 ++++++++-
 12 files changed, 66 insertions(+), 9 deletions(-)

diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql
index 62215a846..e215de44d 100644
--- a/install/sql/ispconfig3.sql
+++ b/install/sql/ispconfig3.sql
@@ -1578,6 +1578,7 @@ CREATE TABLE `sys_session` (
   `session_id` varchar(64) NOT NULL DEFAULT '',
   `date_created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
   `last_updated` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+  `permanent` enum('n','y') NOT NULL DEFAULT 'n',
   `session_data` longtext,
   PRIMARY KEY (`session_id`),
   KEY `last_updated` (`last_updated`)
diff --git a/install/tpl/system.ini.master b/install/tpl/system.ini.master
index 0d4a300f8..1f305dde8 100644
--- a/install/tpl/system.ini.master
+++ b/install/tpl/system.ini.master
@@ -50,3 +50,4 @@ customer_no_template=C[CUSTOMER_NO]
 customer_no_start=1
 customer_no_counter=0
 session_timeout=0
+session_allow_endless=0
diff --git a/interface/lib/app.inc.php b/interface/lib/app.inc.php
index 6c19f57cf..40f9a9036 100755
--- a/interface/lib/app.inc.php
+++ b/interface/lib/app.inc.php
@@ -68,8 +68,25 @@ class app {
 			$this->uses('session');
 			$tmp = $this->db->queryOneRecord("SELECT `value` FROM sys_config WHERE `config_id` = 2 AND `group` = 'interface' AND `name` = 'session_timeout'");
 			if($tmp && $tmp['value'] > 0) {
-				$this->session->set_timeout($tmp['value']);
-				session_set_cookie_params(($tmp['value'] * 60) + 300); // make the cookie live 5 minutes longer
+				/* check if user wants to stay logged in */
+				if(isset($_POST['s_mod']) && isset($_POST['s_pg']) && $_POST['s_mod'] == 'login' && $_POST['s_pg'] == 'index' && isset($_POST['stay']) && $_POST['stay'] == '1') {
+					/* check if staying logged in is allowed */
+					$app->uses('ini_parser');
+					$tmp = $app->db->queryOneRecord('SELECT config FROM sys_ini WHERE sysini_id = 1');
+					$tmp = $app->ini_parser->parse_ini_string(stripslashes($tmp['config']));
+					if(!isset($tmp['misc']['session_allow_endless']) || $tmp['misc']['session_allow_endless'] != 'y') {
+						$this->session->set_timeout($tmp['value']);
+						session_set_cookie_params(($tmp['value'] * 60) + 300); // make the cookie live 5 minutes longer
+					} else {
+						// we are doing login here, so we need to set the session data
+						$this->session->set_permanent(true);
+						$this->session->set_timeout(365 * 24 * 3600); // one year
+						session_set_cookie_params(365 * 24 * 3600); // make the cookie live 5 minutes longer
+					}
+				} else {
+					$this->session->set_timeout($tmp['value']);
+					session_set_cookie_params(($tmp['value'] * 60) + 300); // make the cookie live 5 minutes longer
+				}
 			} else {
 				session_set_cookie_params(0); // until browser is closed
 			}
diff --git a/interface/lib/classes/session.inc.php b/interface/lib/classes/session.inc.php
index 03fad95b0..dcb187b6c 100644
--- a/interface/lib/classes/session.inc.php
+++ b/interface/lib/classes/session.inc.php
@@ -33,6 +33,7 @@ class session {
 	private $session_array = array();
 	private $db;
 	private $timeout = 0;
+	private $permanent = false;
 
 	function __construct($session_timeout = 0) {
 		$this->db = new db;
@@ -44,6 +45,10 @@ class session {
 		$this->timeout = $session_timeout;
 		return $old_timeout;
 	}
+	
+	function set_permanent($value = false) {
+		$this->permanent = $value;
+	}
 
 	function open ($save_path, $session_name) {
 		return true;
@@ -61,7 +66,7 @@ class session {
 	function read ($session_id) {
 		
 		if($this->timeout > 0) {
-			$rec = $this->db->queryOneRecord("SELECT * FROM sys_session WHERE session_id = '".$this->db->quote($session_id)."' AND last_updated >= DATE_SUB(NOW(), INTERVAL " . intval($this->timeout) . " MINUTE)");
+			$rec = $this->db->queryOneRecord("SELECT * FROM sys_session WHERE session_id = '".$this->db->quote($session_id)."' AND (`permanent` = 'y' OR last_updated >= DATE_SUB(NOW(), INTERVAL " . intval($this->timeout) . " MINUTE))");
 		} else {
 			$rec = $this->db->queryOneRecord("SELECT * FROM sys_session WHERE session_id = '".$this->db->quote($session_id)."'");
 		}
@@ -94,14 +99,14 @@ class session {
 			$date_created = date('Y-m-d H:i:s');
 			$last_updated = date('Y-m-d H:i:s');
 			$session_data = $this->db->quote($session_data);
-			$sql = "INSERT INTO sys_session (session_id,date_created,last_updated,session_data) VALUES ('$session_id','$date_created','$last_updated','$session_data')";
+			$sql = "INSERT INTO sys_session (session_id,date_created,last_updated,session_data,permanent) VALUES ('$session_id','$date_created','$last_updated','$session_data','" . ($this->permanent ? 'y' : 'n') . "')";
 			$this->db->query($sql);
 
 		} else {
 			$session_id   = $this->db->quote($session_id);
 			$last_updated = date('Y-m-d H:i:s');
 			$session_data = $this->db->quote($session_data);
-			$sql = "UPDATE sys_session SET last_updated = '$last_updated', session_data = '$session_data' WHERE session_id = '$session_id'";
+			$sql = "UPDATE sys_session SET last_updated = '$last_updated', session_data = '$session_data'" . ($this->permanent ? ", `permanent` = 'y'" : "") . " WHERE session_id = '$session_id'";
 			$this->db->query($sql);
 
 		}
@@ -127,6 +132,13 @@ class session {
 			$dt1 = strtotime("$real_now -$max_lifetime seconds");
 			$dt2 = date('Y-m-d H:i:s', $dt1);
 
+			$sql = "DELETE FROM sys_session WHERE last_updated < '$dt2' AND `permanent` != 'y'";
+			$this->db->query($sql);
+			
+			/* delete very old even if they are permanent */
+			$dt1 = strtotime("$real_now -365 days");
+			$dt2 = date('Y-m-d H:i:s', $dt1);
+
 			$sql = "DELETE FROM sys_session WHERE last_updated < '$dt2'";
 			$this->db->query($sql);
 		//}
diff --git a/interface/web/admin/form/system_config.tform.php b/interface/web/admin/form/system_config.tform.php
index 28d2ac890..2303e61b9 100644
--- a/interface/web/admin/form/system_config.tform.php
+++ b/interface/web/admin/form/system_config.tform.php
@@ -481,6 +481,12 @@ $form["tabs"]['misc'] = array (
 			'width'  => '30',
 			'maxlength' => '255'
 		),
+		'session_allow_endless' => array (
+			'datatype' => 'VARCHAR',
+			'formtype' => 'CHECKBOX',
+			'default' => 'n',
+			'value'  => array(0 => 'n', 1 => 'y')
+		),
 		//#################################
 		// ENDE Datatable fields
 		//#################################
diff --git a/interface/web/admin/lib/lang/de_system_config.lng b/interface/web/admin/lib/lang/de_system_config.lng
index 06733187f..53432cd9d 100644
--- a/interface/web/admin/lib/lang/de_system_config.lng
+++ b/interface/web/admin/lib/lang/de_system_config.lng
@@ -64,4 +64,5 @@ $wb['customer_no_template_error_regex_txt'] = 'Die Kundennummer-Vorlage enthält
 $wb['customer_no_start_txt'] = 'Kundennummer Startwert';
 $wb['customer_no_counter_txt'] = 'Kundennummer Zähler';
 $wb['session_timeout_txt'] = 'Session-Timeout (Minuten)';
+$wb['session_allow_endless_txt'] = '"Eingeloggt bleiben" aktivieren';
 ?>
\ No newline at end of file
diff --git a/interface/web/admin/lib/lang/en_system_config.lng b/interface/web/admin/lib/lang/en_system_config.lng
index d9bd9ec6f..deeda4fa0 100644
--- a/interface/web/admin/lib/lang/en_system_config.lng
+++ b/interface/web/admin/lib/lang/en_system_config.lng
@@ -64,4 +64,5 @@ $wb['customer_no_template_error_regex_txt'] = 'The customer No. template contain
 $wb['customer_no_start_txt'] = 'Customer No. start value';
 $wb['customer_no_counter_txt'] = 'Customer No. counter';
 $wb['session_timeout_txt'] = 'Session timeout (minutes)';
+$wb['session_allow_endless_txt'] = 'Enable "stay logged in"';
 ?>
diff --git a/interface/web/admin/templates/system_config_misc_edit.htm b/interface/web/admin/templates/system_config_misc_edit.htm
index de9e3c345..ea9844e45 100644
--- a/interface/web/admin/templates/system_config_misc_edit.htm
+++ b/interface/web/admin/templates/system_config_misc_edit.htm
@@ -84,6 +84,12 @@
 			<div class="ctrlHolder">
                 <label for="session_timeout">{tmpl_var name='session_timeout_txt'}</label>
                 <input name="session_timeout" id="session_timeout" value="{tmpl_var name='session_timeout'}" size="30" maxlength="255" type="text" class="textInput formLengthHalf" />
+            </div>
+			<div class="ctrlHolder">
+                <p class="label">{tmpl_var name='session_allow_endless_txt'}</p>
+                <div class="multiField">
+                    {tmpl_var name='session_allow_endless'}
+                </div>
             </div>
 			<div class="ctrlHolder">
                 <p class="label">{tmpl_var name='maintenance_mode_txt'}</p>
diff --git a/interface/web/login/index.php b/interface/web/login/index.php
index 6e8f9ce5b..951dbaf29 100644
--- a/interface/web/login/index.php
+++ b/interface/web/login/index.php
@@ -122,7 +122,7 @@ class login_index {
 						else {
 							die("You don't have the right to 'login as'!");
 						}
-					} elseif($_SESSION['s']['user']['typ'] != 'admin') {
+					} elseif($_SESSION['s']['user']['typ'] != 'admin' && (!isset($_SESSION['s_old']['user']) || $_SESSION['s_old']['user']['typ'] != 'admin')) {
 						/* a reseller wants to 'login as', we need to check if he is allowed to */
 						$res_client_group_id = $app->functions->intval($_SESSION["s"]["user"]["default_group"]);
 						$res_client = $app->db->queryOneRecord("SELECT client.client_id FROM sys_group, client WHERE sys_group.client_id = client.client_id and sys_group.groupid = $res_client_group_id");
@@ -230,7 +230,6 @@ class login_index {
 								$_SESSION['s']['user']['theme'] = isset($user['app_theme']) ? $user['app_theme'] : 'default';
 								$_SESSION['s']['language'] = $user['language'];
 								$_SESSION["s"]['theme'] = $_SESSION['s']['user']['theme'];
-								$_SESSION['s']['session_timeout'] = $server_config_array['session_timeout'];
 								
 								if(is_file($_SESSION['s']['user']['startmodule'].'/lib/module.conf.php')) {
 									include_once $_SESSION['s']['user']['startmodule'].'/lib/module.conf.php';
@@ -318,12 +317,15 @@ class login_index {
 		if($error != ''){
 			$error = '<div class="box box_error"><h1>Error</h1>'.$error.'</div>';
 		}
-
+		
 		$app->tpl->setVar('error', $error);
 		$app->tpl->setVar('pw_lost_txt', $app->lng('pw_lost_txt'));
 		$app->tpl->setVar('username_txt', $app->lng('username_txt'));
 		$app->tpl->setVar('password_txt', $app->lng('password_txt'));
+		$app->tpl->setVar('stay_logged_in_txt', $app->lng('stay_logged_in_txt'));
 		$app->tpl->setVar('login_button_txt', $app->lng('login_button_txt'));
+		$app->tpl->setVar('session_timeout', $server_config_array['session_timeout']);
+		$app->tpl->setVar('session_allow_endless', $server_config_array['session_allow_endless']);
 		$app->tpl->setInclude('content_tpl', 'login/templates/index.htm');
 		$app->tpl_defaults();
 
diff --git a/interface/web/login/lib/lang/de.lng b/interface/web/login/lib/lang/de.lng
index 93372b210..38a9763c2 100644
--- a/interface/web/login/lib/lang/de.lng
+++ b/interface/web/login/lib/lang/de.lng
@@ -22,4 +22,5 @@ $wb['email_txt'] = 'E-Mail';
 $wb['error_maintenance_mode'] = 'Diese ISPConfig Installation wird gerade gewartet. Wir sind in Kürze wieder für Sie da. Vielen Dank für Ihre Geduld.';
 $wb['theme_not_compatible'] = 'Das gewählte Design ist mit dieser ISPConfig Version nicht kompatibel. Bitte prüfen Sie, ob ein Update des Themes verfügbar ist.<br />Es wurde nun automatisch das Standard Design aktiviert.';
 $wb['back_txt'] = 'Zur&uuml;ck';
+$wb['stay_logged_in_txt'] = 'Dauerhaft eingeloggt bleiben';
 ?>
\ No newline at end of file
diff --git a/interface/web/login/lib/lang/en.lng b/interface/web/login/lib/lang/en.lng
index 082d1c226..768eaba6a 100644
--- a/interface/web/login/lib/lang/en.lng
+++ b/interface/web/login/lib/lang/en.lng
@@ -27,4 +27,5 @@ $wb['back_txt'] = 'Back';
 $wb['error_maintenance_mode'] = 'This ISPConfig installation is currently under maintenance. We should be back shortly. Thank you for your patience.';
 
 $wb['theme_not_compatible'] = 'The chosen theme is not compatible with the current ISPConfig version. Please check for a new version of the theme.<br />The default theme as been activated automatically.';
+$wb['stay_logged_in_txt'] = 'Keep me logged in';
 ?>
\ No newline at end of file
diff --git a/interface/web/login/templates/index.htm b/interface/web/login/templates/index.htm
index a956701d4..eaf9e0808 100644
--- a/interface/web/login/templates/index.htm
+++ b/interface/web/login/templates/index.htm
@@ -19,7 +19,15 @@
             <div class="ctrlHolder">
                 <label for="passwort">{tmpl_var name='password_txt'}</label>
                 <input name="passwort" id="passwort" value="" size="30" maxlength="255" type="password" class="formLengthEmailUser"  onkeypress="if (event.keyCode && event.keyCode == 13) {submitLoginForm('pageForm'); return false;};" />
-            </div>			
+            </div>
+            <tmpl_if name="session_timeout" op=">" value="0">
+				<tmpl_if name="session_allow_endless" value="y">
+            <div class="ctrlHolder">
+                <label for="passwort">{tmpl_var name='stay_logged_in_txt'}</label>
+                <input name="stay" id="stay" value="1" type="checkbox" onkeypress="if (event.keyCode && event.keyCode == 13) {submitLoginForm('pageForm'); return false;};" />
+            </div>
+				</tmpl_if>
+            </tmpl_if>
         </fieldset>
 
         <input type="hidden" name="s_mod" value="login" />
-- 
GitLab