mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-08-27 19:19:21 +03:00
Split Admin actions from User actions
This commit is contained in:
parent
398c77eb35
commit
2a3e22344e
4 changed files with 682 additions and 681 deletions
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
678
snappymail/v/0.0.0/app/libraries/RainLoop/ActionsAdmin.php
Normal file
678
snappymail/v/0.0.0/app/libraries/RainLoop/ActionsAdmin.php
Normal file
|
|
@ -0,0 +1,678 @@
|
|||
<?php
|
||||
|
||||
namespace RainLoop;
|
||||
|
||||
class ActionsAdmin extends Actions
|
||||
{
|
||||
|
||||
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
|
||||
{
|
||||
$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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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));
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue