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 | /** |
||
3 | * Copyright (c) 2014, Tobia De Koninck hey--at--ledfan.be |
||
4 | * This file is licensed under the AGPL version 3 or later. |
||
5 | * See the COPYING file. |
||
6 | */ |
||
7 | |||
8 | namespace OCA\Chat\App; |
||
9 | |||
10 | use \OCA\Chat\IBackend; |
||
11 | use \OCA\Chat\IBackendManager; |
||
12 | use \OCA\Chat\OCH\Db\UserOnlineMapper; |
||
13 | use \OCA\Chat\OCH\Commands\SyncOnline; |
||
14 | use \OCP\IUser; |
||
15 | use \OCP\Contacts\IManager; |
||
16 | use \OCP\Files\IRootFolder; |
||
17 | |||
18 | |||
19 | /** |
||
20 | * Class Chat |
||
21 | * @package OCA\Chat\App |
||
22 | */ |
||
23 | class Chat { |
||
24 | |||
25 | const APP=1; |
||
26 | const INTEGRATED=2; |
||
27 | |||
28 | /** |
||
29 | * @var array used to cache the parsed contacts for every request |
||
30 | */ |
||
31 | private static $contacts; |
||
32 | |||
33 | /** |
||
34 | * @var array used to cache the parsed initConvs for every request |
||
35 | */ |
||
36 | private static $initConvs; |
||
37 | |||
38 | /** |
||
39 | * @var string used to cache the user id for every request |
||
40 | */ |
||
41 | private static $userId; |
||
42 | |||
43 | /** |
||
44 | * @var IBackendManager |
||
45 | */ |
||
46 | private $backendManager; |
||
47 | |||
48 | /** |
||
49 | * @var UserOnlineMapper |
||
50 | */ |
||
51 | private $userOnlineMapper; |
||
52 | |||
53 | /** |
||
54 | * @var SyncOnline |
||
55 | */ |
||
56 | private $syncOnline; |
||
57 | |||
58 | /** |
||
59 | * @var string Current user |
||
60 | */ |
||
61 | private $user; |
||
62 | |||
63 | /** |
||
64 | * @var IManager |
||
65 | */ |
||
66 | private $contactsManager; |
||
67 | |||
68 | /** |
||
69 | * @var IRootFolder |
||
70 | */ |
||
71 | private $rootFolder; |
||
72 | |||
73 | public $viewType; |
||
74 | |||
75 | public function __construct( |
||
76 | IBackendManager $backendManager, |
||
77 | UserOnlineMapper $userOnlineMapper, |
||
78 | SyncOnline $syncOnline, |
||
79 | $user, |
||
80 | IManager $contactsManager, |
||
81 | IRootFolder $rootFolder |
||
82 | ) { |
||
83 | $this->backendManager = $backendManager; |
||
84 | $this->userOnlineMapper = $userOnlineMapper; |
||
85 | $this->syncOnline = $syncOnline; |
||
86 | $this->user = $user; |
||
87 | $this->contactsManager = $contactsManager; |
||
88 | $this->rootFolder = $rootFolder; |
||
89 | $this->setViewType(); |
||
90 | } |
||
91 | |||
92 | private function setViewType(){ |
||
93 | $requestUri = \OCP\Util::getRequestUri(); |
||
94 | if(substr($requestUri, -5) === 'chat/'){ |
||
95 | $this->viewType = self::APP; |
||
96 | } else { |
||
97 | $this->viewType = self::INTEGRATED; |
||
98 | } |
||
99 | } |
||
100 | |||
101 | public function registerBackend(IBackend $backend){ |
||
102 | $backendManager = $this->backendManager; |
||
103 | $backendManager::registerBackend($backend); |
||
104 | } |
||
105 | |||
106 | /** |
||
107 | * Retrieves all contacts from the ContactsManager and parse them to a |
||
108 | * usable format. |
||
109 | * @return array Returns array with contacts, contacts as a list and |
||
110 | * contacts as an associative array |
||
111 | */ |
||
112 | public function getContacts(){ |
||
113 | if(count(self::$contacts) === 0){ |
||
114 | // *** |
||
115 | // the following code should be ported |
||
116 | // so multiple backends are allowed |
||
117 | $userOnlineMapper = $this->userOnlineMapper; |
||
118 | $usersOnline = $userOnlineMapper->getOnlineUsers(); |
||
119 | $syncOnline = $this->syncOnline; |
||
120 | $syncOnline->execute(); |
||
121 | // *** |
||
122 | |||
123 | $cm = $this->contactsManager; |
||
124 | $result = $cm->search('',array('FN')); |
||
125 | $receivers = array(); |
||
126 | $contactList = array(); |
||
127 | $contactsObj = array(); |
||
128 | $order = 0; |
||
129 | foreach ($result as $r) { |
||
130 | $order++; |
||
131 | |||
132 | $data = array(); |
||
133 | |||
134 | $contactList[] = $r['id']; |
||
135 | |||
136 | $data['id'] = $r['id']; |
||
137 | $data['online'] = in_array($r['id'], $usersOnline); |
||
138 | $data['displayname'] = $r['FN']; |
||
139 | $data['order'] = $order; |
||
140 | $data['saved'] = true; |
||
141 | |||
142 | if(!isset($r['EMAIL'])){ |
||
143 | $r['EMAIL'] = array(); |
||
144 | } |
||
145 | |||
146 | if(!isset($r['IMPP'])){ |
||
147 | $r['IMPP'] = array(); |
||
148 | } |
||
149 | $data['backends'] = $this->contactBackendToBackend($r['EMAIL'], $r['IMPP']); |
||
150 | $addressbookKey = explode(':', $r['addressbook-key']); |
||
151 | if(count($addressbookKey) === 2){ |
||
152 | $data['address_book_id'] = $addressbookKey[1]; |
||
153 | $data['address_book_backend'] = $addressbookKey[0]; |
||
154 | } else { |
||
155 | $data['address_book_id'] = ''; |
||
156 | $data['address_book_backend'] = $addressbookKey[0]; |
||
157 | } |
||
158 | $receivers[] = $data; |
||
159 | $contactsObj[$r['id']] = $data; |
||
160 | } |
||
161 | self::$contacts = array( |
||
162 | 'contacts' => $receivers, |
||
163 | 'contactsList' => $contactList, |
||
164 | 'contactsObj' => $contactsObj |
||
165 | ); |
||
166 | } |
||
167 | return self::$contacts; |
||
168 | } |
||
169 | |||
170 | |||
171 | /** |
||
172 | * @return array |
||
173 | */ |
||
174 | public function getBackends(){ |
||
175 | return $this->backendManager->getEnabledBackends(); |
||
176 | } |
||
177 | |||
178 | /** |
||
179 | * Parse the emails and IMPPS properties stored in the contacts app to |
||
180 | * a format that can be used in the Chat client. |
||
181 | * @param array $emails |
||
182 | * @param array $impps |
||
183 | * @return array |
||
184 | * @example of return value parsed to JSOn |
||
185 | * backends : [ |
||
186 | * 0 : { |
||
187 | * id : 0,1,2 |
||
188 | * displayname : "ownCloud Handle", |
||
189 | * protocol : "x-owncloud-handle" , |
||
190 | * namespace : "och", |
||
191 | * value : "derp" // i.e. the owncloud username |
||
192 | * }, |
||
193 | * 1 { |
||
194 | * id : null, |
||
195 | * displayname : "E-mail", |
||
196 | * protocl : "email", |
||
197 | * namespace : "email", |
||
198 | * value : "[email protected]" |
||
199 | * } |
||
200 | * ] |
||
201 | */ |
||
202 | private function contactBackendToBackend(array $emails=array(), array $impps=array()){ |
||
203 | $backends = array(); |
||
204 | $backendManager = $this->backendManager; |
||
205 | |||
206 | if(is_array($emails)){ |
||
207 | $backend = array(); |
||
208 | $backend['id'] = 'email'; |
||
209 | $backend['displayname'] = 'E-mail'; |
||
210 | $backend['protocol'] = 'email'; |
||
211 | $backend['namespace'] = ' email'; |
||
212 | $backend['value'] = array($emails); |
||
213 | $backends[] = $backend; |
||
214 | } |
||
215 | |||
216 | if(isset($impps)){ |
||
217 | foreach($impps as $impp){ |
||
218 | $backend = array(); |
||
219 | $exploded = explode(":", $impp); |
||
220 | if(!isset($exploded[1])){ |
||
221 | // protocol not provided -> xmpp |
||
222 | $info = $backendManager->getBackendByProtocol('xmpp'); |
||
223 | $value = $exploded[0]; |
||
224 | $protocol = 'xmpp'; |
||
225 | } else { |
||
226 | $info = $backendManager->getBackendByProtocol($exploded[0]); |
||
227 | $value = $exploded[1]; |
||
228 | $protocol = $exploded[0]; |
||
229 | } |
||
230 | $backend['id'] = $info->getId(); |
||
231 | $backend['displayname'] = $info->getDisplayName(); |
||
232 | $backend['protocol'] = $protocol; |
||
233 | $backend['namespace'] = $info->getId(); |
||
234 | $backend['value'] = $value ; |
||
235 | $backends[] = $backend; |
||
236 | } |
||
237 | } |
||
238 | |||
239 | return $backends; |
||
240 | } |
||
241 | |||
242 | /** |
||
243 | * @param string $protocol |
||
244 | * @return \OCA\Chat\IBackend |
||
245 | */ |
||
246 | private function getBackend($protocol){ |
||
247 | $this->backendManager->getBackendByProtocol($protocol); |
||
248 | } |
||
249 | |||
250 | /** |
||
251 | * Get the contact of the current ownCloud user |
||
252 | * @return array |
||
253 | */ |
||
254 | public function getCurrentUser(){ |
||
255 | return $this->getUserasContact($this->getUserId()); |
||
256 | } |
||
257 | |||
258 | /** |
||
259 | * @param $id |
||
260 | * @return array |
||
261 | */ |
||
262 | public function getUserasContact($id){ |
||
263 | if(count(self::$contacts) === 0) { |
||
264 | $this->getContacts(); |
||
265 | } |
||
266 | return self::$contacts['contactsObj'][$id]; |
||
267 | } |
||
268 | /** |
||
269 | * @return array |
||
270 | * @todo porting |
||
271 | */ |
||
272 | public function getInitConvs(){ |
||
273 | if(count(self::$initConvs) === 0) { |
||
274 | $backends = $this->getBackends(); |
||
275 | $result = array(); |
||
276 | foreach($backends as $backend){ |
||
277 | $result[$backend->getId()] = $backend->getInitConvs(); |
||
278 | } |
||
279 | self::$initConvs = $result; |
||
280 | } |
||
281 | return self::$initConvs; |
||
282 | } |
||
283 | |||
284 | /** |
||
285 | * @param $path path to file |
||
286 | * @return int id of the file |
||
287 | */ |
||
288 | public function getFileId($path){ |
||
289 | $userFolder = $this->rootFolder->getUserFolder(); |
||
290 | $file = $userFolder->get($path); |
||
291 | return $file->getId(); |
||
292 | } |
||
293 | |||
294 | /** |
||
295 | * @return string current ownCloud user id |
||
296 | */ |
||
297 | public function getUserId(){ |
||
298 | return $this->user; |
||
299 | } |
||
300 | |||
301 | |||
302 | public function registerExceptionHandler(){ |
||
303 | set_exception_handler(function(\Exception $e){ |
||
304 | $this->exceptionHandler($e); |
||
305 | }); |
||
306 | |||
307 | } |
||
308 | |||
309 | private static $errors; |
||
310 | |||
311 | public function exceptionHandler(\Exception $e){ |
||
312 | self::$errors = [ |
||
313 | 0 => [ |
||
314 | "check" => function($msg) { |
||
315 | if (substr($msg, 0, 17) === 'js file not found') { |
||
316 | return true; |
||
317 | } |
||
318 | if (substr($msg, 0, 18) === 'css file not found') { |
||
319 | return true; |
||
320 | } |
||
321 | return false; |
||
322 | }, |
||
323 | "brief" => 'JS or CSS files not generated', |
||
324 | "info" => <<<INFO |
||
325 | There are two options to solve this problem: <br> |
||
326 | 1. generate them yourself <br> |
||
327 | 2. download packaged Chat app |
||
328 | |||
329 | Click the "more information" button for more information. |
||
330 | INFO |
||
331 | ,"link" => "https://github.com/owncloud/chat#install" |
||
332 | |||
333 | ], |
||
334 | 1 => [ |
||
335 | "check" => function($msg){ |
||
336 | if (substr($msg, 0, 23) === '[404] Contact not found') { |
||
337 | return true; |
||
338 | } |
||
339 | }, |
||
340 | "brief" => "Contact app failed to load some contacts", |
||
341 | "info" => <<<INFO |
||
342 | This is a bug in the Contacts app, which is fixed in the latest version of ownCloud and the Contacts app.<br> |
||
343 | Please open an issue if this issue keeps occurring after updating the Contacts app. |
||
344 | INFO |
||
345 | ,"link" => "" |
||
346 | ], |
||
347 | 2 => [ |
||
348 | "check" => function($msg){ |
||
349 | if(\OCP\App::isEnabled('user_ldap')){ |
||
350 | return true; |
||
351 | } |
||
352 | }, |
||
353 | "brief" => "Chat app doens't work with user_ldap enabled", |
||
354 | "info" => <<<INFO |
||
355 | There is an bug in core with user_ldap. Therefore the Chat app can't be used. This bug is solved in the latest version of the Chat app. |
||
356 | INFO |
||
357 | ,"link" => "" |
||
358 | ] |
||
359 | |||
360 | |||
361 | ]; |
||
362 | foreach (self::$errors as $possibleError) { |
||
363 | if($possibleError['check']($e->getMessage())){ |
||
364 | $brief = $possibleError["brief"]; |
||
365 | $info = $possibleError["info"]; |
||
366 | $link = $possibleError["link"]; |
||
367 | $raw = $e->getMessage(); |
||
368 | } |
||
369 | } |
||
370 | $version = \OCP\App::getAppVersion('chat'); |
||
371 | $requesttoken = \OC::$server->getSession()->get('requesttoken'); |
||
372 | |||
373 | |||
374 | include(__DIR__ . "/../templates/error.php"); |
||
375 | die(); |
||
0 ignored issues
–
show
|
|||
376 | } |
||
377 | |||
378 | } |
||
379 |
An exit expression should only be used in rare cases. For example, if you write a short command line script.
In most cases however, using an
exit
expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.