X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=index.php;h=58ae2ddb780a9315755df398c77eaa5773b0e712;hb=refs%2Fheads%2Fgitolite_local%2Fldap;hp=28dfd3b473dbd3f7b39d61295a0ec055681afacd;hpb=1b93137e16694f52952c930848e1a7928e8a00a6;p=github%2Fshaarli%2FShaarli.git diff --git a/index.php b/index.php index 28dfd3b4..58ae2ddb 100644 --- a/index.php +++ b/index.php @@ -74,13 +74,13 @@ require_once 'application/Url.php'; require_once 'application/Utils.php'; require_once 'application/PluginManager.php'; require_once 'application/Router.php'; -require_once 'application/Thumbnailer.php'; require_once 'application/Updater.php'; -use \Shaarli\Languages; -use \Shaarli\ThemeUtils; use \Shaarli\Config\ConfigManager; +use \Shaarli\Languages; use \Shaarli\Security\LoginManager; use \Shaarli\Security\SessionManager; +use \Shaarli\ThemeUtils; +use \Shaarli\Thumbnailer; // Ensure the PHP version is supported try { @@ -121,7 +121,32 @@ if (isset($_COOKIE['shaarli']) && !SessionManager::checkId($_COOKIE['shaarli'])) $_COOKIE['shaarli'] = session_id(); } -$conf = new ConfigManager(); +$folderBase = getenv("BASE"); + +if (getenv("USERSPACE")) { + if (isset($_GET["do"]) && $_GET["do"] == "login") { + header("Location: $folderBase/?do=login"); + exit; + } + $userspace = preg_replace("/[^-_A-Za-z0-9]/", '', getenv("USERSPACE")); +} else if (isset($_SESSION["username"]) && $_SESSION["username"]) { + header("Location: " . $folderBase . "/" . $_SESSION["username"] . "?"); + exit; +} else if (!isset($_GET["do"]) || $_GET["do"] != "login") { + header("Location: $folderBase/?do=login"); + exit; +} + +if (!isset($userspace) && isset($_POST["login"])) { + $userspace = preg_replace("/[^-_A-Za-z0-9]/", '', $_POST["login"]); + error_log("debugImmae: setting userspace from POST: " . $userspace); +} + +if (isset($userspace)) { + $conf = new ConfigManager(null, $userspace); +} else { + $conf = new ConfigManager(); +} $sessionManager = new SessionManager($_SESSION, $conf); $loginManager = new LoginManager($GLOBALS, $conf, $sessionManager); $loginManager->generateStaySignedInToken($_SERVER['REMOTE_ADDR']); @@ -175,7 +200,7 @@ if (! is_file($conf->getConfigFileExt())) { } // Display the installation form if no existing config is found - install($conf, $sessionManager, $loginManager); + install($conf, $sessionManager, $loginManager, $userspace); } $loginManager->checkLoginState($_COOKIE, $clientIpId); @@ -205,6 +230,7 @@ if (isset($_POST['login'])) { && $loginManager->checkCredentials($_SERVER['REMOTE_ADDR'], $clientIpId, $_POST['login'], $_POST['password']) ) { $loginManager->handleSuccessfulLogin($_SERVER); + $userspace = $_POST['login']; $cookiedir = ''; if (dirname($_SERVER['SCRIPT_NAME']) != '/') { @@ -241,25 +267,25 @@ if (isset($_POST['login'])) { $uri .= '&'.$param.'='.urlencode($_GET[$param]); } } - header('Location: '. $uri); + header('Location: '. $userspace . $uri); exit; } if (isset($_GET['edit_link'])) { - header('Location: ?edit_link='. escape($_GET['edit_link'])); + header('Location: ' . $userspace . '?edit_link='. escape($_GET['edit_link'])); exit; } if (isset($_POST['returnurl'])) { // Prevent loops over login screen. if (strpos($_POST['returnurl'], 'do=login') === false) { - header('Location: '. generateLocation($_POST['returnurl'], $_SERVER['HTTP_HOST'])); + header('Location: ' . generateLocation($_POST['returnurl'], $_SERVER['HTTP_HOST'])); exit; } } - header('Location: ?'); exit; + header('Location: '. $userspace . '?'); exit; } else { - $loginManager->handleFailedLogin($_SERVER); + $errorReason = $loginManager->handleFailedLogin($_SERVER); $redir = '&username='. urlencode($_POST['login']); if (isset($_GET['post'])) { $redir .= '&post=' . urlencode($_GET['post']); @@ -270,7 +296,7 @@ if (isset($_POST['login'])) { } } // Redirect to login screen. - echo ''; + echo ''; exit; } } @@ -356,7 +382,6 @@ function showDailyRSS($conf, $loginManager) { $conf->get('redirector.url'), $conf->get('redirector.encode_url') ); - $link['thumbnail'] = thumbnail($conf, $link['url']); $link['timestamp'] = $link['created']->getTimestamp(); if (startsWith($link['url'], '?')) { $link['url'] = index_url($_SERVER) . $link['url']; // make permalink URL absolute @@ -371,6 +396,7 @@ function showDailyRSS($conf, $loginManager) { $tpl->assign('links', $links); $tpl->assign('rssdate', escape($dayDate->format(DateTime::RSS))); $tpl->assign('hide_timestamps', $conf->get('privacy.hide_timestamps', false)); + $tpl->assign('index_url', $pageaddr); $html = $tpl->draw('dailyrss', true); echo $html . PHP_EOL; @@ -433,7 +459,6 @@ function showDaily($pageBuilder, $LINKSDB, $conf, $pluginManager, $loginManager) $conf->get('redirector.url'), $conf->get('redirector.encode_url') ); - $linksToDisplay[$key]['thumbnail'] = thumbnail($conf, $link['url']); $linksToDisplay[$key]['timestamp'] = $link['created']->getTimestamp(); } @@ -514,7 +539,8 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, read_updates_file($conf->get('resource.updates')), $LINKSDB, $conf, - $loginManager->isLoggedIn() + $loginManager->isLoggedIn(), + $_SESSION ); try { $newUpdates = $updater->update(); @@ -529,7 +555,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, die($e->getMessage()); } - $PAGE = new PageBuilder($conf, $LINKSDB, $sessionManager->generateToken(), $loginManager->isLoggedIn()); + $PAGE = new PageBuilder($conf, $_SESSION, $LINKSDB, $sessionManager->generateToken(), $loginManager->isLoggedIn()); $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('privateLinkcount', count_private($LINKSDB)); $PAGE->assign('plugin_errors', $pluginManager->getErrors()); @@ -602,8 +628,10 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, // -------- Picture wall if ($targetPage == Router::$PAGE_PICWALL) { - if (! $conf->get('thumbnails.enabled')) { - header('Location: ?'); + $PAGE->assign('pagetitle', t('Picture wall') .' - '. $conf->get('general.title', 'Shaarli')); + if (! $conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) === Thumbnailer::MODE_NONE) { + $PAGE->assign('linksToDisplay', []); + $PAGE->renderPage('picwall'); exit; } @@ -611,43 +639,13 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, $links = $LINKSDB->filterSearch($_GET); $linksToDisplay = array(); - $thumbnailer = new Thumbnailer($conf); - - - $cpt = 0; // Get only links which have a thumbnail. - foreach($links as $link) + // Note: we do not retrieve thumbnails here, the request is too heavy. + foreach($links as $key => $link) { - $permalink='?'.$link['shorturl']; - // Not a note, - // and (never retrieved yet or no valid cache file) - if ($link['url'][0] != '?' - && (! isset($link['thumbnail']) || ($link['thumbnail'] !== false && ! is_file($link['thumbnail']))) - ) { - $link['thumbnail'] = $thumbnailer->get($link['url']); - // FIXME! we really need to get rid of ArrayAccess... - $item = $LINKSDB[$link['linkdate']]; - $item['thumbnail'] = $link['thumbnail']; - $LINKSDB[$link['linkdate']] = $item; - $updateDB = true; - $cpt++; - } - if (isset($link['thumbnail']) && $link['thumbnail'] !== false) { $linksToDisplay[] = $link; // Add to array. } - - // If we retrieved new thumbnails, we update the database every 20 links. - // Downloading everything the first time may take a very long time - if (!empty($updateDB) && $cpt == 20) { - $LINKSDB->save($conf->get('resource.page_cache')); - $updateDB = false; - $cpt = 0; - } - } - - if (!empty($updateDB)) { - $LINKSDB->save($conf->get('resource.page_cache')); } $data = array( @@ -659,7 +657,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, $PAGE->assign($key, $value); } - $PAGE->assign('pagetitle', t('Picture wall') .' - '. $conf->get('general.title', 'Shaarli')); + $PAGE->renderPage('picwall'); exit; } @@ -1041,7 +1039,16 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, $conf->set('api.enabled', !empty($_POST['enableApi'])); $conf->set('api.secret', escape($_POST['apiSecret'])); $conf->set('translation.language', escape($_POST['language'])); - $conf->set('thumbnails.enabled', !empty($_POST['enableThumbnails'])); + + $thumbnailsMode = extension_loaded('gd') ? $_POST['enableThumbnails'] : Thumbnailer::MODE_NONE; + if ($thumbnailsMode !== Thumbnailer::MODE_NONE + && $thumbnailsMode !== $conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) + ) { + $_SESSION['warnings'][] = t( + 'You have enabled or changed thumbnails mode. Please synchronize them.' + ); + } + $conf->set('thumbnails.mode', $thumbnailsMode); try { $conf->write($loginManager->isLoggedIn()); @@ -1081,6 +1088,8 @@ 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('gd_enabled', extension_loaded('gd')); + $PAGE->assign('thumbnails_mode', $conf->get('thumbnails.mode', Thumbnailer::MODE_NONE)); $PAGE->assign('pagetitle', t('Configure') .' - '. $conf->get('general.title', 'Shaarli')); $PAGE->renderPage('configure'); exit; @@ -1137,7 +1146,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, // Linkdate is kept here to: // - use the same permalink for notes as they're displayed when creating them // - let users hack creation date of their posts - // See: https://shaarli.readthedocs.io/en/master/Various-hacks/#changing-the-timestamp-for-a-shaare + // See: https://shaarli.readthedocs.io/en/master/guides/various-hacks/#changing-the-timestamp-for-a-shaare $linkdate = escape($_POST['lf_linkdate']); if (isset($LINKSDB[$id])) { // Edit @@ -1182,7 +1191,7 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, $link['title'] = $link['url']; } - if ($conf->get('thumbnails.enabled')) { + if ($conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE) { $thumbnailer = new Thumbnailer($conf); $link['thumbnail'] = $thumbnailer->get($url); } @@ -1525,6 +1534,43 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history, $sessionManager, exit; } + // -------- Thumbnails Update + if ($targetPage == Router::$PAGE_THUMBS_UPDATE) { + $ids = []; + foreach ($LINKSDB as $link) { + // A note or not HTTP(S) + if ($link['url'][0] === '?' || ! startsWith(strtolower($link['url']), 'http')) { + continue; + } + $ids[] = $link['id']; + } + $PAGE->assign('ids', $ids); + $PAGE->assign('pagetitle', t('Thumbnails update') .' - '. $conf->get('general.title', 'Shaarli')); + $PAGE->renderPage('thumbnails'); + exit; + } + + // -------- Single Thumbnail Update + if ($targetPage == Router::$AJAX_THUMB_UPDATE) { + if (! isset($_POST['id']) || ! ctype_digit($_POST['id'])) { + http_response_code(400); + exit; + } + $id = (int) $_POST['id']; + if (empty($LINKSDB[$id])) { + http_response_code(404); + exit; + } + $thumbnailer = new Thumbnailer($conf); + $link = $LINKSDB[$id]; + $link['thumbnail'] = $thumbnailer->get($link['url']); + $LINKSDB[$id] = $link; + $LINKSDB->save($conf->get('resource.page_cache')); + + echo json_encode($link); + exit; + } + // -------- Otherwise, simply display search form and links: showLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager); exit; @@ -1589,7 +1635,8 @@ function buildLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager) $i = ($page-1) * $_SESSION['LINKS_PER_PAGE']; $end = $i + $_SESSION['LINKS_PER_PAGE']; - if ($conf->get('thumbnails.enabled')) { + $thumbnailsEnabled = $conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE; + if ($thumbnailsEnabled) { $thumbnailer = new Thumbnailer($conf); } @@ -1614,17 +1661,16 @@ function buildLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager) uasort($taglist, 'strcasecmp'); $link['taglist'] = $taglist; - // Thumbnails enabled, not a note, + // Logged in, thumbnails enabled, not a note, // and (never retrieved yet or no valid cache file) - if ($conf->get('thumbnails.enabled') && $link['url'][0] != '?' + if ($loginManager->isLoggedIn() && $thumbnailsEnabled && $link['url'][0] != '?' && (! isset($link['thumbnail']) || ($link['thumbnail'] !== false && ! is_file($link['thumbnail']))) ) { - $link['thumbnail'] = $thumbnailer->get($link['url']); - // FIXME! we really need to get rid of ArrayAccess... - $item = $LINKSDB[$keys[$i]]; - $item['thumbnail'] = $link['thumbnail']; - $LINKSDB[$keys[$i]] = $item; + $elem = $LINKSDB[$keys[$i]]; + $elem['thumbnail'] = $thumbnailer->get($link['url']); + $LINKSDB[$keys[$i]] = $elem; $updateDB = true; + $link['thumbnail'] = $elem['thumbnail']; } // Check for both signs of a note: starting with ? and 7 chars long. @@ -1699,7 +1745,7 @@ function buildLinkList($PAGE, $LINKSDB, $conf, $pluginManager, $loginManager) * @param SessionManager $sessionManager SessionManager instance * @param LoginManager $loginManager LoginManager instance */ -function install($conf, $sessionManager, $loginManager) { +function install($conf, $sessionManager, $loginManager, $userspace) { // 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); @@ -1735,7 +1781,7 @@ function install($conf, $sessionManager, $loginManager) { } - if (!empty($_POST['setlogin']) && !empty($_POST['setpassword'])) + if (true) { $tz = 'UTC'; if (!empty($_POST['continent']) && !empty($_POST['city']) @@ -1744,15 +1790,15 @@ function install($conf, $sessionManager, $loginManager) { $tz = $_POST['continent'].'/'.$_POST['city']; } $conf->set('general.timezone', $tz); - $login = $_POST['setlogin']; - $conf->set('credentials.login', $login); + $conf->set('credentials.login', $userspace); $salt = sha1(uniqid('', true) .'_'. mt_rand()); $conf->set('credentials.salt', $salt); - $conf->set('credentials.hash', sha1($_POST['setpassword'] . $login . $salt)); + $hash = sha1(uniqid('', true) .'_'. mt_rand()); + $conf->set('credentials.hash', $hash); if (!empty($_POST['title'])) { $conf->set('general.title', escape($_POST['title'])); } else { - $conf->set('general.title', 'Shared links on '.escape(index_url($_SERVER))); + $conf->set('general.title', ucwords(str_replace("_", " ", $userspace))); } $conf->set('translation.language', escape($_POST['language'])); $conf->set('updates.check_updates', !empty($_POST['updateCheck'])); @@ -1782,7 +1828,7 @@ function install($conf, $sessionManager, $loginManager) { exit; } - $PAGE = new PageBuilder($conf, null, $sessionManager->generateToken()); + $PAGE = new PageBuilder($conf, $_SESSION, null, $sessionManager->generateToken()); list($continents, $cities) = generateTimeZoneData(timezone_identifiers_list(), date_default_timezone_get()); $PAGE->assign('continents', $continents); $PAGE->assign('cities', $cities); @@ -1791,7 +1837,11 @@ function install($conf, $sessionManager, $loginManager) { exit; } -if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=dailyrss')) { showDailyRSS($conf); exit; } +if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=dailyrss')) { + showDailyRSS($conf, $loginManager); + exit; +} + if (!isset($_SESSION['LINKS_PER_PAGE'])) { $_SESSION['LINKS_PER_PAGE'] = $conf->get('general.links_per_page', 20); } @@ -1817,20 +1867,31 @@ $container['history'] = $history; $app = new \Slim\App($container); // REST API routes -$app->group('/api/v1', function() { +if (isset($userspace)) { + $mountpoint = '/' . $userspace . '/api/v1'; +} else { + $mountpoint = '/api/v1'; +} +$app->group($mountpoint, function() { $this->get('/info', '\Shaarli\Api\Controllers\Info:getInfo')->setName('getInfo'); $this->get('/links', '\Shaarli\Api\Controllers\Links:getLinks')->setName('getLinks'); $this->get('/links/{id:[\d]+}', '\Shaarli\Api\Controllers\Links:getLink')->setName('getLink'); $this->post('/links', '\Shaarli\Api\Controllers\Links:postLink')->setName('postLink'); $this->put('/links/{id:[\d]+}', '\Shaarli\Api\Controllers\Links:putLink')->setName('putLink'); $this->delete('/links/{id:[\d]+}', '\Shaarli\Api\Controllers\Links:deleteLink')->setName('deleteLink'); + + $this->get('/tags', '\Shaarli\Api\Controllers\Tags:getTags')->setName('getTags'); + $this->get('/tags/{tagName:[\w]+}', '\Shaarli\Api\Controllers\Tags:getTag')->setName('getTag'); + $this->put('/tags/{tagName:[\w]+}', '\Shaarli\Api\Controllers\Tags:putTag')->setName('putTag'); + $this->delete('/tags/{tagName:[\w]+}', '\Shaarli\Api\Controllers\Tags:deleteTag')->setName('deleteTag'); + $this->get('/history', '\Shaarli\Api\Controllers\History:getHistory')->setName('getHistory'); })->add('\Shaarli\Api\ApiMiddleware'); $response = $app->run(true); // Hack to make Slim and Shaarli router work together: // If a Slim route isn't found and NOT API call, we call renderPage(). -if ($response->getStatusCode() == 404 && strpos($_SERVER['REQUEST_URI'], '/api/v1') === false) { +if ($response->getStatusCode() == 404 && strpos($_SERVER['REQUEST_URI'], $mountpoint) === false) { // We use UTF-8 for proper international characters handling. header('Content-Type: text/html; charset=utf-8'); renderPage($conf, $pluginManager, $linkDb, $history, $sessionManager, $loginManager);