diff options
author | ArthurHoaro <arthur@hoa.ro> | 2020-07-22 18:12:10 +0200 |
---|---|---|
committer | ArthurHoaro <arthur@hoa.ro> | 2020-07-23 21:19:21 +0200 |
commit | fabff3835da26e6c95cea56b2a01a03749dec7c8 (patch) | |
tree | 4818fb25f92ff9ed15d3d25b78d2dfc9c064fc3a | |
parent | a8c11451e8d885a243c1ad52012093ba8d121e2c (diff) | |
download | Shaarli-fabff3835da26e6c95cea56b2a01a03749dec7c8.tar.gz Shaarli-fabff3835da26e6c95cea56b2a01a03749dec7c8.tar.zst Shaarli-fabff3835da26e6c95cea56b2a01a03749dec7c8.zip |
Move PHP and config init to dedicated file
in order to keep index.php as minimal as possible
-rw-r--r-- | application/render/PageBuilder.php | 20 | ||||
-rw-r--r-- | application/security/SessionManager.php | 14 | ||||
-rw-r--r-- | index.php | 143 | ||||
-rw-r--r-- | init.php | 85 |
4 files changed, 122 insertions, 140 deletions
diff --git a/application/render/PageBuilder.php b/application/render/PageBuilder.php index 85e1d59d..471724c0 100644 --- a/application/render/PageBuilder.php +++ b/application/render/PageBuilder.php | |||
@@ -158,10 +158,6 @@ class PageBuilder | |||
158 | */ | 158 | */ |
159 | protected function finalize(): void | 159 | protected function finalize(): void |
160 | { | 160 | { |
161 | //FIXME - DEV _ REMOVE ME | ||
162 | $this->assign('base_path', '/Shaarli'); | ||
163 | $this->assign('asset_path', '/Shaarli/tpl/default'); | ||
164 | |||
165 | // TODO: use the SessionManager | 161 | // TODO: use the SessionManager |
166 | $messageKeys = [ | 162 | $messageKeys = [ |
167 | SessionManager::KEY_SUCCESS_MESSAGES, | 163 | SessionManager::KEY_SUCCESS_MESSAGES, |
@@ -248,20 +244,4 @@ class PageBuilder | |||
248 | 244 | ||
249 | return $this->tpl->draw($page, true); | 245 | return $this->tpl->draw($page, true); |
250 | } | 246 | } |
251 | |||
252 | /** | ||
253 | * Render a 404 page (uses the template : tpl/404.tpl) | ||
254 | * usage: $PAGE->render404('The link was deleted') | ||
255 | * | ||
256 | * @param string $message A message to display what is not found | ||
257 | */ | ||
258 | public function render404($message = '') | ||
259 | { | ||
260 | if (empty($message)) { | ||
261 | $message = t('The page you are trying to reach does not exist or has been deleted.'); | ||
262 | } | ||
263 | header($_SERVER['SERVER_PROTOCOL'] . ' ' . t('404 Not Found')); | ||
264 | $this->tpl->assign('error_message', $message); | ||
265 | $this->renderPage('404'); | ||
266 | } | ||
267 | } | 247 | } |
diff --git a/application/security/SessionManager.php b/application/security/SessionManager.php index 46219a3d..76b0afe8 100644 --- a/application/security/SessionManager.php +++ b/application/security/SessionManager.php | |||
@@ -49,6 +49,20 @@ class SessionManager | |||
49 | } | 49 | } |
50 | 50 | ||
51 | /** | 51 | /** |
52 | * Initialize XSRF token and links per page session variables. | ||
53 | */ | ||
54 | public function initialize(): void | ||
55 | { | ||
56 | if (!isset($this->session['tokens'])) { | ||
57 | $this->session['tokens'] = []; | ||
58 | } | ||
59 | |||
60 | if (!isset($this->session['LINKS_PER_PAGE'])) { | ||
61 | $this->session['LINKS_PER_PAGE'] = $this->conf->get('general.links_per_page', 20); | ||
62 | } | ||
63 | } | ||
64 | |||
65 | /** | ||
52 | * Define whether the user should stay signed in across browser sessions | 66 | * Define whether the user should stay signed in across browser sessions |
53 | * | 67 | * |
54 | * @param bool $staySignedIn Keep the user signed in | 68 | * @param bool $staySignedIn Keep the user signed in |
@@ -12,41 +12,6 @@ | |||
12 | * Licence: http://www.opensource.org/licenses/zlib-license.php | 12 | * Licence: http://www.opensource.org/licenses/zlib-license.php |
13 | */ | 13 | */ |
14 | 14 | ||
15 | // Set 'UTC' as the default timezone if it is not defined in php.ini | ||
16 | // See http://php.net/manual/en/datetime.configuration.php#ini.date.timezone | ||
17 | if (date_default_timezone_get() == '') { | ||
18 | date_default_timezone_set('UTC'); | ||
19 | } | ||
20 | |||
21 | /* | ||
22 | * PHP configuration | ||
23 | */ | ||
24 | |||
25 | // http://server.com/x/shaarli --> /shaarli/ | ||
26 | define('WEB_PATH', substr($_SERVER['REQUEST_URI'], 0, 1+strrpos($_SERVER['REQUEST_URI'], '/', 0))); | ||
27 | |||
28 | // High execution time in case of problematic imports/exports. | ||
29 | ini_set('max_input_time', '60'); | ||
30 | |||
31 | // Try to set max upload file size and read | ||
32 | ini_set('memory_limit', '128M'); | ||
33 | ini_set('post_max_size', '16M'); | ||
34 | ini_set('upload_max_filesize', '16M'); | ||
35 | |||
36 | // See all error except warnings | ||
37 | error_reporting(E_ALL^E_WARNING); | ||
38 | |||
39 | // 3rd-party libraries | ||
40 | if (! file_exists(__DIR__ . '/vendor/autoload.php')) { | ||
41 | header('Content-Type: text/plain; charset=utf-8'); | ||
42 | echo "Error: missing Composer configuration\n\n" | ||
43 | ."If you installed Shaarli through Git or using the development branch,\n" | ||
44 | ."please refer to the installation documentation to install PHP" | ||
45 | ." dependencies using Composer:\n" | ||
46 | ."- https://shaarli.readthedocs.io/en/master/Server-configuration/\n" | ||
47 | ."- https://shaarli.readthedocs.io/en/master/Download-and-Installation/"; | ||
48 | exit; | ||
49 | } | ||
50 | require_once 'inc/rain.tpl.class.php'; | 15 | require_once 'inc/rain.tpl.class.php'; |
51 | require_once __DIR__ . '/vendor/autoload.php'; | 16 | require_once __DIR__ . '/vendor/autoload.php'; |
52 | 17 | ||
@@ -55,12 +20,11 @@ require_once 'application/bookmark/LinkUtils.php'; | |||
55 | require_once 'application/config/ConfigPlugin.php'; | 20 | require_once 'application/config/ConfigPlugin.php'; |
56 | require_once 'application/http/HttpUtils.php'; | 21 | require_once 'application/http/HttpUtils.php'; |
57 | require_once 'application/http/UrlUtils.php'; | 22 | require_once 'application/http/UrlUtils.php'; |
58 | require_once 'application/updater/UpdaterUtils.php'; | ||
59 | require_once 'application/FileUtils.php'; | ||
60 | require_once 'application/TimeZone.php'; | 23 | require_once 'application/TimeZone.php'; |
61 | require_once 'application/Utils.php'; | 24 | require_once 'application/Utils.php'; |
62 | 25 | ||
63 | use Shaarli\ApplicationUtils; | 26 | require_once __DIR__ . '/init.php'; |
27 | |||
64 | use Shaarli\Config\ConfigManager; | 28 | use Shaarli\Config\ConfigManager; |
65 | use Shaarli\Container\ContainerBuilder; | 29 | use Shaarli\Container\ContainerBuilder; |
66 | use Shaarli\Languages; | 30 | use Shaarli\Languages; |
@@ -70,45 +34,6 @@ use Shaarli\Security\LoginManager; | |||
70 | use Shaarli\Security\SessionManager; | 34 | use Shaarli\Security\SessionManager; |
71 | use Slim\App; | 35 | use Slim\App; |
72 | 36 | ||
73 | // Ensure the PHP version is supported | ||
74 | try { | ||
75 | ApplicationUtils::checkPHPVersion('7.1', PHP_VERSION); | ||
76 | } catch (Exception $exc) { | ||
77 | header('Content-Type: text/plain; charset=utf-8'); | ||
78 | echo $exc->getMessage(); | ||
79 | exit; | ||
80 | } | ||
81 | |||
82 | define('SHAARLI_VERSION', ApplicationUtils::getVersion(__DIR__ .'/'. ApplicationUtils::$VERSION_FILE)); | ||
83 | |||
84 | // Force cookie path (but do not change lifetime) | ||
85 | $cookie = session_get_cookie_params(); | ||
86 | $cookiedir = ''; | ||
87 | if (dirname($_SERVER['SCRIPT_NAME']) != '/') { | ||
88 | $cookiedir = dirname($_SERVER["SCRIPT_NAME"]).'/'; | ||
89 | } | ||
90 | // Set default cookie expiration and path. | ||
91 | session_set_cookie_params($cookie['lifetime'], $cookiedir, $_SERVER['SERVER_NAME']); | ||
92 | // Set session parameters on server side. | ||
93 | // Use cookies to store session. | ||
94 | ini_set('session.use_cookies', 1); | ||
95 | // Force cookies for session (phpsessionID forbidden in URL). | ||
96 | ini_set('session.use_only_cookies', 1); | ||
97 | // Prevent PHP form using sessionID in URL if cookies are disabled. | ||
98 | ini_set('session.use_trans_sid', false); | ||
99 | |||
100 | session_name('shaarli'); | ||
101 | // Start session if needed (Some server auto-start sessions). | ||
102 | if (session_status() == PHP_SESSION_NONE) { | ||
103 | session_start(); | ||
104 | } | ||
105 | |||
106 | // Regenerate session ID if invalid or not defined in cookie. | ||
107 | if (isset($_COOKIE['shaarli']) && !SessionManager::checkId($_COOKIE['shaarli'])) { | ||
108 | session_regenerate_id(true); | ||
109 | $_COOKIE['shaarli'] = session_id(); | ||
110 | } | ||
111 | |||
112 | $conf = new ConfigManager(); | 37 | $conf = new ConfigManager(); |
113 | 38 | ||
114 | // In dev mode, throw exception on any warning | 39 | // In dev mode, throw exception on any warning |
@@ -122,15 +47,10 @@ if ($conf->get('dev.debug', false)) { | |||
122 | } | 47 | } |
123 | 48 | ||
124 | $sessionManager = new SessionManager($_SESSION, $conf, session_save_path()); | 49 | $sessionManager = new SessionManager($_SESSION, $conf, session_save_path()); |
50 | $sessionManager->initialize(); | ||
125 | $cookieManager = new CookieManager($_COOKIE); | 51 | $cookieManager = new CookieManager($_COOKIE); |
126 | $loginManager = new LoginManager($conf, $sessionManager, $cookieManager); | 52 | $loginManager = new LoginManager($conf, $sessionManager, $cookieManager); |
127 | $loginManager->generateStaySignedInToken($_SERVER['REMOTE_ADDR']); | 53 | $loginManager->generateStaySignedInToken($_SERVER['REMOTE_ADDR']); |
128 | $clientIpId = client_ip_id($_SERVER); | ||
129 | |||
130 | // LC_MESSAGES isn't defined without php-intl, in this case use LC_COLLATE locale instead. | ||
131 | if (! defined('LC_MESSAGES')) { | ||
132 | define('LC_MESSAGES', LC_COLLATE); | ||
133 | } | ||
134 | 54 | ||
135 | // Sniff browser language and set date format accordingly. | 55 | // Sniff browser language and set date format accordingly. |
136 | if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { | 56 | if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { |
@@ -141,6 +61,7 @@ new Languages(setlocale(LC_MESSAGES, 0), $conf); | |||
141 | 61 | ||
142 | $conf->setEmpty('general.timezone', date_default_timezone_get()); | 62 | $conf->setEmpty('general.timezone', date_default_timezone_get()); |
143 | $conf->setEmpty('general.title', t('Shared bookmarks on '). escape(index_url($_SERVER))); | 63 | $conf->setEmpty('general.title', t('Shared bookmarks on '). escape(index_url($_SERVER))); |
64 | |||
144 | RainTPL::$tpl_dir = $conf->get('resource.raintpl_tpl').'/'.$conf->get('resource.theme').'/'; // template directory | 65 | RainTPL::$tpl_dir = $conf->get('resource.raintpl_tpl').'/'.$conf->get('resource.theme').'/'; // template directory |
145 | RainTPL::$cache_dir = $conf->get('resource.raintpl_tmp'); // cache directory | 66 | RainTPL::$cache_dir = $conf->get('resource.raintpl_tmp'); // cache directory |
146 | 67 | ||
@@ -149,48 +70,13 @@ $pluginManager->load($conf->get('general.enabled_plugins')); | |||
149 | 70 | ||
150 | date_default_timezone_set($conf->get('general.timezone', 'UTC')); | 71 | date_default_timezone_set($conf->get('general.timezone', 'UTC')); |
151 | 72 | ||
152 | ob_start(); // Output buffering for the page cache. | 73 | $loginManager->checkLoginState(client_ip_id($_SERVER)); |
153 | |||
154 | // Prevent caching on client side or proxy: (yes, it's ugly) | ||
155 | header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); | ||
156 | header("Cache-Control: no-store, no-cache, must-revalidate"); | ||
157 | header("Cache-Control: post-check=0, pre-check=0", false); | ||
158 | header("Pragma: no-cache"); | ||
159 | |||
160 | $loginManager->checkLoginState($clientIpId); | ||
161 | |||
162 | // ------------------------------------------------------------------------------------------ | ||
163 | // Token management for XSRF protection | ||
164 | // Token should be used in any form which acts on data (create,update,delete,import...). | ||
165 | if (!isset($_SESSION['tokens'])) { | ||
166 | $_SESSION['tokens']=array(); // Token are attached to the session. | ||
167 | } | ||
168 | |||
169 | if (!isset($_SESSION['LINKS_PER_PAGE'])) { | ||
170 | $_SESSION['LINKS_PER_PAGE'] = $conf->get('general.links_per_page', 20); | ||
171 | } | ||
172 | 74 | ||
173 | $containerBuilder = new ContainerBuilder($conf, $sessionManager, $cookieManager, $loginManager); | 75 | $containerBuilder = new ContainerBuilder($conf, $sessionManager, $cookieManager, $loginManager); |
174 | $container = $containerBuilder->build(); | 76 | $container = $containerBuilder->build(); |
175 | $app = new App($container); | 77 | $app = new App($container); |
176 | 78 | ||
177 | // REST API routes | 79 | // Main Shaarli routes |
178 | $app->group('/api/v1', function () { | ||
179 | $this->get('/info', '\Shaarli\Api\Controllers\Info:getInfo')->setName('getInfo'); | ||
180 | $this->get('/links', '\Shaarli\Api\Controllers\Links:getLinks')->setName('getLinks'); | ||
181 | $this->get('/links/{id:[\d]+}', '\Shaarli\Api\Controllers\Links:getLink')->setName('getLink'); | ||
182 | $this->post('/links', '\Shaarli\Api\Controllers\Links:postLink')->setName('postLink'); | ||
183 | $this->put('/links/{id:[\d]+}', '\Shaarli\Api\Controllers\Links:putLink')->setName('putLink'); | ||
184 | $this->delete('/links/{id:[\d]+}', '\Shaarli\Api\Controllers\Links:deleteLink')->setName('deleteLink'); | ||
185 | |||
186 | $this->get('/tags', '\Shaarli\Api\Controllers\Tags:getTags')->setName('getTags'); | ||
187 | $this->get('/tags/{tagName:[\w]+}', '\Shaarli\Api\Controllers\Tags:getTag')->setName('getTag'); | ||
188 | $this->put('/tags/{tagName:[\w]+}', '\Shaarli\Api\Controllers\Tags:putTag')->setName('putTag'); | ||
189 | $this->delete('/tags/{tagName:[\w]+}', '\Shaarli\Api\Controllers\Tags:deleteTag')->setName('deleteTag'); | ||
190 | |||
191 | $this->get('/history', '\Shaarli\Api\Controllers\HistoryController:getHistory')->setName('getHistory'); | ||
192 | })->add('\Shaarli\Api\ApiMiddleware'); | ||
193 | |||
194 | $app->group('', function () { | 80 | $app->group('', function () { |
195 | $this->get('/install', '\Shaarli\Front\Controller\Visitor\InstallController:index')->setName('displayInstall'); | 81 | $this->get('/install', '\Shaarli\Front\Controller\Visitor\InstallController:index')->setName('displayInstall'); |
196 | $this->get('/install/session-test', '\Shaarli\Front\Controller\Visitor\InstallController:sessionTest'); | 82 | $this->get('/install/session-test', '\Shaarli\Front\Controller\Visitor\InstallController:sessionTest'); |
@@ -247,6 +133,23 @@ $app->group('', function () { | |||
247 | $this->get('/untagged-only', '\Shaarli\Front\Controller\Admin\SessionFilterController:untaggedOnly'); | 133 | $this->get('/untagged-only', '\Shaarli\Front\Controller\Admin\SessionFilterController:untaggedOnly'); |
248 | })->add('\Shaarli\Front\ShaarliMiddleware'); | 134 | })->add('\Shaarli\Front\ShaarliMiddleware'); |
249 | 135 | ||
136 | // REST API routes | ||
137 | $app->group('/api/v1', function () { | ||
138 | $this->get('/info', '\Shaarli\Api\Controllers\Info:getInfo')->setName('getInfo'); | ||
139 | $this->get('/links', '\Shaarli\Api\Controllers\Links:getLinks')->setName('getLinks'); | ||
140 | $this->get('/links/{id:[\d]+}', '\Shaarli\Api\Controllers\Links:getLink')->setName('getLink'); | ||
141 | $this->post('/links', '\Shaarli\Api\Controllers\Links:postLink')->setName('postLink'); | ||
142 | $this->put('/links/{id:[\d]+}', '\Shaarli\Api\Controllers\Links:putLink')->setName('putLink'); | ||
143 | $this->delete('/links/{id:[\d]+}', '\Shaarli\Api\Controllers\Links:deleteLink')->setName('deleteLink'); | ||
144 | |||
145 | $this->get('/tags', '\Shaarli\Api\Controllers\Tags:getTags')->setName('getTags'); | ||
146 | $this->get('/tags/{tagName:[\w]+}', '\Shaarli\Api\Controllers\Tags:getTag')->setName('getTag'); | ||
147 | $this->put('/tags/{tagName:[\w]+}', '\Shaarli\Api\Controllers\Tags:putTag')->setName('putTag'); | ||
148 | $this->delete('/tags/{tagName:[\w]+}', '\Shaarli\Api\Controllers\Tags:deleteTag')->setName('deleteTag'); | ||
149 | |||
150 | $this->get('/history', '\Shaarli\Api\Controllers\HistoryController:getHistory')->setName('getHistory'); | ||
151 | })->add('\Shaarli\Api\ApiMiddleware'); | ||
152 | |||
250 | $response = $app->run(true); | 153 | $response = $app->run(true); |
251 | 154 | ||
252 | $app->respond($response); | 155 | $app->respond($response); |
diff --git a/init.php b/init.php new file mode 100644 index 00000000..f0b84368 --- /dev/null +++ b/init.php | |||
@@ -0,0 +1,85 @@ | |||
1 | <?php | ||
2 | |||
3 | require_once __DIR__ . '/vendor/autoload.php'; | ||
4 | |||
5 | use Shaarli\ApplicationUtils; | ||
6 | use Shaarli\Security\SessionManager; | ||
7 | |||
8 | // Set 'UTC' as the default timezone if it is not defined in php.ini | ||
9 | // See http://php.net/manual/en/datetime.configuration.php#ini.date.timezone | ||
10 | if (date_default_timezone_get() == '') { | ||
11 | date_default_timezone_set('UTC'); | ||
12 | } | ||
13 | |||
14 | // High execution time in case of problematic imports/exports. | ||
15 | ini_set('max_input_time', '60'); | ||
16 | |||
17 | // Try to set max upload file size and read | ||
18 | ini_set('memory_limit', '128M'); | ||
19 | ini_set('post_max_size', '16M'); | ||
20 | ini_set('upload_max_filesize', '16M'); | ||
21 | |||
22 | // See all error except warnings | ||
23 | error_reporting(E_ALL^E_WARNING); | ||
24 | |||
25 | // 3rd-party libraries | ||
26 | if (! file_exists(__DIR__ . '/vendor/autoload.php')) { | ||
27 | header('Content-Type: text/plain; charset=utf-8'); | ||
28 | echo "Error: missing Composer configuration\n\n" | ||
29 | ."If you installed Shaarli through Git or using the development branch,\n" | ||
30 | ."please refer to the installation documentation to install PHP" | ||
31 | ." dependencies using Composer:\n" | ||
32 | ."- https://shaarli.readthedocs.io/en/master/Server-configuration/\n" | ||
33 | ."- https://shaarli.readthedocs.io/en/master/Download-and-Installation/"; | ||
34 | exit; | ||
35 | } | ||
36 | |||
37 | // Ensure the PHP version is supported | ||
38 | try { | ||
39 | ApplicationUtils::checkPHPVersion('7.1', PHP_VERSION); | ||
40 | } catch (Exception $exc) { | ||
41 | header('Content-Type: text/plain; charset=utf-8'); | ||
42 | echo $exc->getMessage(); | ||
43 | exit; | ||
44 | } | ||
45 | |||
46 | // Force cookie path (but do not change lifetime) | ||
47 | $cookie = session_get_cookie_params(); | ||
48 | $cookiedir = ''; | ||
49 | if (dirname($_SERVER['SCRIPT_NAME']) != '/') { | ||
50 | $cookiedir = dirname($_SERVER["SCRIPT_NAME"]).'/'; | ||
51 | } | ||
52 | // Set default cookie expiration and path. | ||
53 | session_set_cookie_params($cookie['lifetime'], $cookiedir, $_SERVER['SERVER_NAME']); | ||
54 | // Set session parameters on server side. | ||
55 | // Use cookies to store session. | ||
56 | ini_set('session.use_cookies', 1); | ||
57 | // Force cookies for session (phpsessionID forbidden in URL). | ||
58 | ini_set('session.use_only_cookies', 1); | ||
59 | // Prevent PHP form using sessionID in URL if cookies are disabled. | ||
60 | ini_set('session.use_trans_sid', false); | ||
61 | |||
62 | define('SHAARLI_VERSION', ApplicationUtils::getVersion(__DIR__ .'/'. ApplicationUtils::$VERSION_FILE)); | ||
63 | |||
64 | session_name('shaarli'); | ||
65 | // Start session if needed (Some server auto-start sessions). | ||
66 | if (session_status() == PHP_SESSION_NONE) { | ||
67 | session_start(); | ||
68 | } | ||
69 | |||
70 | // Regenerate session ID if invalid or not defined in cookie. | ||
71 | if (isset($_COOKIE['shaarli']) && !SessionManager::checkId($_COOKIE['shaarli'])) { | ||
72 | session_regenerate_id(true); | ||
73 | $_COOKIE['shaarli'] = session_id(); | ||
74 | } | ||
75 | |||
76 | // LC_MESSAGES isn't defined without php-intl, in this case use LC_COLLATE locale instead. | ||
77 | if (! defined('LC_MESSAGES')) { | ||
78 | define('LC_MESSAGES', LC_COLLATE); | ||
79 | } | ||
80 | |||
81 | // Prevent caching on client side or proxy: (yes, it's ugly) | ||
82 | header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); | ||
83 | header("Cache-Control: no-store, no-cache, must-revalidate"); | ||
84 | header("Cache-Control: post-check=0, pre-check=0", false); | ||
85 | header("Pragma: no-cache"); | ||