diff options
Diffstat (limited to 'application/front/ShaarliMiddleware.php')
-rw-r--r-- | application/front/ShaarliMiddleware.php | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/application/front/ShaarliMiddleware.php b/application/front/ShaarliMiddleware.php new file mode 100644 index 00000000..d1aa1399 --- /dev/null +++ b/application/front/ShaarliMiddleware.php | |||
@@ -0,0 +1,114 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Shaarli\Front; | ||
4 | |||
5 | use Shaarli\Container\ShaarliContainer; | ||
6 | use Shaarli\Front\Exception\UnauthorizedException; | ||
7 | use Slim\Http\Request; | ||
8 | use Slim\Http\Response; | ||
9 | |||
10 | /** | ||
11 | * Class ShaarliMiddleware | ||
12 | * | ||
13 | * This will be called before accessing any Shaarli controller. | ||
14 | */ | ||
15 | class ShaarliMiddleware | ||
16 | { | ||
17 | /** @var ShaarliContainer contains all Shaarli DI */ | ||
18 | protected $container; | ||
19 | |||
20 | public function __construct(ShaarliContainer $container) | ||
21 | { | ||
22 | $this->container = $container; | ||
23 | } | ||
24 | |||
25 | /** | ||
26 | * Middleware execution: | ||
27 | * - run updates | ||
28 | * - if not logged in open shaarli, redirect to login | ||
29 | * - execute the controller | ||
30 | * - return the response | ||
31 | * | ||
32 | * In case of error, the error template will be displayed with the exception message. | ||
33 | * | ||
34 | * @param Request $request Slim request | ||
35 | * @param Response $response Slim response | ||
36 | * @param callable $next Next action | ||
37 | * | ||
38 | * @return Response response. | ||
39 | */ | ||
40 | public function __invoke(Request $request, Response $response, callable $next): Response | ||
41 | { | ||
42 | $this->initBasePath($request); | ||
43 | |||
44 | try { | ||
45 | if (!is_file($this->container->conf->getConfigFileExt()) | ||
46 | && !in_array($next->getName(), ['displayInstall', 'saveInstall'], true) | ||
47 | ) { | ||
48 | return $response->withRedirect($this->container->basePath . '/install'); | ||
49 | } | ||
50 | |||
51 | $this->runUpdates(); | ||
52 | $this->checkOpenShaarli($request, $response, $next); | ||
53 | |||
54 | return $next($request, $response); | ||
55 | } catch (UnauthorizedException $e) { | ||
56 | $returnUrl = urlencode($this->container->environment['REQUEST_URI']); | ||
57 | |||
58 | return $response->withRedirect($this->container->basePath . '/login?returnurl=' . $returnUrl); | ||
59 | } | ||
60 | // Other exceptions are handled by ErrorController | ||
61 | } | ||
62 | |||
63 | /** | ||
64 | * Run the updater for every requests processed while logged in. | ||
65 | */ | ||
66 | protected function runUpdates(): void | ||
67 | { | ||
68 | if ($this->container->loginManager->isLoggedIn() !== true) { | ||
69 | return; | ||
70 | } | ||
71 | |||
72 | $this->container->updater->setBasePath($this->container->basePath); | ||
73 | $newUpdates = $this->container->updater->update(); | ||
74 | if (!empty($newUpdates)) { | ||
75 | $this->container->updater->writeUpdates( | ||
76 | $this->container->conf->get('resource.updates'), | ||
77 | $this->container->updater->getDoneUpdates() | ||
78 | ); | ||
79 | |||
80 | $this->container->pageCacheManager->invalidateCaches(); | ||
81 | } | ||
82 | } | ||
83 | |||
84 | /** | ||
85 | * Access is denied to most pages with `hide_public_links` + `force_login` settings. | ||
86 | */ | ||
87 | protected function checkOpenShaarli(Request $request, Response $response, callable $next): bool | ||
88 | { | ||
89 | if (// if the user isn't logged in | ||
90 | !$this->container->loginManager->isLoggedIn() | ||
91 | // and Shaarli doesn't have public content... | ||
92 | && $this->container->conf->get('privacy.hide_public_links') | ||
93 | // and is configured to enforce the login | ||
94 | && $this->container->conf->get('privacy.force_login') | ||
95 | // and the current page isn't already the login page | ||
96 | // and the user is not requesting a feed (which would lead to a different content-type as expected) | ||
97 | && !in_array($next->getName(), ['login', 'processLogin', 'atom', 'rss'], true) | ||
98 | ) { | ||
99 | throw new UnauthorizedException(); | ||
100 | } | ||
101 | |||
102 | return true; | ||
103 | } | ||
104 | |||
105 | /** | ||
106 | * Initialize the URL base path if it hasn't been defined yet. | ||
107 | */ | ||
108 | protected function initBasePath(Request $request): void | ||
109 | { | ||
110 | if (null === $this->container->basePath) { | ||
111 | $this->container->basePath = rtrim($request->getUri()->getBasePath(), '/'); | ||
112 | } | ||
113 | } | ||
114 | } | ||