3 namespace Shaarli\Front
;
5 use Shaarli\Container\ShaarliContainer
;
6 use Shaarli\Front\Exception\ShaarliFrontException
;
7 use Shaarli\Front\Exception\UnauthorizedException
;
9 use Slim\Http\Response
;
12 * Class ShaarliMiddleware
14 * This will be called before accessing any Shaarli controller.
16 class ShaarliMiddleware
18 /** @var ShaarliContainer contains all Shaarli DI */
21 public function __construct(ShaarliContainer
$container)
23 $this->container
= $container;
27 * Middleware execution:
29 * - if not logged in open shaarli, redirect to login
30 * - execute the controller
31 * - return the response
33 * In case of error, the error template will be displayed with the exception message.
35 * @param Request $request Slim request
36 * @param Response $response Slim response
37 * @param callable $next Next action
39 * @return Response response.
41 public function __invoke(Request
$request, Response
$response, callable
$next): Response
43 $this->container
->basePath
= rtrim($request->getUri()->getBasePath(), '/');
46 if (!is_file($this->container
->conf
->getConfigFileExt())
47 && !in_array($next->getName(), ['displayInstall', 'saveInstall'], true)
49 return $response->withRedirect($this->container
->basePath
. '/install');
53 $this->checkOpenShaarli($request, $response, $next);
55 return $next($request, $response);
56 } catch (ShaarliFrontException
$e) {
57 // Possible functional error
58 $this->container
->pageBuilder
->reset();
59 $this->container
->pageBuilder
->assign('message', $e->getMessage());
61 $response = $response->withStatus($e->getCode());
63 return $response->write($this->container
->pageBuilder
->render('error'));
64 } catch (UnauthorizedException
$e) {
65 $returnUrl = urlencode($this->container
->environment
['REQUEST_URI']);
67 return $response->withRedirect($this->container
->basePath
. '/login?returnurl=' . $returnUrl);
68 } catch (\Throwable
$e) {
69 // Unknown error encountered
70 $this->container
->pageBuilder
->reset();
71 if ($this->container
->conf
->get('dev.debug', false)) {
72 $this->container
->pageBuilder
->assign('message', $e->getMessage());
73 $this->container
->pageBuilder
->assign(
75 nl2br(get_class($e) .': '. PHP_EOL
. $e->getTraceAsString())
78 $this->container
->pageBuilder
->assign('message', t('An unexpected error occurred.'));
81 $response = $response->withStatus(500);
83 return $response->write($this->container
->pageBuilder
->render('error'));
88 * Run the updater for every requests processed while logged in.
90 protected function runUpdates(): void
92 if ($this->container
->loginManager
->isLoggedIn() !== true) {
96 $newUpdates = $this->container
->updater
->update();
97 if (!empty($newUpdates)) {
98 $this->container
->updater
->writeUpdates(
99 $this->container
->conf
->get('resource.updates'),
100 $this->container
->updater
->getDoneUpdates()
103 $this->container
->pageCacheManager
->invalidateCaches();
108 * Access is denied to most pages with `hide_public_links` + `force_login` settings.
110 protected function checkOpenShaarli(Request
$request, Response
$response, callable
$next): bool
112 if (// if the user isn't logged in
113 !$this->container
->loginManager
->isLoggedIn()
114 // and Shaarli doesn't have public content...
115 && $this->container
->conf
->get('privacy.hide_public_links')
116 // and is configured to enforce the login
117 && $this->container
->conf
->get('privacy.force_login')
118 // and the current page isn't already the login page
119 // and the user is not requesting a feed (which would lead to a different content-type as expected)
120 && !in_array($next->getName(), ['login', 'atom', 'rss'], true)
122 throw new UnauthorizedException();