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