Passed
Push — master ( b808b9...919917 )
by Ehsan
04:54
created

EventListener::isThisBot()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 6
cts 6
cp 1
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 6
nc 3
nop 0
crap 3
1
<?php
2
3
namespace Botonomous\listener;
4
5
use Botonomous\Event;
6
use Botonomous\utility\StringUtility;
7
8
/**
9
 * Class EventListener.
10
 */
11
class EventListener extends AbstractBaseListener
12
{
13
    private $token;
14
    private $teamId;
15
    private $apiAppId;
16
    private $event;
17
    private $requestEventMaps = [
18
        'ts'       => 'timestamp',
19
        'event_ts' => 'eventTimestamp',
20
    ];
21
22
    /**
23
     * @return mixed
24
     */
25 11
    public function extractRequest()
26
    {
27 11
        return $this->getRequestUtility()->getPostedBody();
28
    }
29
30
    /**
31
     * @return string
32
     */
33 1
    public function getToken()
34
    {
35 1
        return $this->token;
36
    }
37
38
    /**
39
     * @param string $token
40
     */
41 1
    public function setToken($token)
42
    {
43 1
        $this->token = $token;
44 1
    }
45
46
    /**
47
     * @return string
48
     */
49 1
    public function getTeamId()
50
    {
51 1
        return $this->teamId;
52
    }
53
54
    /**
55
     * @param string $teamId
56
     */
57 1
    public function setTeamId($teamId)
58
    {
59 1
        $this->teamId = $teamId;
60 1
    }
61
62
    /**
63
     * @return string
64
     */
65 1
    public function getApiAppId()
66
    {
67 1
        return $this->apiAppId;
68
    }
69
70
    /**
71
     * @param string $apiAppId
72
     */
73 1
    public function setApiAppId($apiAppId)
74
    {
75 1
        $this->apiAppId = $apiAppId;
76 1
    }
77
78
    /**
79
     * @return Event
80
     */
81 10
    public function getEvent()
82
    {
83 10
        if (!isset($this->event)) {
84 9
            $this->loadEvent();
85
        }
86
87 9
        return $this->event;
88
    }
89
90
    /**
91
     * @param Event $event
92
     */
93 7
    public function setEvent(Event $event)
94
    {
95 7
        $this->event = $event;
96 7
    }
97
98
    /**
99
     * @throws \Exception
100
     */
101 9
    private function loadEvent()
102
    {
103 9
        $request = $this->getRequest();
104
105 9
        if (!isset($request['event'])) {
106 2
            return;
107
        }
108
109 7
        $request = $request['event'];
110
111 7
        if (!isset($request['type'])) {
112 1
            throw new \Exception('Event type must be specified');
113
        }
114
115
        // create the event
116 6
        $eventObject = new Event($request['type']);
117
118
        // exclude type from the args since it's already passed
119 6
        unset($request['type']);
120
121 6
        $stringUtility = new StringUtility();
122 6
        foreach ($request as $argKey => $argValue) {
123 6
            if (array_key_exists($argKey, $this->requestEventMaps)) {
124 5
                $argKey = $this->requestEventMaps[$argKey];
125
            }
126
127 6
            $setterName = 'set'.$stringUtility->snakeCaseToCamelCase($argKey);
128
129
            // ignore calling the method if setter does not exist
130 6
            if (!method_exists($eventObject, $setterName)) {
131 5
                continue;
132
            }
133
134 6
            $eventObject->$setterName($argValue);
135
        }
136
137
        // set it
138 6
        $this->setEvent($eventObject);
139 6
    }
140
141
    /**
142
     * @throws \Exception
143
     *
144
     * @return array<string,boolean|string>
145
     */
146 3
    public function verifyOrigin()
147
    {
148 3
        $request = $this->getRequest();
149
150 3
        if (!isset($request['token']) || !isset($request['api_app_id'])) {
151
            return [
152 1
                'success' => false,
153
                'message' => 'Token or api_app_id is not provided',
154
            ];
155
        }
156
157 3
        $verificationToken = $this->getConfig()->get('verificationToken');
158
159 3
        if (empty($verificationToken)) {
160 1
            throw new \Exception('Verification token must be provided');
161
        }
162
163 2
        $expectedApiAppId = $this->getConfig()->get('apiAppId');
164
165 2
        if (empty($expectedApiAppId)) {
166 1
            throw new \Exception('Api app id must be provided');
167
        }
168
169 1
        if ($verificationToken === $request['token'] &&
170 1
            $expectedApiAppId === $request['api_app_id']) {
171
            return [
172 1
                'success' => true,
173
                'message' => 'O La la!',
174
            ];
175
        }
176
177
        return [
178 1
            'success' => false,
179
            'message' => 'Token or api_app_id mismatch',
180
        ];
181
    }
182
183
    /**
184
     * Check if the request belongs to the bot itself.
185
     *
186
     * @throws \Exception
187
     *
188
     * @return bool
189
     */
190 3
    public function isThisBot()
191
    {
192 3
        $subType = $this->getRequest('subtype');
193
194 3
        if ($subType === 'bot_message') {
195 1
            return true;
196
        }
197
198 3
        $event = $this->getEvent();
199
200 3
        return $event instanceof Event && !empty($event->getBotId());
201
    }
202
}
203