1: | <?php |
2: | |
3: | |
4: | |
5: | |
6: | |
7: | |
8: | namespace Aurora\Modules\RocketChatWebclient; |
9: | |
10: | use Aurora\Api; |
11: | use Aurora\Modules\Contacts\Module as ContactsModule; |
12: | use Aurora\Modules\Core\Module as CoreModule; |
13: | use Aurora\System\Enums\UserRole; |
14: | use Aurora\System\Exceptions\ApiException; |
15: | use Aurora\System\Utils; |
16: | use GuzzleHttp\Client; |
17: | use GuzzleHttp\Exception\ConnectException; |
18: | use GuzzleHttp\HandlerStack; |
19: | use GuzzleHttp\MessageFormatter; |
20: | use GuzzleHttp\Middleware; |
21: | use Illuminate\Support\Str; |
22: | use Monolog\Handler\RotatingFileHandler; |
23: | use Monolog\Logger; |
24: | |
25: | |
26: | |
27: | |
28: | |
29: | |
30: | |
31: | |
32: | class Module extends \Aurora\System\Module\AbstractModule |
33: | { |
34: | public $oRocketChatSettingsManager = null; |
35: | |
36: | protected $sChatUrl= ""; |
37: | |
38: | protected $sDemoPass = "demo"; |
39: | |
40: | |
41: | |
42: | |
43: | protected $client = null; |
44: | |
45: | protected $adminAccount = null; |
46: | |
47: | protected $stack = null; |
48: | |
49: | protected $curUserData = false; |
50: | |
51: | protected function initConfig() |
52: | { |
53: | $oSettings = $this->GetModuleSettings(); |
54: | $this->sChatUrl = $oSettings->GetValue('ChatUrl', ''); |
55: | $sAdminUser = $oSettings->GetValue('AdminUsername', ''); |
56: | |
57: | if (!empty($this->sChatUrl) && !empty($sAdminUser)) { |
58: | $this->client = new Client([ |
59: | 'base_uri' => \rtrim($this->sChatUrl, '/') . '/api/v1/', |
60: | 'verify' => false, |
61: | 'handler' => $this->stack |
62: | ]); |
63: | } |
64: | } |
65: | |
66: | protected function isDemoUser($sEmail) |
67: | { |
68: | $oDemoModePlugin = Api::GetModule('DemoModePlugin'); |
69: | return !empty($oDemoModePlugin) && $oDemoModePlugin->CheckDemoUser($sEmail); |
70: | } |
71: | |
72: | protected function initLogging() |
73: | { |
74: | if ($this->getConfig('EnableLogging', false)) { |
75: | $stack = HandlerStack::create(); |
76: | collect([ |
77: | 'REQUEST: {method} - {uri} - HTTP/{version} - {req_headers} - {req_body}', |
78: | 'RESPONSE: {code} - {res_body}', |
79: | ])->each(function ($messageFormat) use ($stack) { |
80: | |
81: | $oLogger = new Logger('rocketchat-log'); |
82: | $oLogger->pushProcessor(function ($record) { |
83: | $record['message'] = str_replace(Api::$aSecretWords, '*****', $record['message']); |
84: | $record['message'] = preg_replace('/(X-Auth-Token|X-2fa-code):(.+?\s)/i', '$1: ***** ', $record['message']); |
85: | $record['message'] = preg_replace('/("bcrypt"):(.*?\})/i', '$1:"*****"}', $record['message']); |
86: | $record['message'] = preg_replace('/("authToken"):(.*?,)/i', '$1:"*****",', $record['message']); |
87: | return $record; |
88: | }); |
89: | $stack->unshift( |
90: | Middleware::log( |
91: | $oLogger->pushHandler( |
92: | new RotatingFileHandler(Api::GetLogFileDir() . 'rocketchat-log.txt') |
93: | ), |
94: | new MessageFormatter($messageFormat) |
95: | ) |
96: | ); |
97: | }); |
98: | $this->stack = $stack; |
99: | } |
100: | } |
101: | |
102: | public function init() |
103: | { |
104: | $this->initLogging(); |
105: | |
106: | $this->oRocketChatSettingsManager = new Managers\RocketChatSettings\Manager($this); |
107: | |
108: | $this->initConfig(); |
109: | |
110: | $this->AddEntry('chat', 'EntryChat'); |
111: | $this->AddEntry('chat-direct', 'EntryChatDirect'); |
112: | |
113: | $this->subscribeEvent('Login::after', array($this, 'onAfterLogin'), 10); |
114: | $this->subscribeEvent('Core::Logout::before', array($this, 'onBeforeLogout')); |
115: | $this->subscribeEvent('Core::DeleteUser::before', array($this, 'onBeforeDeleteUser')); |
116: | } |
117: | |
118: | protected function getClient($iTenantId = null) |
119: | { |
120: | $mResult = null; |
121: | $oSettings = $this->GetModuleSettings(); |
122: | $sChatUrl = ''; |
123: | if (isset($iTenantId)) { |
124: | $oTenant = Api::getTenantById($iTenantId); |
125: | if ($oTenant) { |
126: | $sChatUrl = $oSettings->GetTenantValue($oTenant->Name, 'ChatUrl', ''); |
127: | } |
128: | } else { |
129: | $sChatUrl = $oSettings->GetValue('ChatUrl', ''); |
130: | if (isset($this->client)) { |
131: | return $this->client; |
132: | } |
133: | } |
134: | if (!empty($sChatUrl)) { |
135: | $mResult = new Client([ |
136: | 'base_uri' => \rtrim($sChatUrl, '/') . '/api/v1/', |
137: | 'verify' => false, |
138: | 'handler' => $this->stack |
139: | ]); |
140: | } |
141: | |
142: | return $mResult; |
143: | } |
144: | |
145: | |
146: | |
147: | |
148: | |
149: | |
150: | public function GetSettings($TenantId = null) |
151: | { |
152: | Api::checkUserRoleIsAtLeast(UserRole::NormalUser); |
153: | |
154: | $sChatUrl = ''; |
155: | $sAdminUsername = ''; |
156: | |
157: | $oSettings = $this->GetModuleSettings(); |
158: | if (!empty($TenantId)) { |
159: | Api::checkUserRoleIsAtLeast(UserRole::TenantAdmin); |
160: | $oTenant = Api::getTenantById($TenantId); |
161: | |
162: | if ($oTenant) { |
163: | $sChatUrl = $oSettings->GetTenantValue($oTenant->Name, 'ChatUrl', $sChatUrl); |
164: | $sAdminUsername = $oSettings->GetTenantValue($oTenant->Name, 'AdminUsername', $sAdminUsername); |
165: | } |
166: | } else { |
167: | $sChatUrl = $oSettings->GetValue('ChatUrl', $sChatUrl); |
168: | $sAdminUsername = $oSettings->GetValue('AdminUsername', $sAdminUsername); |
169: | } |
170: | |
171: | $oUser = \Aurora\System\Api::getAuthenticatedUser(); |
172: | if ($oUser instanceof \Aurora\Modules\Core\Models\User) { |
173: | if ($oUser->isNormalOrTenant()) { |
174: | $mResult = [ |
175: | 'ChatUrl' => $sChatUrl, |
176: | 'AllowAddMeetingLinkToEvent' => $this->getConfig('AllowAddMeetingLinkToEvent', false), |
177: | 'MeetingLinkUrl' => $this->getConfig('MeetingLinkUrl', '') |
178: | ]; |
179: | |
180: | return $mResult; |
181: | } elseif ($oUser->Role === UserRole::SuperAdmin) { |
182: | return [ |
183: | 'ChatUrl' => $sChatUrl, |
184: | 'AdminUsername' => $sAdminUsername |
185: | ]; |
186: | } |
187: | } |
188: | |
189: | return []; |
190: | } |
191: | |
192: | |
193: | |
194: | |
195: | |
196: | |
197: | |
198: | public function UpdateSettings($TenantId, $ChatUrl, $AdminUsername, $AdminPassword = null) |
199: | { |
200: | $oSettings = $this->GetModuleSettings(); |
201: | if (!empty($TenantId)) { |
202: | Api::checkUserRoleIsAtLeast(UserRole::TenantAdmin); |
203: | $oTenant = Api::getTenantById($TenantId); |
204: | |
205: | if ($oTenant) { |
206: | $oSettings->SetTenantValue($oTenant->Name, 'ChatUrl', $ChatUrl); |
207: | $oSettings->SetTenantValue($oTenant->Name, 'AdminUsername', $AdminUsername); |
208: | if (isset($AdminPassword)) { |
209: | $oSettings->SetTenantValue($oTenant->Name, 'AdminPassword', Utils::EncryptValue($AdminPassword)); |
210: | } |
211: | |
212: | return $oSettings->SaveTenantSettings($oTenant->Name); |
213: | } |
214: | } else { |
215: | Api::checkUserRoleIsAtLeast(UserRole::SuperAdmin); |
216: | |
217: | $oSettings->SetValue('ChatUrl', $ChatUrl); |
218: | $oSettings->SetValue('AdminUsername', $AdminUsername); |
219: | if (isset($AdminPassword)) { |
220: | $oSettings->SetValue('AdminPassword', Utils::EncryptValue($AdminPassword)); |
221: | } |
222: | |
223: | return $oSettings->Save(); |
224: | } |
225: | |
226: | return false; |
227: | } |
228: | |
229: | public function GetRocketChatSettings($TenantId = null) |
230: | { |
231: | \Aurora\System\Api::checkUserRoleIsAtLeast(UserRole::SuperAdmin); |
232: | |
233: | return $this->oRocketChatSettingsManager->get( |
234: | $this->getClient($TenantId), |
235: | $this->getAdminHeaders($TenantId) |
236: | ); |
237: | } |
238: | |
239: | public function ApplyRocketChatRequiredChanges($TenantId = null) |
240: | { |
241: | \Aurora\System\Api::checkUserRoleIsAtLeast(UserRole::SuperAdmin); |
242: | |
243: | return $this->oRocketChatSettingsManager->setConfigs( |
244: | $this->getClient($TenantId), |
245: | $this->getAdminHeaders($TenantId) |
246: | ); |
247: | } |
248: | |
249: | public function ApplyRocketChatTextChanges($TenantId = null) |
250: | { |
251: | \Aurora\System\Api::checkUserRoleIsAtLeast(UserRole::SuperAdmin); |
252: | |
253: | return $this->oRocketChatSettingsManager->setTexts( |
254: | $this->getClient($TenantId), |
255: | $this->getAdminHeaders($TenantId) |
256: | ); |
257: | } |
258: | |
259: | public function ApplyRocketChatCssChanges($TenantId = null) |
260: | { |
261: | \Aurora\System\Api::checkUserRoleIsAtLeast(UserRole::SuperAdmin); |
262: | |
263: | return $this->oRocketChatSettingsManager->setCss( |
264: | $this->getClient($TenantId), |
265: | $this->getAdminHeaders($TenantId) |
266: | ); |
267: | } |
268: | |
269: | protected function initUser() |
270: | { |
271: | $mResult = true; |
272: | if (!$this->getCurrentUserInfo()) { |
273: | if (!$this->createCurrentUser()) { |
274: | $mResult = false; |
275: | } |
276: | } |
277: | |
278: | return $mResult; |
279: | } |
280: | |
281: | public function EntryChatDirect() |
282: | { |
283: | try { |
284: | Api::checkUserRoleIsAtLeast(UserRole::NormalUser); |
285: | |
286: | $sContactUuid = $this->oHttp->GetQuery('chat-direct'); |
287: | $oCurrentUser = Api::getAuthenticatedUser(); |
288: | $oContact = ContactsModule::Decorator()->GetContact($sContactUuid, $oCurrentUser->Id); |
289: | $oUser = $oContact ? Api::getUserById($oContact->IdUser) : null; |
290: | if ($oCurrentUser && $oUser && $oCurrentUser->IdTenant === $oUser->IdTenant) { |
291: | $sDirect = $this->GetLoginForEmail($oUser->PublicId); |
292: | |
293: | if ($sDirect) { |
294: | $this->showChat('direct/' . $sDirect . '?layout=embedded'); |
295: | } else { |
296: | $this->showError('User not found'); |
297: | } |
298: | } else { |
299: | $this->showError('User not found'); |
300: | } |
301: | } catch (ApiException $oEx) { |
302: | $this->showError('User not found'); |
303: | } |
304: | } |
305: | |
306: | public function EntryChat() |
307: | { |
308: | $oIntegrator = \Aurora\System\Managers\Integrator::getInstance(); |
309: | $this->showChat('', $oIntegrator->buildHeadersLink()); |
310: | } |
311: | |
312: | protected function showChat($sUrl = '', $sIntegratorLinks = '') |
313: | { |
314: | $aUser = $this->InitChat(); |
315: | $sResult = \file_get_contents($this->GetPath().'/templates/Chat.html'); |
316: | if (\is_string($sResult)) { |
317: | echo strtr($sResult, [ |
318: | '{{TOKEN}}' => $aUser ? $aUser['authToken'] : '', |
319: | '{{URL}}' => $this->sChatUrl . $sUrl, |
320: | '{{IntegratorLinks}}' => $sIntegratorLinks, |
321: | ]); |
322: | } |
323: | } |
324: | |
325: | protected function showError($sMessage= '') |
326: | { |
327: | echo $sMessage; |
328: | } |
329: | |
330: | protected function getUserNameFromEmail($sEmail) |
331: | { |
332: | $mResult = false; |
333: | |
334: | $oSettings = $this->GetModuleSettings(); |
335: | $iChatUsernameFormat = $oSettings->GetValue('ChatUsernameFormat', \Aurora\Modules\RocketChatWebclient\Enums\UsernameFormat::UsernameAndDomain); |
336: | |
337: | $aEmailParts = explode("@", $sEmail); |
338: | if (isset($aEmailParts[1])) { |
339: | $aDomainParts = explode(".", $aEmailParts[1]); |
340: | } |
341: | |
342: | if (isset($aEmailParts[0])) { |
343: | $mResult = $aEmailParts[0]; |
344: | if (isset($aDomainParts[0]) && ($iChatUsernameFormat == \Aurora\Modules\RocketChatWebclient\Enums\UsernameFormat::UsernameAndDomain)) { |
345: | $mResult .= ".". $aDomainParts[0]; |
346: | } |
347: | if (isset($aEmailParts[1]) && ($iChatUsernameFormat == \Aurora\Modules\RocketChatWebclient\Enums\UsernameFormat::UsernameAndFullDomainName)) { |
348: | $mResult .= ".". $aEmailParts[1]; |
349: | } |
350: | } |
351: | |
352: | return $mResult; |
353: | } |
354: | |
355: | protected function getAdminCredentials($TenantId = null, $EncrypdedPassword = true) |
356: | { |
357: | $mResult = false; |
358: | |
359: | $oSettings = $this->GetModuleSettings(); |
360: | if (isset($TenantId)) { |
361: | $oTenant = Api::getTenantById($TenantId); |
362: | if ($oTenant) { |
363: | $mResult = []; |
364: | $mResult['AdminUser'] = $oSettings->GetTenantValue($oTenant->Name, 'AdminUsername', ''); |
365: | $mResult['AdminPass'] = $oSettings->GetTenantValue($oTenant->Name, 'AdminPassword', ''); |
366: | Api::AddSecret($mResult['AdminPass']); |
367: | if ($EncrypdedPassword) { |
368: | $mResult['AdminPass'] = Utils::DecryptValue($mResult['AdminPass']); |
369: | } else { |
370: | $oSettings->SetTenantValue($oTenant->Name, 'AdminPassword', Utils::EncryptValue($mResult['AdminPass'])); |
371: | $oSettings->SaveTenantSettings($oTenant->Name); |
372: | } |
373: | } |
374: | } else { |
375: | $mResult = []; |
376: | $mResult['AdminUser'] = $oSettings->GetValue('AdminUsername', ''); |
377: | $mResult['AdminPass'] = $oSettings->GetValue('AdminPassword', ''); |
378: | Api::AddSecret($mResult['AdminPass']); |
379: | if ($EncrypdedPassword) { |
380: | $mResult['AdminPass'] = Utils::DecryptValue($mResult['AdminPass']); |
381: | } else { |
382: | $oSettings->SetValue('AdminPassword', Utils::EncryptValue($mResult['AdminPass'])); |
383: | $oSettings->Save(); |
384: | } |
385: | } |
386: | if (is_array($mResult) && isset($mResult['AdminPass'])) { |
387: | Api::AddSecret($mResult['AdminPass']); |
388: | } |
389: | |
390: | return $mResult; |
391: | } |
392: | |
393: | protected function loginAdminAccount($TenantId, $aAdminCreds) |
394: | { |
395: | $mResult = false; |
396: | |
397: | $client = $this->getClient($TenantId); |
398: | try { |
399: | if ($client && $aAdminCreds) { |
400: | $res = $client->post('login', [ |
401: | 'form_params' => [ |
402: | 'user' => $aAdminCreds['AdminUser'], |
403: | 'password' => $aAdminCreds['AdminPass'] |
404: | ], |
405: | 'http_errors' => false |
406: | ]); |
407: | if ($res->getStatusCode() === 200) { |
408: | $mResult = \json_decode($res->getBody()); |
409: | } |
410: | } |
411: | } catch (ConnectException $oException) { |
412: | } |
413: | |
414: | return $mResult; |
415: | } |
416: | |
417: | protected function getAdminAccount($TenantId = null) |
418: | { |
419: | $mResult = false; |
420: | |
421: | if (!isset($TenantId) && isset($this->adminAccount)) { |
422: | return $this->adminAccount; |
423: | } |
424: | |
425: | $aAdminCreds = $this->getAdminCredentials($TenantId); |
426: | $mResult = $this->loginAdminAccount($TenantId, $aAdminCreds); |
427: | if (!$mResult) { |
428: | $aAdminCreds = $this->getAdminCredentials($TenantId, false); |
429: | $mResult = $this->loginAdminAccount($TenantId, $aAdminCreds); |
430: | } |
431: | if (!isset($TenantId)) { |
432: | $this->adminAccount = $mResult; |
433: | } |
434: | |
435: | return $mResult; |
436: | } |
437: | |
438: | protected function getAdminHeaders($TenantId = null) |
439: | { |
440: | $oAdmin = $this->getAdminAccount($TenantId); |
441: | $aAdminCreds = $this->getAdminCredentials($TenantId); |
442: | if ($oAdmin && $aAdminCreds) { |
443: | return [ |
444: | 'X-Auth-Token' => $oAdmin->data->authToken, |
445: | 'X-User-Id' => $oAdmin->data->userId, |
446: | 'X-2fa-code' => hash('sha256', $aAdminCreds['AdminPass']), |
447: | 'X-2fa-method' => 'password' |
448: | ]; |
449: | } |
450: | return []; |
451: | } |
452: | |
453: | protected function getUserInfo($sEmail) |
454: | { |
455: | $mResult = false; |
456: | $sUserName = $this->getUserNameFromEmail($sEmail); |
457: | try { |
458: | if ($this->client) { |
459: | $res = $this->client->get('users.info', [ |
460: | 'query' => [ |
461: | 'username' => $this->getUserNameFromEmail($sEmail) |
462: | ], |
463: | 'headers' => $this->getAdminHeaders(), |
464: | 'http_errors' => false |
465: | ]); |
466: | if ($res->getStatusCode() === 200) { |
467: | $mResult = \json_decode($res->getBody()); |
468: | } |
469: | } |
470: | } catch (ConnectException $oException) { |
471: | \Aurora\System\Api::Log('Cannot get ' . $sUserName . ' user info. Exception is below.'); |
472: | \Aurora\System\Api::LogException($oException); |
473: | } |
474: | |
475: | return $mResult; |
476: | } |
477: | |
478: | protected function getCurrentUserInfo() |
479: | { |
480: | $mResult = false; |
481: | |
482: | $oUser = Api::getAuthenticatedUser(); |
483: | if ($oUser) { |
484: | $mResult = $this->getUserInfo($oUser->PublicId); |
485: | } |
486: | |
487: | return $mResult; |
488: | } |
489: | |
490: | protected function createUser($sEmail) |
491: | { |
492: | $mResult = false; |
493: | |
494: | $oAccount = CoreModule::Decorator()->GetAccountUsedToAuthorize($sEmail); |
495: | if ($oAccount && $this->client) { |
496: | if (!$this->isDemoUser($sEmail)) { |
497: | $sPassword = $oAccount->getPassword(); |
498: | } else { |
499: | $sPassword = $this->sDemoPass; |
500: | } |
501: | |
502: | Api::AddSecret($sPassword); |
503: | |
504: | $sLogin = $this->getUserNameFromEmail($sEmail); |
505: | $sName = isset($oAccount->FriendlyName) && $oAccount->FriendlyName !== '' ? $oAccount->FriendlyName : $sLogin; |
506: | try { |
507: | $res = $this->client->post('users.create', [ |
508: | 'json' => [ |
509: | 'email' => $sEmail, |
510: | 'name' => $sName, |
511: | 'password' => $sPassword, |
512: | 'username' => $sLogin |
513: | ], |
514: | 'headers' => $this->getAdminHeaders(), |
515: | 'http_errors' => false |
516: | ]); |
517: | if ($res->getStatusCode() === 200) { |
518: | $mResult = \json_decode($res->getBody()); |
519: | } |
520: | } catch (ConnectException $oException) { |
521: | \Aurora\System\Api::Log('Cannot create ' . $sEmail . ' user. Exception is below.'); |
522: | \Aurora\System\Api::LogException($oException); |
523: | } |
524: | } |
525: | return $mResult; |
526: | } |
527: | |
528: | protected function createCurrentUser() |
529: | { |
530: | $mResult = false; |
531: | |
532: | $oUser = Api::getAuthenticatedUser(); |
533: | |
534: | if ($oUser) { |
535: | $mResult = $this->createUser($oUser->PublicId); |
536: | } |
537: | |
538: | return $mResult; |
539: | } |
540: | |
541: | protected function loginCurrentUser() |
542: | { |
543: | $mResult = false; |
544: | |
545: | $oUser = Api::getAuthenticatedUser(); |
546: | if ($oUser) { |
547: | $oAccount = CoreModule::Decorator()->GetAccountUsedToAuthorize($oUser->PublicId); |
548: | if ($oAccount && $this->client) { |
549: | if (!$this->isDemoUser($oUser->PublicId)) { |
550: | $sPassword = $oAccount->getPassword(); |
551: | } else { |
552: | $sPassword = $this->sDemoPass; |
553: | } |
554: | Api::AddSecret($sPassword); |
555: | try { |
556: | $res = $this->client->post('login', [ |
557: | 'form_params' => [ |
558: | 'user' => $this->getUserNameFromEmail($oUser->PublicId), |
559: | 'password' => $sPassword |
560: | ], |
561: | 'http_errors' => false |
562: | ]); |
563: | if ($res->getStatusCode() === 200) { |
564: | $mResult = \json_decode($res->getBody()); |
565: | $sLang = ''; |
566: | if (isset($mResult->data->me->settings->preferences->language)) { |
567: | $sLang = $mResult->data->me->settings->preferences->language; |
568: | } |
569: | $sUserLang = Utils::ConvertLanguageNameToShort($oUser->Language); |
570: | if ($sUserLang !== $sLang) { |
571: | $this->updateLanguage($mResult->data->userId, $mResult->data->authToken, $sUserLang); |
572: | } |
573: | } |
574: | } catch (ConnectException $oException) { |
575: | } |
576: | } |
577: | } |
578: | |
579: | return $mResult; |
580: | } |
581: | |
582: | protected function logout() |
583: | { |
584: | $mResult = false; |
585: | |
586: | if ($this->client) { |
587: | try { |
588: | $sAuthToken = isset($_COOKIE['RocketChatAuthToken']) ? $_COOKIE['RocketChatAuthToken'] : null; |
589: | $sUserId = isset($_COOKIE['RocketChatUserId']) ? $_COOKIE['RocketChatUserId'] : null; |
590: | if ($sAuthToken !== null && $sUserId !== null) { |
591: | $res = $this->client->post('logout', [ |
592: | 'headers' => [ |
593: | "X-Auth-Token" => $sAuthToken, |
594: | "X-User-Id" => $sUserId, |
595: | ], |
596: | 'http_errors' => false |
597: | ]); |
598: | if ($res->getStatusCode() === 200) { |
599: | $mResult = \json_decode($res->getBody()); |
600: | } |
601: | } |
602: | } catch (ConnectException $oException) { |
603: | Api::LogException($oException); |
604: | } |
605: | } |
606: | |
607: | return $mResult; |
608: | } |
609: | |
610: | protected function updateLanguage($sUserId, $sToken, $sLang) |
611: | { |
612: | if ($this->client) { |
613: | $this->client->post('users.setPreferences', [ |
614: | 'json' => [ |
615: | 'userId' => $sUserId, |
616: | 'data' => [ |
617: | "language" => $sLang |
618: | ] |
619: | ], |
620: | 'headers' => [ |
621: | "X-Auth-Token" => $sToken, |
622: | "X-User-Id" => $sUserId |
623: | ], |
624: | 'http_errors' => false |
625: | ]); |
626: | } |
627: | } |
628: | |
629: | protected function updateUserPassword($userInfo) |
630: | { |
631: | $mResult = false; |
632: | $oUser = Api::getAuthenticatedUser(); |
633: | if ($oUser) { |
634: | $oAccount = CoreModule::Decorator()->GetAccountUsedToAuthorize($oUser->PublicId); |
635: | if ($oAccount && $this->client) { |
636: | Api::AddSecret($oAccount->getPassword()); |
637: | $res = $this->client->post('users.update', [ |
638: | 'json' => [ |
639: | 'userId' => $userInfo->user->_id, |
640: | 'data' => [ |
641: | 'password' => $oAccount->getPassword() |
642: | ] |
643: | ], |
644: | 'headers' => $this->getAdminHeaders(), |
645: | 'http_errors' => false |
646: | ]); |
647: | $mResult = ($res->getStatusCode() === 200); |
648: | } |
649: | } |
650: | |
651: | return $mResult; |
652: | } |
653: | |
654: | public function InitChat() |
655: | { |
656: | if (!$this->curUserData) { |
657: | $mResult = false; |
658: | $oUser = Api::getAuthenticatedUser(); |
659: | if ($oUser && $this->client && $this->initUser()) { |
660: | $sAuthToken = isset($_COOKIE['RocketChatAuthToken']) ? $_COOKIE['RocketChatAuthToken'] : null; |
661: | $sUserId = isset($_COOKIE['RocketChatUserId']) ? $_COOKIE['RocketChatUserId'] : null; |
662: | if ($sAuthToken !== null && $sUserId !== null) { |
663: | $sAuthToken = Utils::DecryptValue($sAuthToken); |
664: | Api::AddSecret($sAuthToken); |
665: | try { |
666: | $res = $this->client->get('me', [ |
667: | 'headers' => [ |
668: | "X-Auth-Token" => $sAuthToken, |
669: | "X-User-Id" => $sUserId, |
670: | ], |
671: | 'http_errors' => false |
672: | ]); |
673: | if ($res->getStatusCode() === 200) { |
674: | $body = \json_decode($res->getBody(), true); |
675: | $sLang = ''; |
676: | if (isset($body->settings->preferences->language)) { |
677: | $sLang = $body->settings->preferences->language; |
678: | } |
679: | $sUserLang = Utils::ConvertLanguageNameToShort($oUser->Language); |
680: | if ($sUserLang !== $sLang) { |
681: | $this->updateLanguage($sUserId, $sAuthToken, $sUserLang); |
682: | } |
683: | |
684: | $mResult = [ |
685: | 'authToken' => $sAuthToken, |
686: | 'userId' => $sUserId |
687: | ]; |
688: | } |
689: | } catch (ConnectException $oException) { |
690: | } |
691: | } |
692: | |
693: | if (!$mResult) { |
694: | $currentUserInfo = $this->getCurrentUserInfo(); |
695: | if ($currentUserInfo) { |
696: | $mResult = $this->loginCurrentUser(); |
697: | if (!$mResult && !$this->isDemoUser($oUser->PublicId)) { |
698: | if ($this->updateUserPassword($currentUserInfo)) { |
699: | $mResult = $this->loginCurrentUser(); |
700: | } |
701: | } |
702: | } elseif ($this->createCurrentUser() !== false) { |
703: | $mResult = $this->loginCurrentUser(); |
704: | } |
705: | |
706: | if ($mResult && isset($mResult->data)) { |
707: | $iAuthTokenCookieExpireTime = (int) \Aurora\System\Api::GetModule('Core')->getConfig('AuthTokenCookieExpireTime', 30); |
708: | @\setcookie( |
709: | 'RocketChatAuthToken', |
710: | Utils::EncryptValue($mResult->data->authToken), |
711: | \strtotime('+' . $iAuthTokenCookieExpireTime . ' days'), |
712: | \Aurora\System\Api::getCookiePath(), |
713: | null, |
714: | \Aurora\System\Api::getCookieSecure() |
715: | ); |
716: | @\setcookie( |
717: | 'RocketChatUserId', |
718: | $mResult->data->userId, |
719: | \strtotime('+' . $iAuthTokenCookieExpireTime . ' days'), |
720: | \Aurora\System\Api::getCookiePath(), |
721: | null, |
722: | \Aurora\System\Api::getCookieSecure() |
723: | ); |
724: | $oUser->save(); |
725: | $mResult = [ |
726: | 'authToken' => $mResult->data->authToken, |
727: | 'userId' => $mResult->data->userId |
728: | ]; |
729: | } |
730: | } |
731: | } |
732: | |
733: | $this->curUserData = $mResult; |
734: | } |
735: | |
736: | return $this->curUserData; |
737: | } |
738: | |
739: | public function GetLoginForCurrentUser() |
740: | { |
741: | $mResult = false; |
742: | |
743: | $oUser = Api::getAuthenticatedUser(); |
744: | if ($oUser) { |
745: | $mResult = $this->getUserNameFromEmail($oUser->PublicId); |
746: | } |
747: | |
748: | return $mResult; |
749: | } |
750: | |
751: | public function GetLoginForEmail($Email) |
752: | { |
753: | $mResult = false; |
754: | $oUserInfo = $this->getUserInfo($Email); |
755: | if (!$oUserInfo) { |
756: | $oUserInfo = $this->createUser($Email); |
757: | } |
758: | if ($oUserInfo && $oUserInfo->success) { |
759: | $mResult = $oUserInfo->user->username; |
760: | } |
761: | |
762: | return $mResult; |
763: | } |
764: | |
765: | public function GetUnreadCounter() |
766: | { |
767: | $mResult = 0; |
768: | $aCurUser = $this->InitChat(); |
769: | if ($aCurUser && $this->client) { |
770: | try { |
771: | $res = $this->client->get('subscriptions.get', [ |
772: | 'headers' => [ |
773: | "X-Auth-Token" => $aCurUser['authToken'], |
774: | "X-User-Id" => $aCurUser['userId'], |
775: | ], |
776: | 'http_errors' => false |
777: | ]); |
778: | if ($res->getStatusCode() === 200) { |
779: | $aResponse = \json_decode($res->getBody(), true); |
780: | if (is_array($aResponse['update'])) { |
781: | foreach ($aResponse['update'] as $update) { |
782: | $mResult += $update['unread']; |
783: | } |
784: | } |
785: | } |
786: | } catch (ConnectException $oException) { |
787: | } |
788: | } |
789: | |
790: | return $mResult; |
791: | } |
792: | |
793: | public function onAfterLogin(&$aArgs, &$mResult) |
794: | { |
795: | |
796: | |
797: | |
798: | |
799: | |
800: | } |
801: | |
802: | public function onBeforeLogout(&$aArgs, &$mResult) |
803: | { |
804: | |
805: | |
806: | |
807: | } |
808: | |
809: | public function onBeforeDeleteUser(&$aArgs, &$mResult) |
810: | { |
811: | $client = null; |
812: | $adminHeaders = null; |
813: | $oAuthenticatedUser = Api::getAuthenticatedUser(); |
814: | if ($oAuthenticatedUser && $oAuthenticatedUser->isNormalOrTenant() && |
815: | $oAuthenticatedUser->Id === (int) $aArgs['UserId'] |
816: | ) { |
817: | |
818: | $client = $this->client; |
819: | $adminHeaders = $this->getAdminHeaders(); |
820: | } else { |
821: | $oUser = Api::getUserById((int) $aArgs['UserId']); |
822: | if ($oUser) { |
823: | if ($oAuthenticatedUser->Role === UserRole::TenantAdmin && $oUser->IdTenant === $oAuthenticatedUser->IdTenant) { |
824: | \Aurora\System\Api::checkUserRoleIsAtLeast(UserRole::TenantAdmin); |
825: | } elseif ($oAuthenticatedUser->Role === UserRole::SuperAdmin) { |
826: | \Aurora\System\Api::checkUserRoleIsAtLeast(UserRole::SuperAdmin); |
827: | } |
828: | |
829: | $client = $this->getClient($oUser->IdTenant); |
830: | $adminHeaders = $this->getAdminHeaders($oUser->IdTenant); |
831: | } |
832: | } |
833: | |
834: | $sUserName = $this->getUserNameFromEmail(Api::getUserPublicIdById($aArgs['UserId'])); |
835: | try { |
836: | if ($client) { |
837: | $oRes = $client->post('users.delete', [ |
838: | 'json' => [ |
839: | 'username' => $sUserName |
840: | ], |
841: | 'headers' => $adminHeaders, |
842: | 'http_errors' => false, |
843: | 'timeout' => 1 |
844: | ]); |
845: | if ($oRes->getStatusCode() === 200) { |
846: | $mResult = true; |
847: | } |
848: | } |
849: | } catch (ConnectException $oException) { |
850: | \Aurora\System\Api::Log('Cannot delete ' . $sUserName . ' user from RocketChat. Exception is below.'); |
851: | \Aurora\System\Api::LogException($oException); |
852: | } |
853: | } |
854: | } |
855: | |