xref: /webtrees/app/Http/Middleware/CheckCsrf.php (revision 3976b4703df669696105ed6b024b96d433c8fbdb)
1ccb0284cSGreg Roach<?php
2*3976b470SGreg Roach
3ccb0284cSGreg Roach/**
4ccb0284cSGreg Roach * webtrees: online genealogy
58fcd0d32SGreg Roach * Copyright (C) 2019 webtrees development team
6ccb0284cSGreg Roach * This program is free software: you can redistribute it and/or modify
7ccb0284cSGreg Roach * it under the terms of the GNU General Public License as published by
8ccb0284cSGreg Roach * the Free Software Foundation, either version 3 of the License, or
9ccb0284cSGreg Roach * (at your option) any later version.
10ccb0284cSGreg Roach * This program is distributed in the hope that it will be useful,
11ccb0284cSGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of
12ccb0284cSGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13ccb0284cSGreg Roach * GNU General Public License for more details.
14ccb0284cSGreg Roach * You should have received a copy of the GNU General Public License
15ccb0284cSGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>.
16ccb0284cSGreg Roach */
17ccb0284cSGreg Roachdeclare(strict_types=1);
18ccb0284cSGreg Roach
19ccb0284cSGreg Roachnamespace Fisharebest\Webtrees\Http\Middleware;
20ccb0284cSGreg Roach
216ccdf4f0SGreg Roachuse Fig\Http\Message\RequestMethodInterface;
22094bd4e5SGreg Roachuse Fisharebest\Webtrees\FlashMessages;
23ccb0284cSGreg Roachuse Fisharebest\Webtrees\I18N;
24ccb0284cSGreg Roachuse Fisharebest\Webtrees\Session;
256ccdf4f0SGreg Roachuse Psr\Http\Message\ResponseInterface;
266ccdf4f0SGreg Roachuse Psr\Http\Message\ServerRequestInterface;
276ccdf4f0SGreg Roachuse Psr\Http\Server\MiddlewareInterface;
286ccdf4f0SGreg Roachuse Psr\Http\Server\RequestHandlerInterface;
29*3976b470SGreg Roach
30ba8e6c18SGreg Roachuse function in_array;
31ccb0284cSGreg Roach
32ccb0284cSGreg Roach/**
33ccb0284cSGreg Roach * Middleware to wrap a request in a transaction.
34ccb0284cSGreg Roach */
35c1010edaSGreg Roachclass CheckCsrf implements MiddlewareInterface
36c1010edaSGreg Roach{
37ba8e6c18SGreg Roach    private const EXCLUDE_ROUTES = [
38ba8e6c18SGreg Roach        'language',
39ba8e6c18SGreg Roach        'theme',
40ba8e6c18SGreg Roach    ];
41ba8e6c18SGreg Roach
42ccb0284cSGreg Roach    /**
436ccdf4f0SGreg Roach     * @param ServerRequestInterface  $request
446ccdf4f0SGreg Roach     * @param RequestHandlerInterface $handler
45ccb0284cSGreg Roach     *
466ccdf4f0SGreg Roach     * @return ResponseInterface
47ccb0284cSGreg Roach     */
486ccdf4f0SGreg Roach    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
49c1010edaSGreg Roach    {
506ccdf4f0SGreg Roach        if ($request->getMethod() === RequestMethodInterface::METHOD_POST) {
514f2a4a62SGreg Roach            $route = $request->getQueryParams()['route'] ?? '';
52ba8e6c18SGreg Roach
53310b7a5aSGreg Roach            if (!in_array($route, self::EXCLUDE_ROUTES, true)) {
54e106ff43SGreg Roach                $client_token  = $request->getParsedBody()['csrf'] ?? $request->getHeaderLine('X-CSRF-TOKEN');
55ccb0284cSGreg Roach                $session_token = Session::get('CSRF_TOKEN');
56ccb0284cSGreg Roach
57310b7a5aSGreg Roach                if ($client_token !== $session_token) {
58094bd4e5SGreg Roach                    FlashMessages::addMessage(I18N::translate('This form has expired. Try again.'));
59094bd4e5SGreg Roach
60add3fa41SGreg Roach                    return redirect($request->getAttribute('request_uri'));
61ccb0284cSGreg Roach                }
62310b7a5aSGreg Roach            }
63310b7a5aSGreg Roach        }
64ccb0284cSGreg Roach
656ccdf4f0SGreg Roach        return $handler->handle($request);
66ccb0284cSGreg Roach    }
67ccb0284cSGreg Roach}
68