From 88110550b89617dcda16441212599b8a40faa20c Mon Sep 17 00:00:00 2001 From: VirtualTam Date: Fri, 16 Feb 2018 21:51:44 +0100 Subject: Refactor client session hijacking protection Signed-off-by: VirtualTam --- application/HttpUtils.php | 33 +++++++++++++++++++++++- index.php | 14 ++-------- tests/HttpUtils/ClientIpIdTest.php | 52 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 13 deletions(-) create mode 100644 tests/HttpUtils/ClientIpIdTest.php diff --git a/application/HttpUtils.php b/application/HttpUtils.php index 83a4c5e2..e9282506 100644 --- a/application/HttpUtils.php +++ b/application/HttpUtils.php @@ -1,7 +1,7 @@ get('security.session_protection_disabled') === false && $_SESSION['ip'] != allIPs()) + || ($conf->get('security.session_protection_disabled') === false && $_SESSION['ip'] != client_ip_id($_SERVER)) || time() >= $_SESSION['expires_on']) { logout(); @@ -231,16 +231,6 @@ $userIsLoggedIn = setup_login_state($conf); // ------------------------------------------------------------------------------------------ // Session management -// Returns the IP address of the client (Used to prevent session cookie hijacking.) -function allIPs() -{ - $ip = $_SERVER['REMOTE_ADDR']; - // Then we use more HTTP headers to prevent session hijacking from users behind the same proxy. - if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ip=$ip.'_'.$_SERVER['HTTP_X_FORWARDED_FOR']; } - if (isset($_SERVER['HTTP_CLIENT_IP'])) { $ip=$ip.'_'.$_SERVER['HTTP_CLIENT_IP']; } - return $ip; -} - /** * Load user session. * @@ -249,7 +239,7 @@ function allIPs() function fillSessionInfo($conf) { $_SESSION['uid'] = sha1(uniqid('',true).'_'.mt_rand()); // Generate unique random number (different than phpsessionid) - $_SESSION['ip']=allIPs(); // We store IP address(es) of the client to make sure session is not hijacked. + $_SESSION['ip'] = client_ip_id($_SERVER); $_SESSION['username']= $conf->get('credentials.login'); $_SESSION['expires_on']=time()+INACTIVITY_TIMEOUT; // Set session expiration. } diff --git a/tests/HttpUtils/ClientIpIdTest.php b/tests/HttpUtils/ClientIpIdTest.php new file mode 100644 index 00000000..c15ac5cc --- /dev/null +++ b/tests/HttpUtils/ClientIpIdTest.php @@ -0,0 +1,52 @@ +assertEquals( + '10.1.167.42', + client_ip_id(['REMOTE_ADDR' => '10.1.167.42']) + ); + } + + /** + * Get a remote client ID based on its IP and proxy information (1) + */ + public function testClientIpIdRemoteForwarded() + { + $this->assertEquals( + '10.1.167.42_127.0.1.47', + client_ip_id([ + 'REMOTE_ADDR' => '10.1.167.42', + 'HTTP_X_FORWARDED_FOR' => '127.0.1.47' + ]) + ); + } + + /** + * Get a remote client ID based on its IP and proxy information (2) + */ + public function testClientIpIdRemoteForwardedClient() + { + $this->assertEquals( + '10.1.167.42_10.1.167.56_127.0.1.47', + client_ip_id([ + 'REMOTE_ADDR' => '10.1.167.42', + 'HTTP_X_FORWARDED_FOR' => '10.1.167.56', + 'HTTP_CLIENT_IP' => '127.0.1.47' + ]) + ); + } +} -- cgit v1.2.3 From db45a36a53dbd722e5e891827e49d9e7651f2a5e Mon Sep 17 00:00:00 2001 From: VirtualTam Date: Fri, 16 Feb 2018 22:21:59 +0100 Subject: Refactor SessionManager::$INACTIVITY_TIMEOUT Changed: - move INACTIVITY_TIMEOUT to SessionManager - inject a dependency to a SessionManager instance in: - fillSessionInfo() - setup_login_state() - check_auth() - cleanup related code and comments Signed-off-by: VirtualTam --- application/SessionManager.php | 4 ++++ index.php | 48 +++++++++++++++++++++--------------------- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/application/SessionManager.php b/application/SessionManager.php index 71f0b38d..704f8504 100644 --- a/application/SessionManager.php +++ b/application/SessionManager.php @@ -6,6 +6,10 @@ namespace Shaarli; */ class SessionManager { + /** Session expiration timeout, in seconds */ + public static $INACTIVITY_TIMEOUT = 3600; + + /** Local reference to the global $_SESSION array */ protected $session = []; /** diff --git a/index.php b/index.php index 08a69327..9cbc9241 100644 --- a/index.php +++ b/index.php @@ -101,8 +101,6 @@ if (dirname($_SERVER['SCRIPT_NAME']) != '/') { // Set default cookie expiration and path. session_set_cookie_params($cookie['lifetime'], $cookiedir, $_SERVER['SERVER_NAME']); // Set session parameters on server side. -// If the user does not access any page within this time, his/her session is considered expired. -define('INACTIVITY_TIMEOUT', 3600); // in seconds. // Use cookies to store session. ini_set('session.use_cookies', 1); // Force cookies for session (phpsessionID forbidden in URL). @@ -183,11 +181,12 @@ define('STAY_SIGNED_IN_TOKEN', sha1($conf->get('credentials.hash') . $_SERVER['R /** * Checking session state (i.e. is the user still logged in) * - * @param ConfigManager $conf The configuration manager. + * @param ConfigManager $conf Configuration Manager instance. + * @param SessionManager $sessionManager SessionManager instance * - * @return bool: true if the user is logged in, false otherwise. + * @return bool true if the user is logged in, false otherwise. */ -function setup_login_state($conf) +function setup_login_state($conf, $sessionManager) { if ($conf->get('security.open_shaarli')) { return true; @@ -202,7 +201,7 @@ function setup_login_state($conf) $_COOKIE['shaarli_staySignedIn']===STAY_SIGNED_IN_TOKEN && !$loginFailure) { - fillSessionInfo($conf); + fillSessionInfo($conf, $sessionManager); $userIsLoggedIn = true; } // If session does not exist on server side, or IP address has changed, or session has expired, logout. @@ -216,9 +215,8 @@ function setup_login_state($conf) } if (!empty($_SESSION['longlastingsession'])) { $_SESSION['expires_on']=time()+$_SESSION['longlastingsession']; // In case of "Stay signed in" checked. - } - else { - $_SESSION['expires_on']=time()+INACTIVITY_TIMEOUT; // Standard session expiration date. + } else { + $_SESSION['expires_on'] = time() + $sessionManager::$INACTIVITY_TIMEOUT; } if (!$loginFailure) { $userIsLoggedIn = true; @@ -226,39 +224,42 @@ function setup_login_state($conf) return $userIsLoggedIn; } -$userIsLoggedIn = setup_login_state($conf); + +$userIsLoggedIn = setup_login_state($conf, $sessionManager); // ------------------------------------------------------------------------------------------ // Session management /** - * Load user session. + * Load user session * - * @param ConfigManager $conf Configuration Manager instance. + * @param ConfigManager $conf Configuration Manager instance. + * @param SessionManager $sessionManager SessionManager instance */ -function fillSessionInfo($conf) +function fillSessionInfo($conf, $sessionManager) { $_SESSION['uid'] = sha1(uniqid('',true).'_'.mt_rand()); // Generate unique random number (different than phpsessionid) $_SESSION['ip'] = client_ip_id($_SERVER); $_SESSION['username']= $conf->get('credentials.login'); - $_SESSION['expires_on']=time()+INACTIVITY_TIMEOUT; // Set session expiration. + $_SESSION['expires_on'] = time() + $sessionManager::$INACTIVITY_TIMEOUT; } /** * Check that user/password is correct. * - * @param string $login Username - * @param string $password User password - * @param ConfigManager $conf Configuration Manager instance. + * @param string $login Username + * @param string $password User password + * @param ConfigManager $conf Configuration Manager instance. + * @param SessionManager $sessionManager SessionManager instance * * @return bool: authentication successful or not. */ -function check_auth($login, $password, $conf) +function check_auth($login, $password, $conf, $sessionManager) { $hash = sha1($password . $login . $conf->get('credentials.salt')); - if ($login == $conf->get('credentials.login') && $hash == $conf->get('credentials.hash')) - { // Login/password is correct. - fillSessionInfo($conf); + if ($login == $conf->get('credentials.login') && $hash == $conf->get('credentials.hash')) { + // Login/password is correct. + fillSessionInfo($conf, $sessionManager); logm($conf->get('resource.log'), $_SERVER['REMOTE_ADDR'], 'Login successful'); return true; } @@ -287,14 +288,13 @@ function logout() { // ------------------------------------------------------------------------------------------ // Process login form: Check if login/password is correct. -if (isset($_POST['login'])) -{ +if (isset($_POST['login'])) { if (! $loginManager->canLogin($_SERVER)) { die(t('I said: NO. You are banned for the moment. Go away.')); } if (isset($_POST['password']) && $sessionManager->checkToken($_POST['token']) - && (check_auth($_POST['login'], $_POST['password'], $conf)) + && (check_auth($_POST['login'], $_POST['password'], $conf, $sessionManager)) ) { // Login/password is OK. $loginManager->handleSuccessfulLogin($_SERVER); -- cgit v1.2.3 From 49f183231662c642ca9df6ceabf43fe128a5ffc1 Mon Sep 17 00:00:00 2001 From: VirtualTam Date: Sat, 17 Feb 2018 01:14:58 +0100 Subject: Refactor PHP session handling during login/logout Changed: - move $_SESSION handling to SessionManager - code cleanup Signed-off-by: VirtualTam --- application/SessionManager.php | 40 ++++++++++++++++++++++++++++++++++ index.php | 49 +++++++++++------------------------------- 2 files changed, 53 insertions(+), 36 deletions(-) diff --git a/application/SessionManager.php b/application/SessionManager.php index 704f8504..7bfd2220 100644 --- a/application/SessionManager.php +++ b/application/SessionManager.php @@ -9,9 +9,15 @@ class SessionManager /** Session expiration timeout, in seconds */ public static $INACTIVITY_TIMEOUT = 3600; + /** Name of the cookie set after logging in **/ + public static $LOGGED_IN_COOKIE = 'shaarli_staySignedIn'; + /** Local reference to the global $_SESSION array */ protected $session = []; + /** ConfigManager instance **/ + protected $conf = null; + /** * Constructor * @@ -84,4 +90,38 @@ class SessionManager return true; } + + /** + * Store user login information after a successful login + * + * @param array $server The global $_SERVER array + */ + public function storeLoginInfo($server) + { + // Generate unique random number (different than phpsessionid) + $this->session['uid'] = sha1(uniqid('', true) . '_' . mt_rand()); + $this->session['ip'] = client_ip_id($server); + $this->session['username'] = $this->conf->get('credentials.login'); + $this->session['expires_on'] = time() + self::$INACTIVITY_TIMEOUT; + } + + /** + * Logout a user by unsetting all login information + * + * See: + * - https://secure.php.net/manual/en/function.setcookie.php + * + * @param string $webPath path on the server in which the cookie will be available on + */ + public function logout($webPath) + { + if (isset($this->session)) { + unset($this->session['uid']); + unset($this->session['ip']); + unset($this->session['username']); + unset($this->session['visibility']); + unset($this->session['untaggedonly']); + } + setcookie(self::$LOGGED_IN_COOKIE, 'false', 0, $webPath); + } } diff --git a/index.php b/index.php index 9cbc9241..34785209 100644 --- a/index.php +++ b/index.php @@ -197,11 +197,11 @@ function setup_login_state($conf, $sessionManager) $userIsLoggedIn = false; // Shaarli is not configured yet. $loginFailure = true; } - if (isset($_COOKIE['shaarli_staySignedIn']) && - $_COOKIE['shaarli_staySignedIn']===STAY_SIGNED_IN_TOKEN && - !$loginFailure) - { - fillSessionInfo($conf, $sessionManager); + if (isset($_COOKIE[SessionManager::$LOGGED_IN_COOKIE]) + && $_COOKIE[SessionManager::$LOGGED_IN_COOKIE] === STAY_SIGNED_IN_TOKEN + && !$loginFailure + ) { + $sessionManager->storeLoginInfo($_SERVER); $userIsLoggedIn = true; } // If session does not exist on server side, or IP address has changed, or session has expired, logout. @@ -209,7 +209,7 @@ function setup_login_state($conf, $sessionManager) || ($conf->get('security.session_protection_disabled') === false && $_SESSION['ip'] != client_ip_id($_SERVER)) || time() >= $_SESSION['expires_on']) { - logout(); + $sessionManager->logout(WEB_PATH); $userIsLoggedIn = false; $loginFailure = true; } @@ -230,20 +230,6 @@ $userIsLoggedIn = setup_login_state($conf, $sessionManager); // ------------------------------------------------------------------------------------------ // Session management -/** - * Load user session - * - * @param ConfigManager $conf Configuration Manager instance. - * @param SessionManager $sessionManager SessionManager instance - */ -function fillSessionInfo($conf, $sessionManager) -{ - $_SESSION['uid'] = sha1(uniqid('',true).'_'.mt_rand()); // Generate unique random number (different than phpsessionid) - $_SESSION['ip'] = client_ip_id($_SERVER); - $_SESSION['username']= $conf->get('credentials.login'); - $_SESSION['expires_on'] = time() + $sessionManager::$INACTIVITY_TIMEOUT; -} - /** * Check that user/password is correct. * @@ -259,7 +245,7 @@ function check_auth($login, $password, $conf, $sessionManager) $hash = sha1($password . $login . $conf->get('credentials.salt')); if ($login == $conf->get('credentials.login') && $hash == $conf->get('credentials.hash')) { // Login/password is correct. - fillSessionInfo($conf, $sessionManager); + $sessionManager->storeLoginInfo($_SERVER); logm($conf->get('resource.log'), $_SERVER['REMOTE_ADDR'], 'Login successful'); return true; } @@ -274,18 +260,6 @@ function isLoggedIn() return $userIsLoggedIn; } -// Force logout. -function logout() { - if (isset($_SESSION)) { - unset($_SESSION['uid']); - unset($_SESSION['ip']); - unset($_SESSION['username']); - unset($_SESSION['visibility']); - unset($_SESSION['untaggedonly']); - } - setcookie('shaarli_staySignedIn', FALSE, 0, WEB_PATH); -} - // ------------------------------------------------------------------------------------------ // Process login form: Check if login/password is correct. if (isset($_POST['login'])) { @@ -303,10 +277,13 @@ if (isset($_POST['login'])) { if (!empty($_POST['longlastingsession'])) { $_SESSION['longlastingsession'] = 31536000; // (31536000 seconds = 1 year) $expiration = time() + $_SESSION['longlastingsession']; // calculate relative cookie expiration (1 year from now) - setcookie('shaarli_staySignedIn', STAY_SIGNED_IN_TOKEN, $expiration, WEB_PATH); + setcookie($sessionManager::$LOGGED_IN_COOKIE, STAY_SIGNED_IN_TOKEN, $expiration, WEB_PATH); $_SESSION['expires_on'] = $expiration; // Set session expiration on server-side. - $cookiedir = ''; if(dirname($_SERVER['SCRIPT_NAME'])!='/') $cookiedir=dirname($_SERVER["SCRIPT_NAME"]).'/'; + $cookiedir = ''; + if (dirname($_SERVER['SCRIPT_NAME']) != '/') { + $cookiedir = dirname($_SERVER["SCRIPT_NAME"]) . '/'; + } session_set_cookie_params($_SESSION['longlastingsession'],$cookiedir,$_SERVER['SERVER_NAME']); // Set session cookie expiration on client side // Note: Never forget the trailing slash on the cookie path! session_regenerate_id(true); // Send cookie with new expiration date to browser. @@ -676,7 +653,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=logout')) { invalidateCaches($conf->get('resource.page_cache')); - logout(); + $sessionManager->logout(WEB_PATH); header('Location: ?'); exit; } -- cgit v1.2.3 From 63ea23c2a67d2a1cf6cda79fa2fe49a143571cde Mon Sep 17 00:00:00 2001 From: VirtualTam Date: Sat, 17 Feb 2018 01:46:27 +0100 Subject: Refactor user credential validation at login time Changed: - move login/password verification to LoginManager - code cleanup Signed-off-by: VirtualTam --- application/LoginManager.php | 109 +++++++++++++++++++++++++++++++- index.php | 144 ++++++++++++------------------------------- tests/LoginManagerTest.php | 4 +- 3 files changed, 146 insertions(+), 111 deletions(-) diff --git a/application/LoginManager.php b/application/LoginManager.php index 397bc6e3..8f6bf0da 100644 --- a/application/LoginManager.php +++ b/application/LoginManager.php @@ -8,20 +8,123 @@ class LoginManager { protected $globals = []; protected $configManager = null; + protected $sessionManager = null; protected $banFile = ''; + protected $isLoggedIn = false; + protected $openShaarli = false; /** * Constructor * - * @param array $globals The $GLOBALS array (reference) - * @param ConfigManager $configManager Configuration Manager instance. + * @param array $globals The $GLOBALS array (reference) + * @param ConfigManager $configManager Configuration Manager instance + * @param SessionManager $sessionManager SessionManager instance */ - public function __construct(& $globals, $configManager) + public function __construct(& $globals, $configManager, $sessionManager) { $this->globals = &$globals; $this->configManager = $configManager; + $this->sessionManager = $sessionManager; $this->banFile = $this->configManager->get('resource.ban_file', 'data/ipbans.php'); $this->readBanFile(); + if ($this->configManager->get('security.open_shaarli')) { + $this->openShaarli = true; + } + } + + /** + * Check user session state and validity (expiration) + * + * @param array $server The $_SERVER array + * @param array $session The $_SESSION array (reference) + * @param array $cookie The $_COOKIE array + * @param string $webPath Path on the server in which the cookie will be available on + * @param string $token Session token + * + * @return bool true if the user session is valid, false otherwise + */ + public function checkLoginState($server, & $session, $cookie, $webPath, $token) + { + if (! $this->configManager->exists('credentials.login')) { + // Shaarli is not configured yet + $this->isLoggedIn = false; + return; + } + + if (isset($cookie[SessionManager::$LOGGED_IN_COOKIE]) + && $cookie[SessionManager::$LOGGED_IN_COOKIE] === $token + ) { + $this->sessionManager->storeLoginInfo($server); + $this->isLoggedIn = true; + } + + // Logout when: + // - the session does not exist on the server side + // - the session has expired + // - the client IP address has changed + if (empty($session['uid']) + || ($this->configManager->get('security.session_protection_disabled') === false + && $session['ip'] != client_ip_id($server)) + || time() >= $session['expires_on'] + ) { + $this->sessionManager->logout($webPath); + $this->isLoggedIn = false; + return; + } + + // Extend session validity + if (! empty($session['longlastingsession'])) { + // "Stay signed in" is enabled + $session['expires_on'] = time() + $session['longlastingsession']; + } else { + $session['expires_on'] = time() + SessionManager::$INACTIVITY_TIMEOUT; + } + } + + /** + * Return whether the user is currently logged in + * + * @return true when the user is logged in, false otherwise + */ + public function isLoggedIn() + { + if ($this->openShaarli) { + return true; + } + return $this->isLoggedIn; + } + + /** + * Check user credentials are valid + * + * @param array $server The $_SERVER array + * @param string $login Username + * @param string $password Password + * + * @return bool true if the provided credentials are valid, false otherwise + */ + public function checkCredentials($server, $login, $password) + { + $hash = sha1($password . $login . $this->configManager->get('credentials.salt')); + + if ($login != $this->configManager->get('credentials.login') + || $hash != $this->configManager->get('credentials.hash') + ) { + logm( + $this->configManager->get('resource.log'), + $server['REMOTE_ADDR'], + 'Login failed for user ' . $login + ); + return false; + } + + $this->sessionManager->storeLoginInfo($server); + logm( + $this->configManager->get('resource.log'), + $server['REMOTE_ADDR'], + 'Login successful' + ); + return true; } /** diff --git a/index.php b/index.php index 34785209..5e15b9c2 100644 --- a/index.php +++ b/index.php @@ -121,8 +121,8 @@ if (isset($_COOKIE['shaarli']) && !SessionManager::checkId($_COOKIE['shaarli'])) } $conf = new ConfigManager(); -$loginManager = new LoginManager($GLOBALS, $conf); $sessionManager = new SessionManager($_SESSION, $conf); +$loginManager = new LoginManager($GLOBALS, $conf, $sessionManager); // LC_MESSAGES isn't defined without php-intl, in this case use LC_COLLATE locale instead. if (! defined('LC_MESSAGES')) { @@ -178,88 +178,20 @@ if (! is_file($conf->getConfigFileExt())) { // a token depending of deployment salt, user password, and the current ip define('STAY_SIGNED_IN_TOKEN', sha1($conf->get('credentials.hash') . $_SERVER['REMOTE_ADDR'] . $conf->get('credentials.salt'))); -/** - * Checking session state (i.e. is the user still logged in) - * - * @param ConfigManager $conf Configuration Manager instance. - * @param SessionManager $sessionManager SessionManager instance - * - * @return bool true if the user is logged in, false otherwise. - */ -function setup_login_state($conf, $sessionManager) -{ - if ($conf->get('security.open_shaarli')) { - return true; - } - $userIsLoggedIn = false; // By default, we do not consider the user as logged in; - $loginFailure = false; // If set to true, every attempt to authenticate the user will fail. This indicates that an important condition isn't met. - if (! $conf->exists('credentials.login')) { - $userIsLoggedIn = false; // Shaarli is not configured yet. - $loginFailure = true; - } - if (isset($_COOKIE[SessionManager::$LOGGED_IN_COOKIE]) - && $_COOKIE[SessionManager::$LOGGED_IN_COOKIE] === STAY_SIGNED_IN_TOKEN - && !$loginFailure - ) { - $sessionManager->storeLoginInfo($_SERVER); - $userIsLoggedIn = true; - } - // If session does not exist on server side, or IP address has changed, or session has expired, logout. - if (empty($_SESSION['uid']) - || ($conf->get('security.session_protection_disabled') === false && $_SESSION['ip'] != client_ip_id($_SERVER)) - || time() >= $_SESSION['expires_on']) - { - $sessionManager->logout(WEB_PATH); - $userIsLoggedIn = false; - $loginFailure = true; - } - if (!empty($_SESSION['longlastingsession'])) { - $_SESSION['expires_on']=time()+$_SESSION['longlastingsession']; // In case of "Stay signed in" checked. - } else { - $_SESSION['expires_on'] = time() + $sessionManager::$INACTIVITY_TIMEOUT; - } - if (!$loginFailure) { - $userIsLoggedIn = true; - } - - return $userIsLoggedIn; -} - -$userIsLoggedIn = setup_login_state($conf, $sessionManager); - -// ------------------------------------------------------------------------------------------ -// Session management +$loginManager->checkLoginState($_SERVER, $_SESSION, $_COOKIE, WEB_PATH, STAY_SIGNED_IN_TOKEN); /** - * Check that user/password is correct. - * - * @param string $login Username - * @param string $password User password - * @param ConfigManager $conf Configuration Manager instance. - * @param SessionManager $sessionManager SessionManager instance + * Adapter function for PageBuilder * - * @return bool: authentication successful or not. + * TODO: update PageBuilder and tests */ -function check_auth($login, $password, $conf, $sessionManager) -{ - $hash = sha1($password . $login . $conf->get('credentials.salt')); - if ($login == $conf->get('credentials.login') && $hash == $conf->get('credentials.hash')) { - // Login/password is correct. - $sessionManager->storeLoginInfo($_SERVER); - logm($conf->get('resource.log'), $_SERVER['REMOTE_ADDR'], 'Login successful'); - return true; - } - logm($conf->get('resource.log'), $_SERVER['REMOTE_ADDR'], 'Login failed for user '.$login); - return false; -} - -// Returns true if the user is logged in. function isLoggedIn() { - global $userIsLoggedIn; - return $userIsLoggedIn; + global $loginManager; + return $loginManager->isLoggedIn(); } + // ------------------------------------------------------------------------------------------ // Process login form: Check if login/password is correct. if (isset($_POST['login'])) { @@ -268,7 +200,7 @@ if (isset($_POST['login'])) { } if (isset($_POST['password']) && $sessionManager->checkToken($_POST['token']) - && (check_auth($_POST['login'], $_POST['password'], $conf, $sessionManager)) + && $loginManager->checkCredentials($_SERVER, $_POST['login'], $_POST['password']) ) { // Login/password is OK. $loginManager->handleSuccessfulLogin($_SERVER); @@ -347,15 +279,16 @@ if (!isset($_SESSION['tokens'])) $_SESSION['tokens']=array(); // Token are atta * Gives the last 7 days (which have links). * This RSS feed cannot be filtered. * - * @param ConfigManager $conf Configuration Manager instance. + * @param ConfigManager $conf Configuration Manager instance + * @param LoginManager $loginManager LoginManager instance */ -function showDailyRSS($conf) { +function showDailyRSS($conf, $loginManager) { // Cache system $query = $_SERVER['QUERY_STRING']; $cache = new CachedPage( $conf->get('config.PAGE_CACHE'), page_url($_SERVER), - startsWith($query,'do=dailyrss') && !isLoggedIn() + startsWith($query,'do=dailyrss') && !$loginManager->isLoggedIn() ); $cached = $cache->cachedVersion(); if (!empty($cached)) { @@ -367,7 +300,7 @@ function showDailyRSS($conf) { // Read links from database (and filter private links if used it not logged in). $LINKSDB = new LinkDB( $conf->get('resource.datastore'), - isLoggedIn(), + $loginManager->isLoggedIn(), $conf->get('privacy.hide_public_links'), $conf->get('redirector.url'), $conf->get('redirector.encode_url') @@ -509,7 +442,7 @@ function showDaily($pageBuilder, $LINKSDB, $conf, $pluginManager) /* Hook is called before column construction so that plugins don't have to deal with columns. */ - $pluginManager->executeHooks('render_daily', $data, array('loggedin' => isLoggedIn())); + $pluginManager->executeHooks('render_daily', $data, array('loggedin' => $loginManager->isLoggedIn())); /* We need to spread the articles on 3 columns. I did not want to use a JavaScript lib like http://masonry.desandro.com/ @@ -553,8 +486,8 @@ function showDaily($pageBuilder, $LINKSDB, $conf, $pluginManager) * @param ConfigManager $conf Configuration Manager instance. * @param PluginManager $pluginManager Plugin Manager instance. */ -function showLinkList($PAGE, $LINKSDB, $conf, $pluginManager) { - buildLinkList($PAGE,$LINKSDB, $conf, $pluginManager); // Compute list of links to display +function showLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager) { + buildLinkList($PAGE,$LINKSDB, $conf, $pluginManager, $loginManager); $PAGE->renderPage('linklist'); } @@ -574,7 +507,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, read_updates_file($conf->get('resource.updates')), $LINKSDB, $conf, - isLoggedIn() + $loginManager->isLoggedIn() ); try { $newUpdates = $updater->update(); @@ -596,11 +529,11 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, // Determine which page will be rendered. $query = (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : ''; - $targetPage = Router::findPage($query, $_GET, isLoggedIn()); + $targetPage = Router::findPage($query, $_GET, $loginManager->isLoggedIn()); if ( // if the user isn't logged in - !isLoggedIn() && + !$loginManager->isLoggedIn() && // and Shaarli doesn't have public content... $conf->get('privacy.hide_public_links') && // and is configured to enforce the login @@ -628,7 +561,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, $pluginManager->executeHooks('render_' . $name, $plugin_data, array( 'target' => $targetPage, - 'loggedin' => isLoggedIn() + 'loggedin' => $loginManager->isLoggedIn() ) ); $PAGE->assign('plugins_' . $name, $plugin_data); @@ -680,7 +613,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, $data = array( 'linksToDisplay' => $linksToDisplay, ); - $pluginManager->executeHooks('render_picwall', $data, array('loggedin' => isLoggedIn())); + $pluginManager->executeHooks('render_picwall', $data, array('loggedin' => $loginManager->isLoggedIn())); foreach ($data as $key => $value) { $PAGE->assign($key, $value); @@ -727,7 +660,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, 'search_tags' => $searchTags, 'tags' => $tagList, ); - $pluginManager->executeHooks('render_tagcloud', $data, array('loggedin' => isLoggedIn())); + $pluginManager->executeHooks('render_tagcloud', $data, array('loggedin' => $loginManager->isLoggedIn())); foreach ($data as $key => $value) { $PAGE->assign($key, $value); @@ -760,7 +693,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, 'search_tags' => $searchTags, 'tags' => $tags, ]; - $pluginManager->executeHooks('render_taglist', $data, ['loggedin' => isLoggedIn()]); + $pluginManager->executeHooks('render_taglist', $data, ['loggedin' => $loginManager->isLoggedIn()]); foreach ($data as $key => $value) { $PAGE->assign($key, $value); @@ -787,7 +720,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, $cache = new CachedPage( $conf->get('resource.page_cache'), page_url($_SERVER), - startsWith($query,'do='. $targetPage) && !isLoggedIn() + startsWith($query,'do='. $targetPage) && !$loginManager->isLoggedIn() ); $cached = $cache->cachedVersion(); if (!empty($cached)) { @@ -796,15 +729,15 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, } // Generate data. - $feedGenerator = new FeedBuilder($LINKSDB, $feedType, $_SERVER, $_GET, isLoggedIn()); + $feedGenerator = new FeedBuilder($LINKSDB, $feedType, $_SERVER, $_GET, $loginManager->isLoggedIn()); $feedGenerator->setLocale(strtolower(setlocale(LC_COLLATE, 0))); - $feedGenerator->setHideDates($conf->get('privacy.hide_timestamps') && !isLoggedIn()); + $feedGenerator->setHideDates($conf->get('privacy.hide_timestamps') && !$loginManager->isLoggedIn()); $feedGenerator->setUsePermalinks(isset($_GET['permalinks']) || !$conf->get('feed.rss_permalinks')); $data = $feedGenerator->buildData(); // Process plugin hook. $pluginManager->executeHooks('render_feed', $data, array( - 'loggedin' => isLoggedIn(), + 'loggedin' => $loginManager->isLoggedIn(), 'target' => $targetPage, )); @@ -952,7 +885,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, } // -------- Handle other actions allowed for non-logged in users: - if (!isLoggedIn()) + if (!$loginManager->isLoggedIn()) { // User tries to post new link but is not logged in: // Show login screen, then redirect to ?post=... @@ -968,7 +901,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, exit; } - showLinkList($PAGE, $LINKSDB, $conf, $pluginManager); + showLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager); if (isset($_GET['edit_link'])) { header('Location: ?do=login&edit_link='. escape($_GET['edit_link'])); exit; @@ -1019,7 +952,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, $conf->set('credentials.salt', sha1(uniqid('', true) .'_'. mt_rand())); $conf->set('credentials.hash', sha1($_POST['setpassword'] . $conf->get('credentials.login') . $conf->get('credentials.salt'))); try { - $conf->write(isLoggedIn()); + $conf->write($loginManager->isLoggedIn()); } catch(Exception $e) { error_log( @@ -1070,7 +1003,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, $conf->set('translation.language', escape($_POST['language'])); try { - $conf->write(isLoggedIn()); + $conf->write($loginManager->isLoggedIn()); $history->updateSettings(); invalidateCaches($conf->get('resource.page_cache')); } @@ -1522,7 +1455,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, else { $conf->set('general.enabled_plugins', save_plugin_config($_POST)); } - $conf->write(isLoggedIn()); + $conf->write($loginManager->isLoggedIn()); $history->updateSettings(); } catch (Exception $e) { @@ -1547,7 +1480,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, } // -------- Otherwise, simply display search form and links: - showLinkList($PAGE, $LINKSDB, $conf, $pluginManager); + showLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager); exit; } @@ -1559,8 +1492,9 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, * @param LinkDB $LINKSDB LinkDB instance. * @param ConfigManager $conf Configuration Manager instance. * @param PluginManager $pluginManager Plugin Manager instance. + * @param LoginManager $loginManager LoginManager instance */ -function buildLinkList($PAGE,$LINKSDB, $conf, $pluginManager) +function buildLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager) { // Used in templates if (isset($_GET['searchtags'])) { @@ -1599,8 +1533,6 @@ function buildLinkList($PAGE,$LINKSDB, $conf, $pluginManager) $keys[] = $key; } - - // Select articles according to paging. $pagecount = ceil(count($keys) / $_SESSION['LINKS_PER_PAGE']); $pagecount = $pagecount == 0 ? 1 : $pagecount; @@ -1681,7 +1613,7 @@ function buildLinkList($PAGE,$LINKSDB, $conf, $pluginManager) $data['pagetitle'] .= '- '. $conf->get('general.title'); } - $pluginManager->executeHooks('render_linklist', $data, array('loggedin' => isLoggedIn())); + $pluginManager->executeHooks('render_linklist', $data, array('loggedin' => $loginManager->isLoggedIn())); foreach ($data as $key => $value) { $PAGE->assign($key, $value); @@ -1952,7 +1884,7 @@ function install($conf, $sessionManager) { ); try { // Everything is ok, let's create config file. - $conf->write(isLoggedIn()); + $conf->write($loginManager->isLoggedIn()); } catch(Exception $e) { error_log( @@ -2216,7 +2148,7 @@ try { $linkDb = new LinkDB( $conf->get('resource.datastore'), - isLoggedIn(), + $loginManager->isLoggedIn(), $conf->get('privacy.hide_public_links'), $conf->get('redirector.url'), $conf->get('redirector.encode_url') diff --git a/tests/LoginManagerTest.php b/tests/LoginManagerTest.php index 4159038e..27ca0db5 100644 --- a/tests/LoginManagerTest.php +++ b/tests/LoginManagerTest.php @@ -38,7 +38,7 @@ class LoginManagerTest extends TestCase $this->globals = &$GLOBALS; unset($this->globals['IPBANS']); - $this->loginManager = new LoginManager($this->globals, $this->configManager); + $this->loginManager = new LoginManager($this->globals, $this->configManager, null); $this->server['REMOTE_ADDR'] = $this->ipAddr; } @@ -59,7 +59,7 @@ class LoginManagerTest extends TestCase $this->banFile, " array('127.0.0.1' => 99));\n?>" ); - new LoginManager($this->globals, $this->configManager); + new LoginManager($this->globals, $this->configManager, null); $this->assertEquals(99, $this->globals['IPBANS']['FAILURES']['127.0.0.1']); } -- cgit v1.2.3 From 1b28c66cc77b59f716aa47e6207142a7f86c2c2d Mon Sep 17 00:00:00 2001 From: VirtualTam Date: Wed, 4 Apr 2018 00:43:48 +0200 Subject: Document LoginManager properties Signed-off-by: VirtualTam --- application/LoginManager.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/application/LoginManager.php b/application/LoginManager.php index 8f6bf0da..d81c6c05 100644 --- a/application/LoginManager.php +++ b/application/LoginManager.php @@ -6,11 +6,22 @@ namespace Shaarli; */ class LoginManager { + /** @var array A reference to the $_GLOBALS array */ protected $globals = []; + + /** @var ConfigManager Configuration Manager instance **/ protected $configManager = null; + + /** @var SessionManager Session Manager instance **/ protected $sessionManager = null; + + /** @var string Path to the file containing IP bans */ protected $banFile = ''; + + /** @var bool Whether the user is logged in **/ protected $isLoggedIn = false; + + /** @var bool Whether the Shaarli instance is open to public edition **/ protected $openShaarli = false; /** -- cgit v1.2.3 From c7721487b2459e6760cae9d6292b7d39c306d3d6 Mon Sep 17 00:00:00 2001 From: VirtualTam Date: Wed, 4 Apr 2018 00:54:59 +0200 Subject: Delegate session operations to SessionManager Signed-off-by: VirtualTam --- application/LoginManager.php | 27 +++++++---------- application/SessionManager.php | 66 +++++++++++++++++++++++++++++++++++++----- 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 @@ sessionManager->storeLoginInfo($server); + $this->sessionManager->storeLoginInfo($clientIpId); $this->isLoggedIn = true; } - // Logout when: - // - the session does not exist on the server side - // - the session has expired - // - the client IP address has changed - if (empty($session['uid']) - || ($this->configManager->get('security.session_protection_disabled') === false - && $session['ip'] != client_ip_id($server)) - || time() >= $session['expires_on'] + if ($this->sessionManager->hasSessionExpired() + || $this->sessionManager->hasClientIpChanged($clientIpId) ) { $this->sessionManager->logout($webPath); $this->isLoggedIn = false; return; } - // Extend session validity - if (! empty($session['longlastingsession'])) { - // "Stay signed in" is enabled - $session['expires_on'] = time() + $session['longlastingsession']; - } else { - $session['expires_on'] = time() + SessionManager::$INACTIVITY_TIMEOUT; - } + $this->sessionManager->extendSession(); } /** @@ -129,7 +121,8 @@ class LoginManager return false; } - $this->sessionManager->storeLoginInfo($server); + $clientIpId = client_ip_id($server); + $this->sessionManager->storeLoginInfo($clientIpId); logm( $this->configManager->get('resource.log'), $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 @@ session['uid'] = sha1(uniqid('', true) . '_' . mt_rand()); - $this->session['ip'] = client_ip_id($server); + $this->session['ip'] = $clientIpId; $this->session['username'] = $this->conf->get('credentials.login'); $this->session['expires_on'] = time() + self::$INACTIVITY_TIMEOUT; } + /** + * Extend session validity + */ + public function extendSession() + { + if (! empty($this->session['longlastingsession'])) { + // "Stay signed in" is enabled + $this->session['expires_on'] = time() + $this->session['longlastingsession']; + return; + } + $this->session['expires_on'] = time() + self::$INACTIVITY_TIMEOUT; + } + /** * Logout a user by unsetting all login information * @@ -124,4 +139,41 @@ class SessionManager } setcookie(self::$LOGGED_IN_COOKIE, 'false', 0, $webPath); } + + /** + * Check whether the session has expired + * + * @param string $clientIpId Client IP address identifier + * + * @return bool true if the session has expired, false otherwise + */ + public function hasSessionExpired() + { + if (empty($this->session['uid'])) { + return true; + } + if (time() >= $this->session['expires_on']) { + return true; + } + return false; + } + + /** + * Check whether the client IP address has changed + * + * @param string $clientIpId Client IP address identifier + * + * @return bool true if the IP has changed, false if it has not, or + * if session protection has been disabled + */ + public function hasClientIpChanged($clientIpId) + { + if ($this->conf->get('security.session_protection_disabled') === true) { + return false; + } + if ($this->session['ip'] == $clientIpId) { + return false; + } + return true; + } } -- cgit v1.2.3 From 847420847455c1339f3302b1b67568ee0f382a11 Mon Sep 17 00:00:00 2001 From: VirtualTam Date: Wed, 18 Apr 2018 23:09:45 +0200 Subject: Pass the client IP ID to LoginManager Signed-off-by: VirtualTam --- application/LoginManager.php | 28 +++++++++++++--------------- index.php | 5 +++-- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/application/LoginManager.php b/application/LoginManager.php index 347fb3b9..5ce836fa 100644 --- a/application/LoginManager.php +++ b/application/LoginManager.php @@ -48,15 +48,15 @@ class LoginManager /** * Check user session state and validity (expiration) * - * @param array $server The $_SERVER array - * @param array $session The $_SESSION array (reference) - * @param array $cookie The $_COOKIE array - * @param string $webPath Path on the server in which the cookie will be available on - * @param string $token Session token + * @param array $session The $_SESSION array (reference) + * @param array $cookie The $_COOKIE array + * @param string $webPath Path on the server in which the cookie will be available on + * @param string $clientIpId Client IP address identifier + * @param string $token Session token * * @return bool true if the user session is valid, false otherwise */ - public function checkLoginState($server, & $session, $cookie, $webPath, $token) + public function checkLoginState(& $session, $cookie, $webPath, $clientIpId, $token) { if (! $this->configManager->exists('credentials.login')) { // Shaarli is not configured yet @@ -64,8 +64,6 @@ class LoginManager return; } - $clientIpId = client_ip_id($server); - if (isset($cookie[SessionManager::$LOGGED_IN_COOKIE]) && $cookie[SessionManager::$LOGGED_IN_COOKIE] === $token ) { @@ -100,13 +98,14 @@ class LoginManager /** * Check user credentials are valid * - * @param array $server The $_SERVER array - * @param string $login Username - * @param string $password Password + * @param string $remoteIp Remote client IP address + * @param string $clientIpId Client IP address identifier + * @param string $login Username + * @param string $password Password * * @return bool true if the provided credentials are valid, false otherwise */ - public function checkCredentials($server, $login, $password) + public function checkCredentials($remoteIp, $clientIpId, $login, $password) { $hash = sha1($password . $login . $this->configManager->get('credentials.salt')); @@ -115,17 +114,16 @@ class LoginManager ) { logm( $this->configManager->get('resource.log'), - $server['REMOTE_ADDR'], + $remoteIp, 'Login failed for user ' . $login ); return false; } - $clientIpId = client_ip_id($server); $this->sessionManager->storeLoginInfo($clientIpId); logm( $this->configManager->get('resource.log'), - $server['REMOTE_ADDR'], + $remoteIp, 'Login successful' ); return true; diff --git a/index.php b/index.php index 5e15b9c2..04b0e4ba 100644 --- a/index.php +++ b/index.php @@ -123,6 +123,7 @@ if (isset($_COOKIE['shaarli']) && !SessionManager::checkId($_COOKIE['shaarli'])) $conf = new ConfigManager(); $sessionManager = new SessionManager($_SESSION, $conf); $loginManager = new LoginManager($GLOBALS, $conf, $sessionManager); +$clientIpId = client_ip_id($_SERVER); // LC_MESSAGES isn't defined without php-intl, in this case use LC_COLLATE locale instead. if (! defined('LC_MESSAGES')) { @@ -178,7 +179,7 @@ if (! is_file($conf->getConfigFileExt())) { // a token depending of deployment salt, user password, and the current ip define('STAY_SIGNED_IN_TOKEN', sha1($conf->get('credentials.hash') . $_SERVER['REMOTE_ADDR'] . $conf->get('credentials.salt'))); -$loginManager->checkLoginState($_SERVER, $_SESSION, $_COOKIE, WEB_PATH, STAY_SIGNED_IN_TOKEN); +$loginManager->checkLoginState($_SESSION, $_COOKIE, WEB_PATH, $clientIpId, STAY_SIGNED_IN_TOKEN); /** * Adapter function for PageBuilder @@ -200,7 +201,7 @@ if (isset($_POST['login'])) { } if (isset($_POST['password']) && $sessionManager->checkToken($_POST['token']) - && $loginManager->checkCredentials($_SERVER, $_POST['login'], $_POST['password']) + && $loginManager->checkCredentials($_SERVER['REMOTE_ADDR'], $clientIpId, $_POST['login'], $_POST['password']) ) { // Login/password is OK. $loginManager->handleSuccessfulLogin($_SERVER); -- cgit v1.2.3 From 89ccc83ba497fa91eaaf2a2a52d8549aea5e2aee Mon Sep 17 00:00:00 2001 From: VirtualTam Date: Wed, 18 Apr 2018 23:45:05 +0200 Subject: Login: update PageBuilder and default/vintage templates Signed-off-by: VirtualTam --- application/PageBuilder.php | 9 +++++++-- index.php | 15 +++++++++------ tpl/default/linklist.html | 8 ++++---- tpl/default/linklist.paging.html | 4 ++-- tpl/default/page.footer.html | 2 +- tpl/default/page.header.html | 10 +++++----- tpl/default/tag.list.html | 6 +++--- tpl/vintage/daily.html | 2 +- tpl/vintage/linklist.html | 4 ++-- tpl/vintage/linklist.paging.html | 2 +- tpl/vintage/page.footer.html | 2 +- tpl/vintage/page.header.html | 4 ++-- 12 files changed, 38 insertions(+), 30 deletions(-) diff --git a/application/PageBuilder.php b/application/PageBuilder.php index 3233d6b6..a4483870 100644 --- a/application/PageBuilder.php +++ b/application/PageBuilder.php @@ -25,6 +25,9 @@ class PageBuilder * @var LinkDB $linkDB instance. */ protected $linkDB; + + /** @var bool $isLoggedIn Whether the user is logged in **/ + protected $isLoggedIn = false; /** * PageBuilder constructor. @@ -34,12 +37,13 @@ class PageBuilder * @param LinkDB $linkDB instance. * @param string $token Session token */ - public function __construct(&$conf, $linkDB = null, $token = null) + public function __construct(&$conf, $linkDB = null, $token = null, $isLoggedIn = false) { $this->tpl = false; $this->conf = $conf; $this->linkDB = $linkDB; $this->token = $token; + $this->isLoggedIn = $isLoggedIn; } /** @@ -55,7 +59,7 @@ class PageBuilder $this->conf->get('resource.update_check'), $this->conf->get('updates.check_updates_interval'), $this->conf->get('updates.check_updates'), - isLoggedIn(), + $this->isLoggedIn, $this->conf->get('updates.check_updates_branch') ); $this->tpl->assign('newVersion', escape($version)); @@ -67,6 +71,7 @@ class PageBuilder $this->tpl->assign('versionError', escape($exc->getMessage())); } + $this->tpl->assign('is_logged_in', $this->isLoggedIn); $this->tpl->assign('feedurl', escape(index_url($_SERVER))); $searchcrits = ''; // Search criteria if (!empty($_GET['searchtags'])) { diff --git a/index.php b/index.php index 04b0e4ba..c87ebf65 100644 --- a/index.php +++ b/index.php @@ -182,9 +182,11 @@ define('STAY_SIGNED_IN_TOKEN', sha1($conf->get('credentials.hash') . $_SERVER['R $loginManager->checkLoginState($_SESSION, $_COOKIE, WEB_PATH, $clientIpId, STAY_SIGNED_IN_TOKEN); /** - * Adapter function for PageBuilder + * Adapter function to ensure compatibility with third-party templates * - * TODO: update PageBuilder and tests + * @see https://github.com/shaarli/Shaarli/pull/1086 + * + * @return bool true when the user is logged in, false otherwise */ function isLoggedIn() { @@ -383,9 +385,10 @@ function showDailyRSS($conf, $loginManager) { * @param PageBuilder $pageBuilder Template engine wrapper. * @param LinkDB $LINKSDB LinkDB instance. * @param ConfigManager $conf Configuration Manager instance. - * @param PluginManager $pluginManager Plugin Manager instane. + * @param PluginManager $pluginManager Plugin Manager instance. + * @param LoginManager $loginManager Login Manager instance */ -function showDaily($pageBuilder, $LINKSDB, $conf, $pluginManager) +function showDaily($pageBuilder, $LINKSDB, $conf, $pluginManager, $loginManager) { $day = date('Ymd', strtotime('-1 day')); // Yesterday, in format YYYYMMDD. if (isset($_GET['day'])) { @@ -523,7 +526,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, die($e->getMessage()); } - $PAGE = new PageBuilder($conf, $LINKSDB, $sessionManager->generateToken()); + $PAGE = new PageBuilder($conf, $LINKSDB, $sessionManager->generateToken(), $loginManager->isLoggedIn()); $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('privateLinkcount', count_private($LINKSDB)); $PAGE->assign('plugin_errors', $pluginManager->getErrors()); @@ -708,7 +711,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, // Daily page. if ($targetPage == Router::$PAGE_DAILY) { - showDaily($PAGE, $LINKSDB, $conf, $pluginManager); + showDaily($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager); } // ATOM and RSS feed. diff --git a/tpl/default/linklist.html b/tpl/default/linklist.html index d546be0a..322cddd5 100644 --- a/tpl/default/linklist.html +++ b/tpl/default/linklist.html @@ -136,7 +136,7 @@ {/if} - {if="isLoggedIn()"} + {if="$is_logged_in"}