Passed
Push — dependabot/composer/doctrine/d... ( 71e71a...50cb9e )
by
unknown
42:38 queued 27:52
created

AjaxAction::checkCsrfTokenInHeader()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
cc 4
eloc 8
nc 2
nop 0
dl 0
loc 15
ccs 0
cts 11
cp 0
crap 20
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Backend\Core\Engine\Base;
4
5
use Backend\Core\Engine\Model;
6
use Backend\Core\Language\Language;
7
use Common\Exception\RedirectException;
8
use ForkCMS\App\KernelLoader;
9
use Symfony\Component\HttpFoundation\JsonResponse;
10
use Symfony\Component\HttpFoundation\Request;
11
use Symfony\Component\HttpFoundation\Response;
12
13
/**
14
 * This class implements a lot of functionality that can be extended by a specific AJAX action
15
 */
16
class AjaxAction extends KernelLoader
17
{
18
    /**
19
     * @var array
20
     */
21
    private $content;
22
23
    public function execute(): void
24
    {
25
        $this->checkCsrfTokenInHeader();
26
    }
27
28
    /**
29
     * Since the display action in the backend is rather complicated and we
30
     * want to make this work with our Kernel, I've added this getContent
31
     * method to extract the output from the actual displaying.
32
     *
33
     * With this function we'll be able to get the content and return it as a
34
     * Symfony output object.
35
     *
36
     * @return Response
37
     */
38
    public function getContent(): Response
39
    {
40
        return new Response(
41
            json_encode($this->content),
42
            $this->content['code'] ?? Response::HTTP_OK,
43
            ['content-type' => 'application/json']
44
        );
45
    }
46
47
    /**
48
     * Output an answer to the browser
49
     *
50
     * @param int $statusCode The status code for the response, use the HTTP constants from the Symfony Response class
51
     * @param mixed $data The data to output.
52
     * @param string $message The text-message to send.
53
     */
54
    public function output(int $statusCode, $data = null, string $message = null): void
55
    {
56
        $this->content = ['code' => $statusCode, 'data' => $data, 'message' => $message];
57
    }
58
59
    /**
60
     * Get the request from the container.
61
     *
62
     * @return Request
63
     */
64
    public function getRequest(): Request
65
    {
66
        return Model::getRequest();
67
    }
68
69
    public function getAction(): string
70
    {
71
        return $this->get('url')->getAction();
72
    }
73
74
    public function getModule(): string
75
    {
76
        return $this->get('url')->getModule();
77
    }
78
79
    protected function checkCsrfTokenInHeader(): void
80
    {
81
        $fromSession = Model::getSession()->get('csrf_token', '');
82
        $fromHeader = $this->getRequest()->headers->get('X-CSRF-Token', '');
83
84
        if ($fromSession !== '' && $fromHeader !== '' && $fromSession === $fromHeader) {
85
            return;
86
        }
87
88
        // clear the token
89
        Model::getSession()->set('csrf_token', '');
90
91
        throw new RedirectException(
92
            'Invalid csrf token',
93
            JsonResponse::create(Language::err('Csrf'), JsonResponse::HTTP_FORBIDDEN)
94
        );
95
    }
96
}
97