Completed
Push — master ( f8decb...0d0ae6 )
by Arnaud
15s
created

AjaxController::checkXlmRequest()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Core;
4
5
6
/**
7
 * Class AjaxController
8
 * @package Core
9
 *
10
 * out parent controller for all ajax calls
11
 *
12
 */
13
abstract class AjaxController extends Controller
14
{
15
16
    /**
17
     * The request object to handle all gets and posts
18
     * @var Dependency\Request
19
     *
20
     */
21
    protected $request;
22
23
    /**
24
     * The response module to handle response messages
25
     * @var Dependency\Response
26
     */
27
    protected $response;
28
29
    /**
30
     * On construction, we imediatly check for security and bail out on the first sign of fraude
31
     * Only allow XmlHTTPRequests or throw an exception
32
     * Only allowed to call if Csrf token is valid or throw a json error
33
     * AjaxController constructor.
34
     * @param Container $container
35
     * @throws \Exception
36
     *
37
     */
38
    public function __construct(Container $container)
39
    {
40
        parent::__construct($container);
41
42
        $this->request = $container->getRequest(); //adding our request object as it will be needed in the ajax calls
43
        $this->response = $container->getResponse();
44
45
        //we only allow xmlHTTPRequests here for security
46
        $this->checkXlmRequest();
47
        $this->checkReferer();
48
        $this->csrf->checkJsonCsrf();
49
    }
50
51
    /**
52
     * Checks if we have an Xml Http request and throws an error if not
53
     * @throws \ErrorException
54
     */
55
    private function checkXlmRequest(): void
56
    {
57
        if (!$this->request->isXmlRequest()) {
58
            throw new \ErrorException('Call not permitted', 404);
59
        }
60
    }
61
62
    /**
63
     * Check if the request is coming from the same domain as the base url of the site
64
     * @throws JsonException
65
     */
66
    private function checkReferer(): void
67
    {
68
69
        $referer = $this->request->getReferer();
70
        $baseUrl = $this->request->getBaseUrl();
71
        $inUrl = strpos($referer, $baseUrl);
72
        if ($inUrl === false || $inUrl > 0) { //not at start of referer
73
            if ($referer !== null) {//the referer can be null with certain navigators, so don't block on that
74
                throw new JsonException('Illegal referer.');
75
76
            }
77
78
        }
79
    }
80
81
    /**
82
     * Construct our json reply message
83
     * @param $message
84
     * @param int $code
85
     * @return string json encoded message
86
     */
87
    public function jsonResponse($message = null, $code = 200): string
88
    {
89
        // clear the old headers
90
        //header_remove(); //->this removes our csrf error checking so no go for the moment.
91
        // set the actual code
92
        http_response_code($code);
93
        // set the header to make sure cache is forced
94
        header("Cache-Control: no-transform,public,max-age=300,s-maxage=900");
95
        // treat this as json
96
        //header('Content-Type: application/json');
97
        $this->response->setHeaderContentType('json');
98
        $status = array(
99
            200 => '200 OK',
100
            400 => '400 Bad Request',
101
            422 => 'Unprocessable Entity',
102
            500 => '500 Internal Server Error'
103
        );
104
        // ok, validation error, or failure
105
        header('Status: ' . $status[$code]);
106
        // return the encoded json
107
        return json_encode(array(
108
            'status' => $code < 300, // success or not?
109
            'message' => $message
110
        ));
111
    }
112
113
114
}