diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Admin.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Admin.php index d2dd5a0eb..26d736a07 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Admin.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/Admin.php @@ -13,7 +13,7 @@ use RainLoop\Utils; trait Admin { - private static $AUTH_ADMIN_TOKEN_KEY = 'smadmin'; + protected static $AUTH_ADMIN_TOKEN_KEY = 'smadmin'; public function IsAdminLoggined(bool $bThrowExceptionOnFalse = true) : bool { @@ -32,7 +32,7 @@ trait Admin return false; } - private function getAdminAuthKey() : string + protected function getAdminAuthKey() : string { $cookie = Utils::GetCookie(static::$AUTH_ADMIN_TOKEN_KEY, ''); if ($cookie) { @@ -44,679 +44,4 @@ trait Admin } return ''; } - - private function setAdminAuthToken(string $sToken) : void - { - Utils::SetCookie(static::$AUTH_ADMIN_TOKEN_KEY, $sToken, 0); - } - - public function ClearAdminAuthToken() : void - { - $sAdminKey = $this->getAdminAuthKey(); - if ($sAdminKey) { - $this->Cacher(null, true)->Delete(KeyPathHelper::SessionAdminKey($sAdminKey)); - } - Utils::ClearCookie(static::$AUTH_ADMIN_TOKEN_KEY); - } - - private function getAdminToken() : string - { - $sRand = \MailSo\Base\Utils::Sha1Rand(); - if (!$this->Cacher(null, true)->Set(KeyPathHelper::SessionAdminKey($sRand), \time())) - { - $this->oLogger->Write('Cannot store an admin token', - \MailSo\Log\Enumerations\Type::WARNING); - return ''; - } - - return Utils::EncodeKeyValuesQ(array('token', $sRand)); - } - - public function DoAdminClearCache() : array - { - $this->Cacher()->GC(0); - if (\is_dir(APP_PRIVATE_DATA . 'cache')) { - \MailSo\Base\Utils::RecRmDir(APP_PRIVATE_DATA.'cache'); - } - return $this->TrueResponse(__FUNCTION__); - } - - public function DoAdminSettingsGet() : array - { - $aConfig = $this->Config()->jsonSerialize(); - unset($aConfig['version']); - return $this->DefaultResponse(__FUNCTION__, $aConfig); - } - - public function DoAdminSettingsSet() : array - { - // TODO - $aConfig = $this->GetActionParam('config', []); - unset($aConfig['version']); - /* Sections: - [webmail] => Array - [interface] => Array - [contacts] => Array - [security] => Array - [ssl] => Array - [capa] => Array - [login] => Array - [plugins] => Array - [defaults] => Array - [logs] => Array - [cache] => Array - [labs] => Array - */ - return $this->TrueResponse(__FUNCTION__); - } - - public function DoAdminSettingsUpdate() : array - { -// sleep(3); -// return $this->DefaultResponse(__FUNCTION__, false); - - $this->IsAdminLoggined(); - - $oConfig = $this->Config(); - - $self = $this; - - $this->setConfigFromParams($oConfig, 'Language', 'webmail', 'language', 'string', function ($sLanguage) use ($self) { - return $self->ValidateLanguage($sLanguage, '', false); - }); - - $this->setConfigFromParams($oConfig, 'LanguageAdmin', 'webmail', 'language_admin', 'string', function ($sLanguage) use ($self) { - return $self->ValidateLanguage($sLanguage, '', true); - }); - - $this->setConfigFromParams($oConfig, 'Theme', 'webmail', 'theme', 'string', function ($sTheme) use ($self) { - return $self->ValidateTheme($sTheme); - }); - - $this->setConfigFromParams($oConfig, 'VerifySslCertificate', 'ssl', 'verify_certificate', 'bool'); - $this->setConfigFromParams($oConfig, 'AllowSelfSigned', 'ssl', 'allow_self_signed', 'bool'); - - $this->setConfigFromParams($oConfig, 'UseLocalProxyForExternalImages', 'labs', 'use_local_proxy_for_external_images', 'bool'); - - $this->setConfigFromParams($oConfig, 'NewMoveToFolder', 'interface', 'new_move_to_folder_button', 'bool'); - - $this->setConfigFromParams($oConfig, 'AllowLanguagesOnSettings', 'webmail', 'allow_languages_on_settings', 'bool'); - $this->setConfigFromParams($oConfig, 'AllowLanguagesOnLogin', 'login', 'allow_languages_on_login', 'bool'); - $this->setConfigFromParams($oConfig, 'hideSubmitButton', 'login', 'hide_submit_button', 'bool'); - $this->setConfigFromParams($oConfig, 'AttachmentLimit', 'webmail', 'attachment_size_limit', 'int'); - - $this->setConfigFromParams($oConfig, 'LoginDefaultDomain', 'login', 'default_domain', 'string'); - - $this->setConfigFromParams($oConfig, 'ContactsEnable', 'contacts', 'enable', 'bool'); - $this->setConfigFromParams($oConfig, 'ContactsSync', 'contacts', 'allow_sync', 'bool'); - $this->setConfigFromParams($oConfig, 'ContactsPdoDsn', 'contacts', 'pdo_dsn', 'string'); - $this->setConfigFromParams($oConfig, 'ContactsPdoUser', 'contacts', 'pdo_user', 'string'); - $this->setConfigFromParams($oConfig, 'ContactsPdoPassword', 'contacts', 'pdo_password', 'dummy'); - - $this->setConfigFromParams($oConfig, 'ContactsPdoType', 'contacts', 'type', 'string', function ($sType) use ($self) { - return \RainLoop\Providers\AddressBook\PdoAddressBook::validPdoType($sType); - }); - - $this->setConfigFromParams($oConfig, 'CapaAdditionalAccounts', 'webmail', 'allow_additional_accounts', 'bool'); - $this->setConfigFromParams($oConfig, 'CapaIdentities', 'webmail', 'allow_additional_identities', 'bool'); - $this->setConfigFromParams($oConfig, 'CapaAttachmentThumbnails', 'interface', 'show_attachment_thumbnail', 'bool'); - $this->setConfigFromParams($oConfig, 'CapaThemes', 'webmail', 'allow_themes', 'bool'); - $this->setConfigFromParams($oConfig, 'CapaUserBackground', 'webmail', 'allow_user_background', 'bool'); - $this->setConfigFromParams($oConfig, 'CapaOpenPGP', 'security', 'openpgp', 'bool'); - - $this->setConfigFromParams($oConfig, 'DetermineUserLanguage', 'login', 'determine_user_language', 'bool'); - $this->setConfigFromParams($oConfig, 'DetermineUserDomain', 'login', 'determine_user_domain', 'bool'); - - $this->setConfigFromParams($oConfig, 'Title', 'webmail', 'title', 'string'); - $this->setConfigFromParams($oConfig, 'LoadingDescription', 'webmail', 'loading_description', 'string'); - $this->setConfigFromParams($oConfig, 'FaviconUrl', 'webmail', 'favicon_url', 'string'); - - $this->setConfigFromParams($oConfig, 'TokenProtection', 'security', 'csrf_protection', 'bool'); - $this->setConfigFromParams($oConfig, 'EnabledPlugins', 'plugins', 'enable', 'bool'); - - return $this->DefaultResponse(__FUNCTION__, $oConfig->Save()); - } - - /** - * @throws \MailSo\Base\Exceptions\Exception - */ - public function DoAdminLogin() : array - { - $sLogin = trim($this->GetActionParam('Login', '')); - $sPassword = $this->GetActionParam('Password', ''); - - $this->Logger()->AddSecret($sPassword); - - $totp = $this->Config()->Get('security', 'admin_totp', ''); - - // \explode(':',`getent shadow root`)[1]; - if (!\strlen($sLogin) || !\strlen($sPassword) || - !$this->Config()->Get('security', 'allow_admin_panel', true) || - $sLogin !== $this->Config()->Get('security', 'admin_login', '') || - !$this->Config()->ValidatePassword($sPassword) - || ($totp && !\SnappyMail\TOTP::Verify($totp, $this->GetActionParam('TOTP', '')))) - { - $this->LoggerAuthHelper(null, $this->getAdditionalLogParamsByUserLogin($sLogin, true), true); - $this->loginErrorDelay(); - throw new ClientException(Notifications::AuthError); - } - - $sToken = $this->getAdminToken(); - $this->setAdminAuthToken($sToken); - - return $this->DefaultResponse(__FUNCTION__, $sToken ? $this->AppData(true) : false); - } - - public function DoAdminLogout() : array - { - $this->ClearAdminAuthToken(); - return $this->TrueResponse(__FUNCTION__); - } - - public function DoAdminContactsTest() : array - { - $this->IsAdminLoggined(); - - $oConfig = $this->Config(); - - $this->setConfigFromParams($oConfig, 'ContactsPdoDsn', 'contacts', 'pdo_dsn', 'string'); - $this->setConfigFromParams($oConfig, 'ContactsPdoUser', 'contacts', 'pdo_user', 'string'); - $this->setConfigFromParams($oConfig, 'ContactsPdoPassword', 'contacts', 'pdo_password', 'dummy'); - - $self = $this; - $this->setConfigFromParams($oConfig, 'ContactsPdoType', 'contacts', 'type', 'string', function ($sType) use ($self) { - return \RainLoop\Providers\AddressBook\PdoAddressBook::validPdoType($sType); - }); - - $sTestMessage = $this->AddressBookProvider(null, true)->Test(); - return $this->DefaultResponse(__FUNCTION__, array( - 'Result' => '' === $sTestMessage, - 'Message' => \MailSo\Base\Utils::Utf8Clear($sTestMessage) - )); - } - - public function DoAdminPasswordUpdate() : array - { - $this->IsAdminLoggined(); - - $bResult = false; - $oConfig = $this->Config(); - - $sLogin = \trim($this->GetActionParam('Login', '')); - $sPassword = $this->GetActionParam('Password', ''); - $this->Logger()->AddSecret($sPassword); - - $sNewPassword = $this->GetActionParam('NewPassword', ''); - if (\strlen(\trim($sNewPassword))) - { - $this->Logger()->AddSecret($sNewPassword); - } - - $passfile = APP_PRIVATE_DATA.'admin_password.txt'; - - $oConfig->Set('security', 'admin_totp', $this->GetActionParam('TOTP', '')); - - if ($oConfig->ValidatePassword($sPassword)) - { - if (\strlen($sLogin)) - { - $oConfig->Set('security', 'admin_login', $sLogin); - } - - if (\strlen(\trim($sNewPassword))) - { - $oConfig->SetPassword($sNewPassword); - if (\is_file($passfile) && \trim(\file_get_contents($passfile)) !== $sNewPassword) { - \unlink($passfile); - } - } - - $bResult = $oConfig->Save(); - } - - return $this->DefaultResponse(__FUNCTION__, $bResult - ? array('Weak' => \is_file($passfile)) - : false); - } - - public function DoAdminDomainLoad() : array - { - $this->IsAdminLoggined(); - - return $this->DefaultResponse(__FUNCTION__, - $this->DomainProvider()->Load($this->GetActionParam('Name', ''), false, false)); - } - - public function DoAdminDomainList() : array - { - $this->IsAdminLoggined(); - $bIncludeAliases = !empty($this->GetActionParam('IncludeAliases', '1')); - return $this->DefaultResponse(__FUNCTION__, $this->DomainProvider()->GetList($bIncludeAliases)); - } - - public function DoAdminDomainDelete() : array - { - $this->IsAdminLoggined(); - - return $this->DefaultResponse(__FUNCTION__, - $this->DomainProvider()->Delete((string) $this->GetActionParam('Name', ''))); - } - - public function DoAdminDomainDisable() : array - { - $this->IsAdminLoggined(); - - return $this->DefaultResponse(__FUNCTION__, $this->DomainProvider()->Disable( - (string) $this->GetActionParam('Name', ''), - '1' === (string) $this->GetActionParam('Disabled', '0') - )); - } - - public function DoAdminDomainSave() : array - { - $this->IsAdminLoggined(); - - $oDomain = $this->DomainProvider()->LoadOrCreateNewFromAction($this); - - return $this->DefaultResponse(__FUNCTION__, - $oDomain ? $this->DomainProvider()->Save($oDomain) : false); - } - - public function DoAdminDomainAliasSave() : array - { - $this->IsAdminLoggined(); - - return $this->DefaultResponse(__FUNCTION__, $this->DomainProvider()->SaveAlias( - (string) $this->GetActionParam('Name', ''), - (string) $this->GetActionParam('Alias', '') - )); - } - - public function DoAdminDomainTest() : array - { - $this->IsAdminLoggined(); - - $bImapResult = false; - $sImapErrorDesc = ''; - $bSmtpResult = false; - $sSmtpErrorDesc = ''; - $bSieveResult = false; - $sSieveErrorDesc = ''; - - $iConnectionTimeout = 5; - - $oDomain = $this->DomainProvider()->LoadOrCreateNewFromAction($this, 'test.example.com'); - if ($oDomain) - { - try - { - $oImapClient = new \MailSo\Imap\ImapClient(); - $oImapClient->SetLogger($this->Logger()); - $oImapClient->SetTimeOuts($iConnectionTimeout); - - $iTime = \microtime(true); - $oImapClient->Connect($oDomain->IncHost(), $oDomain->IncPort(), $oDomain->IncSecure(), - !!$this->Config()->Get('ssl', 'verify_certificate', false), - !!$this->Config()->Get('ssl', 'allow_self_signed', true), - $this->Config()->Get('ssl', 'client_cert', '') - ); - - $oImapClient->Disconnect(); - $bImapResult = true; - } - catch (\MailSo\Net\Exceptions\SocketCanNotConnectToHostException $oException) - { - $this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); - $sImapErrorDesc = $oException->getSocketMessage(); - if (empty($sImapErrorDesc)) - { - $sImapErrorDesc = $oException->getMessage(); - } - } - catch (\Throwable $oException) - { - $this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); - $sImapErrorDesc = $oException->getMessage(); - } - - if ($oDomain->OutUsePhpMail()) - { - $bSmtpResult = \MailSo\Base\Utils::FunctionExistsAndEnabled('mail'); - if (!$bSmtpResult) - { - $sSmtpErrorDesc = 'PHP: mail() function is undefined'; - } - } - else - { - try - { - $oSmtpClient = new \MailSo\Smtp\SmtpClient(); - $oSmtpClient->SetLogger($this->Logger()); - $oSmtpClient->SetTimeOuts($iConnectionTimeout); - - $iTime = \microtime(true); - $oSmtpClient->Connect($oDomain->OutHost(), $oDomain->OutPort(), $oDomain->OutSecure(), - !!$this->Config()->Get('ssl', 'verify_certificate', false), - !!$this->Config()->Get('ssl', 'allow_self_signed', true), - '', \MailSo\Smtp\SmtpClient::EhloHelper() - ); - - $oSmtpClient->Disconnect(); - $bSmtpResult = true; - } - catch (\MailSo\Net\Exceptions\SocketCanNotConnectToHostException $oException) - { - $this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); - $sSmtpErrorDesc = $oException->getSocketMessage(); - if (empty($sSmtpErrorDesc)) - { - $sSmtpErrorDesc = $oException->getMessage(); - } - } - catch (\Throwable $oException) - { - $this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); - $sSmtpErrorDesc = $oException->getMessage(); - } - } - - if ($oDomain->UseSieve()) - { - try - { - $oSieveClient = new \MailSo\Sieve\ManageSieveClient(); - $oSieveClient->SetLogger($this->Logger()); - $oSieveClient->SetTimeOuts($iConnectionTimeout); - - $iTime = \microtime(true); - $oSieveClient->Connect($oDomain->SieveHost(), $oDomain->SievePort(), $oDomain->SieveSecure(), - !!$this->Config()->Get('ssl', 'verify_certificate', false), - !!$this->Config()->Get('ssl', 'allow_self_signed', true) - ); - - $oSieveClient->Disconnect(); - $bSieveResult = true; - } - catch (\MailSo\Net\Exceptions\SocketCanNotConnectToHostException $oException) - { - $this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); - $sSieveErrorDesc = $oException->getSocketMessage(); - if (empty($sSieveErrorDesc)) - { - $sSieveErrorDesc = $oException->getMessage(); - } - } - catch (\Throwable $oException) - { - $this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); - $sSieveErrorDesc = $oException->getMessage(); - } - } - else - { - $bSieveResult = true; - } - } - - return $this->DefaultResponse(__FUNCTION__, array( - 'Imap' => $bImapResult ? true : $sImapErrorDesc, - 'Smtp' => $bSmtpResult ? true : $sSmtpErrorDesc, - 'Sieve' => $bSieveResult ? true : $sSieveErrorDesc - )); - } - - public function DoAdminPHPExtensions() : array - { - $aResult = [ - [ - 'name' => 'PHP ' . PHP_VERSION, - 'loaded' => true - ] - ]; - foreach (['APCu', 'cURL','GnuPG','GD','Gmagick','Imagick','iconv','intl','LDAP','OpenSSL','pdo_mysql','pdo_pgsql','pdo_sqlite','redis','Sodium','Tidy','uuid','XXTEA','Zip'] as $name) { - $aResult[] = [ - 'name' => $name, - 'loaded' => \extension_loaded(\strtolower($name)) - ]; - } - return $this->DefaultResponse(__FUNCTION__, $aResult); - } - - public function DoAdminPackagesList() : array - { - return $this->DefaultResponse(__FUNCTION__, \SnappyMail\Repository::getPackagesList()); - } - - public function DoAdminPackageDelete() : array - { - $sId = $this->GetActionParam('Id', ''); - $bResult = \SnappyMail\Repository::deletePackage($sId); - static::pluginEnable($sId, false); - return $this->DefaultResponse(__FUNCTION__, $bResult); - } - - public function DoAdminPackageInstall() : array - { - $sType = $this->GetActionParam('Type', ''); - $bResult = \SnappyMail\Repository::installPackage( - $sType, - $this->GetActionParam('Id', ''), - $this->GetActionParam('File', '') - ); - return $this->DefaultResponse(__FUNCTION__, $bResult ? - ('plugin' !== $sType ? array('Reload' => true) : true) : false); - } - - private function pluginEnable(string $sName, bool $bEnable = true) : bool - { - if (!\strlen($sName)) - { - return false; - } - - $oConfig = $this->Config(); - - $sEnabledPlugins = $oConfig->Get('plugins', 'enabled_list', ''); - $aEnabledPlugins = \explode(',', \strtolower($sEnabledPlugins)); - $aEnabledPlugins = \array_map('trim', $aEnabledPlugins); - - $aNewEnabledPlugins = array(); - if ($bEnable) - { - $aNewEnabledPlugins = $aEnabledPlugins; - $aNewEnabledPlugins[] = $sName; - } - else - { - foreach ($aEnabledPlugins as $sPlugin) - { - if ($sName !== $sPlugin && \strlen($sPlugin)) - { - $aNewEnabledPlugins[] = $sPlugin; - } - } - } - - $oConfig->Set('plugins', 'enabled_list', \trim(\implode(',', \array_unique($aNewEnabledPlugins)), ' ,')); - - return $oConfig->Save(); - } - - public function DoAdminPluginDisable() : array - { - $this->IsAdminLoggined(); - - $sId = (string) $this->GetActionParam('Id', ''); - $bDisable = '1' === (string) $this->GetActionParam('Disabled', '1'); - - if (!$bDisable) - { - $oPlugin = $this->Plugins()->CreatePluginByName($sId); - if ($oPlugin) - { - $sValue = $oPlugin->Supported(); - if (\strlen($sValue)) - { - return $this->FalseResponse(__FUNCTION__, Notifications::UnsupportedPluginPackage, $sValue); - } - } - else - { - return $this->FalseResponse(__FUNCTION__, Notifications::InvalidPluginPackage); - } - } - - return $this->DefaultResponse(__FUNCTION__, $this->pluginEnable($sId, !$bDisable)); - } - - public function DoAdminPluginLoad() : array - { - $this->IsAdminLoggined(); - - $mResult = false; - $sId = (string) $this->GetActionParam('Id', ''); - - if (!empty($sId)) { - $oPlugin = $this->Plugins()->CreatePluginByName($sId); - if ($oPlugin) { - $mResult = array( - '@Object' => 'Object/Plugin', - 'Id' => $sId, - 'Name' => $oPlugin->Name(), - 'Readme' => $oPlugin->Description(), - 'Config' => array() - ); - - $aMap = $oPlugin->ConfigMap(); - if (\is_array($aMap)) { - $oConfig = $oPlugin->Config(); - foreach ($aMap as $oItem) { - if ($oItem) { - if ($oItem instanceof \RainLoop\Plugins\Property) { - if (PluginPropertyType::PASSWORD === $oItem->Type()) { - $oItem->SetValue(APP_DUMMY); - } else { - $oItem->SetValue($oConfig->Get('plugin', $oItem->Name(), '')); - } - $mResult['Config'][] = $oItem; - } else if ($oItem instanceof \RainLoop\Plugins\PropertyCollection) { - foreach ($oItem as $oSubItem) { - if ($oSubItem && $oSubItem instanceof \RainLoop\Plugins\Property) { - if (PluginPropertyType::PASSWORD === $oSubItem->Type()) { - $oSubItem->SetValue(APP_DUMMY); - } else { - $oSubItem->SetValue($oConfig->Get('plugin', $oSubItem->Name(), '')); - } - } - } - $mResult['Config'][] = $oItem; - } - } - } - } - } - } - - return $this->DefaultResponse(__FUNCTION__, $mResult); - } - - public function DoAdminPluginSettingsUpdate() : array - { - $this->IsAdminLoggined(); - - $mResult = false; - $sId = (string) $this->GetActionParam('Id', ''); - - if (!empty($sId)) - { - $oPlugin = $this->Plugins()->CreatePluginByName($sId); - if ($oPlugin) - { - $oConfig = $oPlugin->Config(); - $aMap = $oPlugin->ConfigMap(true); - if (is_array($aMap)) - { - $aSettings = (array) $this->GetActionParam('Settings', []); - foreach ($aMap as $oItem) - { - $sKey = $oItem->Name(); - $sValue = $aSettings[$sKey] ?? $oConfig->Get('plugin', $sKey); - if (PluginPropertyType::PASSWORD !== $oItem->Type() || APP_DUMMY !== $sValue) - { - $mResultValue = null; - switch ($oItem->Type()) { - case PluginPropertyType::INT: - $mResultValue = (int) $sValue; - break; - case PluginPropertyType::BOOL: - $mResultValue = '1' === (string) $sValue; - break; - case PluginPropertyType::SELECTION: - if (is_array($oItem->DefaultValue()) && in_array($sValue, $oItem->DefaultValue())) - { - $mResultValue = (string) $sValue; - } - break; - case PluginPropertyType::PASSWORD: - case PluginPropertyType::STRING: - case PluginPropertyType::STRING_TEXT: - case PluginPropertyType::URL: - $mResultValue = (string) $sValue; - break; - } - - if (null !== $mResultValue) - { - $oConfig->Set('plugin', $sKey, $mResultValue); - } - } - } - } - - $mResult = $oConfig->Save(); - } - } - - if (!$mResult) - { - throw new ClientException(Notifications::CantSavePluginSettings); - } - - return $this->DefaultResponse(__FUNCTION__, true); - } - - private function setConfigFromParams(\RainLoop\Config\Application $oConfig, string $sParamName, string $sConfigSector, string $sConfigName, string $sType = 'string', ?callable $mStringCallback = null): void - { - $sValue = $this->GetActionParam($sParamName, ''); - if ($this->HasActionParam($sParamName)) { - switch ($sType) { - default: - case 'string': - $sValue = (string)$sValue; - if ($mStringCallback && is_callable($mStringCallback)) { - $sValue = $mStringCallback($sValue); - } - - $oConfig->Set($sConfigSector, $sConfigName, $sValue); - break; - - case 'dummy': - $sValue = (string) $this->GetActionParam($sParamName, APP_DUMMY); - if (APP_DUMMY !== $sValue) { - $oConfig->Set($sConfigSector, $sConfigName, $sValue); - } - break; - - case 'int': - $iValue = (int)$sValue; - $oConfig->Set($sConfigSector, $sConfigName, $iValue); - break; - - case 'bool': - $oConfig->Set($sConfigSector, $sConfigName, !empty($sValue) && 'false' !== $sValue); - break; - } - } - } } diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/ActionsAdmin.php b/snappymail/v/0.0.0/app/libraries/RainLoop/ActionsAdmin.php new file mode 100644 index 000000000..07f34e391 --- /dev/null +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/ActionsAdmin.php @@ -0,0 +1,678 @@ +Cacher()->GC(0); + if (\is_dir(APP_PRIVATE_DATA . 'cache')) { + \MailSo\Base\Utils::RecRmDir(APP_PRIVATE_DATA.'cache'); + } + return $this->TrueResponse(__FUNCTION__); + } + + public function DoAdminSettingsGet() : array + { + $aConfig = $this->Config()->jsonSerialize(); + unset($aConfig['version']); + return $this->DefaultResponse(__FUNCTION__, $aConfig); + } + + public function DoAdminSettingsSet() : array + { + // TODO + $aConfig = $this->GetActionParam('config', []); + unset($aConfig['version']); + /* Sections: + [webmail] => Array + [interface] => Array + [contacts] => Array + [security] => Array + [ssl] => Array + [capa] => Array + [login] => Array + [plugins] => Array + [defaults] => Array + [logs] => Array + [cache] => Array + [labs] => Array + */ + return $this->TrueResponse(__FUNCTION__); + } + + public function DoAdminSettingsUpdate() : array + { +// sleep(3); +// return $this->DefaultResponse(__FUNCTION__, false); + + $this->IsAdminLoggined(); + + $oConfig = $this->Config(); + + $self = $this; + + $this->setConfigFromParams($oConfig, 'Language', 'webmail', 'language', 'string', function ($sLanguage) use ($self) { + return $self->ValidateLanguage($sLanguage, '', false); + }); + + $this->setConfigFromParams($oConfig, 'LanguageAdmin', 'webmail', 'language_admin', 'string', function ($sLanguage) use ($self) { + return $self->ValidateLanguage($sLanguage, '', true); + }); + + $this->setConfigFromParams($oConfig, 'Theme', 'webmail', 'theme', 'string', function ($sTheme) use ($self) { + return $self->ValidateTheme($sTheme); + }); + + $this->setConfigFromParams($oConfig, 'VerifySslCertificate', 'ssl', 'verify_certificate', 'bool'); + $this->setConfigFromParams($oConfig, 'AllowSelfSigned', 'ssl', 'allow_self_signed', 'bool'); + + $this->setConfigFromParams($oConfig, 'UseLocalProxyForExternalImages', 'labs', 'use_local_proxy_for_external_images', 'bool'); + + $this->setConfigFromParams($oConfig, 'NewMoveToFolder', 'interface', 'new_move_to_folder_button', 'bool'); + + $this->setConfigFromParams($oConfig, 'AllowLanguagesOnSettings', 'webmail', 'allow_languages_on_settings', 'bool'); + $this->setConfigFromParams($oConfig, 'AllowLanguagesOnLogin', 'login', 'allow_languages_on_login', 'bool'); + $this->setConfigFromParams($oConfig, 'hideSubmitButton', 'login', 'hide_submit_button', 'bool'); + $this->setConfigFromParams($oConfig, 'AttachmentLimit', 'webmail', 'attachment_size_limit', 'int'); + + $this->setConfigFromParams($oConfig, 'LoginDefaultDomain', 'login', 'default_domain', 'string'); + + $this->setConfigFromParams($oConfig, 'ContactsEnable', 'contacts', 'enable', 'bool'); + $this->setConfigFromParams($oConfig, 'ContactsSync', 'contacts', 'allow_sync', 'bool'); + $this->setConfigFromParams($oConfig, 'ContactsPdoDsn', 'contacts', 'pdo_dsn', 'string'); + $this->setConfigFromParams($oConfig, 'ContactsPdoUser', 'contacts', 'pdo_user', 'string'); + $this->setConfigFromParams($oConfig, 'ContactsPdoPassword', 'contacts', 'pdo_password', 'dummy'); + + $this->setConfigFromParams($oConfig, 'ContactsPdoType', 'contacts', 'type', 'string', function ($sType) use ($self) { + return \RainLoop\Providers\AddressBook\PdoAddressBook::validPdoType($sType); + }); + + $this->setConfigFromParams($oConfig, 'CapaAdditionalAccounts', 'webmail', 'allow_additional_accounts', 'bool'); + $this->setConfigFromParams($oConfig, 'CapaIdentities', 'webmail', 'allow_additional_identities', 'bool'); + $this->setConfigFromParams($oConfig, 'CapaAttachmentThumbnails', 'interface', 'show_attachment_thumbnail', 'bool'); + $this->setConfigFromParams($oConfig, 'CapaThemes', 'webmail', 'allow_themes', 'bool'); + $this->setConfigFromParams($oConfig, 'CapaUserBackground', 'webmail', 'allow_user_background', 'bool'); + $this->setConfigFromParams($oConfig, 'CapaOpenPGP', 'security', 'openpgp', 'bool'); + + $this->setConfigFromParams($oConfig, 'DetermineUserLanguage', 'login', 'determine_user_language', 'bool'); + $this->setConfigFromParams($oConfig, 'DetermineUserDomain', 'login', 'determine_user_domain', 'bool'); + + $this->setConfigFromParams($oConfig, 'Title', 'webmail', 'title', 'string'); + $this->setConfigFromParams($oConfig, 'LoadingDescription', 'webmail', 'loading_description', 'string'); + $this->setConfigFromParams($oConfig, 'FaviconUrl', 'webmail', 'favicon_url', 'string'); + + $this->setConfigFromParams($oConfig, 'TokenProtection', 'security', 'csrf_protection', 'bool'); + $this->setConfigFromParams($oConfig, 'EnabledPlugins', 'plugins', 'enable', 'bool'); + + return $this->DefaultResponse(__FUNCTION__, $oConfig->Save()); + } + + /** + * @throws \MailSo\Base\Exceptions\Exception + */ + public function DoAdminLogin() : array + { + $sLogin = trim($this->GetActionParam('Login', '')); + $sPassword = $this->GetActionParam('Password', ''); + + $this->Logger()->AddSecret($sPassword); + + $totp = $this->Config()->Get('security', 'admin_totp', ''); + + // \explode(':',`getent shadow root`)[1]; + if (!\strlen($sLogin) || !\strlen($sPassword) || + !$this->Config()->Get('security', 'allow_admin_panel', true) || + $sLogin !== $this->Config()->Get('security', 'admin_login', '') || + !$this->Config()->ValidatePassword($sPassword) + || ($totp && !\SnappyMail\TOTP::Verify($totp, $this->GetActionParam('TOTP', '')))) + { + $this->LoggerAuthHelper(null, $this->getAdditionalLogParamsByUserLogin($sLogin, true), true); + $this->loginErrorDelay(); + throw new ClientException(Notifications::AuthError); + } + + $sToken = $this->getAdminToken(); + $this->setAdminAuthToken($sToken); + + return $this->DefaultResponse(__FUNCTION__, $sToken ? $this->AppData(true) : false); + } + + public function DoAdminLogout() : array + { + $sAdminKey = $this->getAdminAuthKey(); + if ($sAdminKey) { + $this->Cacher(null, true)->Delete(KeyPathHelper::SessionAdminKey($sAdminKey)); + } + Utils::ClearCookie(static::$AUTH_ADMIN_TOKEN_KEY); + return $this->TrueResponse(__FUNCTION__); + } + + public function DoAdminContactsTest() : array + { + $this->IsAdminLoggined(); + + $oConfig = $this->Config(); + + $this->setConfigFromParams($oConfig, 'ContactsPdoDsn', 'contacts', 'pdo_dsn', 'string'); + $this->setConfigFromParams($oConfig, 'ContactsPdoUser', 'contacts', 'pdo_user', 'string'); + $this->setConfigFromParams($oConfig, 'ContactsPdoPassword', 'contacts', 'pdo_password', 'dummy'); + + $self = $this; + $this->setConfigFromParams($oConfig, 'ContactsPdoType', 'contacts', 'type', 'string', function ($sType) use ($self) { + return \RainLoop\Providers\AddressBook\PdoAddressBook::validPdoType($sType); + }); + + $sTestMessage = $this->AddressBookProvider(null, true)->Test(); + return $this->DefaultResponse(__FUNCTION__, array( + 'Result' => '' === $sTestMessage, + 'Message' => \MailSo\Base\Utils::Utf8Clear($sTestMessage) + )); + } + + public function DoAdminPasswordUpdate() : array + { + $this->IsAdminLoggined(); + + $bResult = false; + $oConfig = $this->Config(); + + $sLogin = \trim($this->GetActionParam('Login', '')); + $sPassword = $this->GetActionParam('Password', ''); + $this->Logger()->AddSecret($sPassword); + + $sNewPassword = $this->GetActionParam('NewPassword', ''); + if (\strlen(\trim($sNewPassword))) + { + $this->Logger()->AddSecret($sNewPassword); + } + + $passfile = APP_PRIVATE_DATA.'admin_password.txt'; + + $oConfig->Set('security', 'admin_totp', $this->GetActionParam('TOTP', '')); + + if ($oConfig->ValidatePassword($sPassword)) + { + if (\strlen($sLogin)) + { + $oConfig->Set('security', 'admin_login', $sLogin); + } + + if (\strlen(\trim($sNewPassword))) + { + $oConfig->SetPassword($sNewPassword); + if (\is_file($passfile) && \trim(\file_get_contents($passfile)) !== $sNewPassword) { + \unlink($passfile); + } + } + + $bResult = $oConfig->Save(); + } + + return $this->DefaultResponse(__FUNCTION__, $bResult + ? array('Weak' => \is_file($passfile)) + : false); + } + + public function DoAdminDomainLoad() : array + { + $this->IsAdminLoggined(); + + return $this->DefaultResponse(__FUNCTION__, + $this->DomainProvider()->Load($this->GetActionParam('Name', ''), false, false)); + } + + public function DoAdminDomainList() : array + { + $this->IsAdminLoggined(); + $bIncludeAliases = !empty($this->GetActionParam('IncludeAliases', '1')); + return $this->DefaultResponse(__FUNCTION__, $this->DomainProvider()->GetList($bIncludeAliases)); + } + + public function DoAdminDomainDelete() : array + { + $this->IsAdminLoggined(); + + return $this->DefaultResponse(__FUNCTION__, + $this->DomainProvider()->Delete((string) $this->GetActionParam('Name', ''))); + } + + public function DoAdminDomainDisable() : array + { + $this->IsAdminLoggined(); + + return $this->DefaultResponse(__FUNCTION__, $this->DomainProvider()->Disable( + (string) $this->GetActionParam('Name', ''), + '1' === (string) $this->GetActionParam('Disabled', '0') + )); + } + + public function DoAdminDomainSave() : array + { + $this->IsAdminLoggined(); + + $oDomain = $this->DomainProvider()->LoadOrCreateNewFromAction($this); + + return $this->DefaultResponse(__FUNCTION__, + $oDomain ? $this->DomainProvider()->Save($oDomain) : false); + } + + public function DoAdminDomainAliasSave() : array + { + $this->IsAdminLoggined(); + + return $this->DefaultResponse(__FUNCTION__, $this->DomainProvider()->SaveAlias( + (string) $this->GetActionParam('Name', ''), + (string) $this->GetActionParam('Alias', '') + )); + } + + public function DoAdminDomainTest() : array + { + $this->IsAdminLoggined(); + + $bImapResult = false; + $sImapErrorDesc = ''; + $bSmtpResult = false; + $sSmtpErrorDesc = ''; + $bSieveResult = false; + $sSieveErrorDesc = ''; + + $iConnectionTimeout = 5; + + $oDomain = $this->DomainProvider()->LoadOrCreateNewFromAction($this, 'test.example.com'); + if ($oDomain) + { + try + { + $oImapClient = new \MailSo\Imap\ImapClient(); + $oImapClient->SetLogger($this->Logger()); + $oImapClient->SetTimeOuts($iConnectionTimeout); + + $iTime = \microtime(true); + $oImapClient->Connect($oDomain->IncHost(), $oDomain->IncPort(), $oDomain->IncSecure(), + !!$this->Config()->Get('ssl', 'verify_certificate', false), + !!$this->Config()->Get('ssl', 'allow_self_signed', true), + $this->Config()->Get('ssl', 'client_cert', '') + ); + + $oImapClient->Disconnect(); + $bImapResult = true; + } + catch (\MailSo\Net\Exceptions\SocketCanNotConnectToHostException $oException) + { + $this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); + $sImapErrorDesc = $oException->getSocketMessage(); + if (empty($sImapErrorDesc)) + { + $sImapErrorDesc = $oException->getMessage(); + } + } + catch (\Throwable $oException) + { + $this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); + $sImapErrorDesc = $oException->getMessage(); + } + + if ($oDomain->OutUsePhpMail()) + { + $bSmtpResult = \MailSo\Base\Utils::FunctionExistsAndEnabled('mail'); + if (!$bSmtpResult) + { + $sSmtpErrorDesc = 'PHP: mail() function is undefined'; + } + } + else + { + try + { + $oSmtpClient = new \MailSo\Smtp\SmtpClient(); + $oSmtpClient->SetLogger($this->Logger()); + $oSmtpClient->SetTimeOuts($iConnectionTimeout); + + $iTime = \microtime(true); + $oSmtpClient->Connect($oDomain->OutHost(), $oDomain->OutPort(), $oDomain->OutSecure(), + !!$this->Config()->Get('ssl', 'verify_certificate', false), + !!$this->Config()->Get('ssl', 'allow_self_signed', true), + '', \MailSo\Smtp\SmtpClient::EhloHelper() + ); + + $oSmtpClient->Disconnect(); + $bSmtpResult = true; + } + catch (\MailSo\Net\Exceptions\SocketCanNotConnectToHostException $oException) + { + $this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); + $sSmtpErrorDesc = $oException->getSocketMessage(); + if (empty($sSmtpErrorDesc)) + { + $sSmtpErrorDesc = $oException->getMessage(); + } + } + catch (\Throwable $oException) + { + $this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); + $sSmtpErrorDesc = $oException->getMessage(); + } + } + + if ($oDomain->UseSieve()) + { + try + { + $oSieveClient = new \MailSo\Sieve\ManageSieveClient(); + $oSieveClient->SetLogger($this->Logger()); + $oSieveClient->SetTimeOuts($iConnectionTimeout); + + $iTime = \microtime(true); + $oSieveClient->Connect($oDomain->SieveHost(), $oDomain->SievePort(), $oDomain->SieveSecure(), + !!$this->Config()->Get('ssl', 'verify_certificate', false), + !!$this->Config()->Get('ssl', 'allow_self_signed', true) + ); + + $oSieveClient->Disconnect(); + $bSieveResult = true; + } + catch (\MailSo\Net\Exceptions\SocketCanNotConnectToHostException $oException) + { + $this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); + $sSieveErrorDesc = $oException->getSocketMessage(); + if (empty($sSieveErrorDesc)) + { + $sSieveErrorDesc = $oException->getMessage(); + } + } + catch (\Throwable $oException) + { + $this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR); + $sSieveErrorDesc = $oException->getMessage(); + } + } + else + { + $bSieveResult = true; + } + } + + return $this->DefaultResponse(__FUNCTION__, array( + 'Imap' => $bImapResult ? true : $sImapErrorDesc, + 'Smtp' => $bSmtpResult ? true : $sSmtpErrorDesc, + 'Sieve' => $bSieveResult ? true : $sSieveErrorDesc + )); + } + + public function DoAdminPHPExtensions() : array + { + $aResult = [ + [ + 'name' => 'PHP ' . PHP_VERSION, + 'loaded' => true + ] + ]; + foreach (['APCu', 'cURL','GnuPG','GD','Gmagick','Imagick','iconv','intl','LDAP','OpenSSL','pdo_mysql','pdo_pgsql','pdo_sqlite','redis','Sodium','Tidy','uuid','XXTEA','Zip'] as $name) { + $aResult[] = [ + 'name' => $name, + 'loaded' => \extension_loaded(\strtolower($name)) + ]; + } + return $this->DefaultResponse(__FUNCTION__, $aResult); + } + + public function DoAdminPackagesList() : array + { + return $this->DefaultResponse(__FUNCTION__, \SnappyMail\Repository::getPackagesList()); + } + + public function DoAdminPackageDelete() : array + { + $sId = $this->GetActionParam('Id', ''); + $bResult = \SnappyMail\Repository::deletePackage($sId); + static::pluginEnable($sId, false); + return $this->DefaultResponse(__FUNCTION__, $bResult); + } + + public function DoAdminPackageInstall() : array + { + $sType = $this->GetActionParam('Type', ''); + $bResult = \SnappyMail\Repository::installPackage( + $sType, + $this->GetActionParam('Id', ''), + $this->GetActionParam('File', '') + ); + return $this->DefaultResponse(__FUNCTION__, $bResult ? + ('plugin' !== $sType ? array('Reload' => true) : true) : false); + } + + public function DoAdminPluginDisable() : array + { + $this->IsAdminLoggined(); + + $sId = (string) $this->GetActionParam('Id', ''); + $bDisable = '1' === (string) $this->GetActionParam('Disabled', '1'); + + if (!$bDisable) + { + $oPlugin = $this->Plugins()->CreatePluginByName($sId); + if ($oPlugin) + { + $sValue = $oPlugin->Supported(); + if (\strlen($sValue)) + { + return $this->FalseResponse(__FUNCTION__, Notifications::UnsupportedPluginPackage, $sValue); + } + } + else + { + return $this->FalseResponse(__FUNCTION__, Notifications::InvalidPluginPackage); + } + } + + return $this->DefaultResponse(__FUNCTION__, $this->pluginEnable($sId, !$bDisable)); + } + + public function DoAdminPluginLoad() : array + { + $this->IsAdminLoggined(); + + $mResult = false; + $sId = (string) $this->GetActionParam('Id', ''); + + if (!empty($sId)) { + $oPlugin = $this->Plugins()->CreatePluginByName($sId); + if ($oPlugin) { + $mResult = array( + '@Object' => 'Object/Plugin', + 'Id' => $sId, + 'Name' => $oPlugin->Name(), + 'Readme' => $oPlugin->Description(), + 'Config' => array() + ); + + $aMap = $oPlugin->ConfigMap(); + if (\is_array($aMap)) { + $oConfig = $oPlugin->Config(); + foreach ($aMap as $oItem) { + if ($oItem) { + if ($oItem instanceof \RainLoop\Plugins\Property) { + if (PluginPropertyType::PASSWORD === $oItem->Type()) { + $oItem->SetValue(APP_DUMMY); + } else { + $oItem->SetValue($oConfig->Get('plugin', $oItem->Name(), '')); + } + $mResult['Config'][] = $oItem; + } else if ($oItem instanceof \RainLoop\Plugins\PropertyCollection) { + foreach ($oItem as $oSubItem) { + if ($oSubItem && $oSubItem instanceof \RainLoop\Plugins\Property) { + if (PluginPropertyType::PASSWORD === $oSubItem->Type()) { + $oSubItem->SetValue(APP_DUMMY); + } else { + $oSubItem->SetValue($oConfig->Get('plugin', $oSubItem->Name(), '')); + } + } + } + $mResult['Config'][] = $oItem; + } + } + } + } + } + } + + return $this->DefaultResponse(__FUNCTION__, $mResult); + } + + public function DoAdminPluginSettingsUpdate() : array + { + $this->IsAdminLoggined(); + + $mResult = false; + $sId = (string) $this->GetActionParam('Id', ''); + + if (!empty($sId)) + { + $oPlugin = $this->Plugins()->CreatePluginByName($sId); + if ($oPlugin) + { + $oConfig = $oPlugin->Config(); + $aMap = $oPlugin->ConfigMap(true); + if (\is_array($aMap)) + { + $aSettings = (array) $this->GetActionParam('Settings', []); + foreach ($aMap as $oItem) + { + $sKey = $oItem->Name(); + $sValue = $aSettings[$sKey] ?? $oConfig->Get('plugin', $sKey); + if (PluginPropertyType::PASSWORD !== $oItem->Type() || APP_DUMMY !== $sValue) + { + $mResultValue = null; + switch ($oItem->Type()) { + case PluginPropertyType::INT: + $mResultValue = (int) $sValue; + break; + case PluginPropertyType::BOOL: + $mResultValue = '1' === (string) $sValue; + break; + case PluginPropertyType::SELECTION: + if (is_array($oItem->DefaultValue()) && in_array($sValue, $oItem->DefaultValue())) + { + $mResultValue = (string) $sValue; + } + break; + case PluginPropertyType::PASSWORD: + case PluginPropertyType::STRING: + case PluginPropertyType::STRING_TEXT: + case PluginPropertyType::URL: + $mResultValue = (string) $sValue; + break; + } + + if (null !== $mResultValue) + { + $oConfig->Set('plugin', $sKey, $mResultValue); + } + } + } + } + + $mResult = $oConfig->Save(); + } + } + + if (!$mResult) + { + throw new ClientException(Notifications::CantSavePluginSettings); + } + + return $this->DefaultResponse(__FUNCTION__, true); + } + + private function setAdminAuthToken(string $sToken) : void + { + Utils::SetCookie(static::$AUTH_ADMIN_TOKEN_KEY, $sToken, 0); + } + + private function getAdminToken() : string + { + $sRand = \MailSo\Base\Utils::Sha1Rand(); + if (!$this->Cacher(null, true)->Set(KeyPathHelper::SessionAdminKey($sRand), \time())) + { + $this->oLogger->Write('Cannot store an admin token', + \MailSo\Log\Enumerations\Type::WARNING); + return ''; + } + + return Utils::EncodeKeyValuesQ(array('token', $sRand)); + } + + private function pluginEnable(string $sName, bool $bEnable = true) : bool + { + if (!\strlen($sName)) + { + return false; + } + + $oConfig = $this->Config(); + + $sEnabledPlugins = $oConfig->Get('plugins', 'enabled_list', ''); + $aEnabledPlugins = \explode(',', \strtolower($sEnabledPlugins)); + $aEnabledPlugins = \array_map('trim', $aEnabledPlugins); + + $aNewEnabledPlugins = array(); + if ($bEnable) + { + $aNewEnabledPlugins = $aEnabledPlugins; + $aNewEnabledPlugins[] = $sName; + } + else + { + foreach ($aEnabledPlugins as $sPlugin) + { + if ($sName !== $sPlugin && \strlen($sPlugin)) + { + $aNewEnabledPlugins[] = $sPlugin; + } + } + } + + $oConfig->Set('plugins', 'enabled_list', \trim(\implode(',', \array_unique($aNewEnabledPlugins)), ' ,')); + + return $oConfig->Save(); + } + + private function setConfigFromParams(\RainLoop\Config\Application $oConfig, string $sParamName, string $sConfigSector, string $sConfigName, string $sType = 'string', ?callable $mStringCallback = null): void + { + if ($this->HasActionParam($sParamName)) { + $sValue = $this->GetActionParam($sParamName, ''); + switch ($sType) { + default: + case 'string': + $sValue = (string)$sValue; + if ($mStringCallback && is_callable($mStringCallback)) { + $sValue = $mStringCallback($sValue); + } + + $oConfig->Set($sConfigSector, $sConfigName, $sValue); + break; + + case 'dummy': + $sValue = (string) $this->GetActionParam($sParamName, APP_DUMMY); + if (APP_DUMMY !== $sValue) { + $oConfig->Set($sConfigSector, $sConfigName, $sValue); + } + break; + + case 'int': + $iValue = (int)$sValue; + $oConfig->Set($sConfigSector, $sConfigName, $iValue); + break; + + case 'bool': + $oConfig->Set($sConfigSector, $sConfigName, !empty($sValue) && 'false' !== $sValue); + break; + } + } + } + +} diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Service.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Service.php index 598b30341..e91b87da7 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Service.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Service.php @@ -87,8 +87,7 @@ abstract class Service $bAdmin = true; } - $oActions = Api::Actions(); -// $oActions = $bAdmin ? new ActionsAdmin() : Api::Actions(); + $oActions = $bAdmin ? new ActionsAdmin() : Api::Actions(); $oActions->Plugins()->RunHook('filter.http-paths', array(&$aPaths)); diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/ServiceActions.php b/snappymail/v/0.0.0/app/libraries/RainLoop/ServiceActions.php index c7f147fea..b36c089fc 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/ServiceActions.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/ServiceActions.php @@ -99,8 +99,7 @@ class ServiceActions } else if (!empty($sAction)) { - // if ($this->oActions instanceof ActionsAdmin) - if (0 === \stripos($sAction, 'Admin') && 'AdminLogin' !== $sAction && 'AdminLogout' !== $sAction) { + if ($this->oActions instanceof ActionsAdmin && 0 === \stripos($sAction, 'Admin') && !\in_array($sAction, ['AdminLogin', 'AdminLogout'])) { $this->oActions->IsAdminLoggined(); }