1: | <?php |
2: | |
3: | |
4: | |
5: | |
6: | |
7: | |
8: | namespace Aurora\Modules\Core; |
9: | |
10: | use Aurora\Api; |
11: | use Aurora\Modules\Contacts\Enums\StorageType; |
12: | use Aurora\Modules\Contacts\Models\Contact; |
13: | use Aurora\Modules\Core\Enums\ErrorCodes; |
14: | use Aurora\Modules\Core\Models\Group; |
15: | use Aurora\Modules\Core\Models\User; |
16: | use Aurora\Modules\Core\Models\UserBlock; |
17: | use Aurora\System\Enums\UserRole; |
18: | use Aurora\System\Exceptions\ApiException; |
19: | use Aurora\System\Notifications; |
20: | use Illuminate\Database\Eloquent\Builder; |
21: | use stdClass; |
22: | use Symfony\Component\Console\Input\ArrayInput; |
23: | use Symfony\Component\Console\Output\NullOutput; |
24: | use Symfony\Component\Console\Output\BufferedOutput; |
25: | |
26: | |
27: | |
28: | |
29: | |
30: | |
31: | |
32: | |
33: | |
34: | |
35: | class Module extends \Aurora\System\Module\AbstractModule |
36: | { |
37: | protected $oTenantsManager = null; |
38: | |
39: | protected $oChannelsManager = null; |
40: | |
41: | protected $oUsersManager = null; |
42: | |
43: | protected $oIntegratorManager = null; |
44: | |
45: | |
46: | |
47: | |
48: | |
49: | public static function getInstance() |
50: | { |
51: | return \Aurora\System\Api::GetModule(self::GetName()); |
52: | } |
53: | |
54: | public function getTenantsManager() |
55: | { |
56: | if ($this->oTenantsManager === null) { |
57: | $this->oTenantsManager = new Managers\Tenants($this); |
58: | } |
59: | |
60: | return $this->oTenantsManager; |
61: | } |
62: | |
63: | public function getChannelsManager() |
64: | { |
65: | if ($this->oChannelsManager === null) { |
66: | $this->oChannelsManager = new Managers\Channels($this); |
67: | } |
68: | |
69: | return $this->oChannelsManager; |
70: | } |
71: | |
72: | public function getUsersManager() |
73: | { |
74: | if ($this->oUsersManager === null) { |
75: | $this->oUsersManager = new Managers\Users($this); |
76: | } |
77: | |
78: | return $this->oUsersManager; |
79: | } |
80: | |
81: | public function getIntegratorManager() |
82: | { |
83: | if ($this->oIntegratorManager === null) { |
84: | $this->oIntegratorManager = new \Aurora\System\Managers\Integrator(); |
85: | } |
86: | |
87: | return $this->oIntegratorManager; |
88: | } |
89: | |
90: | |
91: | |
92: | |
93: | |
94: | |
95: | |
96: | |
97: | public function init() |
98: | { |
99: | $this->aErrors = [ |
100: | Enums\ErrorCodes::ChannelDoesNotExist => $this->i18N('ERROR_CHANNEL_NOT_EXISTS'), |
101: | Enums\ErrorCodes::TenantAlreadyExists => $this->i18N('ERROR_TENANT_ALREADY_EXISTS'), |
102: | Enums\ErrorCodes::GroupAlreadyExists => $this->i18N('ERROR_GROUP_ALREADY_EXISTS'), |
103: | Enums\ErrorCodes::MySqlConfigError => 'Please make sure your PHP/MySQL environment meets the minimal system requirements.', |
104: | ]; |
105: | |
106: | \Aurora\System\Router::getInstance()->registerArray( |
107: | self::GetName(), |
108: | [ |
109: | 'api' => [$this, 'EntryApi'], |
110: | 'ping' => [$this, 'EntryPing'], |
111: | 'pull' => [$this, 'EntryPull'], |
112: | 'mobile' => [$this, 'EntryMobile'], |
113: | 'sso' => [$this, 'EntrySso'], |
114: | 'postlogin' => [$this, 'EntryPostlogin'], |
115: | 'file-cache' => [$this, 'EntryFileCache'] |
116: | ] |
117: | ); |
118: | |
119: | \Aurora\System\EventEmitter::getInstance()->onAny( |
120: | [ |
121: | ['CreateAccount', [$this, 'onCreateAccount'], 100], |
122: | ['Core::GetCompatibilities::after', [$this, 'onAfterGetCompatibilities']], |
123: | ['System::RunEntry::before', [$this, 'onBeforeRunEntry'], 100] |
124: | ] |
125: | ); |
126: | |
127: | $this->denyMethodsCallByWebApi([ |
128: | 'UpdateUserObject', |
129: | 'GetUserByUUID', |
130: | 'GetUserByPublicId', |
131: | 'GetAdminUser', |
132: | 'GetTenantUnchecked', |
133: | 'GetTenantName', |
134: | 'GetTenantIdByName', |
135: | 'GetDefaultGlobalTenant', |
136: | 'UpdateTenantObject', |
137: | 'GetUserUnchecked', |
138: | 'UpdateTokensValidFromTimestamp', |
139: | 'GetAccountUsedToAuthorize', |
140: | 'GetDigestHash', |
141: | 'VerifyPassword', |
142: | 'SetAuthDataAndGetAuthToken', |
143: | 'IsModuleDisabledForObject', |
144: | 'GetBlockedUser', |
145: | 'BlockUser', |
146: | 'CheckIsBlockedUser', |
147: | 'GetAllGroup' |
148: | ]); |
149: | } |
150: | |
151: | |
152: | |
153: | |
154: | |
155: | private function getUploadData() |
156: | { |
157: | $mResult = false; |
158: | $oFile = null; |
159: | if (isset($_FILES) && count($_FILES) > 0) { |
160: | $oFile = current($_FILES); |
161: | } |
162: | if (isset($oFile, $oFile['name'], $oFile['tmp_name'], $oFile['size'], $oFile['type'])) { |
163: | $iError = (isset($oFile['error'])) ? (int) $oFile['error'] : UPLOAD_ERR_OK; |
164: | $mResult = (UPLOAD_ERR_OK === $iError) ? $oFile : false; |
165: | } |
166: | |
167: | return $mResult; |
168: | } |
169: | |
170: | |
171: | |
172: | |
173: | |
174: | |
175: | |
176: | |
177: | |
178: | |
179: | |
180: | |
181: | public function onCreateAccount(&$Args, &$Result) |
182: | { |
183: | $oUser = null; |
184: | |
185: | if (isset($Args['UserId']) && (int)$Args['UserId'] > 0) { |
186: | $oUser = $this->getUsersManager()->getUser($Args['UserId']); |
187: | } else { |
188: | $Email = (isset($Args['Email'])) ? $Args['Email'] : ''; |
189: | $PublicId = (isset($Args['PublicId'])) ? $Args['PublicId'] : ''; |
190: | $sPublicId = null; |
191: | if (!empty($PublicId)) { |
192: | $sPublicId = $PublicId; |
193: | } elseif (!empty($Email)) { |
194: | $sPublicId = $Email; |
195: | } |
196: | if (!empty($sPublicId)) { |
197: | $oUser = $this->getUsersManager()->getUserByPublicId($sPublicId); |
198: | } |
199: | if (!isset($oUser)) { |
200: | $bPrevState = \Aurora\System\Api::skipCheckUserRole(true); |
201: | $iUserId = self::Decorator()->CreateUser(isset($Args['TenantId']) ? (int) $Args['TenantId'] : 0, $sPublicId); |
202: | \Aurora\System\Api::skipCheckUserRole($bPrevState); |
203: | $oUser = $this->getUsersManager()->getUser($iUserId); |
204: | } |
205: | |
206: | if (isset($oUser) && isset($oUser->Id)) { |
207: | $Args['UserId'] = $oUser->Id; |
208: | } |
209: | } |
210: | |
211: | $Result = $oUser; |
212: | } |
213: | |
214: | |
215: | |
216: | |
217: | |
218: | |
219: | public function onAfterGetCompatibilities($aArgs, &$mResult) |
220: | { |
221: | $aCompatibility['php.version'] = phpversion(); |
222: | $aCompatibility['php.version.valid'] = (int) (version_compare($aCompatibility['php.version'], '7.2.5') > -1); |
223: | |
224: | $aCompatibility['safe-mode'] = @ini_get('safe_mode'); |
225: | $aCompatibility['safe-mode.valid'] = is_numeric($aCompatibility['safe-mode']) |
226: | ? !((bool) $aCompatibility['safe-mode']) |
227: | : ('off' === strtolower($aCompatibility['safe-mode']) || empty($aCompatibility['safe-mode'])); |
228: | |
229: | $aCompatibility['mysql.valid'] = (int) extension_loaded('mysql'); |
230: | $aCompatibility['pdo.valid'] = (int) |
231: | ((bool) extension_loaded('pdo') && (bool) extension_loaded('pdo_mysql')); |
232: | |
233: | $aCompatibility['mysqlnd.valid'] = (int) ( |
234: | function_exists('mysqli_fetch_all') && |
235: | strpos(mysqli_get_client_info(), "mysqlnd") !== false |
236: | ); |
237: | |
238: | $aCompatibility['socket.valid'] = (int) function_exists('fsockopen'); |
239: | $aCompatibility['iconv.valid'] = (int) function_exists('iconv'); |
240: | $aCompatibility['curl.valid'] = (int) function_exists('curl_init'); |
241: | $aCompatibility['mbstring.valid'] = (int) function_exists('mb_detect_encoding'); |
242: | $aCompatibility['openssl.valid'] = (int) extension_loaded('openssl'); |
243: | $aCompatibility['xml.valid'] = (int) (class_exists('DOMDocument') && function_exists('xml_parser_create')); |
244: | $aCompatibility['json.valid'] = (int) function_exists('json_decode'); |
245: | $aCompatibility['gd.valid'] = (int) extension_loaded('gd'); |
246: | |
247: | $aCompatibility['ini-get.valid'] = (int) function_exists('ini_get'); |
248: | $aCompatibility['ini-set.valid'] = (int) function_exists('ini_set'); |
249: | $aCompatibility['set-time-limit.valid'] = (int) function_exists('set_time_limit'); |
250: | |
251: | $aCompatibility['session.valid'] = (int) (function_exists('session_start') && isset($_SESSION['checksessionindex'])); |
252: | |
253: | $dataPath = \Aurora\System\Api::DataPath(); |
254: | |
255: | $aCompatibility['data.dir'] = $dataPath; |
256: | $aCompatibility['data.dir.valid'] = (int) (@is_dir($aCompatibility['data.dir']) && @is_writable($aCompatibility['data.dir'])); |
257: | |
258: | $sTempPathName = '_must_be_deleted_'.md5(time()); |
259: | |
260: | $aCompatibility['data.dir.create'] = |
261: | (int) @mkdir($aCompatibility['data.dir'].'/'.$sTempPathName); |
262: | $aCompatibility['data.file.create'] = |
263: | (int) (bool) @fopen($aCompatibility['data.dir'].'/'.$sTempPathName.'/'.$sTempPathName.'.test', 'w+'); |
264: | $aCompatibility['data.file.delete'] = |
265: | (int) (bool) @unlink($aCompatibility['data.dir'].'/'.$sTempPathName.'/'.$sTempPathName.'.test'); |
266: | $aCompatibility['data.dir.delete'] = |
267: | (int) @rmdir($aCompatibility['data.dir'].'/'.$sTempPathName); |
268: | |
269: | |
270: | $oSettings =& \Aurora\System\Api::GetSettings(); |
271: | |
272: | $aCompatibility['settings.file'] = $oSettings ? $oSettings->GetPath() : ''; |
273: | |
274: | $aCompatibility['settings.file.exist'] = (int) @file_exists($aCompatibility['settings.file']); |
275: | $aCompatibility['settings.file.read'] = (int) @is_readable($aCompatibility['settings.file']); |
276: | $aCompatibility['settings.file.write'] = (int) @is_writable($aCompatibility['settings.file']); |
277: | |
278: | $aCompatibilities = [ |
279: | [ |
280: | 'Name' => 'PHP version', |
281: | 'Result' => $aCompatibility['php.version.valid'], |
282: | 'Value' => $aCompatibility['php.version.valid'] |
283: | ? 'OK' |
284: | : [$aCompatibility['php.version'].' detected, 7.2.5 or above required.', |
285: | 'You need to upgrade PHP engine installed on your server. |
286: | If it\'s a dedicated or your local server, you can download the latest version of PHP from its |
287: | <a href="http://php.net/downloads.php" target="_blank">official site</a> and install it yourself. |
288: | In case of a shared hosting, you need to ask your hosting provider to perform the upgrade.'] |
289: | ], |
290: | [ |
291: | 'Name' => 'Safe Mode is off', |
292: | 'Result' => $aCompatibility['safe-mode.valid'], |
293: | 'Value' => ($aCompatibility['safe-mode.valid']) |
294: | ? 'OK' |
295: | : ['Error, safe_mode is enabled.', |
296: | 'You need to <a href="http://php.net/manual/en/ini.sect.safe-mode.php" target="_blank">disable it in your php.ini</a> |
297: | or contact your hosting provider and ask to do this.'] |
298: | ], |
299: | [ |
300: | 'Name' => 'PDO MySQL Extension', |
301: | 'Result' => $aCompatibility['pdo.valid'], |
302: | 'Value' => ($aCompatibility['pdo.valid']) |
303: | ? 'OK' |
304: | : ['Error, PHP PDO MySQL extension not detected.', |
305: | 'You need to install this PHP extension or enable it in php.ini file.'] |
306: | ], |
307: | [ |
308: | 'Name' => 'MySQL Native Driver (mysqlnd)', |
309: | 'Result' => $aCompatibility['mysqlnd.valid'], |
310: | 'Value' => ($aCompatibility['mysqlnd.valid']) |
311: | ? 'OK' |
312: | : ['Error, MySQL Native Driver not found.', |
313: | 'You need to install this PHP extension or enable it in php.ini file.'] |
314: | ], |
315: | [ |
316: | 'Name' => 'Iconv Extension', |
317: | 'Result' => $aCompatibility['iconv.valid'], |
318: | 'Value' => ($aCompatibility['iconv.valid']) |
319: | ? 'OK' |
320: | : ['Error, iconv extension not detected.', |
321: | 'You need to install this PHP extension or enable it in php.ini file.'] |
322: | ], |
323: | [ |
324: | 'Name' => 'Multibyte String Extension', |
325: | 'Result' => $aCompatibility['mbstring.valid'], |
326: | 'Value' => ($aCompatibility['mbstring.valid']) |
327: | ? 'OK' |
328: | : ['Error, mb_string extension not detected.', |
329: | 'You need to install this PHP extension or enable it in php.ini file.'] |
330: | ], |
331: | [ |
332: | 'Name' => 'CURL Extension', |
333: | 'Result' => $aCompatibility['curl.valid'], |
334: | 'Value' => ($aCompatibility['curl.valid']) |
335: | ? 'OK' |
336: | : ['Error, curl extension not detected.', |
337: | 'You need to install this PHP extension or enable it in php.ini file.'] |
338: | ], |
339: | [ |
340: | 'Name' => 'JSON Extension', |
341: | 'Result' => $aCompatibility['json.valid'], |
342: | 'Value' => ($aCompatibility['json.valid']) |
343: | ? 'OK' |
344: | : ['Error, JSON extension not detected.', |
345: | 'You need to install this PHP extension or enable it in php.ini file.'] |
346: | ], |
347: | [ |
348: | 'Name' => 'XML/DOM Extension', |
349: | 'Result' => $aCompatibility['xml.valid'], |
350: | 'Value' => ($aCompatibility['xml.valid']) |
351: | ? 'OK' |
352: | : ['Error, xml (DOM) extension not detected.', |
353: | 'You need to install this PHP extension or enable it in php.ini file.'] |
354: | ], |
355: | [ |
356: | 'Name' => 'GD Extension', |
357: | 'Result' => $aCompatibility['gd.valid'], |
358: | 'Value' => ($aCompatibility['gd.valid']) |
359: | ? 'OK' |
360: | : ['Error, GD extension not detected.', |
361: | 'You need to install this PHP extension or enable it in php.ini file.'] |
362: | ], |
363: | [ |
364: | 'Name' => 'Sockets', |
365: | 'Result' => $aCompatibility['socket.valid'], |
366: | 'Value' => ($aCompatibility['socket.valid']) |
367: | ? 'OK' |
368: | : ['Error, creating network sockets must be enabled.', ' |
369: | To enable sockets, you should remove fsockopen function from the list of prohibited functions in disable_functions directive of your php.ini file. |
370: | In case of a shared hosting, you need to ask your hosting provider to do this.'] |
371: | ], |
372: | [ |
373: | 'Name' => 'SSL (OpenSSL extension)', |
374: | 'Result' => $aCompatibility['openssl.valid'], |
375: | 'Value' => ($aCompatibility['openssl.valid']) |
376: | ? 'OK' |
377: | : ['SSL connections (like Gmail) will not be available. ', ' |
378: | You need to enable OpenSSL support in your PHP configuration and make sure OpenSSL library is installed on your server. |
379: | For instructions, please refer to the official PHP documentation. In case of a shared hosting, |
380: | you need to ask your hosting provider to enable OpenSSL support. |
381: | You may ignore this if you\'re not going to connect to SSL-only mail servers (like Gmail).'] |
382: | ], |
383: | [ |
384: | 'Name' => 'Setting memory limits', |
385: | 'Result' => $aCompatibility['ini-get.valid'], |
386: | 'Value' => ($aCompatibility['ini-get.valid'] && $aCompatibility['ini-set.valid']) |
387: | ? 'OK' |
388: | : ['Opening large e-mails may fail.', ' |
389: | You need to enable setting memory limits in your PHP configuration, i.e. remove ini_get and ini_set functions |
390: | from the list of prohibited functions in disable_functions directive of your php.ini file. |
391: | In case of a shared hosting, you need to ask your hosting provider to do this.'] |
392: | ], |
393: | [ |
394: | 'Name' => 'Setting script timeout', |
395: | 'Result' => $aCompatibility['set-time-limit.valid'], |
396: | 'Value' => ($aCompatibility['set-time-limit.valid']) |
397: | ? 'OK' |
398: | : ['Downloading large mailboxes may fail.', ' |
399: | To enable setting script timeout, you should remove set_time_limit function from the list |
400: | of prohibited functions in disable_functions directive of your php.ini file. |
401: | In case of a shared hosting, you need to ask your hosting provider to do this.'] |
402: | ], |
403: | [ |
404: | 'Name' => 'WebMail data directory', |
405: | 'Result' => $aCompatibility['data.dir.valid'], |
406: | 'Value' => ($aCompatibility['data.dir.valid']) |
407: | ? 'Found' |
408: | : ['Error, data directory path discovery failure.'] |
409: | ], |
410: | [ |
411: | 'Name' => 'Creating/deleting directories', |
412: | 'Result' => $aCompatibility['data.dir.create'] && $aCompatibility['data.dir.delete'], |
413: | 'Value' => ($aCompatibility['data.dir.create'] && $aCompatibility['data.dir.delete']) |
414: | ? 'OK' |
415: | : ['Error, can\'t create/delete sub-directories in the data directory.', ' |
416: | You need to grant read/write permission over data directory and all its contents to your web server user. |
417: | For instructions, please refer to this section of documentation and our |
418: | <a href="https://afterlogic.com/docs/webmail-pro-8/troubleshooting/troubleshooting-issues-with-data-directory" target="_blank">FAQ</a>.'] |
419: | ], |
420: | [ |
421: | 'Name' => 'Creating/deleting files', |
422: | 'Result' => $aCompatibility['data.file.create'] && $aCompatibility['data.file.delete'], |
423: | 'Value' => ($aCompatibility['data.file.create'] && $aCompatibility['data.file.delete']) |
424: | ? 'OK' |
425: | : ['Error, can\'t create/delete files in the data directory.', ' |
426: | You need to grant read/write permission over data directory and all its contents to your web server user. |
427: | For instructions, please refer to this section of documentation and our |
428: | <a href="https://afterlogic.com/docs/webmail-pro-8/troubleshooting/troubleshooting-issues-with-data-directory" target="_blank">FAQ</a>.'] |
429: | ], |
430: | [ |
431: | 'Name' => 'WebMail Settings File', |
432: | 'Result' => $aCompatibility['settings.file.exist'], |
433: | 'Value' => ($aCompatibility['settings.file.exist']) |
434: | ? 'Found' |
435: | : ['Not Found, can\'t find "'.$aCompatibility['settings.file'].'" file.', ' |
436: | Make sure you completely copied the data directory with all its contents from installation package. |
437: | By default, the data directory is webmail subdirectory, and if it\'s not the case make sure its location matches one specified in inc_settings_path.php file.'] |
438: | ], |
439: | [ |
440: | 'Name' => 'Read/write settings file', |
441: | 'Result' => $aCompatibility['settings.file.read'] && $aCompatibility['settings.file.write'], |
442: | 'Value' => ($aCompatibility['settings.file.read'] && $aCompatibility['settings.file.write']) |
443: | ? 'OK / OK' |
444: | : ['Not Found, can\'t find "'.$aCompatibility['settings.file'].'" file.', ' |
445: | You should grant read/write permission over settings file to your web server user. |
446: | For instructions, please refer to this section of documentation and our |
447: | <a href="https://afterlogic.com/docs/webmail-pro-8/troubleshooting/troubleshooting-issues-with-data-directory" target="_blank">FAQ</a>.'] |
448: | ], |
449: | ]; |
450: | |
451: | $mResult[self::GetName()] = $aCompatibilities; |
452: | } |
453: | |
454: | public function onBeforeRunEntry($aArgs, &$mResult) |
455: | { |
456: | \Aurora\Api::removeOldLogs(); |
457: | |
458: | return $this->redirectToHttps($aArgs['EntryName'], $mResult); |
459: | } |
460: | |
461: | |
462: | |
463: | |
464: | |
465: | |
466: | |
467: | |
468: | protected function removeDirByTime($sTempPath, $iTime2Kill, $iNow) |
469: | { |
470: | $iFileCount = 0; |
471: | if (@is_dir($sTempPath)) { |
472: | $rDirH = @opendir($sTempPath); |
473: | if ($rDirH) { |
474: | while (($sFile = @readdir($rDirH)) !== false) { |
475: | if ('.' !== $sFile && '..' !== $sFile) { |
476: | if (@is_dir($sTempPath.'/'.$sFile)) { |
477: | $this->removeDirByTime($sTempPath.'/'.$sFile, $iTime2Kill, $iNow); |
478: | } else { |
479: | $iFileCount++; |
480: | } |
481: | } |
482: | } |
483: | @closedir($rDirH); |
484: | } |
485: | |
486: | if ($iFileCount > 0) { |
487: | if ($this->removeFilesByTime($sTempPath, $iTime2Kill, $iNow)) { |
488: | @rmdir($sTempPath); |
489: | } |
490: | } else { |
491: | @rmdir($sTempPath); |
492: | } |
493: | } |
494: | } |
495: | |
496: | |
497: | |
498: | |
499: | |
500: | |
501: | |
502: | |
503: | |
504: | |
505: | protected function removeFilesByTime($sTempPath, $iTime2Kill, $iNow) |
506: | { |
507: | $bResult = true; |
508: | if (@is_dir($sTempPath)) { |
509: | $rDirH = @opendir($sTempPath); |
510: | if ($rDirH) { |
511: | while (($sFile = @readdir($rDirH)) !== false) { |
512: | if ($sFile !== '.' && $sFile !== '..') { |
513: | if ($iNow - filemtime($sTempPath.'/'.$sFile) > $iTime2Kill) { |
514: | @unlink($sTempPath.'/'.$sFile); |
515: | } else { |
516: | $bResult = false; |
517: | } |
518: | } |
519: | } |
520: | @closedir($rDirH); |
521: | } |
522: | } |
523: | return $bResult; |
524: | } |
525: | |
526: | protected function redirectToHttps($sEntryName, $mResult) |
527: | { |
528: | $oSettings =& \Aurora\Api::GetSettings(); |
529: | if ($oSettings) { |
530: | $bRedirectToHttps = $oSettings->RedirectToHttps; |
531: | |
532: | $bHttps = \Aurora\Api::isHttps(); |
533: | if ($bRedirectToHttps && !$bHttps) { |
534: | if (\strtolower($sEntryName) !== 'api') { |
535: | \header("Location: https://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']); |
536: | } else { |
537: | $mResult = [ |
538: | 'ErrorCode' => 110 |
539: | ]; |
540: | return true; |
541: | } |
542: | } |
543: | } |
544: | } |
545: | |
546: | |
547: | |
548: | |
549: | |
550: | |
551: | |
552: | |
553: | private function deleteTree($dir) |
554: | { |
555: | $files = array_diff(scandir($dir), array('.','..')); |
556: | |
557: | foreach ($files as $file) { |
558: | (is_dir("$dir/$file")) ? $this->deleteTree("$dir/$file") : unlink("$dir/$file"); |
559: | } |
560: | |
561: | return rmdir($dir); |
562: | } |
563: | |
564: | |
565: | |
566: | |
567: | |
568: | |
569: | |
570: | |
571: | public function EntryApi() |
572: | { |
573: | @ob_start(); |
574: | |
575: | if (!is_writable(\Aurora\System\Api::DataPath())) { |
576: | throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::SystemNotConfigured); |
577: | } |
578: | |
579: | $aResponseItem = null; |
580: | $sModule = $this->oHttp->GetPost('Module', null); |
581: | $sMethod = $this->oHttp->GetPost('Method', null); |
582: | $sParameters = $this->oHttp->GetPost('Parameters', null); |
583: | $sFormat = $this->oHttp->GetPost('Format', null); |
584: | $sTenantName = $this->oHttp->GetPost('TenantName', null); |
585: | |
586: | if (isset($sModule, $sMethod)) { |
587: | $oModule = \Aurora\System\Api::GetModule($sModule); |
588: | if ($oModule instanceof \Aurora\System\Module\AbstractModule) { |
589: | try { |
590: | \Aurora\System\Api::Log(" "); |
591: | \Aurora\System\Api::Log(" ===== API: " . $sModule . '::' . $sMethod); |
592: | |
593: | $bIsEmptyAuthToken = !\Aurora\System\Api::getAuthTokenFromHeaders(); |
594: | |
595: | if ($this->getConfig('CsrfTokenProtection', true) && !\Aurora\System\Api::validateCsrfToken()) { |
596: | throw new \Aurora\System\Exceptions\ApiException( |
597: | \Aurora\System\Notifications::InvalidToken |
598: | ); |
599: | } |
600: | |
601: | if (!empty($sModule) && !empty($sMethod)) { |
602: | if (!\Aurora\System\Api::validateAuthToken() && !$bIsEmptyAuthToken) { |
603: | throw new \Aurora\System\Exceptions\ApiException( |
604: | \Aurora\System\Notifications::AuthError |
605: | ); |
606: | } |
607: | |
608: | \Aurora\System\Api::setTenantName($sTenantName); |
609: | |
610: | $aParameters = []; |
611: | if (isset($sParameters) && \is_string($sParameters)) { |
612: | $aParameters = @\json_decode($sParameters, true); |
613: | if (!\is_array($aParameters)) { |
614: | $aParameters = array($aParameters); |
615: | } |
616: | } |
617: | |
618: | $mUploadData = $this->getUploadData(); |
619: | if (\is_array($mUploadData)) { |
620: | $aParameters['UploadData'] = $mUploadData; |
621: | } |
622: | |
623: | $oModule->CallMethod( |
624: | $sMethod, |
625: | $aParameters, |
626: | true |
627: | ); |
628: | |
629: | $oLastException = \Aurora\System\Api::GetModuleManager()->GetLastException(); |
630: | if (isset($oLastException)) { |
631: | throw $oLastException; |
632: | } |
633: | |
634: | $aResponseItem = $oModule->DefaultResponse( |
635: | $sMethod, |
636: | \Aurora\System\Api::GetModuleManager()->GetResults() |
637: | ); |
638: | } |
639: | |
640: | if (!\is_array($aResponseItem)) { |
641: | throw new \Aurora\System\Exceptions\ApiException( |
642: | \Aurora\System\Notifications::UnknownError |
643: | ); |
644: | } |
645: | } catch (\Exception $oException) { |
646: | \Aurora\System\Api::LogException($oException); |
647: | |
648: | $aAdditionalParams = null; |
649: | if ($oException instanceof \Aurora\System\Exceptions\ApiException) { |
650: | $aAdditionalParams = $oException->GetObjectParams(); |
651: | } |
652: | |
653: | $aResponseItem = $oModule->ExceptionResponse( |
654: | $sMethod, |
655: | $oException, |
656: | $aAdditionalParams |
657: | ); |
658: | } |
659: | } else { |
660: | $oException = new \Aurora\System\Exceptions\ApiException( |
661: | \Aurora\System\Notifications::ModuleNotFound |
662: | ); |
663: | $aResponseItem = $this->ExceptionResponse( |
664: | $sMethod, |
665: | $oException |
666: | ); |
667: | } |
668: | } else { |
669: | $oException = new \Aurora\System\Exceptions\ApiException( |
670: | \Aurora\System\Notifications::InvalidInputParameter |
671: | ); |
672: | $aResponseItem = $this->ExceptionResponse( |
673: | $sMethod, |
674: | $oException |
675: | ); |
676: | } |
677: | |
678: | if (isset($aResponseItem['Parameters'])) { |
679: | unset($aResponseItem['Parameters']); |
680: | } |
681: | |
682: | return \Aurora\System\Managers\Response::GetJsonFromObject($sFormat, $aResponseItem); |
683: | } |
684: | |
685: | |
686: | |
687: | |
688: | public function EntryMobile() |
689: | { |
690: | $oApiIntegrator = $this->getIntegratorManager(); |
691: | $oApiIntegrator->setMobile(true); |
692: | |
693: | \Aurora\System\Api::Location('./'); |
694: | } |
695: | |
696: | |
697: | |
698: | |
699: | public function EntrySso() |
700: | { |
701: | try { |
702: | $sHash = $this->oHttp->GetRequest('hash'); |
703: | if (!empty($sHash)) { |
704: | $sData = \Aurora\System\Api::Cacher()->get('SSO:'.$sHash, true); |
705: | $aData = \Aurora\System\Api::DecodeKeyValues($sData); |
706: | |
707: | if (isset($aData['Password'], $aData['Email'])) { |
708: | $sLanguage = $this->oHttp->GetRequest('lang'); |
709: | $aResult = self::Decorator()->Login($aData['Email'], $aData['Password'], $sLanguage); |
710: | |
711: | if (is_array($aResult) && isset($aResult['AuthToken'])) { |
712: | $iAuthTokenCookieExpireTime = (int) self::getInstance()->getConfig('AuthTokenCookieExpireTime', 30); |
713: | @\setcookie( |
714: | \Aurora\System\Application::AUTH_TOKEN_KEY, |
715: | $aResult['AuthToken'], |
716: | ($iAuthTokenCookieExpireTime === 0) ? 0 : \strtotime('+' . $iAuthTokenCookieExpireTime . ' days'), |
717: | \Aurora\System\Api::getCookiePath(), |
718: | null, |
719: | \Aurora\System\Api::getCookieSecure() |
720: | ); |
721: | } else { |
722: | @\setcookie( |
723: | \Aurora\System\Application::AUTH_TOKEN_KEY, |
724: | null, |
725: | -1 |
726: | ); |
727: | } |
728: | } |
729: | } else { |
730: | self::Decorator()->Logout(); |
731: | } |
732: | } catch (\Exception $oExc) { |
733: | \Aurora\System\Api::LogException($oExc); |
734: | } |
735: | |
736: | \Aurora\System\Api::Location('./'); |
737: | } |
738: | |
739: | |
740: | |
741: | |
742: | public function EntryPostlogin() |
743: | { |
744: | if ($this->getConfig('AllowPostLogin', false)) { |
745: | $sEmail = trim((string) $this->oHttp->GetRequest('Email', '')); |
746: | $sLogin = (string) $this->oHttp->GetRequest('Login', ''); |
747: | |
748: | if ($sLogin==='') { |
749: | $sLogin = $sEmail; |
750: | } |
751: | $sPassword = (string) $this->oHttp->GetRequest('Password', ''); |
752: | |
753: | $sAtDomain = trim(\Aurora\System\Api::GetSettings()->GetValue('LoginAtDomainValue')); |
754: | if (0 < strlen($sAtDomain)) { |
755: | $sEmail = \Aurora\System\Utils::GetAccountNameFromEmail($sLogin).'@'.$sAtDomain; |
756: | $sLogin = $sEmail; |
757: | } |
758: | |
759: | $aResult = self::Decorator()->Login($sLogin, $sPassword); |
760: | if (is_array($aResult) && isset($aResult['AuthToken'])) { |
761: | $iAuthTokenCookieExpireTime = (int) self::getInstance()->getConfig('AuthTokenCookieExpireTime', 30); |
762: | @\setcookie( |
763: | \Aurora\System\Application::AUTH_TOKEN_KEY, |
764: | $aResult['AuthToken'], |
765: | ($iAuthTokenCookieExpireTime === 0) ? 0 : \strtotime('+' . $iAuthTokenCookieExpireTime . ' days'), |
766: | \Aurora\System\Api::getCookiePath(), |
767: | null, |
768: | \Aurora\System\Api::getCookieSecure() |
769: | ); |
770: | } |
771: | |
772: | \Aurora\System\Api::Location('./'); |
773: | } |
774: | } |
775: | |
776: | public function EntryFileCache() |
777: | { |
778: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
779: | |
780: | $sRawKey = \Aurora\System\Router::getItemByIndex(1, ''); |
781: | $sAction = \Aurora\System\Router::getItemByIndex(2, ''); |
782: | $aValues = \Aurora\System\Api::DecodeKeyValues($sRawKey); |
783: | |
784: | $bDownload = true; |
785: | $bThumbnail = false; |
786: | |
787: | switch ($sAction) { |
788: | case 'view': |
789: | $bDownload = false; |
790: | $bThumbnail = false; |
791: | break; |
792: | case 'thumb': |
793: | $bDownload = false; |
794: | $bThumbnail = true; |
795: | break; |
796: | default: |
797: | $bDownload = true; |
798: | $bThumbnail = false; |
799: | break; |
800: | } |
801: | |
802: | $iUserId = (isset($aValues['UserId'])) ? $aValues['UserId'] : 0; |
803: | |
804: | if (isset($aValues['TempFile'], $aValues['TempName'], $aValues['Name'])) { |
805: | $sModule = isset($aValues['Module']) && !empty($aValues['Module']) ? $aValues['Module'] : 'System'; |
806: | $bResult = false; |
807: | $sUUID = \Aurora\System\Api::getUserUUIDById($iUserId); |
808: | $oApiFileCache = new \Aurora\System\Managers\Filecache(); |
809: | $mResult = $oApiFileCache->getFile($sUUID, $aValues['TempName'], '', $sModule); |
810: | |
811: | if (is_resource($mResult)) { |
812: | $bResult = true; |
813: | $sFileName = $aValues['Name']; |
814: | $sContentType = (empty($sFileName)) ? 'text/plain' : \MailSo\Base\Utils::MimeContentType($sFileName); |
815: | $sFileName = \Aurora\System\Utils::clearFileName($sFileName, $sContentType); |
816: | |
817: | \Aurora\System\Utils::OutputFileResource($sUUID, $sContentType, $sFileName, $mResult, $bThumbnail, $bDownload); |
818: | } |
819: | } |
820: | } |
821: | |
822: | public function IsModuleExists($Module) |
823: | { |
824: | return \Aurora\System\Api::GetModuleManager()->ModuleExists($Module); |
825: | } |
826: | |
827: | |
828: | |
829: | |
830: | |
831: | public function GetVersion() |
832: | { |
833: | return \Aurora\System\Api::Version(); |
834: | } |
835: | |
836: | |
837: | |
838: | |
839: | |
840: | |
841: | |
842: | |
843: | |
844: | protected function ClearTempFiles() |
845: | { |
846: | $sTempPath =\Aurora\System\Api::DataPath().'/temp'; |
847: | if (@is_dir($sTempPath)) { |
848: | $iNow = time(); |
849: | |
850: | $iTime2Run = $this->getConfig('CronTimeToRunSeconds', 10800); |
851: | $iTime2Kill = $this->getConfig('CronTimeToKillSeconds', 10800); |
852: | $sDataFile = $this->getConfig('CronTimeFile', '.clear.dat'); |
853: | |
854: | $iFiletTime = -1; |
855: | if (@file_exists(\Aurora\System\Api::DataPath().'/'.$sDataFile)) { |
856: | $iFiletTime = (int) @file_get_contents(\Aurora\System\Api::DataPath().'/'.$sDataFile); |
857: | } |
858: | |
859: | if ($iFiletTime === -1 || $iNow - $iFiletTime > $iTime2Run) { |
860: | $this->removeDirByTime($sTempPath, $iTime2Kill, $iNow); |
861: | @file_put_contents(\Aurora\System\Api::DataPath().'/'.$sDataFile, $iNow); |
862: | } |
863: | } |
864: | |
865: | return true; |
866: | } |
867: | |
868: | |
869: | |
870: | |
871: | |
872: | |
873: | |
874: | |
875: | |
876: | |
877: | public function UpdateUserObject($oUser) |
878: | { |
879: | |
880: | |
881: | return $this->getUsersManager()->updateUser($oUser); |
882: | } |
883: | |
884: | |
885: | |
886: | |
887: | |
888: | |
889: | |
890: | |
891: | |
892: | |
893: | public function GetUserUnchecked($UserId = '') |
894: | { |
895: | |
896: | |
897: | |
898: | |
899: | $oUser = $this->getUsersManager()->getUser($UserId); |
900: | |
901: | return $oUser ? $oUser : null; |
902: | } |
903: | |
904: | |
905: | |
906: | |
907: | |
908: | |
909: | |
910: | |
911: | |
912: | |
913: | public function GetUserByUUID($UUID) |
914: | { |
915: | |
916: | |
917: | |
918: | |
919: | $oUser = $this->getUsersManager()->getUser($UUID); |
920: | |
921: | return $oUser ? $oUser : null; |
922: | } |
923: | |
924: | |
925: | |
926: | |
927: | |
928: | |
929: | |
930: | |
931: | |
932: | |
933: | public function GetUserByPublicId($PublicId) |
934: | { |
935: | |
936: | |
937: | $oUser = $this->getUsersManager()->getUserByPublicId($PublicId); |
938: | |
939: | return $oUser ? $oUser : null; |
940: | } |
941: | |
942: | |
943: | |
944: | |
945: | |
946: | |
947: | |
948: | |
949: | |
950: | public function GetAdminUser() |
951: | { |
952: | |
953: | |
954: | |
955: | |
956: | return $this->getIntegratorManager()->GetAdminUser(); |
957: | } |
958: | |
959: | |
960: | |
961: | |
962: | |
963: | |
964: | |
965: | |
966: | |
967: | |
968: | public function GetTenantUnchecked($Id) |
969: | { |
970: | |
971: | |
972: | $oTenant = $this->getTenantsManager()->getTenantById($Id); |
973: | |
974: | return $oTenant ? $oTenant : null; |
975: | } |
976: | |
977: | |
978: | |
979: | |
980: | |
981: | |
982: | |
983: | |
984: | |
985: | |
986: | public function GetTenantIdByName($TenantName = '') |
987: | { |
988: | |
989: | |
990: | $iTenantId = $this->getTenantsManager()->getTenantIdByName((string) $TenantName); |
991: | |
992: | return $iTenantId ? $iTenantId : null; |
993: | } |
994: | |
995: | |
996: | |
997: | |
998: | |
999: | |
1000: | |
1001: | |
1002: | |
1003: | public function GetTenantName() |
1004: | { |
1005: | |
1006: | |
1007: | $sTenant = ''; |
1008: | $sAuthToken = \Aurora\System\Api::getAuthToken(); |
1009: | if (!empty($sAuthToken)) { |
1010: | $iUserId = \Aurora\System\Api::getAuthenticatedUserId(); |
1011: | if ($iUserId !== false && $iUserId > 0) { |
1012: | $oUser = self::Decorator()->GetUserUnchecked($iUserId); |
1013: | if ($oUser) { |
1014: | $oTenant = self::Decorator()->GetTenantUnchecked($oUser->IdTenant); |
1015: | if ($oTenant) { |
1016: | $sTenant = $oTenant->Name; |
1017: | } |
1018: | } |
1019: | } |
1020: | $sPostTenant = $this->oHttp->GetPost('TenantName', ''); |
1021: | if (!empty($sPostTenant) && !empty($sTenant) && $sPostTenant !== $sTenant) { |
1022: | $sTenant = ''; |
1023: | } |
1024: | } else { |
1025: | $sTenant = $this->oHttp->GetRequest('tenant', ''); |
1026: | } |
1027: | \Aurora\System\Api::setTenantName($sTenant); |
1028: | return $sTenant; |
1029: | } |
1030: | |
1031: | |
1032: | |
1033: | |
1034: | public function GetTenantById($Id) |
1035: | { |
1036: | return self::Decorator()->GetTenant($Id); |
1037: | } |
1038: | |
1039: | |
1040: | |
1041: | |
1042: | |
1043: | |
1044: | |
1045: | |
1046: | |
1047: | public function GetDefaultGlobalTenant() |
1048: | { |
1049: | |
1050: | |
1051: | $oTenant = $this->getTenantsManager()->getDefaultGlobalTenant(); |
1052: | |
1053: | return $oTenant ? $oTenant : null; |
1054: | } |
1055: | |
1056: | |
1057: | |
1058: | |
1059: | |
1060: | |
1061: | |
1062: | |
1063: | |
1064: | |
1065: | public function UpdateTenantObject($oTenant) |
1066: | { |
1067: | |
1068: | |
1069: | return $this->getTenantsManager()->updateTenant($oTenant); |
1070: | } |
1071: | |
1072: | |
1073: | |
1074: | |
1075: | |
1076: | |
1077: | |
1078: | |
1079: | public function UpdateTokensValidFromTimestamp($oUser) |
1080: | { |
1081: | |
1082: | |
1083: | $oUser->TokensValidFromTimestamp = time(); |
1084: | $this->getUsersManager()->updateUser($oUser); |
1085: | return $oUser->TokensValidFromTimestamp; |
1086: | } |
1087: | |
1088: | |
1089: | |
1090: | |
1091: | |
1092: | |
1093: | |
1094: | |
1095: | |
1096: | |
1097: | |
1098: | |
1099: | |
1100: | |
1101: | |
1102: | |
1103: | |
1104: | |
1105: | |
1106: | |
1107: | |
1108: | |
1109: | |
1110: | |
1111: | |
1112: | |
1113: | |
1114: | |
1115: | |
1116: | |
1117: | |
1118: | |
1119: | |
1120: | |
1121: | |
1122: | |
1123: | |
1124: | |
1125: | |
1126: | |
1127: | |
1128: | |
1129: | |
1130: | |
1131: | |
1132: | |
1133: | |
1134: | |
1135: | |
1136: | |
1137: | |
1138: | |
1139: | |
1140: | |
1141: | |
1142: | public function DoServerInitializations($Timezone = '') |
1143: | { |
1144: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Customer); |
1145: | $result = true; |
1146: | |
1147: | $iUserId = \Aurora\System\Api::getAuthenticatedUserId(); |
1148: | |
1149: | $oApiIntegrator = $this->getIntegratorManager(); |
1150: | |
1151: | if ($iUserId && $oApiIntegrator) { |
1152: | $oApiIntegrator->resetCookies(); |
1153: | } |
1154: | |
1155: | $oCacher = \Aurora\System\Api::Cacher(); |
1156: | |
1157: | $bDoGC = false; |
1158: | $bDoHepdeskClear = false; |
1159: | if ($oCacher && $oCacher->IsInited()) { |
1160: | $iTime = $oCacher->GetTimer('Cache/ClearFileCache'); |
1161: | if (0 === $iTime || $iTime + 60 * 60 * 24 < time()) { |
1162: | if ($oCacher->SetTimer('Cache/ClearFileCache')) { |
1163: | $bDoGC = true; |
1164: | } |
1165: | } |
1166: | |
1167: | |
1168: | |
1169: | |
1170: | |
1171: | |
1172: | |
1173: | |
1174: | |
1175: | |
1176: | |
1177: | |
1178: | } |
1179: | |
1180: | if ($bDoGC) { |
1181: | \Aurora\System\Api::Log('GC: FileCache / Start'); |
1182: | $oApiFileCache = new \Aurora\System\Managers\Filecache(); |
1183: | $oApiFileCache->gc(); |
1184: | $oCacher->gc(); |
1185: | \Aurora\System\Api::Log('GC: FileCache / End'); |
1186: | } |
1187: | |
1188: | |
1189: | |
1190: | |
1191: | |
1192: | |
1193: | |
1194: | return $result; |
1195: | } |
1196: | |
1197: | |
1198: | |
1199: | |
1200: | |
1201: | |
1202: | |
1203: | |
1204: | |
1205: | |
1206: | |
1207: | |
1208: | |
1209: | |
1210: | |
1211: | |
1212: | |
1213: | |
1214: | |
1215: | |
1216: | |
1217: | |
1218: | |
1219: | |
1220: | |
1221: | |
1222: | |
1223: | |
1224: | |
1225: | |
1226: | |
1227: | |
1228: | |
1229: | |
1230: | public function Ping() |
1231: | { |
1232: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous); |
1233: | |
1234: | return 'Pong'; |
1235: | } |
1236: | |
1237: | |
1238: | |
1239: | |
1240: | |
1241: | |
1242: | |
1243: | |
1244: | |
1245: | |
1246: | |
1247: | |
1248: | |
1249: | |
1250: | |
1251: | |
1252: | |
1253: | |
1254: | |
1255: | |
1256: | |
1257: | |
1258: | |
1259: | |
1260: | |
1261: | |
1262: | |
1263: | |
1264: | |
1265: | |
1266: | |
1267: | |
1268: | |
1269: | |
1270: | |
1271: | |
1272: | |
1273: | |
1274: | |
1275: | |
1276: | |
1277: | public function GetAppData() |
1278: | { |
1279: | $oApiIntegrator = $this->getIntegratorManager(); |
1280: | return $oApiIntegrator->appData(); |
1281: | } |
1282: | |
1283: | |
1284: | |
1285: | |
1286: | |
1287: | |
1288: | |
1289: | |
1290: | |
1291: | |
1292: | |
1293: | |
1294: | |
1295: | |
1296: | |
1297: | |
1298: | |
1299: | |
1300: | |
1301: | |
1302: | |
1303: | |
1304: | |
1305: | |
1306: | |
1307: | |
1308: | |
1309: | |
1310: | |
1311: | |
1312: | |
1313: | |
1314: | |
1315: | |
1316: | |
1317: | |
1318: | |
1319: | |
1320: | |
1321: | |
1322: | |
1323: | |
1324: | |
1325: | |
1326: | |
1327: | |
1328: | |
1329: | |
1330: | |
1331: | |
1332: | |
1333: | |
1334: | |
1335: | |
1336: | |
1337: | |
1338: | |
1339: | |
1340: | |
1341: | |
1342: | |
1343: | |
1344: | |
1345: | |
1346: | |
1347: | |
1348: | public function GetSettings() |
1349: | { |
1350: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous); |
1351: | |
1352: | $oUser = \Aurora\System\Api::getAuthenticatedUser(); |
1353: | |
1354: | $oApiIntegrator = $this->getIntegratorManager(); |
1355: | $iLastErrorCode = $oApiIntegrator->getLastErrorCode(); |
1356: | if (0 < $iLastErrorCode) { |
1357: | $oApiIntegrator->clearLastErrorCode(); |
1358: | } |
1359: | |
1360: | $oSettings =& \Aurora\System\Api::GetSettings(); |
1361: | |
1362: | $aSettings = array( |
1363: | 'AutodetectLanguage' => $this->getConfig('AutodetectLanguage'), |
1364: | 'UserSelectsDateFormat' => $this->getConfig('UserSelectsDateFormat', false), |
1365: | 'DateFormat' => $this->getConfig('DateFormat', 'DD/MM/YYYY'), |
1366: | 'DateFormatList' => $this->getConfig('DateFormatList', ['DD/MM/YYYY', 'MM/DD/YYYY', 'DD Month YYYY']), |
1367: | 'EUserRole' => (new \Aurora\System\Enums\UserRole())->getMap(), |
1368: | 'Language' => \Aurora\System\Api::GetLanguage(), |
1369: | 'ShortLanguage' => \Aurora\System\Utils::ConvertLanguageNameToShort(\Aurora\System\Api::GetLanguage()), |
1370: | 'LanguageList' => $oApiIntegrator->getLanguageList(), |
1371: | 'LastErrorCode' => $iLastErrorCode, |
1372: | 'SiteName' => $this->getConfig('SiteName'), |
1373: | 'SocialName' => '', |
1374: | 'TenantName' => \Aurora\System\Api::getTenantName(), |
1375: | 'EnableMultiTenant' => $oSettings && $oSettings->GetValue('EnableMultiTenant', false), |
1376: | 'TimeFormat' => $this->getConfig('TimeFormat'), |
1377: | 'UserId' => \Aurora\System\Api::getAuthenticatedUserId(), |
1378: | 'IsSystemConfigured' => is_writable(\Aurora\System\Api::DataPath()) && |
1379: | (file_exists(\Aurora\System\Api::GetSaltPath()) && strlen(@file_get_contents(\Aurora\System\Api::GetSaltPath()))), |
1380: | 'Version' => \Aurora\System\Api::VersionFull(), |
1381: | 'ProductName' => $this->getConfig('ProductName'), |
1382: | 'PasswordMinLength' => $oSettings ? $oSettings->GetValue('PasswordMinLength', 0) : 0, |
1383: | 'PasswordMustBeComplex' => $oSettings && $oSettings->GetValue('PasswordMustBeComplex', false), |
1384: | 'CookiePath' => \Aurora\System\Api::getCookiePath(), |
1385: | 'CookieSecure' => \Aurora\System\Api::getCookieSecure(), |
1386: | 'AuthTokenCookieExpireTime' => $this->getConfig('AuthTokenCookieExpireTime', 30), |
1387: | 'StoreAuthTokenInDB' => $oSettings->GetValue('StoreAuthTokenInDB'), |
1388: | 'AvailableClientModules' => $oApiIntegrator->GetClientModuleNames(), |
1389: | 'AvailableBackendModules' => $oApiIntegrator->GetBackendModules(), |
1390: | 'AllowGroups' => $this->getConfig('AllowGroups', false), |
1391: | ); |
1392: | |
1393: | if ($oSettings && !empty($oUser) && $oUser->Role === \Aurora\System\Enums\UserRole::SuperAdmin) { |
1394: | $sAdminPassword = $oSettings->GetValue('AdminPassword'); |
1395: | |
1396: | $aSettings = array_merge($aSettings, array( |
1397: | 'DBHost' => $oSettings->GetValue('DBHost'), |
1398: | 'DBName' => $oSettings->GetValue('DBName'), |
1399: | 'DBLogin' => $oSettings->GetValue('DBLogin'), |
1400: | 'AdminLogin' => $oSettings->GetValue('AdminLogin'), |
1401: | 'AdminHasPassword' => !empty($sAdminPassword), |
1402: | 'AdminLanguage' => $oSettings->GetValue('AdminLanguage'), |
1403: | 'CommonLanguage' => $this->getConfig('Language'), |
1404: | 'SaltNotEmpty' => file_exists(\Aurora\System\Api::GetSaltPath()) && strlen(@file_get_contents(\Aurora\System\Api::GetSaltPath())), |
1405: | 'EnableLogging' => $oSettings->GetValue('EnableLogging'), |
1406: | 'EnableEventLogging' => $oSettings->GetValue('EnableEventLogging'), |
1407: | 'LoggingLevel' => $oSettings->GetValue('LoggingLevel'), |
1408: | 'LogFilesData' => $this->GetLogFilesData(), |
1409: | 'ELogLevel' => (new \Aurora\System\Enums\LogLevel())->getMap() |
1410: | )); |
1411: | } |
1412: | |
1413: | if (!empty($oUser) && $oUser->isNormalOrTenant()) { |
1414: | if ($oUser->DateFormat !== '') { |
1415: | $aSettings['DateFormat'] = $oUser->DateFormat; |
1416: | } |
1417: | $aSettings['TimeFormat'] = $oUser->TimeFormat; |
1418: | $aSettings['Timezone'] = $oUser->DefaultTimeZone; |
1419: | } |
1420: | |
1421: | return $aSettings; |
1422: | } |
1423: | |
1424: | |
1425: | |
1426: | |
1427: | |
1428: | |
1429: | |
1430: | |
1431: | |
1432: | |
1433: | |
1434: | |
1435: | |
1436: | |
1437: | |
1438: | |
1439: | |
1440: | |
1441: | |
1442: | |
1443: | |
1444: | |
1445: | |
1446: | |
1447: | |
1448: | |
1449: | |
1450: | |
1451: | |
1452: | |
1453: | |
1454: | |
1455: | |
1456: | |
1457: | |
1458: | |
1459: | |
1460: | |
1461: | |
1462: | |
1463: | |
1464: | |
1465: | |
1466: | |
1467: | |
1468: | |
1469: | |
1470: | |
1471: | |
1472: | |
1473: | |
1474: | |
1475: | |
1476: | |
1477: | |
1478: | |
1479: | |
1480: | |
1481: | |
1482: | |
1483: | |
1484: | |
1485: | |
1486: | |
1487: | |
1488: | |
1489: | |
1490: | |
1491: | |
1492: | |
1493: | |
1494: | |
1495: | |
1496: | |
1497: | |
1498: | |
1499: | |
1500: | |
1501: | |
1502: | |
1503: | |
1504: | |
1505: | |
1506: | |
1507: | public function UpdateSettings( |
1508: | $DbLogin = null, |
1509: | $DbPassword = null, |
1510: | $DbName = null, |
1511: | $DbHost = null, |
1512: | $AdminLogin = null, |
1513: | $Password = null, |
1514: | $NewPassword = null, |
1515: | $AdminLanguage = null, |
1516: | $SiteName = null, |
1517: | $Language = null, |
1518: | $AutodetectLanguage = null, |
1519: | $TimeFormat = null, |
1520: | $DateFormat = null, |
1521: | $EnableLogging = null, |
1522: | $EnableEventLogging = null, |
1523: | $LoggingLevel = null |
1524: | ) |
1525: | { |
1526: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
1527: | |
1528: | $oUser = \Aurora\System\Api::getAuthenticatedUser(); |
1529: | |
1530: | if ($oUser->Role === \Aurora\System\Enums\UserRole::SuperAdmin) { |
1531: | if ($SiteName !== null || $Language !== null || $TimeFormat !== null || $AutodetectLanguage !== null) { |
1532: | if ($SiteName !== null) { |
1533: | $this->setConfig('SiteName', $SiteName); |
1534: | } |
1535: | if ($AutodetectLanguage !== null) { |
1536: | $this->setConfig('AutodetectLanguage', $AutodetectLanguage); |
1537: | } |
1538: | if ($Language !== null) { |
1539: | $this->setConfig('Language', $Language); |
1540: | } |
1541: | if ($TimeFormat !== null) { |
1542: | $this->setConfig('TimeFormat', (int) $TimeFormat); |
1543: | } |
1544: | $this->saveModuleConfig(); |
1545: | } |
1546: | $oSettings =&\Aurora\System\Api::GetSettings(); |
1547: | if ($DbLogin !== null) { |
1548: | $oSettings->DBLogin = $DbLogin; |
1549: | } |
1550: | if ($DbPassword !== null) { |
1551: | $oSettings->DBPassword = $DbPassword; |
1552: | } |
1553: | if ($DbName !== null) { |
1554: | $oSettings->DBName = $DbName; |
1555: | } |
1556: | if ($DbHost !== null) { |
1557: | $oSettings->DBHost = $DbHost; |
1558: | } |
1559: | if ($AdminLogin !== null && $AdminLogin !== $oSettings->GetValue('AdminLogin')) { |
1560: | $aArgs = array( |
1561: | 'Login' => $AdminLogin |
1562: | ); |
1563: | $this->broadcastEvent( |
1564: | 'CheckAccountExists', |
1565: | $aArgs |
1566: | ); |
1567: | |
1568: | $oSettings->AdminLogin = $AdminLogin; |
1569: | } |
1570: | |
1571: | $sAdminPassword = $oSettings->GetValue('AdminPassword'); |
1572: | if ((empty($sAdminPassword) && empty($Password) || !empty($Password)) && !empty($NewPassword)) { |
1573: | if (empty($sAdminPassword) || crypt(trim($Password), \Aurora\System\Api::$sSalt) === $sAdminPassword) { |
1574: | $oSettings->AdminPassword = crypt(trim($NewPassword), \Aurora\System\Api::$sSalt); |
1575: | } else { |
1576: | throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Exceptions\Errs::UserManager_AccountOldPasswordNotCorrect); |
1577: | } |
1578: | } |
1579: | if ($AdminLanguage !== null) { |
1580: | $oSettings->AdminLanguage = $AdminLanguage; |
1581: | } |
1582: | if ($EnableLogging !== null) { |
1583: | $oSettings->EnableLogging = $EnableLogging; |
1584: | } |
1585: | if ($EnableEventLogging !== null) { |
1586: | $oSettings->EnableEventLogging = $EnableEventLogging; |
1587: | } |
1588: | if ($LoggingLevel !== null) { |
1589: | $oSettings->LoggingLevel = $LoggingLevel; |
1590: | } |
1591: | return $oSettings->Save(); |
1592: | } |
1593: | |
1594: | if ($oUser->isNormalOrTenant()) { |
1595: | if ($Language !== null) { |
1596: | $oUser->Language = $Language; |
1597: | } |
1598: | if ($TimeFormat !== null) { |
1599: | $oUser->TimeFormat = $TimeFormat; |
1600: | } |
1601: | if ($DateFormat !== null) { |
1602: | $oUser->DateFormat = $DateFormat; |
1603: | } |
1604: | return $this->UpdateUserObject($oUser); |
1605: | } |
1606: | |
1607: | return false; |
1608: | } |
1609: | |
1610: | public function UpdateLoggingSettings($EnableLogging = null, $EnableEventLogging = null, $LoggingLevel = null) |
1611: | { |
1612: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::SuperAdmin); |
1613: | |
1614: | $oSettings =&\Aurora\System\Api::GetSettings(); |
1615: | |
1616: | if ($EnableLogging !== null) { |
1617: | $oSettings->EnableLogging = $EnableLogging; |
1618: | } |
1619: | if ($EnableEventLogging !== null) { |
1620: | $oSettings->EnableEventLogging = $EnableEventLogging; |
1621: | } |
1622: | if ($LoggingLevel !== null) { |
1623: | $oSettings->LoggingLevel = $LoggingLevel; |
1624: | } |
1625: | |
1626: | return $oSettings->Save(); |
1627: | } |
1628: | |
1629: | |
1630: | |
1631: | |
1632: | |
1633: | |
1634: | |
1635: | public function SetMobile($Mobile) |
1636: | { |
1637: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous); |
1638: | $oApiIntegrator = $this->getIntegratorManager(); |
1639: | return $oApiIntegrator ? $oApiIntegrator->setMobile($Mobile) : false; |
1640: | } |
1641: | |
1642: | |
1643: | |
1644: | |
1645: | |
1646: | |
1647: | |
1648: | |
1649: | |
1650: | |
1651: | |
1652: | |
1653: | |
1654: | |
1655: | |
1656: | |
1657: | |
1658: | |
1659: | |
1660: | |
1661: | |
1662: | |
1663: | |
1664: | |
1665: | |
1666: | |
1667: | |
1668: | |
1669: | |
1670: | |
1671: | |
1672: | |
1673: | |
1674: | |
1675: | |
1676: | |
1677: | |
1678: | |
1679: | |
1680: | |
1681: | |
1682: | |
1683: | |
1684: | |
1685: | |
1686: | |
1687: | |
1688: | |
1689: | public function CreateTables() |
1690: | { |
1691: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::SuperAdmin); |
1692: | |
1693: | if (!function_exists('mysqli_fetch_all')) { |
1694: | throw new ApiException(0, null, 'Please make sure your PHP/MySQL environment meets the minimal system requirements.'); |
1695: | } |
1696: | |
1697: | $bResult = false; |
1698: | |
1699: | try { |
1700: | $container = \Aurora\Api::GetContainer(); |
1701: | |
1702: | $oPdo = $container['connection']->getPdo(); |
1703: | if ($oPdo && strpos($oPdo->getAttribute(\PDO::ATTR_CLIENT_VERSION), 'mysqlnd') === false) { |
1704: | throw new ApiException(Enums\ErrorCodes::MySqlConfigError); |
1705: | } |
1706: | |
1707: | $container['console']->setAutoExit(false); |
1708: | |
1709: | $container['console']->find('migrate') |
1710: | ->run(new ArrayInput([ |
1711: | '--force' => true, |
1712: | '--seed' => true |
1713: | ]), new NullOutput()); |
1714: | |
1715: | $bResult = true; |
1716: | } catch (\Exception $oEx) { |
1717: | \Aurora\System\Api::LogException($oEx); |
1718: | if ($oEx instanceof ApiException) { |
1719: | throw $oEx; |
1720: | } |
1721: | } |
1722: | |
1723: | return $bResult; |
1724: | } |
1725: | |
1726: | public function GetOrphans() |
1727: | { |
1728: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::SuperAdmin); |
1729: | |
1730: | $bResult = false; |
1731: | |
1732: | try { |
1733: | $container = \Aurora\Api::GetContainer(); |
1734: | $container['console']->setAutoExit(false); |
1735: | |
1736: | $output = new BufferedOutput(); |
1737: | $container['console']->find('get-orphans') |
1738: | ->run(new ArrayInput([]), $output); |
1739: | |
1740: | $content = array_filter(explode(PHP_EOL, $output->fetch())); |
1741: | $bResult = $content; |
1742: | } catch (\Exception $oEx) { |
1743: | \Aurora\System\Api::LogException($oEx); |
1744: | } |
1745: | |
1746: | return $bResult; |
1747: | } |
1748: | |
1749: | |
1750: | |
1751: | |
1752: | |
1753: | public function UpdateConfig() |
1754: | { |
1755: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::SuperAdmin); |
1756: | |
1757: | $bResult = true; |
1758: | try { |
1759: | \Aurora\System\Api::Init(); |
1760: | \Aurora\System\Api::GetModuleManager()->SyncModulesConfigs(); |
1761: | |
1762: | \Aurora\System\Api::GetSettings()->SyncConfigs(); |
1763: | } catch (\Exception $e) { |
1764: | $bResult = false; |
1765: | } |
1766: | |
1767: | return $bResult; |
1768: | } |
1769: | |
1770: | |
1771: | |
1772: | |
1773: | |
1774: | |
1775: | |
1776: | |
1777: | |
1778: | |
1779: | |
1780: | |
1781: | |
1782: | |
1783: | |
1784: | |
1785: | |
1786: | |
1787: | |
1788: | |
1789: | |
1790: | |
1791: | |
1792: | |
1793: | |
1794: | |
1795: | |
1796: | |
1797: | |
1798: | |
1799: | |
1800: | |
1801: | |
1802: | |
1803: | |
1804: | |
1805: | |
1806: | |
1807: | |
1808: | |
1809: | |
1810: | |
1811: | |
1812: | |
1813: | |
1814: | |
1815: | |
1816: | |
1817: | |
1818: | |
1819: | |
1820: | |
1821: | |
1822: | |
1823: | |
1824: | |
1825: | |
1826: | |
1827: | |
1828: | |
1829: | |
1830: | public function TestDbConnection($DbLogin, $DbName, $DbHost, $DbPassword = null) |
1831: | { |
1832: | Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::SuperAdmin); |
1833: | if (!function_exists('mysqli_fetch_all')) { |
1834: | throw new ApiException(0, null, 'Please make sure your PHP/MySQL environment meets the minimal system requirements.'); |
1835: | } |
1836: | $oPdo = null; |
1837: | $oSettings = &Api::GetSettings(); |
1838: | if ($oSettings) { |
1839: | if ($DbPassword === null) { |
1840: | $DbPassword = $oSettings->DBPassword; |
1841: | } |
1842: | $capsule = new \Illuminate\Database\Capsule\Manager(); |
1843: | $capsule->addConnection(Api::GetDbConfig( |
1844: | $oSettings->DBType, |
1845: | $DbHost, |
1846: | $DbName, |
1847: | $oSettings->DBPrefix, |
1848: | $DbLogin, |
1849: | $DbPassword |
1850: | )); |
1851: | $oPdo = $capsule->getConnection()->getPdo(); |
1852: | |
1853: | if ($oPdo && strpos($oPdo->getAttribute(\PDO::ATTR_CLIENT_VERSION), 'mysqlnd') === false) { |
1854: | throw new ApiException(Enums\ErrorCodes::MySqlConfigError); |
1855: | } |
1856: | } |
1857: | |
1858: | return isset($oPdo); |
1859: | } |
1860: | |
1861: | |
1862: | |
1863: | |
1864: | |
1865: | |
1866: | public function GetAuthenticatedAccount($AuthToken) |
1867: | { |
1868: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous); |
1869: | |
1870: | $aUserInfo = \Aurora\System\Api::getAuthenticatedUserInfo($AuthToken); |
1871: | $oAccount = call_user_func_array([$aUserInfo['accountType'], 'find'], [(int)$aUserInfo['account']]); |
1872: | |
1873: | return $oAccount; |
1874: | } |
1875: | |
1876: | |
1877: | |
1878: | |
1879: | |
1880: | |
1881: | |
1882: | |
1883: | public function GetAccounts($AuthToken, $Type = '') |
1884: | { |
1885: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous); |
1886: | |
1887: | $aArgs = array( |
1888: | 'AuthToken' => $AuthToken |
1889: | ); |
1890: | $aResult = []; |
1891: | |
1892: | $this->broadcastEvent( |
1893: | 'GetAccounts', |
1894: | $aArgs, |
1895: | $aResult |
1896: | ); |
1897: | if (!empty($Type)) { |
1898: | $aTempResult = []; |
1899: | foreach ($aResult as $aItem) { |
1900: | if ($aItem['Type'] === $Type) { |
1901: | $aTempResult[] = $aItem; |
1902: | } |
1903: | } |
1904: | $aResult = $aTempResult; |
1905: | } |
1906: | return $aResult; |
1907: | } |
1908: | |
1909: | public function IsBlockedUser($sEmail, $sIp) |
1910: | { |
1911: | $bEnableFailedLoginBlock = $this->getConfig('EnableFailedLoginBlock', false); |
1912: | $iLoginBlockAvailableTriesCount = $this->getConfig('LoginBlockAvailableTriesCount', 3); |
1913: | $iLoginBlockDurationMinutes = $this->getConfig('LoginBlockDurationMinutes', 30); |
1914: | |
1915: | if ($bEnableFailedLoginBlock) { |
1916: | try { |
1917: | $oBlockedUser = $this->GetBlockedUser($sEmail, $sIp); |
1918: | if ($oBlockedUser) { |
1919: | if ($oBlockedUser->ErrorLoginsCount >= $iLoginBlockAvailableTriesCount) { |
1920: | $iBlockTime = (time() - $oBlockedUser->Time) / 60; |
1921: | if ($iBlockTime > $iLoginBlockDurationMinutes) { |
1922: | $oBlockedUser->delete(); |
1923: | } else { |
1924: | throw new \Aurora\System\Exceptions\ApiException( |
1925: | 1000, |
1926: | null, |
1927: | $this->i18N("BLOCKED_USER_MESSAGE_ERROR", [ |
1928: | "N" => $iLoginBlockAvailableTriesCount, |
1929: | "M" => ceil($iLoginBlockDurationMinutes - $iBlockTime) |
1930: | ]) |
1931: | ); |
1932: | } |
1933: | } |
1934: | } |
1935: | } catch (\Aurora\System\Exceptions\DbException $oEx) { |
1936: | \Aurora\System\Api::LogException($oEx); |
1937: | } |
1938: | } |
1939: | } |
1940: | |
1941: | public function GetBlockedUser($sEmail, $sIp) |
1942: | { |
1943: | $mResult = false; |
1944: | |
1945: | if ($this->getConfig('EnableFailedLoginBlock', false)) { |
1946: | try { |
1947: | $mResult = Models\UserBlock::where('Email', $sEmail)->where('IpAddress', $sIp)->first(); |
1948: | } catch (\Exception $oEx) { |
1949: | $mResult = false; |
1950: | } |
1951: | } |
1952: | |
1953: | return $mResult; |
1954: | } |
1955: | |
1956: | public function BlockUser($sEmail, $sIp) |
1957: | { |
1958: | if ($this->getConfig('EnableFailedLoginBlock', false)) { |
1959: | $iLoginBlockAvailableTriesCount = $this->getConfig('LoginBlockAvailableTriesCount', 3); |
1960: | |
1961: | try { |
1962: | $oBlockedUser = $this->GetBlockedUser($sEmail, $sIp); |
1963: | if (!$oBlockedUser) { |
1964: | $oBlockedUser = new Models\UserBlock(); |
1965: | $oBlockedUser->Email = $sEmail; |
1966: | $oBlockedUser->IpAddress = $sIp; |
1967: | } |
1968: | $iUserId = Api::getUserIdByPublicId($sEmail); |
1969: | if ($iUserId && $oBlockedUser->ErrorLoginsCount < $iLoginBlockAvailableTriesCount) { |
1970: | $oBlockedUser->UserId = $iUserId; |
1971: | $oBlockedUser->ErrorLoginsCount = $oBlockedUser->ErrorLoginsCount + 1; |
1972: | $oBlockedUser->Time = time(); |
1973: | |
1974: | $oBlockedUser->save(); |
1975: | } |
1976: | } catch (\Exception $oEx) { |
1977: | \Aurora\System\Api::LogException($oEx); |
1978: | } |
1979: | } |
1980: | } |
1981: | |
1982: | |
1983: | |
1984: | |
1985: | public function Authenticate($Login, $Password, $SignMe = false) |
1986: | { |
1987: | $mResult = false; |
1988: | |
1989: | $aArgs = array( |
1990: | 'Login' => $Login, |
1991: | 'Password' => $Password, |
1992: | 'SignMe' => $SignMe |
1993: | ); |
1994: | |
1995: | try { |
1996: | $this->broadcastEvent( |
1997: | 'Login', |
1998: | $aArgs, |
1999: | $mResult |
2000: | ); |
2001: | } catch (\Exception $oException) { |
2002: | \Aurora\System\Api::GetModuleManager()->SetLastException($oException); |
2003: | } |
2004: | |
2005: | return $mResult; |
2006: | } |
2007: | |
2008: | public function SetAuthDataAndGetAuthToken($aAuthData, $Language = '', $SignMe = false) |
2009: | { |
2010: | $mResult = false; |
2011: | if ($aAuthData && is_array($aAuthData)) { |
2012: | $mResult = $aAuthData; |
2013: | if (isset($aAuthData['token'])) { |
2014: | $iTime = $SignMe ? 0 : time(); |
2015: | $iAuthTokenExpirationLifetimeDays = \Aurora\Api::GetSettings()->GetValue('AuthTokenExpirationLifetimeDays', 0); |
2016: | $iExpire = 0; |
2017: | if ($iAuthTokenExpirationLifetimeDays > 0) { |
2018: | $iExpire = time() + ($iAuthTokenExpirationLifetimeDays * 24 * 60 * 60); |
2019: | } |
2020: | |
2021: | $sAuthToken = \Aurora\System\Api::UserSession()->Set($aAuthData, $iTime, $iExpire); |
2022: | |
2023: | |
2024: | $oUser = \Aurora\System\Api::getAuthenticatedUser($sAuthToken); |
2025: | |
2026: | if ($oUser && $oUser->Role !== \Aurora\System\Enums\UserRole::SuperAdmin) { |
2027: | |
2028: | |
2029: | $oTenant = \Aurora\System\Api::getTenantByWebDomain(); |
2030: | if ($oTenant && $oUser->IdTenant !== $oTenant->Id) { |
2031: | throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::AuthError); |
2032: | } |
2033: | } |
2034: | |
2035: | if ($Language !== '' && $oUser && $oUser->Language !== $Language) { |
2036: | $oUser->Language = $Language; |
2037: | } |
2038: | |
2039: | $oUser->LastLogin = date('Y-m-d H:i:s'); |
2040: | $oUser->LoginsCount = $oUser->LoginsCount + 1; |
2041: | |
2042: | $this->getUsersManager()->updateUser($oUser); |
2043: | \Aurora\System\Api::LogEvent('login-success: ' . $oUser->PublicId, self::GetName()); |
2044: | $mResult = [ |
2045: | 'AuthToken' => $sAuthToken |
2046: | ]; |
2047: | } |
2048: | } else { |
2049: | \Aurora\System\Api::LogEvent('login-failed', self::GetName()); |
2050: | \Aurora\System\Api::GetModuleManager()->SetLastException( |
2051: | new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::AuthError) |
2052: | ); |
2053: | } |
2054: | |
2055: | return $mResult; |
2056: | } |
2057: | |
2058: | |
2059: | |
2060: | |
2061: | |
2062: | |
2063: | |
2064: | |
2065: | |
2066: | |
2067: | |
2068: | |
2069: | |
2070: | |
2071: | |
2072: | |
2073: | |
2074: | |
2075: | |
2076: | |
2077: | |
2078: | |
2079: | |
2080: | |
2081: | |
2082: | |
2083: | |
2084: | |
2085: | |
2086: | |
2087: | |
2088: | |
2089: | |
2090: | |
2091: | |
2092: | |
2093: | |
2094: | |
2095: | |
2096: | |
2097: | |
2098: | |
2099: | |
2100: | |
2101: | |
2102: | |
2103: | |
2104: | |
2105: | |
2106: | |
2107: | |
2108: | |
2109: | |
2110: | |
2111: | |
2112: | |
2113: | public function Login($Login, $Password, $Language = '', $SignMe = false) |
2114: | { |
2115: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous); |
2116: | |
2117: | $sIp = \Aurora\System\Utils::getClientIp(); |
2118: | $this->IsBlockedUser($Login, $sIp); |
2119: | |
2120: | $aAuthData = $this->Decorator()->Authenticate($Login, $Password, $SignMe); |
2121: | |
2122: | if (!$aAuthData) { |
2123: | $this->BlockUser($Login, $sIp); |
2124: | $this->IsBlockedUser($Login, $sIp); |
2125: | } else { |
2126: | $oBlockedUser = $this->GetBlockedUser($Login, $sIp); |
2127: | if ($oBlockedUser) { |
2128: | $oBlockedUser->delete(); |
2129: | } |
2130: | } |
2131: | return $this->Decorator()->SetAuthDataAndGetAuthToken($aAuthData, $Language, $SignMe); |
2132: | } |
2133: | |
2134: | |
2135: | |
2136: | |
2137: | |
2138: | |
2139: | |
2140: | |
2141: | public function GetDigestHash($Login, $Realm, $Type) |
2142: | { |
2143: | |
2144: | |
2145: | $mResult = null; |
2146: | |
2147: | $aArgs = array( |
2148: | 'Login' => $Login, |
2149: | 'Realm' => $Realm, |
2150: | 'Type' => $Type |
2151: | ); |
2152: | |
2153: | $this->broadcastEvent( |
2154: | 'GetDigestHash', |
2155: | $aArgs, |
2156: | $mResult |
2157: | ); |
2158: | |
2159: | return $mResult; |
2160: | } |
2161: | |
2162: | public function GetAccountUsedToAuthorize($Login) |
2163: | { |
2164: | |
2165: | |
2166: | $mResult = null; |
2167: | |
2168: | $aArgs = array( |
2169: | 'Login' => $Login |
2170: | ); |
2171: | |
2172: | $this->broadcastEvent( |
2173: | 'GetAccountUsedToAuthorize', |
2174: | $aArgs, |
2175: | $mResult |
2176: | ); |
2177: | |
2178: | return $mResult; |
2179: | } |
2180: | |
2181: | |
2182: | |
2183: | |
2184: | |
2185: | |
2186: | public function VerifyPassword($Password) |
2187: | { |
2188: | |
2189: | |
2190: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous); |
2191: | $mResult = false; |
2192: | $bResult = false; |
2193: | $sAuthToken = \Aurora\System\Api::getAuthToken(); |
2194: | $oApiIntegrator = $this->getIntegratorManager(); |
2195: | |
2196: | $aUserInfo = $oApiIntegrator->getAuthenticatedUserInfo($sAuthToken); |
2197: | if (isset($aUserInfo['account']) && isset($aUserInfo['accountType'])) { |
2198: | $r = new \ReflectionClass($aUserInfo['accountType']); |
2199: | $oQuery = $r->getMethod('query')->invoke(null); |
2200: | |
2201: | $oAccount = $oQuery->find($aUserInfo['account']); |
2202: | if ($oAccount) { |
2203: | $aArgs = array( |
2204: | 'Login' => $oAccount->getLogin(), |
2205: | 'Password' => $Password, |
2206: | 'SignMe' => false |
2207: | ); |
2208: | $this->broadcastEvent( |
2209: | 'Login', |
2210: | $aArgs, |
2211: | $mResult |
2212: | ); |
2213: | |
2214: | if (is_array($mResult) |
2215: | && isset($mResult['token']) |
2216: | && $mResult['token'] === 'auth' |
2217: | && isset($mResult['id']) |
2218: | ) { |
2219: | $UserId = \Aurora\System\Api::getAuthenticatedUserId(); |
2220: | if ($mResult['id'] === $UserId) { |
2221: | $bResult = true; |
2222: | } |
2223: | } |
2224: | } |
2225: | } |
2226: | |
2227: | return $bResult; |
2228: | } |
2229: | |
2230: | |
2231: | |
2232: | |
2233: | |
2234: | |
2235: | public function ResetPassword($email, $resetOption) |
2236: | { |
2237: | $mResult = false; |
2238: | |
2239: | $aArgs = array( |
2240: | 'email' => $email, |
2241: | 'resetOption' => $resetOption |
2242: | ); |
2243: | $this->broadcastEvent( |
2244: | 'ResetPassword', |
2245: | $aArgs, |
2246: | $mResult |
2247: | ); |
2248: | |
2249: | |
2250: | if (!empty($mResult)) { |
2251: | \Aurora\System\Api::LogEvent('resetPassword-success: ' . $email, self::GetName()); |
2252: | } else { |
2253: | \Aurora\System\Api::LogEvent('resetPassword-failed: ' . $email, self::GetName()); |
2254: | } |
2255: | |
2256: | return $mResult; |
2257: | } |
2258: | |
2259: | |
2260: | public function ResetPasswordBySecurityQuestion($securityAnswer, $securityToken) |
2261: | { |
2262: | $mResult = false; |
2263: | |
2264: | $aArgs = array( |
2265: | 'securityAnswer' => $securityAnswer, |
2266: | 'securityToken' => $securityToken |
2267: | ); |
2268: | $this->broadcastEvent( |
2269: | 'ResetPasswordBySecurityQuestion', |
2270: | $aArgs, |
2271: | $mResult |
2272: | ); |
2273: | |
2274: | |
2275: | if (!empty($mResult)) { |
2276: | \Aurora\System\Api::LogEvent('ResetPasswordBySecurityQuestion-success: ' . $securityAnswer, self::GetName()); |
2277: | return $mResult; |
2278: | } |
2279: | |
2280: | \Aurora\System\Api::LogEvent('ResetPasswordBySecurityQuestion-failed: ' . $securityAnswer, self::GetName()); |
2281: | } |
2282: | |
2283: | public function UpdatePassword($Password, $ConfirmPassword, $Hash) |
2284: | { |
2285: | $mResult = false; |
2286: | |
2287: | $aArgs = array( |
2288: | 'Password' => $Password, |
2289: | 'ConfirmPassword' => $ConfirmPassword, |
2290: | 'Hash' => $Hash |
2291: | ); |
2292: | $this->broadcastEvent( |
2293: | 'UpdatePassword', |
2294: | $aArgs, |
2295: | $mResult |
2296: | ); |
2297: | |
2298: | if (!empty($mResult)) { |
2299: | \Aurora\System\Api::LogEvent('updatePassword-success: ' . $Hash, self::GetName()); |
2300: | return $mResult; |
2301: | } |
2302: | |
2303: | \Aurora\System\Api::LogEvent('updatePassword-failed: ' . $Hash, self::GetName()); |
2304: | } |
2305: | |
2306: | |
2307: | |
2308: | |
2309: | |
2310: | |
2311: | |
2312: | |
2313: | |
2314: | |
2315: | |
2316: | |
2317: | |
2318: | |
2319: | |
2320: | |
2321: | |
2322: | |
2323: | |
2324: | |
2325: | |
2326: | |
2327: | |
2328: | |
2329: | |
2330: | |
2331: | |
2332: | |
2333: | |
2334: | |
2335: | |
2336: | |
2337: | |
2338: | |
2339: | |
2340: | |
2341: | |
2342: | |
2343: | |
2344: | |
2345: | |
2346: | |
2347: | |
2348: | |
2349: | |
2350: | |
2351: | |
2352: | |
2353: | |
2354: | public function Logout() |
2355: | { |
2356: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous); |
2357: | |
2358: | \Aurora\System\Api::LogEvent('logout', self::GetName()); |
2359: | |
2360: | \Aurora\System\Api::UserSession()->Delete( |
2361: | \Aurora\System\Api::getAuthToken() |
2362: | ); |
2363: | |
2364: | |
2365: | return true; |
2366: | } |
2367: | |
2368: | |
2369: | |
2370: | |
2371: | public function GetEntityList($Type, $Offset = 0, $Limit = 0, $Search = '', $TenantId = 0, $Filters = []) |
2372: | { |
2373: | switch ($Type) { |
2374: | case 'Tenant': |
2375: | return self::Decorator()->GetTenants($Offset, $Limit, $Search); |
2376: | case 'User': |
2377: | return self::Decorator()->GetUsers($TenantId, $Offset, $Limit, 'PublicId', \Aurora\System\Enums\SortOrder::ASC, $Search, $Filters); |
2378: | } |
2379: | return null; |
2380: | } |
2381: | |
2382: | |
2383: | |
2384: | |
2385: | public function GetEntity($Type, $Id) |
2386: | { |
2387: | switch ($Type) { |
2388: | case 'Tenant': |
2389: | return self::Decorator()->GetTenant($Id); |
2390: | case 'User': |
2391: | return self::Decorator()->GetUser($Id); |
2392: | } |
2393: | return null; |
2394: | } |
2395: | |
2396: | |
2397: | |
2398: | |
2399: | |
2400: | |
2401: | |
2402: | |
2403: | |
2404: | public function CreateChannel($Login, $Description = '') |
2405: | { |
2406: | $mResult = -1; |
2407: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::SuperAdmin); |
2408: | |
2409: | $mResult = false; |
2410: | |
2411: | $Login = \trim($Login); |
2412: | if ($Login !== '') { |
2413: | $oChannel = new Models\Channel(); |
2414: | |
2415: | $oChannel->Login = $Login; |
2416: | |
2417: | if ($Description !== '') { |
2418: | $oChannel->Description = $Description; |
2419: | } |
2420: | |
2421: | if ($this->getChannelsManager()->createChannel($oChannel)) { |
2422: | $mResult = $oChannel->Id; |
2423: | } |
2424: | } else { |
2425: | throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::InvalidInputParameter); |
2426: | } |
2427: | |
2428: | return $mResult; |
2429: | } |
2430: | |
2431: | |
2432: | |
2433: | |
2434: | |
2435: | |
2436: | |
2437: | |
2438: | |
2439: | |
2440: | public function UpdateChannel($ChannelId, $Login = '', $Description = '') |
2441: | { |
2442: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::SuperAdmin); |
2443: | |
2444: | if ($ChannelId > 0) { |
2445: | $oChannel = $this->getChannelsManager()->getChannelById($ChannelId); |
2446: | |
2447: | if ($oChannel) { |
2448: | $Login = \trim($Login); |
2449: | if (!empty($Login)) { |
2450: | $oChannel->Login = $Login; |
2451: | } |
2452: | if (!empty($Description)) { |
2453: | $oChannel->Description = $Description; |
2454: | } |
2455: | |
2456: | return $this->getChannelsManager()->updateChannel($oChannel); |
2457: | } |
2458: | } else { |
2459: | throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::InvalidInputParameter); |
2460: | } |
2461: | |
2462: | return false; |
2463: | } |
2464: | |
2465: | |
2466: | |
2467: | |
2468: | |
2469: | |
2470: | |
2471: | |
2472: | public function DeleteChannel($ChannelId) |
2473: | { |
2474: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::SuperAdmin); |
2475: | |
2476: | if ($ChannelId > 0) { |
2477: | $oChannel = $this->getChannelsManager()->getChannelById($ChannelId); |
2478: | |
2479: | if ($oChannel) { |
2480: | return $this->getChannelsManager()->deleteChannel($oChannel); |
2481: | } |
2482: | } else { |
2483: | throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::InvalidInputParameter); |
2484: | } |
2485: | |
2486: | return false; |
2487: | } |
2488: | |
2489: | |
2490: | |
2491: | |
2492: | |
2493: | |
2494: | |
2495: | |
2496: | |
2497: | |
2498: | |
2499: | |
2500: | |
2501: | |
2502: | |
2503: | |
2504: | |
2505: | |
2506: | |
2507: | |
2508: | |
2509: | |
2510: | |
2511: | |
2512: | |
2513: | |
2514: | |
2515: | |
2516: | |
2517: | |
2518: | |
2519: | |
2520: | |
2521: | |
2522: | |
2523: | |
2524: | |
2525: | |
2526: | |
2527: | |
2528: | |
2529: | |
2530: | |
2531: | |
2532: | |
2533: | |
2534: | |
2535: | |
2536: | |
2537: | |
2538: | |
2539: | |
2540: | |
2541: | |
2542: | |
2543: | |
2544: | |
2545: | |
2546: | |
2547: | |
2548: | |
2549: | |
2550: | |
2551: | |
2552: | |
2553: | public function GetTenants($Offset = 0, $Limit = 0, $Search = '') |
2554: | { |
2555: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::TenantAdmin); |
2556: | |
2557: | $oAuthenticatedUser = \Aurora\System\Api::getAuthenticatedUser(); |
2558: | $bTenant = $oAuthenticatedUser->Role === \Aurora\System\Enums\UserRole::TenantAdmin; |
2559: | |
2560: | $aTenantsFromDb = $this->getTenantsManager()->getTenantList($Offset, $Limit, $Search); |
2561: | $oSettings = $this->GetModuleSettings(); |
2562: | $aTenants = []; |
2563: | |
2564: | foreach ($aTenantsFromDb as $oTenant) { |
2565: | if (!$bTenant || $oTenant->Id === $oAuthenticatedUser->IdTenant) { |
2566: | $aTenants[] = [ |
2567: | 'Id' => $oTenant->Id, |
2568: | 'Name' => $oTenant->Name, |
2569: | 'SiteName' => $oSettings->GetTenantValue($oTenant->Name, 'SiteName', '') |
2570: | ]; |
2571: | } |
2572: | } |
2573: | |
2574: | $iTenantsCount = $Limit > 0 ? $this->getTenantsManager()->getTenantsCount($Search) : count($aTenantsFromDb); |
2575: | return array( |
2576: | 'Items' => $aTenants, |
2577: | 'Count' => $iTenantsCount, |
2578: | ); |
2579: | } |
2580: | |
2581: | |
2582: | |
2583: | |
2584: | public function GetTenantList($Offset = 0, $Limit = 0, $Search = '') |
2585: | { |
2586: | return self::Decorator()->GetTenants($Offset, $Limit, $Search); |
2587: | } |
2588: | |
2589: | |
2590: | |
2591: | |
2592: | |
2593: | |
2594: | |
2595: | |
2596: | |
2597: | |
2598: | |
2599: | |
2600: | |
2601: | |
2602: | |
2603: | |
2604: | |
2605: | |
2606: | |
2607: | |
2608: | |
2609: | |
2610: | |
2611: | |
2612: | |
2613: | |
2614: | |
2615: | |
2616: | |
2617: | |
2618: | |
2619: | |
2620: | |
2621: | |
2622: | |
2623: | |
2624: | |
2625: | |
2626: | |
2627: | |
2628: | |
2629: | |
2630: | |
2631: | |
2632: | |
2633: | |
2634: | |
2635: | |
2636: | |
2637: | |
2638: | |
2639: | |
2640: | |
2641: | |
2642: | public function GetTenant($Id) |
2643: | { |
2644: | $oAuthenticatedUser = \Aurora\System\Api::getAuthenticatedUser(); |
2645: | if (!empty($oAuthenticatedUser) && $oAuthenticatedUser->Role === \Aurora\System\Enums\UserRole::TenantAdmin && $oAuthenticatedUser->IdTenant === $Id) { |
2646: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::TenantAdmin); |
2647: | } else { |
2648: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::SuperAdmin); |
2649: | } |
2650: | |
2651: | return $this->GetTenantUnchecked($Id); |
2652: | } |
2653: | |
2654: | |
2655: | |
2656: | |
2657: | |
2658: | |
2659: | |
2660: | |
2661: | |
2662: | |
2663: | |
2664: | |
2665: | |
2666: | |
2667: | |
2668: | |
2669: | |
2670: | |
2671: | |
2672: | |
2673: | |
2674: | |
2675: | |
2676: | |
2677: | |
2678: | |
2679: | |
2680: | |
2681: | |
2682: | |
2683: | |
2684: | |
2685: | |
2686: | |
2687: | |
2688: | |
2689: | |
2690: | |
2691: | |
2692: | |
2693: | |
2694: | |
2695: | |
2696: | |
2697: | |
2698: | |
2699: | |
2700: | |
2701: | |
2702: | |
2703: | |
2704: | |
2705: | |
2706: | |
2707: | |
2708: | |
2709: | |
2710: | |
2711: | |
2712: | |
2713: | |
2714: | |
2715: | |
2716: | public function CreateTenant($ChannelId = 0, $Name = '', $Description = '', $WebDomain = '', $SiteName = null) |
2717: | { |
2718: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::SuperAdmin); |
2719: | |
2720: | $oSettings =&\Aurora\System\Api::GetSettings(); |
2721: | if ($ChannelId === 0) { |
2722: | $aChannels = $this->getChannelsManager()->getChannelList(0, 1); |
2723: | $ChannelId = count($aChannels) === 1 ? $aChannels[0]->Id : 0; |
2724: | } |
2725: | $Name = \trim(\Aurora\System\Utils::getSanitizedFilename($Name)); |
2726: | |
2727: | if ($Name !== '' && $ChannelId > 0) { |
2728: | $iTenantsCount = $this->getTenantsManager()->getTenantsByChannelIdCount($ChannelId); |
2729: | if ($oSettings->GetValue('EnableMultiTenant') || $iTenantsCount === 0) { |
2730: | $oTenant = new Models\Tenant(); |
2731: | |
2732: | $oTenant->Name = $Name; |
2733: | $oTenant->Description = $Description; |
2734: | $oTenant->WebDomain = $WebDomain; |
2735: | $oTenant->IdChannel = $ChannelId; |
2736: | |
2737: | if ($this->getTenantsManager()->createTenant($oTenant)) { |
2738: | if ($SiteName !== null) { |
2739: | $oSettings = $this->GetModuleSettings(); |
2740: | $oSettings->SetTenantValue($oTenant->Name, 'SiteName', $SiteName); |
2741: | $oSettings->SaveTenantSettings($oTenant->Name); |
2742: | } |
2743: | return $oTenant->Id; |
2744: | } |
2745: | } |
2746: | } else { |
2747: | throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::InvalidInputParameter); |
2748: | } |
2749: | |
2750: | return false; |
2751: | } |
2752: | |
2753: | |
2754: | |
2755: | |
2756: | |
2757: | |
2758: | |
2759: | |
2760: | |
2761: | |
2762: | |
2763: | |
2764: | |
2765: | |
2766: | |
2767: | |
2768: | |
2769: | |
2770: | |
2771: | |
2772: | |
2773: | |
2774: | |
2775: | |
2776: | |
2777: | |
2778: | |
2779: | |
2780: | |
2781: | |
2782: | |
2783: | |
2784: | |
2785: | |
2786: | |
2787: | |
2788: | |
2789: | |
2790: | |
2791: | |
2792: | |
2793: | |
2794: | |
2795: | |
2796: | |
2797: | |
2798: | |
2799: | |
2800: | |
2801: | |
2802: | |
2803: | |
2804: | |
2805: | |
2806: | |
2807: | |
2808: | |
2809: | |
2810: | |
2811: | |
2812: | |
2813: | |
2814: | |
2815: | public function UpdateTenant($TenantId, $Description = null, $WebDomain = null, $SiteName = null, $ChannelId = 0) |
2816: | { |
2817: | $oAuthenticatedUser = \Aurora\System\Api::getAuthenticatedUser(); |
2818: | if ($oAuthenticatedUser->Role === \Aurora\System\Enums\UserRole::TenantAdmin && $oAuthenticatedUser->IdTenant === $TenantId) { |
2819: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::TenantAdmin); |
2820: | } else { |
2821: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::SuperAdmin); |
2822: | } |
2823: | |
2824: | if (!empty($TenantId)) { |
2825: | $oTenant = $this->getTenantsManager()->getTenantById($TenantId); |
2826: | if ($oTenant) { |
2827: | if ($SiteName !== null) { |
2828: | $oSettings = $this->GetModuleSettings(); |
2829: | $oSettings->SetTenantValue($oTenant->Name, 'SiteName', $SiteName); |
2830: | $oSettings->SaveTenantSettings($oTenant->Name); |
2831: | } |
2832: | if ($Description !== null) { |
2833: | $oTenant->Description = $Description; |
2834: | } |
2835: | if ($WebDomain !== null && $oAuthenticatedUser->Role === \Aurora\System\Enums\UserRole::SuperAdmin) { |
2836: | $oTenant->WebDomain = $WebDomain; |
2837: | } |
2838: | if (!empty($ChannelId) && $oAuthenticatedUser->Role === \Aurora\System\Enums\UserRole::SuperAdmin) { |
2839: | $oTenant->IdChannel = $ChannelId; |
2840: | } |
2841: | |
2842: | return $this->getTenantsManager()->updateTenant($oTenant); |
2843: | } |
2844: | } else { |
2845: | throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::InvalidInputParameter); |
2846: | } |
2847: | |
2848: | return false; |
2849: | } |
2850: | |
2851: | |
2852: | |
2853: | |
2854: | |
2855: | |
2856: | |
2857: | |
2858: | |
2859: | |
2860: | |
2861: | |
2862: | |
2863: | |
2864: | |
2865: | |
2866: | |
2867: | |
2868: | |
2869: | |
2870: | |
2871: | |
2872: | |
2873: | |
2874: | |
2875: | |
2876: | |
2877: | |
2878: | |
2879: | |
2880: | |
2881: | |
2882: | |
2883: | |
2884: | |
2885: | |
2886: | |
2887: | |
2888: | |
2889: | |
2890: | |
2891: | |
2892: | |
2893: | |
2894: | |
2895: | |
2896: | |
2897: | |
2898: | |
2899: | |
2900: | |
2901: | |
2902: | |
2903: | public function DeleteTenants($IdList) |
2904: | { |
2905: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::SuperAdmin); |
2906: | |
2907: | $bResult = true; |
2908: | |
2909: | foreach ($IdList as $sId) { |
2910: | $bResult = $bResult && self::Decorator()->DeleteTenant($sId); |
2911: | } |
2912: | |
2913: | return $bResult; |
2914: | } |
2915: | |
2916: | |
2917: | |
2918: | |
2919: | |
2920: | |
2921: | |
2922: | |
2923: | |
2924: | |
2925: | |
2926: | |
2927: | |
2928: | |
2929: | |
2930: | |
2931: | |
2932: | |
2933: | |
2934: | |
2935: | |
2936: | |
2937: | |
2938: | |
2939: | |
2940: | |
2941: | |
2942: | |
2943: | |
2944: | |
2945: | |
2946: | |
2947: | |
2948: | |
2949: | |
2950: | |
2951: | |
2952: | |
2953: | |
2954: | |
2955: | |
2956: | |
2957: | |
2958: | |
2959: | |
2960: | |
2961: | |
2962: | |
2963: | |
2964: | |
2965: | |
2966: | |
2967: | |
2968: | |
2969: | |
2970: | public function DeleteTenant($TenantId) |
2971: | { |
2972: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::SuperAdmin); |
2973: | |
2974: | if (!empty($TenantId)) { |
2975: | $oTenant = $this->getTenantsManager()->getTenantById($TenantId); |
2976: | |
2977: | if ($oTenant) { |
2978: | |
2979: | $sTenantSpacePath = \Aurora\System\Api::GetModuleManager()->GetModulesSettingsPath().'tenants/'.$oTenant->Name; |
2980: | if (@is_dir($sTenantSpacePath)) { |
2981: | $this->deleteTree($sTenantSpacePath); |
2982: | } |
2983: | |
2984: | |
2985: | return $this->getTenantsManager()->deleteTenant($oTenant); |
2986: | } |
2987: | } else { |
2988: | throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::InvalidInputParameter); |
2989: | } |
2990: | |
2991: | return false; |
2992: | } |
2993: | |
2994: | |
2995: | |
2996: | |
2997: | |
2998: | |
2999: | |
3000: | |
3001: | |
3002: | |
3003: | |
3004: | |
3005: | |
3006: | |
3007: | |
3008: | |
3009: | |
3010: | |
3011: | |
3012: | |
3013: | |
3014: | |
3015: | |
3016: | |
3017: | |
3018: | |
3019: | |
3020: | |
3021: | |
3022: | |
3023: | |
3024: | |
3025: | |
3026: | |
3027: | |
3028: | |
3029: | |
3030: | |
3031: | |
3032: | |
3033: | |
3034: | |
3035: | |
3036: | |
3037: | |
3038: | |
3039: | |
3040: | |
3041: | |
3042: | |
3043: | |
3044: | |
3045: | |
3046: | |
3047: | |
3048: | |
3049: | |
3050: | |
3051: | |
3052: | |
3053: | |
3054: | |
3055: | |
3056: | |
3057: | |
3058: | |
3059: | |
3060: | |
3061: | |
3062: | |
3063: | |
3064: | |
3065: | |
3066: | public function GetUsers($TenantId = 0, $Offset = 0, $Limit = 0, $OrderBy = 'PublicId', $OrderType = \Aurora\System\Enums\SortOrder::ASC, $Search = '', $Filters = null, $GroupId = -1) |
3067: | { |
3068: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::TenantAdmin); |
3069: | |
3070: | $oAuthenticatedUser = \Aurora\System\Api::getAuthenticatedUser(); |
3071: | if ($oAuthenticatedUser->Role === \Aurora\System\Enums\UserRole::TenantAdmin && $oAuthenticatedUser->IdTenant === $TenantId) { |
3072: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::TenantAdmin); |
3073: | } else { |
3074: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::SuperAdmin); |
3075: | } |
3076: | |
3077: | $aResult = [ |
3078: | 'Items' => [], |
3079: | 'Count' => 0, |
3080: | ]; |
3081: | |
3082: | $Filters = ($Filters instanceof Builder) ? $Filters : Models\User::query(); |
3083: | if ($TenantId !== 0) { |
3084: | $Filters = $Filters->where('IdTenant', $TenantId); |
3085: | } |
3086: | |
3087: | $aResult['Count'] = $this->getUsersManager()->getUsersCount($Search, $Filters, $GroupId); |
3088: | $aUsers = $this->getUsersManager()->getUserList($Offset, $Limit, $OrderBy, $OrderType, $Search, $Filters, $GroupId); |
3089: | foreach ($aUsers as $oUser) { |
3090: | $aGroups = []; |
3091: | if ($this->getConfig('AllowGroups', false)) { |
3092: | foreach ($oUser->Groups as $oGroup) { |
3093: | if (!$oGroup->IsAll) { |
3094: | $aGroups[] = [ |
3095: | 'Id' => $oGroup->Id, |
3096: | 'TenantId' => $oGroup->TenantId, |
3097: | 'Name' => $oGroup->Name |
3098: | ]; |
3099: | } |
3100: | } |
3101: | } |
3102: | $aResult['Items'][] = [ |
3103: | 'Id' => $oUser->Id, |
3104: | 'UUID' => $oUser->UUID, |
3105: | 'Name' => $oUser->Name, |
3106: | 'PublicId' => $oUser->PublicId, |
3107: | 'Role' => $oUser->Role, |
3108: | 'Groups' => $aGroups |
3109: | ]; |
3110: | } |
3111: | |
3112: | return $aResult; |
3113: | } |
3114: | |
3115: | |
3116: | |
3117: | |
3118: | public function GetUserList($TenantId = 0, $Offset = 0, $Limit = 0, $OrderBy = 'PublicId', $OrderType = \Aurora\System\Enums\SortOrder::ASC, $Search = '', $Filters = []) |
3119: | { |
3120: | return self::Decorator()->GetUsers($TenantId, $Offset, $Limit, $OrderBy, $OrderType, $Search, $Filters); |
3121: | } |
3122: | |
3123: | public function GetTotalUsersCount() |
3124: | { |
3125: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::TenantAdmin); |
3126: | |
3127: | return $this->getUsersManager()->getTotalUsersCount(); |
3128: | } |
3129: | |
3130: | |
3131: | |
3132: | |
3133: | |
3134: | |
3135: | |
3136: | |
3137: | |
3138: | |
3139: | |
3140: | |
3141: | |
3142: | |
3143: | |
3144: | |
3145: | |
3146: | |
3147: | |
3148: | |
3149: | |
3150: | |
3151: | |
3152: | |
3153: | |
3154: | |
3155: | |
3156: | |
3157: | |
3158: | |
3159: | |
3160: | |
3161: | |
3162: | |
3163: | |
3164: | |
3165: | |
3166: | |
3167: | |
3168: | |
3169: | |
3170: | |
3171: | |
3172: | |
3173: | |
3174: | |
3175: | |
3176: | |
3177: | |
3178: | |
3179: | |
3180: | |
3181: | |
3182: | |
3183: | |
3184: | |
3185: | |
3186: | |
3187: | |
3188: | public function GetUser($Id = '') |
3189: | { |
3190: | $oUser = $this->getUsersManager()->getUser($Id); |
3191: | $oAuthenticatedUser = \Aurora\System\Api::getAuthenticatedUser(); |
3192: | |
3193: | if (!empty($oUser)) { |
3194: | if (!empty($oAuthenticatedUser) && $oAuthenticatedUser->Role === \Aurora\System\Enums\UserRole::NormalUser && $oAuthenticatedUser->Id === $oUser->Id) { |
3195: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
3196: | } elseif (!empty($oAuthenticatedUser) && $oAuthenticatedUser->Role === \Aurora\System\Enums\UserRole::TenantAdmin && $oAuthenticatedUser->IdTenant === $oUser->IdTenant) { |
3197: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::TenantAdmin); |
3198: | } else { |
3199: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::SuperAdmin); |
3200: | } |
3201: | |
3202: | return $oUser; |
3203: | } |
3204: | |
3205: | return null; |
3206: | } |
3207: | |
3208: | public function TurnOffSeparateLogs() |
3209: | { |
3210: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::TenantAdmin); |
3211: | |
3212: | $aResults = $this->getUsersManager()->getUserList(0, 0, 'PublicId', \Aurora\System\Enums\SortOrder::ASC, '', User::where('WriteSeparateLog', true)); |
3213: | foreach ($aResults as $aUser) { |
3214: | $oUser = self::Decorator()->GetUser($aUser['EntityId']); |
3215: | if ($oUser) { |
3216: | $oUser->WriteSeparateLog = false; |
3217: | $this->UpdateUserObject($oUser); |
3218: | } |
3219: | } |
3220: | |
3221: | return true; |
3222: | } |
3223: | |
3224: | public function ClearSeparateLogs() |
3225: | { |
3226: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::TenantAdmin); |
3227: | |
3228: | \Aurora\System\Api::RemoveSeparateLogs(); |
3229: | |
3230: | return true; |
3231: | } |
3232: | |
3233: | public function GetUsersWithSeparateLog() |
3234: | { |
3235: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::TenantAdmin); |
3236: | |
3237: | $aResults = $this->getUsersManager()->getUserList(0, 0, 'PublicId', \Aurora\System\Enums\SortOrder::ASC, '', Models\User::where('WriteSeparateLog', true)); |
3238: | $aUsers = []; |
3239: | foreach ($aResults as $aUser) { |
3240: | $aUsers[] = $aUser['PublicId']; |
3241: | } |
3242: | return $aUsers; |
3243: | } |
3244: | |
3245: | |
3246: | |
3247: | |
3248: | |
3249: | |
3250: | |
3251: | |
3252: | |
3253: | |
3254: | |
3255: | |
3256: | |
3257: | |
3258: | |
3259: | |
3260: | |
3261: | |
3262: | |
3263: | |
3264: | |
3265: | |
3266: | |
3267: | |
3268: | |
3269: | |
3270: | |
3271: | |
3272: | |
3273: | |
3274: | |
3275: | |
3276: | |
3277: | |
3278: | |
3279: | |
3280: | |
3281: | |
3282: | |
3283: | |
3284: | |
3285: | |
3286: | |
3287: | |
3288: | |
3289: | |
3290: | |
3291: | |
3292: | |
3293: | |
3294: | |
3295: | |
3296: | |
3297: | |
3298: | |
3299: | |
3300: | |
3301: | |
3302: | |
3303: | |
3304: | public function CreateUser($TenantId = 0, $PublicId = '', $Role = \Aurora\System\Enums\UserRole::NormalUser, $WriteSeparateLog = false) |
3305: | { |
3306: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::TenantAdmin); |
3307: | |
3308: | if (!\Aurora\System\Enums\UserRole::validateValue($Role)) { |
3309: | throw new ApiException(Notifications::InvalidInputParameter); |
3310: | } |
3311: | |
3312: | if ($TenantId === 0) { |
3313: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::SuperAdmin); |
3314: | $aTenants = $this->getTenantsManager()->getTenantList(0, 1, ''); |
3315: | $TenantId = count($aTenants) === 1 ? $aTenants[0]->Id : 0; |
3316: | } |
3317: | |
3318: | $oAuthenticatedUser = \Aurora\System\Api::getAuthenticatedUser(); |
3319: | if (!empty($oAuthenticatedUser) && $oAuthenticatedUser->Role === \Aurora\System\Enums\UserRole::TenantAdmin && $oAuthenticatedUser->IdTenant === $TenantId) { |
3320: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::TenantAdmin); |
3321: | } else { |
3322: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::SuperAdmin); |
3323: | } |
3324: | |
3325: | $oTenant = $this->getTenantsManager()->getTenantById($TenantId); |
3326: | if (!$oTenant) { |
3327: | throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::InvalidInputParameter); |
3328: | } |
3329: | |
3330: | $PublicId = \trim($PublicId); |
3331: | if (substr_count($PublicId, '@') > 1) { |
3332: | throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::InvalidInputParameter); |
3333: | } |
3334: | |
3335: | if (!empty($TenantId) && !empty($PublicId)) { |
3336: | $oUser = $this->getUsersManager()->getUserByPublicId($PublicId); |
3337: | if ($oUser instanceof \Aurora\Modules\Core\Models\User) { |
3338: | throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::UserAlreadyExists); |
3339: | } else { |
3340: | $oLicense = \Aurora\System\Api::GetModuleDecorator('Licensing'); |
3341: | if ($oLicense instanceof \Aurora\System\Module\Decorator) { |
3342: | if (!$oLicense->ValidateUsersCount($this->GetTotalUsersCount()) || !$oLicense->ValidatePeriod()) { |
3343: | \Aurora\System\Api::Log("Error: License limit"); |
3344: | throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::LicenseLimit); |
3345: | } |
3346: | } |
3347: | } |
3348: | |
3349: | $oUser = new Models\User(); |
3350: | |
3351: | $oUser->PublicId = $PublicId; |
3352: | $oUser->IdTenant = $TenantId; |
3353: | $oUser->Role = $Role; |
3354: | $oUser->WriteSeparateLog = $WriteSeparateLog; |
3355: | |
3356: | $oUser->Language = \Aurora\System\Api::GetLanguage(true); |
3357: | $oUser->TimeFormat = self::getInstance()->getConfig('TimeFormat'); |
3358: | $oUser->DateFormat = self::getInstance()->getConfig('DateFormat'); |
3359: | $oUser->DefaultTimeZone = ''; |
3360: | |
3361: | if ($this->getUsersManager()->createUser($oUser)) { |
3362: | return $oUser->Id; |
3363: | } |
3364: | } else { |
3365: | throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::InvalidInputParameter); |
3366: | } |
3367: | |
3368: | return false; |
3369: | } |
3370: | |
3371: | |
3372: | |
3373: | |
3374: | |
3375: | |
3376: | |
3377: | |
3378: | |
3379: | |
3380: | |
3381: | |
3382: | |
3383: | |
3384: | |
3385: | |
3386: | |
3387: | |
3388: | |
3389: | |
3390: | |
3391: | |
3392: | |
3393: | |
3394: | |
3395: | |
3396: | |
3397: | |
3398: | |
3399: | |
3400: | |
3401: | |
3402: | |
3403: | |
3404: | |
3405: | |
3406: | |
3407: | |
3408: | |
3409: | |
3410: | |
3411: | |
3412: | |
3413: | |
3414: | |
3415: | |
3416: | |
3417: | |
3418: | |
3419: | |
3420: | |
3421: | |
3422: | |
3423: | |
3424: | |
3425: | |
3426: | |
3427: | |
3428: | |
3429: | |
3430: | |
3431: | |
3432: | public function UpdateUser($UserId, $PublicId = '', $TenantId = 0, $Role = -1, $WriteSeparateLog = null, $GroupIds = null) |
3433: | { |
3434: | $PublicId = \trim($PublicId); |
3435: | if (!empty($PublicId) && empty($TenantId) && $UserId === \Aurora\System\Api::getAuthenticatedUserId()) { |
3436: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
3437: | } else { |
3438: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::TenantAdmin); |
3439: | } |
3440: | |
3441: | if ($UserId > 0) { |
3442: | $oUser = $this->getUsersManager()->getUser($UserId); |
3443: | |
3444: | if ($oUser) { |
3445: | \Aurora\System\Api::checkUserAccess($oUser); |
3446: | |
3447: | if (!empty($PublicId)) { |
3448: | $oUser->PublicId = $PublicId; |
3449: | } |
3450: | if (!empty($TenantId)) { |
3451: | $oUser->IdTenant = $TenantId; |
3452: | } |
3453: | if (\Aurora\System\Enums\UserRole::validateValue($Role)) { |
3454: | $oUser->Role = $Role; |
3455: | } |
3456: | if ($WriteSeparateLog !== null) { |
3457: | $oUser->WriteSeparateLog = $WriteSeparateLog; |
3458: | } |
3459: | |
3460: | $mResult = $this->getUsersManager()->updateUser($oUser); |
3461: | if ($mResult && $this->getConfig('AllowGroups', false) && $GroupIds !== null) { |
3462: | self::Decorator()->UpdateUserGroups($UserId, $GroupIds); |
3463: | } |
3464: | |
3465: | return $mResult; |
3466: | } |
3467: | } else { |
3468: | throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::InvalidInputParameter); |
3469: | } |
3470: | |
3471: | return false; |
3472: | } |
3473: | |
3474: | |
3475: | |
3476: | |
3477: | |
3478: | |
3479: | |
3480: | |
3481: | |
3482: | |
3483: | |
3484: | |
3485: | |
3486: | |
3487: | |
3488: | |
3489: | |
3490: | |
3491: | |
3492: | |
3493: | |
3494: | |
3495: | |
3496: | |
3497: | |
3498: | |
3499: | |
3500: | |
3501: | |
3502: | |
3503: | |
3504: | |
3505: | |
3506: | |
3507: | |
3508: | |
3509: | |
3510: | |
3511: | |
3512: | |
3513: | |
3514: | |
3515: | |
3516: | |
3517: | |
3518: | |
3519: | |
3520: | |
3521: | |
3522: | |
3523: | |
3524: | |
3525: | |
3526: | public function DeleteUsers($IdList) |
3527: | { |
3528: | $bResult = true; |
3529: | |
3530: | foreach ($IdList as $sId) { |
3531: | $bResult = $bResult && self::Decorator()->DeleteUser($sId); |
3532: | } |
3533: | |
3534: | return $bResult; |
3535: | } |
3536: | |
3537: | |
3538: | |
3539: | |
3540: | |
3541: | |
3542: | |
3543: | |
3544: | |
3545: | |
3546: | |
3547: | |
3548: | |
3549: | |
3550: | |
3551: | |
3552: | |
3553: | |
3554: | |
3555: | |
3556: | |
3557: | |
3558: | |
3559: | |
3560: | |
3561: | |
3562: | |
3563: | |
3564: | |
3565: | |
3566: | |
3567: | |
3568: | |
3569: | |
3570: | |
3571: | |
3572: | |
3573: | |
3574: | |
3575: | |
3576: | |
3577: | |
3578: | |
3579: | |
3580: | |
3581: | |
3582: | |
3583: | |
3584: | |
3585: | |
3586: | |
3587: | |
3588: | |
3589: | |
3590: | |
3591: | public function DeleteUser($UserId = 0) |
3592: | { |
3593: | $oAuthenticatedUser = \Aurora\System\Api::getAuthenticatedUser(); |
3594: | |
3595: | $oUser = self::Decorator()->GetUserUnchecked($UserId); |
3596: | |
3597: | if ($oUser instanceof \Aurora\Modules\Core\Models\User && $oAuthenticatedUser->Role === \Aurora\System\Enums\UserRole::TenantAdmin && $oUser->IdTenant === $oAuthenticatedUser->IdTenant) { |
3598: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::TenantAdmin); |
3599: | } else { |
3600: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::SuperAdmin); |
3601: | } |
3602: | |
3603: | $bResult = false; |
3604: | |
3605: | if (!empty($UserId) && is_int($UserId)) { |
3606: | $bResult = $this->getUsersManager()->deleteUserById($UserId); |
3607: | if ($bResult) { |
3608: | UserBlock::where('UserId', $UserId)->delete(); |
3609: | } |
3610: | } else { |
3611: | throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::InvalidInputParameter); |
3612: | } |
3613: | |
3614: | return $bResult; |
3615: | } |
3616: | |
3617: | public function GetLogFilesData() |
3618: | { |
3619: | $aData = []; |
3620: | |
3621: | $sFileName = \Aurora\System\Api::GetLogFileName(); |
3622: | $sFilePath = \Aurora\System\Api::GetLogFileDir() . $sFileName; |
3623: | $aData['LogFileName'] = $sFileName; |
3624: | $aData['LogSizeBytes'] = file_exists($sFilePath) ? filesize($sFilePath) : 0; |
3625: | |
3626: | $sEventFileName = \Aurora\System\Api::GetLogFileName(\Aurora\System\Logger::$sEventLogPrefix); |
3627: | $sEventFilePath = \Aurora\System\Api::GetLogFileDir() . $sEventFileName; |
3628: | $aData['EventLogFileName'] = $sEventFileName; |
3629: | $aData['EventLogSizeBytes'] = file_exists($sEventFilePath) ? filesize($sEventFilePath) : 0; |
3630: | |
3631: | return $aData; |
3632: | } |
3633: | |
3634: | public function GetLogFile($EventsLog = false, $PublicId = '') |
3635: | { |
3636: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::SuperAdmin); |
3637: | |
3638: | $sLogFilePrefix = $EventsLog ? \Aurora\System\Logger::$sEventLogPrefix : ''; |
3639: | if ($PublicId !== '') { |
3640: | $sLogFilePrefix = $PublicId . '-'; |
3641: | } |
3642: | $sFileName = \Aurora\System\Api::GetLogFileDir().\Aurora\System\Api::GetLogFileName($sLogFilePrefix); |
3643: | |
3644: | if (file_exists($sFileName)) { |
3645: | $mResult = fopen($sFileName, "r"); |
3646: | |
3647: | if (false !== $mResult && is_resource($mResult)) { |
3648: | $sContentType = \MailSo\Base\Utils::MimeContentType($sFileName); |
3649: | \Aurora\System\Managers\Response::OutputHeaders(true, $sContentType, $sFileName); |
3650: | |
3651: | if ($sContentType === 'text/plain') { |
3652: | $sLogData = stream_get_contents($mResult); |
3653: | echo(\MailSo\Base\HtmlUtils::ClearTags($sLogData)); |
3654: | } else { |
3655: | \MailSo\Base\Utils::FpassthruWithTimeLimitReset($mResult, 8192, function ($sData) { |
3656: | return \MailSo\Base\HtmlUtils::ClearTags($sData); |
3657: | }); |
3658: | } |
3659: | |
3660: | @fclose($mResult); |
3661: | } |
3662: | } |
3663: | } |
3664: | |
3665: | public function GetLog($EventsLog, $PartSize = 10240) |
3666: | { |
3667: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::SuperAdmin); |
3668: | |
3669: | $sLogFilePrefix = $EventsLog ? \Aurora\System\Logger::$sEventLogPrefix : ''; |
3670: | $sFileName = \Aurora\System\Api::GetLogFileDir().\Aurora\System\Api::GetLogFileName($sLogFilePrefix); |
3671: | |
3672: | $logData = ''; |
3673: | |
3674: | if (file_exists($sFileName)) { |
3675: | $iOffset = filesize($sFileName) - $PartSize; |
3676: | $iOffset = $iOffset < 0 ? 0 : $iOffset; |
3677: | $logData = \MailSo\Base\HtmlUtils::ClearTags(file_get_contents($sFileName, false, null, $iOffset, $PartSize)); |
3678: | } |
3679: | |
3680: | return $logData; |
3681: | } |
3682: | |
3683: | |
3684: | |
3685: | |
3686: | |
3687: | |
3688: | public function ClearLog($EventsLog) |
3689: | { |
3690: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::SuperAdmin); |
3691: | |
3692: | $sLogFilePrefix = $EventsLog ? \Aurora\System\Logger::$sEventLogPrefix : ''; |
3693: | $sFileName = \Aurora\System\Api::GetLogFileDir().\Aurora\System\Api::GetLogFileName($sLogFilePrefix); |
3694: | |
3695: | return \Aurora\System\Api::ClearLog($sFileName); |
3696: | } |
3697: | |
3698: | |
3699: | |
3700: | |
3701: | |
3702: | |
3703: | |
3704: | |
3705: | |
3706: | public function SaveContentAsTempFile($UserId, $Content, $FileName) |
3707: | { |
3708: | $mResult = false; |
3709: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
3710: | |
3711: | $sUUID = \Aurora\System\Api::getUserUUIDById($UserId); |
3712: | try { |
3713: | $sTempName = md5($sUUID.$Content.$FileName); |
3714: | $oApiFileCache = new \Aurora\System\Managers\Filecache(); |
3715: | |
3716: | if (!$oApiFileCache->isFileExists($sUUID, $sTempName)) { |
3717: | $oApiFileCache->put($sUUID, $sTempName, $Content); |
3718: | } |
3719: | |
3720: | if ($oApiFileCache->isFileExists($sUUID, $sTempName)) { |
3721: | $mResult = \Aurora\System\Utils::GetClientFileResponse( |
3722: | null, |
3723: | $UserId, |
3724: | $FileName, |
3725: | $sTempName, |
3726: | $oApiFileCache->fileSize($sUUID, $sTempName) |
3727: | ); |
3728: | } |
3729: | } catch (\Exception $oException) { |
3730: | throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::FilesNotAllowed, $oException); |
3731: | } |
3732: | |
3733: | return $mResult; |
3734: | } |
3735: | |
3736: | |
3737: | |
3738: | |
3739: | |
3740: | |
3741: | |
3742: | public function UpdateUserTimezone($Timezone) |
3743: | { |
3744: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
3745: | |
3746: | $oUser = \Aurora\System\Api::getAuthenticatedUser(); |
3747: | |
3748: | if ($oUser && $Timezone) { |
3749: | if ($oUser && $oUser->DefaultTimeZone !== $Timezone) { |
3750: | $oUser->DefaultTimeZone = $Timezone; |
3751: | $this->UpdateUserObject($oUser); |
3752: | } |
3753: | } else { |
3754: | return false; |
3755: | } |
3756: | return true; |
3757: | } |
3758: | |
3759: | public function GetCompatibilities() |
3760: | { |
3761: | return []; |
3762: | } |
3763: | |
3764: | public function IsModuleDisabledForObject($oObject, $sModuleName) |
3765: | { |
3766: | return ($oObject instanceof \Aurora\System\Classes\Model) ? $oObject->isModuleDisabled($sModuleName) : false; |
3767: | } |
3768: | |
3769: | public function GetUserSessions() |
3770: | { |
3771: | $aResult = []; |
3772: | if (\Aurora\Api::GetSettings()->GetValue('StoreAuthTokenInDB', false)) { |
3773: | $oUser = \Aurora\System\Api::getAuthenticatedUser(); |
3774: | $aUserSessions = \Aurora\System\Api::UserSession()->GetUserSessionsFromDB($oUser->Id); |
3775: | foreach ($aUserSessions as $oUserSession) { |
3776: | $aTokenInfo = \Aurora\System\Api::DecodeKeyValues($oUserSession->Token); |
3777: | |
3778: | if ($aTokenInfo !== false && isset($aTokenInfo['id'])) { |
3779: | $aResult[] = [ |
3780: | 'LastUsageDateTime' => $oUserSession->LastUsageDateTime, |
3781: | 'ExpireDateTime' => (int) isset($aTokenInfo['@expire']) ? $aTokenInfo['@expire'] : 0, |
3782: | ]; |
3783: | } |
3784: | } |
3785: | } |
3786: | return $aResult; |
3787: | } |
3788: | |
3789: | public function CreateGroup($TenantId, $Name) |
3790: | { |
3791: | if (!$this->getConfig('AllowGroups', false)) { |
3792: | throw new ApiException(Notifications::MethodAccessDenied); |
3793: | } |
3794: | |
3795: | Api::checkUserRoleIsAtLeast(UserRole::TenantAdmin); |
3796: | |
3797: | $oUser = Api::getAuthenticatedUser(); |
3798: | if ($oUser->Role === UserRole::TenantAdmin && $oUser->IdTenant !== $TenantId) { |
3799: | throw new ApiException(Notifications::AccessDenied); |
3800: | } |
3801: | |
3802: | $oGroup = Group::firstWhere([ |
3803: | 'TenantId' => $TenantId, |
3804: | 'Name' => $Name |
3805: | ]); |
3806: | |
3807: | if ($oGroup) { |
3808: | throw new \Aurora\Modules\Core\Exceptions\Exception(Enums\ErrorCodes::GroupAlreadyExists); |
3809: | } else { |
3810: | $oGroup = new Models\Group(); |
3811: | $oGroup->Name = $Name; |
3812: | $oGroup->TenantId = $TenantId; |
3813: | if ($oGroup->save()) { |
3814: | return $oGroup->Id; |
3815: | } else { |
3816: | return false; |
3817: | } |
3818: | } |
3819: | } |
3820: | |
3821: | public function GetGroup($TenantId, $GroupId) |
3822: | { |
3823: | if (!$this->getConfig('AllowGroups', false)) { |
3824: | return false; |
3825: | } |
3826: | |
3827: | $mResult = false; |
3828: | |
3829: | Api::checkUserRoleIsAtLeast(UserRole::NormalUser); |
3830: | |
3831: | $oUser = Api::getAuthenticatedUser(); |
3832: | if ($oUser && ($oUser->Role === UserRole::TenantAdmin || $oUser->Role === UserRole::NormalUser) && $oUser->IdTenant !== $TenantId) { |
3833: | throw new ApiException(Notifications::AccessDenied); |
3834: | } |
3835: | |
3836: | $mResult = Group::firstWhere([ |
3837: | 'TenantId' => $TenantId, |
3838: | 'Id' => $GroupId |
3839: | ]); |
3840: | |
3841: | return $mResult; |
3842: | } |
3843: | |
3844: | public function GetAllGroup($TenantId) |
3845: | { |
3846: | if (!$this->getConfig('AllowGroups', false)) { |
3847: | return false; |
3848: | } |
3849: | |
3850: | $mResult = false; |
3851: | |
3852: | Api::checkUserRoleIsAtLeast(UserRole::NormalUser); |
3853: | |
3854: | $oUser = Api::getAuthenticatedUser(); |
3855: | if ($oUser && ($oUser->Role === UserRole::TenantAdmin || $oUser->Role === UserRole::NormalUser) && $oUser->IdTenant !== $TenantId) { |
3856: | throw new ApiException(Notifications::AccessDenied); |
3857: | } |
3858: | |
3859: | $oGroup = Group::firstWhere([ |
3860: | 'TenantId' => $TenantId, |
3861: | 'IsAll' => true |
3862: | ]); |
3863: | |
3864: | if (!$oGroup) { |
3865: | $oGroup = new Models\Group(); |
3866: | $oGroup->Name = 'All'; |
3867: | $oGroup->TenantId = $TenantId; |
3868: | $oGroup->IsAll = true; |
3869: | |
3870: | if ($oGroup->save()) { |
3871: | $mResult = $oGroup; |
3872: | } else { |
3873: | $mResult = false; |
3874: | } |
3875: | } else { |
3876: | $mResult = $oGroup; |
3877: | } |
3878: | |
3879: | return $mResult; |
3880: | } |
3881: | |
3882: | public function GetGroups($TenantId, $Search = '') |
3883: | { |
3884: | if (!$this->getConfig('AllowGroups', false)) { |
3885: | return [ |
3886: | 'Items' => [], |
3887: | 'Count' => 0 |
3888: | ]; |
3889: | } |
3890: | |
3891: | Api::checkUserRoleIsAtLeast(UserRole::NormalUser); |
3892: | |
3893: | $oUser = Api::getAuthenticatedUser(); |
3894: | if ($oUser && ($oUser->Role === UserRole::TenantAdmin || $oUser->Role === UserRole::NormalUser) && $oUser->IdTenant !== $TenantId) { |
3895: | throw new ApiException(Notifications::AccessDenied); |
3896: | } |
3897: | |
3898: | $query = Group::where('TenantId', $TenantId); |
3899: | if (!empty($Search)) { |
3900: | $query = $query->where(function ($q) use ($Search) { |
3901: | $q->where('Name', 'LIKE', '%' . $Search . '%'); |
3902: | $q->orWhere('IsAll', true); |
3903: | }); |
3904: | } |
3905: | |
3906: | $this->GetAllGroup($TenantId); |
3907: | |
3908: | $aGroups = $query->get()->map(function ($oGroup) { |
3909: | if ($oGroup->IsAll) { |
3910: | $aEmails = Contact::where('IdTenant', $oGroup->TenantId) |
3911: | ->where('Storage', StorageType::Team)->get()->map( |
3912: | function ($oContact) { |
3913: | if (!empty($oContact->FullName)) { |
3914: | return '"' . $oContact->FullName . '"' . '<' . $oContact->ViewEmail . '>'; |
3915: | } else { |
3916: | return $oContact->ViewEmail; |
3917: | } |
3918: | } |
3919: | )->toArray(); |
3920: | } else { |
3921: | $aEmails = $oGroup->Users->map(function ($oUser) { |
3922: | $oContact = Contact::where('IdUser', $oUser->Id)->where('Storage', 'team')->first(); |
3923: | if (!empty($oContact->FullName)) { |
3924: | return '"' . $oContact->FullName . '"' . '<' . $oUser->PublicId . '>'; |
3925: | } else { |
3926: | return $oUser->PublicId; |
3927: | } |
3928: | })->toArray(); |
3929: | } |
3930: | return [ |
3931: | 'Id' => $oGroup->Id, |
3932: | 'Name' => $oGroup->getName(), |
3933: | 'Emails' => implode(', ', $aEmails), |
3934: | 'IsAll' => !!$oGroup->IsAll |
3935: | ]; |
3936: | })->toArray(); |
3937: | |
3938: | if (!empty($Search)) { |
3939: | $aGroups = array_filter($aGroups, function ($aGroup) use ($Search) { |
3940: | return (stripos($aGroup['Name'], $Search) !== false); |
3941: | }); |
3942: | } |
3943: | |
3944: | return [ |
3945: | 'Items' => $aGroups, |
3946: | 'Count' => count($aGroups) |
3947: | ]; |
3948: | } |
3949: | |
3950: | public function UpdateGroup($GroupId, $Name) |
3951: | { |
3952: | if (!$this->getConfig('AllowGroups', false)) { |
3953: | throw new ApiException(Notifications::MethodAccessDenied); |
3954: | } |
3955: | |
3956: | $mResult = false; |
3957: | |
3958: | Api::checkUserRoleIsAtLeast(UserRole::TenantAdmin); |
3959: | |
3960: | $oGroup = Group::find($GroupId); |
3961: | if ($oGroup && !$oGroup->IsAll) { |
3962: | $oUser = Api::getAuthenticatedUser(); |
3963: | if ($oUser && $oUser->Role === UserRole::TenantAdmin && $oGroup->TenantId !== $oUser->IdTenant) { |
3964: | throw new ApiException(Notifications::AccessDenied); |
3965: | } |
3966: | |
3967: | if ($oGroup->Name !== $Name && Group::where(['TenantId' => $oGroup->TenantId, 'Name' => $Name])->count() > 0) { |
3968: | throw new ApiException(ErrorCodes::GroupAlreadyExists); |
3969: | } else { |
3970: | $oGroup->Name = $Name; |
3971: | $mResult = !!$oGroup->save(); |
3972: | } |
3973: | } |
3974: | |
3975: | return $mResult; |
3976: | } |
3977: | |
3978: | |
3979: | |
3980: | |
3981: | |
3982: | |
3983: | public function DeleteGroups($IdList) |
3984: | { |
3985: | if (!$this->getConfig('AllowGroups', false)) { |
3986: | throw new ApiException(Notifications::MethodAccessDenied); |
3987: | } |
3988: | |
3989: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::SuperAdmin); |
3990: | |
3991: | $bResult = true; |
3992: | |
3993: | foreach ($IdList as $iId) { |
3994: | $bResult = $bResult && self::Decorator()->DeleteGroup($iId); |
3995: | } |
3996: | |
3997: | return $bResult; |
3998: | } |
3999: | |
4000: | public function DeleteGroup($GroupId) |
4001: | { |
4002: | if (!$this->getConfig('AllowGroups', false)) { |
4003: | throw new ApiException(Notifications::MethodAccessDenied); |
4004: | } |
4005: | |
4006: | $mResult = false; |
4007: | |
4008: | Api::checkUserRoleIsAtLeast(UserRole::TenantAdmin); |
4009: | |
4010: | $oGroup = Group::find($GroupId); |
4011: | if ($oGroup && !$oGroup->IsAll) { |
4012: | $oUser = Api::getAuthenticatedUser(); |
4013: | if ($oUser && $oUser->Role === UserRole::TenantAdmin && $oGroup->TenantId !== $oUser->IdTenant) { |
4014: | throw new ApiException(Notifications::AccessDenied); |
4015: | } |
4016: | |
4017: | $mResult = $oGroup->delete(); |
4018: | } |
4019: | |
4020: | return $mResult; |
4021: | } |
4022: | |
4023: | public function GetGroupUsers($TenantId, $GroupId) |
4024: | { |
4025: | if (!$this->getConfig('AllowGroups', false)) { |
4026: | throw new ApiException(Notifications::MethodAccessDenied); |
4027: | } |
4028: | |
4029: | $mResult = []; |
4030: | |
4031: | Api::checkUserRoleIsAtLeast(UserRole::NormalUser); |
4032: | |
4033: | $oGroup = Group::where('TenantId', $TenantId)->where('Id', $GroupId)->first(); |
4034: | if ($oGroup) { |
4035: | $oUser = Api::getAuthenticatedUser(); |
4036: | if ($oUser && ($oUser->Role === UserRole::NormalUser || $oUser->Role === UserRole::TenantAdmin) && $oGroup->TenantId !== $oUser->IdTenant) { |
4037: | throw new ApiException(Notifications::AccessDenied); |
4038: | } |
4039: | |
4040: | if ($oGroup->IsAll) { |
4041: | $mResult = Contact::where('IdTenant', $TenantId) |
4042: | ->where('Storage', StorageType::Team)->get()->map(function ($oContact) { |
4043: | return [ |
4044: | 'UserId' => $oContact->IdUser, |
4045: | 'Name' => $oContact->FullName, |
4046: | 'PublicId' => $oContact->ViewEmail |
4047: | ]; |
4048: | })->toArray(); |
4049: | } else { |
4050: | $mResult = $oGroup->Users()->get()->map(function ($oUser) { |
4051: | return [ |
4052: | 'UserId' => $oUser->Id, |
4053: | 'Name' => $oUser->Name, |
4054: | 'PublicId' => $oUser->PublicId |
4055: | ]; |
4056: | })->toArray(); |
4057: | } |
4058: | } |
4059: | |
4060: | return $mResult; |
4061: | } |
4062: | |
4063: | public function AddUsersToGroup($GroupId, $UserIds) |
4064: | { |
4065: | if (!$this->getConfig('AllowGroups', false)) { |
4066: | throw new ApiException(Notifications::MethodAccessDenied); |
4067: | } |
4068: | |
4069: | $mResult = false; |
4070: | |
4071: | Api::checkUserRoleIsAtLeast(UserRole::TenantAdmin); |
4072: | |
4073: | $oGroup = Group::find($GroupId); |
4074: | if ($oGroup && !$oGroup->IsAll) { |
4075: | $oUser = Api::getAuthenticatedUser(); |
4076: | if ($oUser && $oUser->Role === UserRole::TenantAdmin && $oGroup->TenantId !== $oUser->IdTenant) { |
4077: | throw new ApiException(Notifications::AccessDenied); |
4078: | } |
4079: | |
4080: | $oGroup->Users()->syncWithoutDetaching($UserIds); |
4081: | $mResult = true; |
4082: | } |
4083: | |
4084: | return $mResult; |
4085: | } |
4086: | |
4087: | public function RemoveUsersFromGroup($GroupId, $UserIds) |
4088: | { |
4089: | if (!$this->getConfig('AllowGroups', false)) { |
4090: | throw new ApiException(Notifications::MethodAccessDenied); |
4091: | } |
4092: | |
4093: | $mResult = false; |
4094: | |
4095: | Api::checkUserRoleIsAtLeast(UserRole::TenantAdmin); |
4096: | |
4097: | $oGroup = Group::find($GroupId); |
4098: | if ($oGroup) { |
4099: | $oUser = Api::getAuthenticatedUser(); |
4100: | if ($oUser && $oUser->Role === UserRole::TenantAdmin && $oGroup->TenantId !== $oUser->IdTenant) { |
4101: | throw new ApiException(Notifications::AccessDenied); |
4102: | } |
4103: | |
4104: | $oGroup->Users()->detach($UserIds); |
4105: | $mResult = true; |
4106: | } |
4107: | |
4108: | return $mResult; |
4109: | } |
4110: | |
4111: | public function UpdateUserGroups($UserId, $GroupIds) |
4112: | { |
4113: | if (!$this->getConfig('AllowGroups', false)) { |
4114: | throw new ApiException(Notifications::MethodAccessDenied); |
4115: | } |
4116: | |
4117: | $mResult = false; |
4118: | |
4119: | Api::checkUserRoleIsAtLeast(UserRole::TenantAdmin); |
4120: | $oAuthUser = Api::getAuthenticatedUser(); |
4121: | $oUser = User::find($UserId); |
4122: | |
4123: | if ($oAuthUser && $oAuthUser->Role === UserRole::TenantAdmin && $oAuthUser->TenantId !== $oUser->IdTenant) { |
4124: | throw new ApiException(Notifications::AccessDenied); |
4125: | } |
4126: | if ($oUser) { |
4127: | $aGroupIds = Group::where('IsAll', false)->whereIn('Id', $GroupIds)->get(['Id'])->map(function ($oGroup) { |
4128: | return $oGroup->Id; |
4129: | }); |
4130: | $oUser->Groups()->sync($aGroupIds); |
4131: | $mResult = true; |
4132: | } |
4133: | |
4134: | return $mResult; |
4135: | } |
4136: | |
4137: | } |
4138: | |