Passed
Push — master ( 80fed1...32ef61 )
by Peter
09:46
created

CheckCsrfToken   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 84
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 6
eloc 30
c 1
b 0
f 0
dl 0
loc 84
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A isApiRequest() 0 9 1
A __construct() 0 4 1
A handle() 0 11 3
A writeToResponse() 0 25 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AbterPhp\Admin\Http\Middleware;
6
7
use AbterPhp\Admin\Config\Routes as RoutesConfig;
8
use Closure;
9
use Opulence\Framework\Configuration\Config;
10
use Opulence\Framework\Http\CsrfTokenChecker;
11
use Opulence\Http\InvalidCsrfTokenException;
12
use Opulence\Http\Requests\Request;
13
use Opulence\Http\Responses\Cookie;
14
use Opulence\Http\Responses\Response;
15
use Opulence\Routing\Middleware\IMiddleware;
16
use Opulence\Sessions\ISession;
17
18
/**
19
 * Defines the middleware that checks the CSRF token
20
 */
21
class CheckCsrfToken implements IMiddleware
22
{
23
    /** @var CsrfTokenChecker The CSRF token checker */
24
    protected $csrfTokenChecker = null;
25
    /** @var ISession The current session */
26
    protected $session = null;
27
28
    /**
29
     * @param CsrfTokenChecker $csrfTokenChecker The CSRF token checker
30
     * @param ISession         $session          The current session
31
     */
32
    public function __construct(CsrfTokenChecker $csrfTokenChecker, ISession $session)
33
    {
34
        $this->csrfTokenChecker = $csrfTokenChecker;
35
        $this->session          = $session;
36
    }
37
38
    /**
39
     * @inheritdoc
40
     * @throws InvalidCsrfTokenException Thrown if the CSRF token is invalid
41
     */
42
    public function handle(Request $request, Closure $next): Response
43
    {
44
        if ($this->isApiRequest($request)) {
45
            return $next($request);
46
        }
47
48
        if (!$this->csrfTokenChecker->tokenIsValid($request, $this->session)) {
49
            throw new InvalidCsrfTokenException('Invalid CSRF token');
50
        }
51
52
        return $this->writeToResponse($next($request));
53
    }
54
55
    /**
56
     * @param Request $request
57
     *
58
     * @return bool
59
     */
60
    protected function isApiRequest(Request $request): bool
61
    {
62
        $apiBasePath = RoutesConfig::getApiBasePath();
63
64
        $path = $request->getPath();
65
66
        $isApiRequest = substr($path, 0, strlen($apiBasePath)) === $apiBasePath;
67
68
        return $isApiRequest;
69
    }
70
71
    /**
72
     * @SuppressWarnings(PHPMD.StaticAccess)
73
     *
74
     * Writes data to the response
75
     *
76
     * @param Response $response The response to write to
77
     *
78
     * @return Response The response with the data written to it
79
     */
80
    protected function writeToResponse(Response $response): Response
81
    {
82
        $sessionValue = $this->session->get(CsrfTokenChecker::TOKEN_INPUT_NAME);
83
84
        $lifetime   = Config::get('sessions', 'xsrfcookie.lifetime');
85
        $expiration = time() + $lifetime;
86
87
        $path     = Config::get('sessions', 'cookie.path');
88
        $domain   = Config::get('sessions', 'cookie.domain');
89
        $isSecure = Config::get('sessions', 'cookie.isSecure');
90
91
        // Add an XSRF cookie for JavaScript frameworks to use
92
        $response->getHeaders()->setCookie(
93
            new Cookie(
94
                'XSRF-TOKEN',
95
                $sessionValue,
96
                $expiration,
97
                $path,
0 ignored issues
show
Bug introduced by
It seems like $path can also be of type null; however, parameter $path of Opulence\Http\Responses\Cookie::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

97
                /** @scrutinizer ignore-type */ $path,
Loading history...
98
                $domain,
0 ignored issues
show
Bug introduced by
It seems like $domain can also be of type null; however, parameter $domain of Opulence\Http\Responses\Cookie::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

98
                /** @scrutinizer ignore-type */ $domain,
Loading history...
99
                $isSecure,
0 ignored issues
show
Bug introduced by
It seems like $isSecure can also be of type null; however, parameter $isSecure of Opulence\Http\Responses\Cookie::__construct() does only seem to accept boolean, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

99
                /** @scrutinizer ignore-type */ $isSecure,
Loading history...
100
                false
101
            )
102
        );
103
104
        return $response;
105
    }
106
}
107