aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--application/LoginManager.php27
-rw-r--r--application/SessionManager.php66
2 files changed, 69 insertions, 24 deletions
diff --git a/application/LoginManager.php b/application/LoginManager.php
index d81c6c05..347fb3b9 100644
--- a/application/LoginManager.php
+++ b/application/LoginManager.php
@@ -1,6 +1,8 @@
1<?php 1<?php
2namespace Shaarli; 2namespace Shaarli;
3 3
4use Shaarli\Config\ConfigManager;
5
4/** 6/**
5 * User login management 7 * User login management
6 */ 8 */
@@ -62,34 +64,24 @@ class LoginManager
62 return; 64 return;
63 } 65 }
64 66
67 $clientIpId = client_ip_id($server);
68
65 if (isset($cookie[SessionManager::$LOGGED_IN_COOKIE]) 69 if (isset($cookie[SessionManager::$LOGGED_IN_COOKIE])
66 && $cookie[SessionManager::$LOGGED_IN_COOKIE] === $token 70 && $cookie[SessionManager::$LOGGED_IN_COOKIE] === $token
67 ) { 71 ) {
68 $this->sessionManager->storeLoginInfo($server); 72 $this->sessionManager->storeLoginInfo($clientIpId);
69 $this->isLoggedIn = true; 73 $this->isLoggedIn = true;
70 } 74 }
71 75
72 // Logout when: 76 if ($this->sessionManager->hasSessionExpired()
73 // - the session does not exist on the server side 77 || $this->sessionManager->hasClientIpChanged($clientIpId)
74 // - the session has expired
75 // - the client IP address has changed
76 if (empty($session['uid'])
77 || ($this->configManager->get('security.session_protection_disabled') === false
78 && $session['ip'] != client_ip_id($server))
79 || time() >= $session['expires_on']
80 ) { 78 ) {
81 $this->sessionManager->logout($webPath); 79 $this->sessionManager->logout($webPath);
82 $this->isLoggedIn = false; 80 $this->isLoggedIn = false;
83 return; 81 return;
84 } 82 }
85 83
86 // Extend session validity 84 $this->sessionManager->extendSession();
87 if (! empty($session['longlastingsession'])) {
88 // "Stay signed in" is enabled
89 $session['expires_on'] = time() + $session['longlastingsession'];
90 } else {
91 $session['expires_on'] = time() + SessionManager::$INACTIVITY_TIMEOUT;
92 }
93 } 85 }
94 86
95 /** 87 /**
@@ -129,7 +121,8 @@ class LoginManager
129 return false; 121 return false;
130 } 122 }
131 123
132 $this->sessionManager->storeLoginInfo($server); 124 $clientIpId = client_ip_id($server);
125 $this->sessionManager->storeLoginInfo($clientIpId);
133 logm( 126 logm(
134 $this->configManager->get('resource.log'), 127 $this->configManager->get('resource.log'),
135 $server['REMOTE_ADDR'], 128 $server['REMOTE_ADDR'],
diff --git a/application/SessionManager.php b/application/SessionManager.php
index 7bfd2220..63eeb8aa 100644
--- a/application/SessionManager.php
+++ b/application/SessionManager.php
@@ -1,21 +1,23 @@
1<?php 1<?php
2namespace Shaarli; 2namespace Shaarli;
3 3
4use Shaarli\Config\ConfigManager;
5
4/** 6/**
5 * Manages the server-side session 7 * Manages the server-side session
6 */ 8 */
7class SessionManager 9class SessionManager
8{ 10{
9 /** Session expiration timeout, in seconds */ 11 /** @var int Session expiration timeout, in seconds */
10 public static $INACTIVITY_TIMEOUT = 3600; 12 public static $INACTIVITY_TIMEOUT = 3600;
11 13
12 /** Name of the cookie set after logging in **/ 14 /** @var string Name of the cookie set after logging in **/
13 public static $LOGGED_IN_COOKIE = 'shaarli_staySignedIn'; 15 public static $LOGGED_IN_COOKIE = 'shaarli_staySignedIn';
14 16
15 /** Local reference to the global $_SESSION array */ 17 /** @var array Local reference to the global $_SESSION array */
16 protected $session = []; 18 protected $session = [];
17 19
18 /** ConfigManager instance **/ 20 /** @var ConfigManager Configuration Manager instance **/
19 protected $conf = null; 21 protected $conf = null;
20 22
21 /** 23 /**
@@ -94,18 +96,31 @@ class SessionManager
94 /** 96 /**
95 * Store user login information after a successful login 97 * Store user login information after a successful login
96 * 98 *
97 * @param array $server The global $_SERVER array 99 * @param string $clientIpId Client IP address identifier
98 */ 100 */
99 public function storeLoginInfo($server) 101 public function storeLoginInfo($clientIpId)
100 { 102 {
101 // Generate unique random number (different than phpsessionid) 103 // Generate unique random number (different than phpsessionid)
102 $this->session['uid'] = sha1(uniqid('', true) . '_' . mt_rand()); 104 $this->session['uid'] = sha1(uniqid('', true) . '_' . mt_rand());
103 $this->session['ip'] = client_ip_id($server); 105 $this->session['ip'] = $clientIpId;
104 $this->session['username'] = $this->conf->get('credentials.login'); 106 $this->session['username'] = $this->conf->get('credentials.login');
105 $this->session['expires_on'] = time() + self::$INACTIVITY_TIMEOUT; 107 $this->session['expires_on'] = time() + self::$INACTIVITY_TIMEOUT;
106 } 108 }
107 109
108 /** 110 /**
111 * Extend session validity
112 */
113 public function extendSession()
114 {
115 if (! empty($this->session['longlastingsession'])) {
116 // "Stay signed in" is enabled
117 $this->session['expires_on'] = time() + $this->session['longlastingsession'];
118 return;
119 }
120 $this->session['expires_on'] = time() + self::$INACTIVITY_TIMEOUT;
121 }
122
123 /**
109 * Logout a user by unsetting all login information 124 * Logout a user by unsetting all login information
110 * 125 *
111 * See: 126 * See:
@@ -124,4 +139,41 @@ class SessionManager
124 } 139 }
125 setcookie(self::$LOGGED_IN_COOKIE, 'false', 0, $webPath); 140 setcookie(self::$LOGGED_IN_COOKIE, 'false', 0, $webPath);
126 } 141 }
142
143 /**
144 * Check whether the session has expired
145 *
146 * @param string $clientIpId Client IP address identifier
147 *
148 * @return bool true if the session has expired, false otherwise
149 */
150 public function hasSessionExpired()
151 {
152 if (empty($this->session['uid'])) {
153 return true;
154 }
155 if (time() >= $this->session['expires_on']) {
156 return true;
157 }
158 return false;
159 }
160
161 /**
162 * Check whether the client IP address has changed
163 *
164 * @param string $clientIpId Client IP address identifier
165 *
166 * @return bool true if the IP has changed, false if it has not, or
167 * if session protection has been disabled
168 */
169 public function hasClientIpChanged($clientIpId)
170 {
171 if ($this->conf->get('security.session_protection_disabled') === true) {
172 return false;
173 }
174 if ($this->session['ip'] == $clientIpId) {
175 return false;
176 }
177 return true;
178 }
127} 179}