GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Test Setup Failed
Pull Request — master (#26)
by Gallice
02:07
created

WebhookRequestHandler::addEventSubscriber()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 0
cts 0
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 2
1
<?php
2
3
namespace Tgallice\FBMessenger;
4
5
use GuzzleHttp\Psr7\ServerRequest;
6
use Psr\Http\Message\ServerRequestInterface;
7
use Symfony\Component\EventDispatcher\EventDispatcher;
8
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
9
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
10
use Tgallice\FBMessenger\Callback\CallbackEvent;
11
use Tgallice\FBMessenger\Callback\MessageEvent;
12
use Tgallice\FBMessenger\Callback\PostbackEvent;
13
use Tgallice\FBMessenger\Model\Callback\Entry;
14
15
class WebhookRequestHandler
16
{
17
    /**
18
     * @var ServerRequestInterface
19
     */
20
    private $request;
21
22
    /**
23
     * App secret used to verify the request sha1
24
     *
25
     * @var string
26
     */
27
    private $secret;
28
29
    /**
30
     * @var array
31
     */
32
    private $decodedBody;
33
34
    /**
35
     * @var Entry[]
36
     */
37
    private $hydratedEntries;
38
39
    /**
40
     * @var string
41
     */
42
    private $body;
43
44
    /**
45
     * @var string
46
     */
47
    private $verifyToken;
48
49 10
    /**
50
     * @var EventDispatcherInterface
51 10
     */
52 10
    private $dispatcher;
53 10
54 10
    /**
55
     * @param string $secret
56
     * @param string $verifyToken
57
     * @param ServerRequestInterface|null $request
58
     */
59
    public function __construct($secret, $verifyToken, ServerRequestInterface $request = null, EventDispatcherInterface $dispatcher = null)
60
    {
61
        $this->secret = $secret;
62 1
        $this->verifyToken = $verifyToken;
63
        $this->request = $request ?: ServerRequest::fromGlobals();
64 1
        $this->dispatcher = $dispatcher ?: new EventDispatcher();
65
    }
66
67
    /**
68 1
     * Check if the token match with the given verify token.
69
     * This is useful in the webhook setup process.
70 1
     *
71
     * @return bool
72
     */
73
    public function isValidVerifyTokenRequest()
74 1
    {
75
        if ($this->request->getMethod() !== 'GET') {
76
            return false;
77
        }
78
79
        $params = $this->request->getQueryParams();
80 1
81
        if (!isset($params['hub_verify_token'])) {
82 1
            return false;
83
        }
84 1
85
        return  $params['hub_verify_token'] === $this->verifyToken;
86
    }
87
88
    /**
89
     * @return null|string
90
     */
91
    public function getChallenge()
92 3
    {
93
        $params = $this->request->getQueryParams();
94 3
95 2
        return isset($params['hub_challenge']) ? $params['hub_challenge'] : null;
96
    }
97
98 1
    /**
99
     * Check if the request is a valid webhook request
100 1
     *
101 1
     * @return bool
102
     */
103 1
    public function isValidCallbackRequest()
104
    {
105
        if (!$this->isValidHubSignature()) {
106
            return false;
107
        }
108
109
        $decoded = $this->getDecodedBody();
110
111
        $object = isset($decoded['object']) ? $decoded['object'] : null;
112
        $entry = isset($decoded['entry']) ? $decoded['entry'] : null;
113
114
        return $object === 'page' && null !== $entry;
115
    }
116
117
    /**
118
     * Check if the request is a valid webhook request
119
     *
120
     * @deprecated use WebhookRequestHandler::isValidCallbackRequest() instead
121 1
     *
122
     * @return bool
123 1
     */
124
    public function isValid()
125 1
    {
126 1
        return $this->isValidCallbackRequest();
127 1
    }
128
129 1
    /**
130
     * @return CallbackEvent[]
131
     */
132
    public function getAllCallbackEvents()
133
    {
134
        $events = [];
135 1
136
        foreach ($this->getHydratedEntries() as $hydratedEntry) {
137 1
            $events = array_merge($events, $hydratedEntry->getCallbackEvents());
138
        }
139
140
        return $events;
141
    }
142
143 1
    /**
144
     * @return Entry[]
145 1
     */
146
    public function getEntries()
147
    {
148
        return $this->getHydratedEntries();
149
    }
150
151 4
    /**
152
     * @return ServerRequestInterface
153 4
     */
154
    public function getRequest()
155
    {
156
        return $this->request;
157 4
    }
158
159 4
    /**
160
     * @return array
161
     */
162
    public function getDecodedBody()
163
    {
164
        if (isset($this->decodedBody)) {
165 2
            return $this->decodedBody;
166
        }
167 2
168
        $decoded = @json_decode($this->getBody(), true);
169
170
        return $this->decodedBody = null === $decoded ? [] : $decoded;
171 2
    }
172 2
173
    /**
174 2
     * Dispatch events to listeners
175
     */
176 2
    public function dispatchCallbackEvents()
177 2
    {
178 2
        foreach ($this->getAllCallbackEvents() as $event) {
179
            $this->dispatcher->dispatch($event->getName(), $event);
180 2
181
            if ($event instanceof PostbackEvent) {
182
                // Dispatch postback payload
183
                $this->dispatcher->dispatch($event->getPostback()->getPayload(), $event);
184
            }
185
186 6
            if ($event instanceof MessageEvent && $event->isQuickReply()) {
187
                // Dispatch quick reply payload
188 6
                $this->dispatcher->dispatch($event->getQuickReplyPayload(), $event);
189 1
            }
190
        }
191
    }
192 6
193
    /**
194 6
     * @param EventSubscriberInterface $subscriber
195
     */
196
    public function addEventSubscriber(EventSubscriberInterface $subscriber)
197
    {
198
        $this->dispatcher->addSubscriber($subscriber);
199
    }
200 3
201
    /**
202 3
     * @return Entry[]
203
     */
204 3
    private function getHydratedEntries()
205
    {
206
        if (isset($this->hydratedEntries)) {
207
            return $this->hydratedEntries;
208 3
        }
209
210 3
        $decodedBody = $this->getDecodedBody();
211
        $entries = $decodedBody['entry'];
212
213
        $hydrated = [];
214
215
        foreach ($entries as $entry) {
216
            $hydrated[] = Entry::create($entry);
217
        }
218
219
        return $this->hydratedEntries = $hydrated;
220
    }
221
222
    /**
223
     * @return string
224
     */
225
    private function getBody()
226
    {
227
        if (isset($this->body)) {
228
            return $this->body;
229
        }
230
231
        $this->body = (string) $this->request->getBody();
232
233
        return $this->body;
234
    }
235
236
    /**
237
     * @return bool
238
     */
239
    private function isValidHubSignature()
240
    {
241
        $headers = $this->request->getHeader('X-Hub-Signature');
242
243
        if (empty($headers)) {
244
            return false;
245
        }
246
247
        $signature = XHubSignature::parseHeader($headers[0]);
248
249
        return XHubSignature::validate($this->getBody(), $this->secret, $signature);
250
    }
251
}
252