This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** @noinspection PhpUndefinedFieldInspection */ |
||
3 | |||
4 | /** |
||
5 | * Created by PhpStorm. |
||
6 | * User: shanmaseen |
||
7 | * Date: 23/03/19 |
||
8 | * Time: 07:40 م |
||
9 | */ |
||
10 | |||
11 | namespace Shamaseen\Laravel\Ratchet; |
||
12 | |||
13 | use Illuminate\Validation\ValidationException; |
||
14 | use Shamaseen\Laravel\Ratchet\Exceptions\WebSocketException; |
||
15 | use Shamaseen\Laravel\Ratchet\Facades\WsRoute; |
||
16 | use Shamaseen\Laravel\Ratchet\Objects\Clients\Client; |
||
17 | use Ratchet\ConnectionInterface; |
||
18 | use Ratchet\MessageComponentInterface; |
||
19 | use Shamaseen\Laravel\Ratchet\Requests\WsRequest; |
||
20 | use Shamaseen\Laravel\Ratchet\Traits\WebSocketMessagesManager; |
||
21 | |||
22 | /** |
||
23 | * Class WebSocket |
||
24 | * @package App\WebSockets |
||
25 | */ |
||
26 | class Receiver implements MessageComponentInterface |
||
27 | { |
||
28 | use WebSocketMessagesManager; |
||
29 | |||
30 | /** |
||
31 | * @var Client[] |
||
32 | */ |
||
33 | public $clients; |
||
34 | private $routes; |
||
35 | public $userAuthSocketMapper; |
||
36 | public $rooms = []; |
||
37 | |||
38 | /** |
||
39 | * WebSocket constructor. |
||
40 | */ |
||
41 | public function __construct() |
||
42 | { |
||
43 | $this->clients = []; |
||
44 | /** |
||
45 | * The key will be auth id, the value will be resourceId |
||
46 | */ |
||
47 | $this->userAuthSocketMapper = []; |
||
48 | |||
49 | $this->mainRoutes(); |
||
50 | include base_path() . '/routes/websocket.php'; |
||
51 | $this->routes = WsRoute::getRoutes(); |
||
52 | } |
||
53 | |||
54 | /** |
||
55 | * @param ConnectionInterface $conn |
||
56 | */ |
||
57 | public function onOpen(ConnectionInterface $conn) |
||
58 | { |
||
59 | $this->clients[$conn->resourceId] = new Client(); |
||
60 | $this->clients[$conn->resourceId]->conn = $conn; |
||
61 | } |
||
62 | |||
63 | /** |
||
64 | * @param ConnectionInterface $from |
||
65 | * @param string $msg |
||
66 | * @throws \Exception |
||
67 | */ |
||
68 | public function onMessage(ConnectionInterface $from, $msg) |
||
69 | { |
||
70 | $msg = json_decode($msg,true); |
||
71 | $this->callRoute($from,$msg); |
||
72 | } |
||
73 | |||
74 | function callRoute(ConnectionInterface $from, $msg) |
||
0 ignored issues
–
show
|
|||
75 | { |
||
76 | try { |
||
77 | $this->checkForRequiredInMessage($msg, $from); |
||
78 | |||
79 | $this->resetSession($msg['session']); |
||
80 | |||
81 | $this->resetAuth($msg,$from); |
||
82 | |||
83 | $route = $this->routes[$msg['route']]; |
||
84 | |||
85 | $class = $route->controller; |
||
86 | $method = $route->method; |
||
87 | $controller = new $class; |
||
88 | |||
89 | $this->cloneProperties($this, $controller); |
||
90 | |||
91 | $controller->conn = $from; |
||
92 | $controller->receiver = $this; |
||
93 | |||
94 | $controller->request = new WsRequest($msg); |
||
95 | $controller->route = $route; |
||
96 | |||
97 | if (!method_exists($controller, $method)) { |
||
98 | $this->error($msg, $from, 'Method '.$method.' doesnt\'t exist !'); |
||
99 | } |
||
100 | |||
101 | $controller->$method(); |
||
102 | |||
103 | \Session::save(); |
||
104 | } catch (WebSocketException $exception) { |
||
105 | |||
106 | } catch (ValidationException $exception) { |
||
107 | $this->sendToWebSocketUser($from, [ |
||
108 | 'message' => $exception->getMessage(), |
||
109 | 'errors' => $exception->errors() |
||
110 | ]); |
||
111 | } |
||
112 | } |
||
113 | |||
114 | /** |
||
115 | * @param ConnectionInterface $conn |
||
116 | */ |
||
117 | public function onClose(ConnectionInterface $conn) |
||
118 | { |
||
119 | // The connection is closed, remove it, as we can no longer send it messages |
||
120 | $client = $this->clients[$conn->resourceId]; |
||
121 | $routesToCall = $client->onCloseRoutes; |
||
122 | foreach ($routesToCall as $route) |
||
123 | { |
||
124 | $msg = ['session'=>$client->session,'route'=>$route]; |
||
125 | $this->callRoute($conn,$msg); |
||
126 | } |
||
127 | |||
128 | unset($this->clients[$conn->resourceId]); |
||
129 | unset($this->userAuthSocketMapper[array_search($conn->resourceId,$this->userAuthSocketMapper)]); |
||
130 | |||
131 | echo "Connection {$conn->resourceId} has disconnected\n"; |
||
132 | } |
||
133 | |||
134 | /** |
||
135 | * @param ConnectionInterface $conn |
||
136 | * @param \Exception $exception |
||
137 | * @return null |
||
138 | */ |
||
139 | public function onError(ConnectionInterface $conn, \Exception $exception) |
||
140 | { |
||
141 | echo "An error has occurred: {$exception->getMessage()}\n"; |
||
142 | echo "In {$exception->getFile()} line {$exception->getLine()}\n"; |
||
143 | echo $exception->getTraceAsString(); |
||
144 | |||
145 | $conn->close(); |
||
146 | return null; |
||
147 | } |
||
148 | |||
149 | /** |
||
150 | * @param $msg |
||
151 | * @param ConnectionInterface $from |
||
152 | * @throws WebSocketException |
||
153 | */ |
||
154 | function checkForRequiredInMessage($msg, $from) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
It is recommend to declare an explicit visibility for
checkForRequiredInMessage .
Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed. If you are not sure which visibility to choose, it is a good idea to start with
the most restrictive visibility, and then raise visibility as needed, i.e.
start with ![]() |
|||
155 | { |
||
156 | if (!isset($msg['route']) || !isset($msg['session'])) { |
||
157 | $this->error($msg, $from, 'Either the route is missing in the Request, Or you forget to add the session id ! please refer to the document in github for more details'); |
||
158 | } |
||
159 | |||
160 | if (!isset($this->routes[$msg['route']])) { |
||
161 | $this->error($msg, $from, 'No such route !'); |
||
162 | } |
||
163 | } |
||
164 | |||
165 | /** |
||
166 | * @param Receiver $clonedObject |
||
167 | * @param $clone |
||
168 | */ |
||
169 | function cloneProperties($clonedObject, $clone) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
It is recommend to declare an explicit visibility for
cloneProperties .
Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed. If you are not sure which visibility to choose, it is a good idea to start with
the most restrictive visibility, and then raise visibility as needed, i.e.
start with ![]() |
|||
170 | { |
||
171 | foreach (get_object_vars($clonedObject) as $key => $value) { |
||
172 | $clone->$key = $value; |
||
173 | } |
||
174 | } |
||
175 | |||
176 | function mainRoutes() |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
It is recommend to declare an explicit visibility for
mainRoutes .
Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed. If you are not sure which visibility to choose, it is a good idea to start with
the most restrictive visibility, and then raise visibility as needed, i.e.
start with ![]() |
|||
177 | { |
||
178 | WsRoute::make('initializeWebsocket', 'Shamaseen\Laravel\Ratchet\Controllers\InitializeController', 'index'); |
||
179 | WsRoute::make('room-enter', 'Shamaseen\Laravel\Ratchet\Controllers\RoomController', 'enterRoom'); |
||
180 | WsRoute::make('room-exit', 'Shamaseen\Laravel\Ratchet\Controllers\RoomController', 'exitRoom'); |
||
181 | WsRoute::make('send-to-user', 'Shamaseen\Laravel\Ratchet\Controllers\ChatController', 'sendMessageToUser'); |
||
182 | WsRoute::make('send-to-room', 'Shamaseen\Laravel\Ratchet\Controllers\ChatController', 'sendMessageToRoom'); |
||
183 | } |
||
184 | |||
185 | /** |
||
186 | * Read the session data from the handler. |
||
187 | * |
||
188 | * @param $session_id |
||
189 | * @return array |
||
190 | */ |
||
191 | protected function readFromHandler($session_id) |
||
192 | { |
||
193 | if ($data = \Session::getHandler()->read($session_id)) { |
||
194 | $data = @unserialize($data); |
||
195 | |||
196 | if ($data !== false && ! is_null($data) && is_array($data)) { |
||
197 | return $data; |
||
198 | } |
||
199 | } |
||
200 | |||
201 | return []; |
||
202 | } |
||
203 | |||
204 | function getUserId($session_array) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
It is recommend to declare an explicit visibility for
getUserId .
Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed. If you are not sure which visibility to choose, it is a good idea to start with
the most restrictive visibility, and then raise visibility as needed, i.e.
start with ![]() |
|||
205 | { |
||
206 | return $session_array['login_web_59ba36addc2b2f9401580f014c7f58ea4e30989d']; |
||
207 | } |
||
208 | |||
209 | function getUserModel() |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
It is recommend to declare an explicit visibility for
getUserModel .
Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed. If you are not sure which visibility to choose, it is a good idea to start with
the most restrictive visibility, and then raise visibility as needed, i.e.
start with ![]() |
|||
210 | { |
||
211 | return \Config::get('laravel-ratchet.userModelNamespace','App\Entities\Users\User'); |
||
212 | } |
||
213 | |||
214 | function resetSession($session_id) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
It is recommend to declare an explicit visibility for
resetSession .
Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed. If you are not sure which visibility to choose, it is a good idea to start with
the most restrictive visibility, and then raise visibility as needed, i.e.
start with ![]() |
|||
215 | { |
||
216 | \Session::flush(); |
||
217 | |||
218 | \Session::setId($session_id); |
||
219 | |||
220 | \Session::start(); |
||
221 | } |
||
222 | |||
223 | /** |
||
224 | * @param object $msg |
||
225 | * @param ConnectionInterface $from |
||
226 | * @throws WebSocketException |
||
227 | */ |
||
228 | function resetAuth($msg,$from) |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
It is recommend to declare an explicit visibility for
resetAuth .
Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed. If you are not sure which visibility to choose, it is a good idea to start with
the most restrictive visibility, and then raise visibility as needed, i.e.
start with ![]() |
|||
229 | { |
||
230 | $data = $this->readFromHandler($msg['session']); |
||
231 | |||
232 | if(!empty($data)) |
||
233 | { |
||
234 | $user_id = $this->getUserId($data); |
||
235 | $user = $this->getUserModel()::find($user_id); |
||
236 | if(!$user) |
||
237 | { |
||
238 | $this->error($msg, $from, 'There is no such user.'); |
||
239 | } |
||
240 | \Auth::setUser($user); |
||
241 | |||
242 | $this->clients[$from->resourceId]->id = \Auth::id(); |
||
243 | $this->clients[$from->resourceId]->session = $msg['session']; |
||
244 | $this->userAuthSocketMapper[\Auth::id()] = $from->resourceId; |
||
245 | } |
||
246 | else |
||
247 | { |
||
248 | $this->error($msg, $from, 'Unauthenticated.'); |
||
249 | } |
||
250 | } |
||
251 | } |
||
252 |
Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed.
If you are not sure which visibility to choose, it is a good idea to start with the most restrictive visibility, and then raise visibility as needed, i.e. start with
private
, and only raise it toprotected
if a sub-class needs to have access, orpublic
if an external class needs access.