diff options
Diffstat (limited to 'application/front/ShaarliMiddleware.php')
-rw-r--r-- | application/front/ShaarliMiddleware.php | 73 |
1 files changed, 65 insertions, 8 deletions
diff --git a/application/front/ShaarliMiddleware.php b/application/front/ShaarliMiddleware.php index 7ad610c7..baea6ef2 100644 --- a/application/front/ShaarliMiddleware.php +++ b/application/front/ShaarliMiddleware.php | |||
@@ -25,6 +25,8 @@ class ShaarliMiddleware | |||
25 | 25 | ||
26 | /** | 26 | /** |
27 | * Middleware execution: | 27 | * Middleware execution: |
28 | * - run updates | ||
29 | * - if not logged in open shaarli, redirect to login | ||
28 | * - execute the controller | 30 | * - execute the controller |
29 | * - return the response | 31 | * - return the response |
30 | * | 32 | * |
@@ -36,27 +38,82 @@ class ShaarliMiddleware | |||
36 | * | 38 | * |
37 | * @return Response response. | 39 | * @return Response response. |
38 | */ | 40 | */ |
39 | public function __invoke(Request $request, Response $response, callable $next) | 41 | public function __invoke(Request $request, Response $response, callable $next): Response |
40 | { | 42 | { |
41 | $this->container->basePath = rtrim($request->getUri()->getBasePath(), '/'); | 43 | $this->container->basePath = rtrim($request->getUri()->getBasePath(), '/'); |
42 | 44 | ||
43 | try { | 45 | try { |
44 | $response = $next($request, $response); | 46 | $this->runUpdates(); |
47 | $this->checkOpenShaarli($request, $response, $next); | ||
48 | |||
49 | return $next($request, $response); | ||
45 | } catch (ShaarliFrontException $e) { | 50 | } catch (ShaarliFrontException $e) { |
51 | // Possible functional error | ||
52 | $this->container->pageBuilder->reset(); | ||
46 | $this->container->pageBuilder->assign('message', $e->getMessage()); | 53 | $this->container->pageBuilder->assign('message', $e->getMessage()); |
54 | |||
55 | $response = $response->withStatus($e->getCode()); | ||
56 | |||
57 | return $response->write($this->container->pageBuilder->render('error')); | ||
58 | } catch (UnauthorizedException $e) { | ||
59 | return $response->withRedirect($this->container->basePath . '/login'); | ||
60 | } catch (\Throwable $e) { | ||
61 | // Unknown error encountered | ||
62 | $this->container->pageBuilder->reset(); | ||
47 | if ($this->container->conf->get('dev.debug', false)) { | 63 | if ($this->container->conf->get('dev.debug', false)) { |
64 | $this->container->pageBuilder->assign('message', $e->getMessage()); | ||
48 | $this->container->pageBuilder->assign( | 65 | $this->container->pageBuilder->assign( |
49 | 'stacktrace', | 66 | 'stacktrace', |
50 | nl2br(get_class($this) .': '. $e->getTraceAsString()) | 67 | nl2br(get_class($e) .': '. PHP_EOL . $e->getTraceAsString()) |
51 | ); | 68 | ); |
69 | } else { | ||
70 | $this->container->pageBuilder->assign('message', t('An unexpected error occurred.')); | ||
52 | } | 71 | } |
53 | 72 | ||
54 | $response = $response->withStatus($e->getCode()); | 73 | $response = $response->withStatus(500); |
55 | $response = $response->write($this->container->pageBuilder->render('error')); | 74 | |
56 | } catch (UnauthorizedException $e) { | 75 | return $response->write($this->container->pageBuilder->render('error')); |
57 | return $response->withRedirect($this->container->basePath . '/login'); | 76 | } |
77 | } | ||
78 | |||
79 | /** | ||
80 | * Run the updater for every requests processed while logged in. | ||
81 | */ | ||
82 | protected function runUpdates(): void | ||
83 | { | ||
84 | if ($this->container->loginManager->isLoggedIn() !== true) { | ||
85 | return; | ||
86 | } | ||
87 | |||
88 | $newUpdates = $this->container->updater->update(); | ||
89 | if (!empty($newUpdates)) { | ||
90 | $this->container->updater->writeUpdates( | ||
91 | $this->container->conf->get('resource.updates'), | ||
92 | $this->container->updater->getDoneUpdates() | ||
93 | ); | ||
94 | |||
95 | $this->container->pageCacheManager->invalidateCaches(); | ||
96 | } | ||
97 | } | ||
98 | |||
99 | /** | ||
100 | * Access is denied to most pages with `hide_public_links` + `force_login` settings. | ||
101 | */ | ||
102 | protected function checkOpenShaarli(Request $request, Response $response, callable $next): bool | ||
103 | { | ||
104 | if (// if the user isn't logged in | ||
105 | !$this->container->loginManager->isLoggedIn() | ||
106 | // and Shaarli doesn't have public content... | ||
107 | && $this->container->conf->get('privacy.hide_public_links') | ||
108 | // and is configured to enforce the login | ||
109 | && $this->container->conf->get('privacy.force_login') | ||
110 | // and the current page isn't already the login page | ||
111 | // and the user is not requesting a feed (which would lead to a different content-type as expected) | ||
112 | && !in_array($next->getName(), ['login', 'atom', 'rss'], true) | ||
113 | ) { | ||
114 | throw new UnauthorizedException(); | ||
58 | } | 115 | } |
59 | 116 | ||
60 | return $response; | 117 | return true; |
61 | } | 118 | } |
62 | } | 119 | } |