X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=index.php;h=ddd5dbf56a1cb450ebdff9dff3dadcb84903842b;hb=refs%2Fheads%2Ffix-broken-doc-links;hp=067b8fcb972c3d6517d3448d7895d9502fc618e6;hpb=a381c373b30ed04001ea31ff5c38e077edacaf18;p=github%2Fshaarli%2FShaarli.git diff --git a/index.php b/index.php index 067b8fcb..ddd5dbf5 100644 --- a/index.php +++ b/index.php @@ -48,7 +48,7 @@ if (! file_exists(__DIR__ . '/vendor/autoload.php')) { ."If you installed Shaarli through Git or using the development branch,\n" ."please refer to the installation documentation to install PHP" ." dependencies using Composer:\n" - ."- https://shaarli.readthedocs.io/en/master/Server-requirements/\n" + ."- https://shaarli.readthedocs.io/en/master/Server-configuration/\n" ."- https://shaarli.readthedocs.io/en/master/Download-and-Installation/"; exit; } @@ -78,7 +78,8 @@ require_once 'application/Updater.php'; use \Shaarli\Languages; use \Shaarli\ThemeUtils; use \Shaarli\Config\ConfigManager; -use \Shaarli\SessionManager; +use \Shaarli\Security\LoginManager; +use \Shaarli\Security\SessionManager; // Ensure the PHP version is supported try { @@ -100,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). @@ -123,6 +122,9 @@ if (isset($_COOKIE['shaarli']) && !SessionManager::checkId($_COOKIE['shaarli'])) $conf = new ConfigManager(); $sessionManager = new SessionManager($_SESSION, $conf); +$loginManager = new LoginManager($GLOBALS, $conf, $sessionManager); +$loginManager->generateStaySignedInToken($_SERVER['REMOTE_ADDR']); +$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')) { @@ -172,246 +174,64 @@ if (! is_file($conf->getConfigFileExt())) { } // Display the installation form if no existing config is found - install($conf, $sessionManager); + install($conf, $sessionManager, $loginManager); } -// 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($_COOKIE, $clientIpId); /** - * Checking session state (i.e. is the user still logged in) + * Adapter function to ensure compatibility with third-party templates * - * @param ConfigManager $conf The configuration manager. + * @see https://github.com/shaarli/Shaarli/pull/1086 * - * @return bool: true if the user is logged in, false otherwise. + * @return bool true when the user is logged in, false otherwise */ -function setup_login_state($conf) -{ - 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['shaarli_staySignedIn']) && - $_COOKIE['shaarli_staySignedIn']===STAY_SIGNED_IN_TOKEN && - !$loginFailure) - { - fillSessionInfo($conf); - $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'] != allIPs()) - || time() >= $_SESSION['expires_on']) - { - logout(); - $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()+INACTIVITY_TIMEOUT; // Standard session expiration date. - } - if (!$loginFailure) { - $userIsLoggedIn = true; - } - - return $userIsLoggedIn; -} -$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. - * - * @param ConfigManager $conf Configuration Manager instance. - */ -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['username']= $conf->get('credentials.login'); - $_SESSION['expires_on']=time()+INACTIVITY_TIMEOUT; // Set session expiration. -} - -/** - * Check that user/password is correct. - * - * @param string $login Username - * @param string $password User password - * @param ConfigManager $conf Configuration Manager instance. - * - * @return bool: authentication successful or not. - */ -function check_auth($login, $password, $conf) -{ - $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); - 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; -} - -// 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); + global $loginManager; + return $loginManager->isLoggedIn(); } -// ------------------------------------------------------------------------------------------ -// Brute force protection system -// Several consecutive failed logins will ban the IP address for 30 minutes. -if (!is_file($conf->get('resource.ban_file', 'data/ipbans.php'))) { - // FIXME! globals - file_put_contents( - $conf->get('resource.ban_file', 'data/ipbans.php'), - "array(),'BANS'=>array()),true).";\n?>" - ); -} -include $conf->get('resource.ban_file', 'data/ipbans.php'); -/** - * Signal a failed login. Will ban the IP if too many failures: - * - * @param ConfigManager $conf Configuration Manager instance. - */ -function ban_loginFailed($conf) -{ - $ip = $_SERVER['REMOTE_ADDR']; - $trusted = $conf->get('security.trusted_proxies', array()); - if (in_array($ip, $trusted)) { - $ip = getIpAddressFromProxy($_SERVER, $trusted); - if (!$ip) { - return; - } - } - $gb = $GLOBALS['IPBANS']; - if (! isset($gb['FAILURES'][$ip])) { - $gb['FAILURES'][$ip]=0; - } - $gb['FAILURES'][$ip]++; - if ($gb['FAILURES'][$ip] > ($conf->get('security.ban_after') - 1)) - { - $gb['BANS'][$ip] = time() + $conf->get('security.ban_after', 1800); - logm($conf->get('resource.log'), $_SERVER['REMOTE_ADDR'], 'IP address banned from login'); - } - $GLOBALS['IPBANS'] = $gb; - file_put_contents( - $conf->get('resource.ban_file', 'data/ipbans.php'), - "" - ); -} - -/** - * Signals a successful login. Resets failed login counter. - * - * @param ConfigManager $conf Configuration Manager instance. - */ -function ban_loginOk($conf) -{ - $ip = $_SERVER['REMOTE_ADDR']; - $gb = $GLOBALS['IPBANS']; - unset($gb['FAILURES'][$ip]); unset($gb['BANS'][$ip]); - $GLOBALS['IPBANS'] = $gb; - file_put_contents( - $conf->get('resource.ban_file', 'data/ipbans.php'), - "" - ); -} - -/** - * Checks if the user CAN login. If 'true', the user can try to login. - * - * @param ConfigManager $conf Configuration Manager instance. - * - * @return bool: true if the user is allowed to login. - */ -function ban_canLogin($conf) -{ - $ip=$_SERVER["REMOTE_ADDR"]; $gb=$GLOBALS['IPBANS']; - if (isset($gb['BANS'][$ip])) - { - // User is banned. Check if the ban has expired: - if ($gb['BANS'][$ip]<=time()) - { // Ban expired, user can try to login again. - logm($conf->get('resource.log'), $_SERVER['REMOTE_ADDR'], 'Ban lifted.'); - unset($gb['FAILURES'][$ip]); unset($gb['BANS'][$ip]); - file_put_contents( - $conf->get('resource.ban_file', 'data/ipbans.php'), - "" - ); - return true; // Ban has expired, user can login. - } - return false; // User is banned. - } - return true; // User is not banned. -} - // ------------------------------------------------------------------------------------------ // Process login form: Check if login/password is correct. -if (isset($_POST['login'])) -{ - if (!ban_canLogin($conf)) die(t('I said: NO. You are banned for the moment. Go away.')); +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)) - ) { // Login/password is OK. - ban_loginOk($conf); - // If user wants to keep the session cookie even after the browser closes: - 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); - $_SESSION['expires_on'] = $expiration; // Set session expiration on server-side. + && $loginManager->checkCredentials($_SERVER['REMOTE_ADDR'], $clientIpId, $_POST['login'], $_POST['password']) + ) { + $loginManager->handleSuccessfulLogin($_SERVER); - $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 + $cookiedir = ''; + if (dirname($_SERVER['SCRIPT_NAME']) != '/') { // Note: Never forget the trailing slash on the cookie path! - session_regenerate_id(true); // Send cookie with new expiration date to browser. + $cookiedir = dirname($_SERVER["SCRIPT_NAME"]) . '/'; } - else // Standard session expiration (=when browser closes) - { - $cookiedir = ''; if(dirname($_SERVER['SCRIPT_NAME'])!='/') $cookiedir=dirname($_SERVER["SCRIPT_NAME"]).'/'; - session_set_cookie_params(0,$cookiedir,$_SERVER['SERVER_NAME']); // 0 means "When browser closes" - session_regenerate_id(true); + + if (!empty($_POST['longlastingsession'])) { + // Keep the session cookie even after the browser closes + $sessionManager->setStaySignedIn(true); + $expirationTime = $sessionManager->extendSession(); + + setcookie( + $loginManager::$STAY_SIGNED_IN_COOKIE, + $loginManager->getStaySignedInToken(), + $expirationTime, + WEB_PATH + ); + + } else { + // Standard session expiration (=when browser closes) + $expirationTime = 0; } + // Send cookie with the new expiration date to the browser + session_set_cookie_params($expirationTime, $cookiedir, $_SERVER['SERVER_NAME']); + session_regenerate_id(true); + // Optional redirect after login: if (isset($_GET['post'])) { $uri = '?post='. urlencode($_GET['post']); @@ -437,10 +257,8 @@ if (isset($_POST['login'])) } } header('Location: ?'); exit; - } - else - { - ban_loginFailed($conf); + } else { + $loginManager->handleFailedLogin($_SERVER); $redir = '&username='. urlencode($_POST['login']); if (isset($_GET['post'])) { $redir .= '&post=' . urlencode($_GET['post']); @@ -466,15 +284,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)) { @@ -486,7 +305,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') @@ -568,9 +387,10 @@ function showDailyRSS($conf) { * @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'])) { @@ -628,7 +448,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/ @@ -659,6 +479,7 @@ function showDaily($pageBuilder, $LINKSDB, $conf, $pluginManager) $pageBuilder->assign($key, $value); } + $pageBuilder->assign('pagetitle', t('Daily') .' - '. $conf->get('general.title', 'Shaarli')); $pageBuilder->renderPage('daily'); exit; } @@ -671,8 +492,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'); } @@ -684,14 +505,15 @@ function showLinkList($PAGE, $LINKSDB, $conf, $pluginManager) { * @param LinkDB $LINKSDB * @param History $history instance * @param SessionManager $sessionManager SessionManager instance + * @param LoginManager $loginManager LoginManager instance */ -function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager) +function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, $loginManager) { $updater = new Updater( read_updates_file($conf->get('resource.updates')), $LINKSDB, $conf, - isLoggedIn() + $loginManager->isLoggedIn() ); try { $newUpdates = $updater->update(); @@ -706,18 +528,18 @@ 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()); // 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 @@ -745,7 +567,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); @@ -761,6 +583,8 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager) $PAGE->assign('returnurl',(isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']):'')); // add default state of the 'remember me' checkbox $PAGE->assign('remember_user_default', $conf->get('privacy.remember_user_default')); + $PAGE->assign('user_can_login', $loginManager->canLogin($_SERVER)); + $PAGE->assign('pagetitle', t('Login') .' - '. $conf->get('general.title', 'Shaarli')); $PAGE->renderPage('loginform'); exit; } @@ -768,7 +592,8 @@ 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(); + setcookie(LoginManager::$STAY_SIGNED_IN_COOKIE, 'false', 0, WEB_PATH); header('Location: ?'); exit; } @@ -795,12 +620,13 @@ 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); } + $PAGE->assign('pagetitle', t('Picture wall') .' - '. $conf->get('general.title', 'Shaarli')); $PAGE->renderPage('picwall'); exit; } @@ -836,16 +662,19 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager) ); } + $searchTags = implode(' ', escape($filteringTags)); $data = array( - 'search_tags' => implode(' ', escape($filteringTags)), + '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); } + $searchTags = ! empty($searchTags) ? $searchTags .' - ' : ''; + $PAGE->assign('pagetitle', $searchTags. t('Tag cloud') .' - '. $conf->get('general.title', 'Shaarli')); $PAGE->renderPage('tag.cloud'); exit; } @@ -866,23 +695,26 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager) alphabetical_sort($tags, false, true); } + $searchTags = implode(' ', escape($filteringTags)); $data = [ - 'search_tags' => implode(' ', escape($filteringTags)), + '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); } + $searchTags = ! empty($searchTags) ? $searchTags .' - ' : ''; + $PAGE->assign('pagetitle', $searchTags . t('Tag list') .' - '. $conf->get('general.title', 'Shaarli')); $PAGE->renderPage('tag.list'); exit; } // Daily page. if ($targetPage == Router::$PAGE_DAILY) { - showDaily($PAGE, $LINKSDB, $conf, $pluginManager); + showDaily($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager); } // ATOM and RSS feed. @@ -895,7 +727,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)) { @@ -904,15 +736,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, )); @@ -962,7 +794,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager) if (empty($params['searchtags'])) { $params['searchtags'] = trim($_GET['addtag']); } - else if ($addtag) { + elseif ($addtag) { $params['searchtags'] = trim($params['searchtags']).' '.trim($_GET['addtag']); } @@ -1028,7 +860,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager) } else { unset($_SESSION['visibility']); } - } else if ($_GET['visibility'] === 'public') { + } elseif ($_GET['visibility'] === 'public') { if (empty($_SESSION['visibility']) || $_SESSION['visibility'] !== 'public') { // See only public links $_SESSION['visibility'] = 'public'; @@ -1060,7 +892,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=... @@ -1076,7 +908,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; @@ -1100,6 +932,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager) $PAGE->assign($key, $value); } + $PAGE->assign('pagetitle', t('Tools') .' - '. $conf->get('general.title', 'Shaarli')); $PAGE->renderPage('tools'); exit; } @@ -1126,7 +959,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( @@ -1143,6 +976,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager) } else // show the change password form. { + $PAGE->assign('pagetitle', t('Change password') .' - '. $conf->get('general.title', 'Shaarli')); $PAGE->renderPage('changepassword'); exit; } @@ -1166,7 +1000,6 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager) $conf->set('general.title', escape($_POST['title'])); $conf->set('general.header_link', escape($_POST['titleLink'])); $conf->set('resource.theme', escape($_POST['theme'])); - $conf->set('redirector.url', escape($_POST['redirector'])); $conf->set('security.session_protection_disabled', !empty($_POST['disablesessionprotection'])); $conf->set('privacy.default_private_links', !empty($_POST['privateLinkByDefault'])); $conf->set('feed.rss_permalinks', !empty($_POST['enableRssPermalinks'])); @@ -1177,7 +1010,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')); } @@ -1199,7 +1032,6 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager) $PAGE->assign('title', $conf->get('general.title')); $PAGE->assign('theme', $conf->get('resource.theme')); $PAGE->assign('theme_available', ThemeUtils::getThemes($conf->get('resource.raintpl_tpl'))); - $PAGE->assign('redirector', $conf->get('redirector.url')); list($continents, $cities) = generateTimeZoneData( timezone_identifiers_list(), $conf->get('general.timezone') @@ -1215,6 +1047,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager) $PAGE->assign('api_secret', $conf->get('api.secret')); $PAGE->assign('languages', Languages::getAvailableLanguages()); $PAGE->assign('language', $conf->get('translation.language')); + $PAGE->assign('pagetitle', t('Configure') .' - '. $conf->get('general.title', 'Shaarli')); $PAGE->renderPage('configure'); exit; } @@ -1225,6 +1058,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager) { if (empty($_POST['fromtag']) || (empty($_POST['totag']) && isset($_POST['renametag']))) { $PAGE->assign('fromtag', ! empty($_GET['fromtag']) ? escape($_GET['fromtag']) : ''); + $PAGE->assign('pagetitle', t('Manage tags') .' - '. $conf->get('general.title', 'Shaarli')); $PAGE->renderPage('changetag'); exit; } @@ -1251,6 +1085,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager) // -------- User wants to add a link without using the bookmarklet: Show form. if ($targetPage == Router::$PAGE_ADDLINK) { + $PAGE->assign('pagetitle', t('Shaare a new link') .' - '. $conf->get('general.title', 'Shaarli')); $PAGE->renderPage('addlink'); exit; } @@ -1420,6 +1255,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager) $PAGE->assign($key, $value); } + $PAGE->assign('pagetitle', t('Edit') .' '. t('Shaare') .' - '. $conf->get('general.title', 'Shaarli')); $PAGE->renderPage('editlink'); exit; } @@ -1445,7 +1281,12 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager) if (empty($title) && strpos(get_url_scheme($url), 'http') !== false) { // Short timeout to keep the application responsive // The callback will fill $charset and $title with data from the downloaded page. - get_http_response($url, 25, 4194304, get_curl_download_callback($charset, $title)); + get_http_response( + $url, + $conf->get('general.download_timeout', 30), + $conf->get('general.download_max_size', 4194304), + get_curl_download_callback($charset, $title) + ); if (! empty($title) && strtolower($charset) != 'utf-8') { $title = mb_convert_encoding($title, 'utf-8', $charset); } @@ -1484,6 +1325,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager) $PAGE->assign($key, $value); } + $PAGE->assign('pagetitle', t('Shaare') .' - '. $conf->get('general.title', 'Shaarli')); $PAGE->renderPage('editlink'); exit; } @@ -1492,6 +1334,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager) // Export links as a Netscape Bookmarks file if (empty($_GET['selection'])) { + $PAGE->assign('pagetitle', t('Export') .' - '. $conf->get('general.title', 'Shaarli')); $PAGE->renderPage('export'); exit; } @@ -1553,6 +1396,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager) true ) ); + $PAGE->assign('pagetitle', t('Import') .' - '. $conf->get('general.title', 'Shaarli')); $PAGE->renderPage('import'); exit; } @@ -1601,6 +1445,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager) $PAGE->assign('enabledPlugins', $enabledPlugins); $PAGE->assign('disabledPlugins', $disabledPlugins); + $PAGE->assign('pagetitle', t('Plugin administration') .' - '. $conf->get('general.title', 'Shaarli')); $PAGE->renderPage('pluginsadmin'); exit; } @@ -1617,7 +1462,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) { @@ -1642,7 +1487,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; } @@ -1654,8 +1499,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'])) { @@ -1694,8 +1540,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; @@ -1764,9 +1608,19 @@ function buildLinkList($PAGE,$LINKSDB, $conf, $pluginManager) // If there is only a single link, we change on-the-fly the title of the page. if (count($linksToDisplay) == 1) { $data['pagetitle'] = $linksToDisplay[$keys[0]]['title'] .' - '. $conf->get('general.title'); + } elseif (! empty($searchterm) || ! empty($searchtags)) { + $data['pagetitle'] = t('Search: '); + $data['pagetitle'] .= ! empty($searchterm) ? $searchterm .' ' : ''; + $bracketWrap = function ($tag) { + return '['. $tag .']'; + }; + $data['pagetitle'] .= ! empty($searchtags) + ? implode(' ', array_map($bracketWrap, preg_split('/\s+/', $searchtags))).' ' + : ''; + $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); @@ -1969,8 +1823,9 @@ function lazyThumbnail($conf, $url,$href=false) * * @param ConfigManager $conf Configuration Manager instance. * @param SessionManager $sessionManager SessionManager instance + * @param LoginManager $loginManager LoginManager instance */ -function install($conf, $sessionManager) { +function install($conf, $sessionManager, $loginManager) { // On free.fr host, make sure the /sessions directory exists, otherwise login will not work. if (endsWith($_SERVER['HTTP_HOST'],'.free.fr') && !is_dir($_SERVER['DOCUMENT_ROOT'].'/sessions')) mkdir($_SERVER['DOCUMENT_ROOT'].'/sessions',0705); @@ -2037,7 +1892,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( @@ -2301,7 +2156,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') @@ -2330,7 +2185,7 @@ $response = $app->run(true); if ($response->getStatusCode() == 404 && strpos($_SERVER['REQUEST_URI'], '/api/v1') === false) { // We use UTF-8 for proper international characters handling. header('Content-Type: text/html; charset=utf-8'); - renderPage($conf, $pluginManager, $linkDb, $history, $sessionManager); + renderPage($conf, $pluginManager, $linkDb, $history, $sessionManager, $loginManager); } else { $app->respond($response); }