oHttp = $oHttp;
$this->oActions = $oActions;
$this->aPaths = array();
$this->sQuery = '';
}
/**
* @return \MailSo\Log\Logger
*/
public function Logger()
{
return $this->oActions->Logger();
}
/**
* @return \RainLoop\Plugins\Manager
*/
public function Plugins()
{
return $this->oActions->Plugins();
}
/**
* @return \RainLoop\Application
*/
public function Config()
{
return $this->oActions->Config();
}
/**
* @return \MailSo\Cache\CacheClient
*/
public function Cacher()
{
return $this->oActions->Cacher();
}
/**
* @return \RainLoop\Providers\Storage
*/
public function StorageProvider()
{
return $this->oActions->StorageProvider();
}
/**
* @param array $aPaths
*
* @return \RainLoop\ServiceActions
*/
public function SetPaths($aPaths)
{
$this->aPaths = \is_array($aPaths) ? $aPaths : array();
return $this;
}
/**
* @param string $sQuery
*
* @return \RainLoop\ServiceActions
*/
public function SetQuery($sQuery)
{
$this->sQuery = $sQuery;
return $this;
}
/**
* @return string
*/
public function ServiceAjax()
{
@\ob_start();
$aResponseItem = null;
$oException = null;
$sAction = $this->oHttp->GetPost('Action', null);
if (empty($sAction) && $this->oHttp->IsGet() && !empty($this->aPaths[2]))
{
$sAction = $this->aPaths[2];
}
try
{
if ($this->oHttp->IsPost() && !in_array($sAction, array('JsInfo', 'JsError')) &&
$this->Config()->Get('security', 'csrf_protection', false) &&
$this->oHttp->GetPost('XToken', '') !== \RainLoop\Utils::GetCsrfToken())
{
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::InvalidToken);
}
else if (!empty($sAction))
{
$sMethodName = 'Do'.$sAction;
$this->Logger()->Write('Action: '.$sMethodName, \MailSo\Log\Enumerations\Type::NOTE, 'AJAX');
$aPost = $this->oHttp->GetPostAsArray();
if (\is_array($aPost) && 0 < \count($aPost))
{
$this->oActions->SetActionParams($aPost, $sMethodName);
switch ($sMethodName)
{
case 'DoLogin':
case 'DoAdminLogin':
case 'DoAccountAdd':
$this->Logger()->AddSecret($this->oActions->GetActionParam('Password', ''));
break;
case 'DoChangePassword':
$this->Logger()->AddSecret($this->oActions->GetActionParam('PrevPassword', ''));
$this->Logger()->AddSecret($this->oActions->GetActionParam('NewPassword', ''));
break;
}
$this->Logger()->Write(\MailSo\Base\Utils::Php2js($aPost, $this->Logger()),
\MailSo\Log\Enumerations\Type::INFO, 'POST', true);
}
else if (3 < \count($this->aPaths) && $this->oHttp->IsGet())
{
$this->oActions->SetActionParams(array(
'RawKey' => empty($this->aPaths[3]) ? '' : $this->aPaths[3]
), $sMethodName);
}
if (\method_exists($this->oActions, $sMethodName) &&
\is_callable(array($this->oActions, $sMethodName)))
{
$this->Plugins()->RunHook('ajax.action-pre-call', array($sAction));
$aResponseItem = \call_user_func(array($this->oActions, $sMethodName));
$this->Plugins()->RunHook('ajax.action-post-call', array($sAction, &$aResponseItem));
}
else if ($this->Plugins()->HasAdditionalAjax($sMethodName))
{
$this->Plugins()->RunHook('ajax.action-pre-call', array($sAction));
$aResponseItem = $this->Plugins()->RunAdditionalAjax($sMethodName);
$this->Plugins()->RunHook('ajax.action-post-call', array($sAction, &$aResponseItem));
}
}
if (!\is_array($aResponseItem))
{
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::UnknownError);
}
}
catch (\Exception $oException)
{
$aResponseItem = $this->oActions->ExceptionResponse(
empty($sAction) ? 'Unknown' : $sAction, $oException);
if (\is_array($aResponseItem) && 'Folders' === $sAction && $oException instanceof \RainLoop\Exceptions\ClientException)
{
$aResponseItem['ClearAuth'] = true;
}
}
if (\is_array($aResponseItem))
{
$aResponseItem['Time'] = (int) ((\microtime(true) - APP_START) * 1000);
}
$this->Plugins()->RunHook('filter.ajax-response', array($sAction, &$aResponseItem));
@\header('Content-Type: application/json; charset=utf-8');
$sResult = \MailSo\Base\Utils::Php2js($aResponseItem, $this->Logger());
$sObResult = @\ob_get_clean();
if ($this->Logger()->IsEnabled())
{
if (0 < \strlen($sObResult))
{
$this->Logger()->Write($sObResult, \MailSo\Log\Enumerations\Type::ERROR, 'OB-DATA');
}
if ($oException)
{
$this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR);
}
$iLimit = (int) $this->Config()->Get('labs', 'log_ajax_response_write_limit', 0);
$this->Logger()->Write(0 < $iLimit && $iLimit < \strlen($sResult)
? \substr($sResult, 0, $iLimit).'...' : $sResult, \MailSo\Log\Enumerations\Type::INFO, 'AJAX');
}
return $sResult;
}
/**
* @return string
*/
public function ServiceOwnCloudAuth()
{
if (!\RainLoop\Utils::IsOwnCloud() ||
!isset($_ENV['___rainloop_owncloud_email']) ||
!isset($_ENV['___rainloop_owncloud_password']) ||
empty($_ENV['___rainloop_owncloud_email'])
)
{
$this->oActions->SetAuthLogoutToken();
$this->oActions->Location('./');
return '';
}
$bLogout = true;
$sEmail = $_ENV['___rainloop_owncloud_email'];
$sPassword = $_ENV['___rainloop_owncloud_password'];
try
{
$oAccount = $this->oActions->LoginProcess($sEmail, $sPassword);
$this->oActions->AuthToken($oAccount);
$bLogout = !($oAccount instanceof \RainLoop\Model\Account);
}
catch (\Exception $oException)
{
$this->oActions->Logger()->WriteException($oException);
}
if ($bLogout)
{
$this->oActions->SetAuthLogoutToken();
}
$this->oActions->Location('./');
return '';
}
/**
* @return string
*/
public function ServiceAppend()
{
@\ob_start();
$bResponse = false;
$oException = null;
try
{
if (\method_exists($this->oActions, 'Append') &&
\is_callable(array($this->oActions, 'Append')))
{
$this->oActions->SetActionParams($this->oHttp->GetPostAsArray(), 'Append');
$bResponse = \call_user_func(array($this->oActions, 'Append'));
}
}
catch (\Exception $oException)
{
$bResponse = false;
}
@\header('Content-Type: text/plain; charset=utf-8');
$sResult = true === $bResponse ? '1' : '0';
$sObResult = @\ob_get_clean();
if (0 < \strlen($sObResult))
{
$this->Logger()->Write($sObResult, \MailSo\Log\Enumerations\Type::ERROR, 'OB-DATA');
}
if ($oException)
{
$this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR);
}
$this->Logger()->Write($sResult, \MailSo\Log\Enumerations\Type::INFO, 'APPEND');
return $sResult;
}
/**
* @param string $sAction
* @param int $iSizeLimit = 0
*
* @return string
*/
private function privateUpload($sAction, $iSizeLimit = 0)
{
$oConfig = $this->Config();
@\ob_start();
$aResponseItem = null;
try
{
$aFile = null;
$sInputName = 'uploader';
$iError = \RainLoop\Enumerations\UploadError::UNKNOWN;
$iSizeLimit = (0 < $iSizeLimit ? $iSizeLimit : ((int) $oConfig->Get('webmail', 'attachment_size_limit', 0))) * 1024 * 1024;
$iError = UPLOAD_ERR_OK;
$_FILES = isset($_FILES) ? $_FILES : null;
if (isset($_FILES, $_FILES[$sInputName], $_FILES[$sInputName]['name'], $_FILES[$sInputName]['tmp_name'], $_FILES[$sInputName]['size']))
{
$iError = (isset($_FILES[$sInputName]['error'])) ? (int) $_FILES[$sInputName]['error'] : UPLOAD_ERR_OK;
if (UPLOAD_ERR_OK === $iError && 0 < $iSizeLimit && $iSizeLimit < (int) $_FILES[$sInputName]['size'])
{
$iError = \RainLoop\Enumerations\UploadError::CONFIG_SIZE;
}
if (UPLOAD_ERR_OK === $iError)
{
$aFile = $_FILES[$sInputName];
}
}
else if (!isset($_FILES) || !is_array($_FILES) || 0 === count($_FILES))
{
$iError = UPLOAD_ERR_INI_SIZE;
}
else
{
$iError = \RainLoop\Enumerations\UploadError::EMPTY_FILES_DATA;
}
if (\method_exists($this->oActions, $sAction) &&
\is_callable(array($this->oActions, $sAction)))
{
$aActionParams = $this->oHttp->GetQueryAsArray();
$aActionParams['File'] = $aFile;
$aActionParams['Error'] = $iError;
$this->oActions->SetActionParams($aActionParams, $sAction);
$aResponseItem = \call_user_func(array($this->oActions, $sAction));
}
if (!is_array($aResponseItem))
{
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::UnknownError);
}
}
catch (\Exception $oException)
{
$aResponseItem = $this->oActions->ExceptionResponse($sAction, $oException);
}
if ('iframe' === $this->oHttp->GetPost('jua-post-type', ''))
{
@\header('Content-Type: text/html; charset=utf-8');
}
else
{
@\header('Content-Type: application/json; charset=utf-8');
}
$this->Plugins()->RunHook('filter.upload-response', array(&$aResponseItem));
$sResult = \MailSo\Base\Utils::Php2js($aResponseItem, $this->Logger());
$sObResult = @\ob_get_clean();
if (0 < \strlen($sObResult))
{
$this->Logger()->Write($sObResult, \MailSo\Log\Enumerations\Type::ERROR, 'OB-DATA');
}
$this->Logger()->Write($sResult, \MailSo\Log\Enumerations\Type::INFO, 'UPLOAD');
return $sResult;
}
/**
* @return string
*/
public function ServiceUpload()
{
return $this->privateUpload('Upload');
}
/**
* @return string
*/
public function ServiceUploadContacts()
{
return $this->privateUpload('UploadContacts', 5);
}
/**
* @return string
*/
public function ServiceUploadBackground()
{
return $this->privateUpload('UploadBackground', 1);
}
/**
* @return string
*/
public function ServiceProxyExternal()
{
$bResult = false;
$sData = empty($this->aPaths[1]) ? '' : $this->aPaths[1];
if (!empty($sData) && $this->oActions->Config()->Get('labs', 'use_local_proxy_for_external_images', false))
{
$this->oActions->verifyCacheByKey($sData);
$aData = \RainLoop\Utils::DecodeKeyValues($sData);
if (\is_array($aData) && !empty($aData['Token']) && !empty($aData['Url']) && $aData['Token'] === \RainLoop\Utils::GetConnectionToken())
{
$iCode = 404;
$sContentType = '';
$mResult = $this->oHttp->GetUrlAsString($aData['Url'], 'RainLoop External Proxy', $sContentType, $iCode);
if (false !== $mResult && 200 === $iCode &&
\in_array($sContentType, array('image/png', 'image/jpeg', 'image/jpg', 'image/bmp', 'image/gif')))
{
$bResult = true;
$this->oActions->cacheByKey($sData);
\header('Content-Type: '.$sContentType);
echo $mResult;
}
}
}
if (!$bResult)
{
$this->oHttp->StatusHeader(404);
}
return '';
}
/**
* @return string
*/
public function ServiceRaw()
{
$sResult = '';
$sRawError = '';
$sAction = empty($this->aPaths[2]) ? '' : $this->aPaths[2];
$oException = null;
try
{
$sRawError = 'Invalid action';
if (0 !== \strlen($sAction))
{
$sMethodName = 'Raw'.$sAction;
if (\method_exists($this->oActions, $sMethodName))
{
$sRawError = '';
$this->oActions->SetActionParams(array(
'RawKey' => empty($this->aPaths[3]) ? '' : $this->aPaths[3],
'Params' => $this->aPaths
), $sMethodName);
if (!\call_user_func(array($this->oActions, $sMethodName)))
{
$sRawError = 'False result';
}
else
{
$sRawError = '';
}
}
else
{
$sRawError = 'Unknown action "'.$sAction.'"';
}
}
else
{
$sRawError = 'Empty action';
}
}
catch (\RainLoop\Exceptions\ClientException $oException)
{
$sRawError = 'Exception as result';
switch ($oException->getCode())
{
case \RainLoop\Notifications::AuthError:
$sRawError = 'Authentication failed';
break;
}
}
catch (\Exception $oException)
{
$sRawError = 'Exception as result';
}
if (0 < \strlen($sRawError))
{
$this->oActions->Logger()->Write($sRawError, \MailSo\Log\Enumerations\Type::ERROR);
$this->oActions->Logger()->WriteDump($this->aPaths, \MailSo\Log\Enumerations\Type::ERROR, 'PATHS');
}
if ($oException)
{
$this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR, 'RAW');
}
return $sResult;
}
/**
* @return string
*/
public function ServiceLang()
{
// sleep(2);
$sResult = '';
@\header('Content-Type: application/javascript; charset=utf-8');
if (!empty($this->aPaths[2]))
{
$sLanguage = $this->oActions->ValidateLanguage($this->aPaths[2]);
$bCacheEnabled = $this->Config()->Get('labs', 'cache_system_data', true);
if (!empty($sLanguage) && $bCacheEnabled)
{
$this->oActions->verifyCacheByKey($this->sQuery);
}
$sCacheFileName = '';
if ($bCacheEnabled)
{
$sCacheFileName = \RainLoop\KeyPathHelper::LangCache($sLanguage, $this->oActions->Plugins()->Hash());
$sResult = $this->Cacher()->Get($sCacheFileName);
}
if (0 === \strlen($sResult))
{
$sResult = $this->compileLanguage($sLanguage, false);
if ($bCacheEnabled && 0 < \strlen($sCacheFileName))
{
$this->Cacher()->Set($sCacheFileName, $sResult);
}
}
if ($bCacheEnabled)
{
$this->oActions->cacheByKey($this->sQuery);
}
}
return $sResult;
}
/**
* @return string
*/
public function ServiceTemplates()
{
$sResult = '';
@\header('Content-Type: application/javascript; charset=utf-8');
$bCacheEnabled = $this->Config()->Get('labs', 'cache_system_data', true);
if ($bCacheEnabled)
{
$this->oActions->verifyCacheByKey($this->sQuery);
}
$bAdmin = false !== \strpos($this->sQuery, 'Admin');
$sCacheFileName = '';
if ($bCacheEnabled)
{
$sCacheFileName = \RainLoop\KeyPathHelper::TemplatesCache($bAdmin, $this->oActions->Plugins()->Hash());
$sResult = $this->Cacher()->Get($sCacheFileName);
}
if (0 === \strlen($sResult))
{
$sResult = $this->compileTemplates($bAdmin);
if ($bCacheEnabled && 0 < \strlen($sCacheFileName))
{
$this->Cacher()->Set($sCacheFileName, $sResult);
}
}
if ($bCacheEnabled)
{
$this->oActions->cacheByKey($this->sQuery);
}
return $sResult;
}
/**
* @return string
*/
public function ServicePlugins()
{
$sResult = '';
$bAdmin = !empty($this->aPaths[2]) && 'Admin' === $this->aPaths[2];
@\header('Content-Type: application/javascript; charset=utf-8');
$bCacheEnabled = $this->Config()->Get('labs', 'cache_system_data', true);
if ($bCacheEnabled)
{
$this->oActions->verifyCacheByKey($this->sQuery);
}
$sCacheFileName = '';
if ($bCacheEnabled)
{
$sCacheFileName = \RainLoop\KeyPathHelper::PluginsJsCache($this->oActions->Plugins()->Hash());
$sResult = $this->Cacher()->Get($sCacheFileName);
}
if (0 === strlen($sResult))
{
$sResult = $this->Plugins()->CompileJs($bAdmin);
if ($bCacheEnabled && 0 < \strlen($sCacheFileName))
{
$this->Cacher()->Set($sCacheFileName, $sResult);
}
}
if ($bCacheEnabled)
{
$this->oActions->cacheByKey($this->sQuery);
}
return $sResult;
}
/**
* @return string
*/
public function ServiceCss()
{
$sResult = '';
$bAdmin = !empty($this->aPaths[2]) && 'Admin' === $this->aPaths[2];
$bJson = !empty($this->aPaths[9]) && 'Json' === $this->aPaths[9];
if ($bJson)
{
@\header('Content-Type: application/json; charset=utf-8');
}
else
{
@\header('Content-Type: text/css; charset=utf-8');
}
$sTheme = '';
if (!empty($this->aPaths[4]))
{
$sTheme = $this->oActions->ValidateTheme($this->aPaths[4]);
$sRealTheme = $sTheme;
$bCustomTheme = '@custom' === \substr($sTheme, -7);
if ($bCustomTheme)
{
$sRealTheme = \substr($sTheme, 0, -7);
}
$bCacheEnabled = $this->Config()->Get('labs', 'cache_system_data', true);
if ($bCacheEnabled)
{
$this->oActions->verifyCacheByKey($this->sQuery);
}
$sCacheFileName = '';
if ($bCacheEnabled)
{
$sCacheFileName = \RainLoop\KeyPathHelper::CssCache($sTheme, $this->oActions->Plugins()->Hash());
$sResult = $this->Cacher()->Get($sCacheFileName);
}
if (0 === \strlen($sResult))
{
try
{
include_once APP_VERSION_ROOT_PATH.'app/libraries/lessphp/ctype.php';
include_once APP_VERSION_ROOT_PATH.'app/libraries/lessphp/lessc.inc.php';
$oLess = new \lessc();
$oLess->setFormatter('compressed');
$aResult = array();
$sThemeFile = ($bCustomTheme ? APP_INDEX_ROOT_PATH : APP_VERSION_ROOT_PATH).'themes/'.$sRealTheme.'/styles.less';
$sThemeExtFile = ($bCustomTheme ? APP_INDEX_ROOT_PATH : APP_VERSION_ROOT_PATH).'themes/'.$sRealTheme.'/ext.less';
$sThemeValuesFile = APP_VERSION_ROOT_PATH.'app/templates/Themes/values.less';
$sThemeTemplateFile = APP_VERSION_ROOT_PATH.'app/templates/Themes/template.less';
if (\file_exists($sThemeFile) && \file_exists($sThemeTemplateFile) && \file_exists($sThemeValuesFile))
{
$aResult[] = '@base: "'.
($bCustomTheme ? \RainLoop\Utils::WebPath() : \RainLoop\Utils::WebVersionPath()).
'themes/'.$sRealTheme.'/";';
$aResult[] = \file_get_contents($sThemeValuesFile);
$aResult[] = \file_get_contents($sThemeFile);
$aResult[] = \file_get_contents($sThemeTemplateFile);
if (\file_exists($sThemeExtFile))
{
$aResult[] = \file_get_contents($sThemeExtFile);
}
}
$aResult[] = $this->Plugins()->CompileCss($bAdmin);
$sResult = $oLess->compile(\implode("\n", $aResult));
if ($bCacheEnabled)
{
if (0 < \strlen($sCacheFileName))
{
$this->Cacher()->Set($sCacheFileName, $sResult);
}
}
}
catch (\Exception $oException)
{
$this->Logger()->WriteException($oException, \MailSo\Log\Enumerations\Type::ERROR, 'LESS');
}
}
if ($bCacheEnabled)
{
$this->oActions->cacheByKey($this->sQuery);
}
}
return $bJson ? \MailSo\Base\Utils::Php2js(array($sTheme, $sResult), $this->Logger()) : $sResult;
}
/**
* @return string
*/
public function ServiceSocialGoogle()
{
return $this->oActions->Social()->GooglePopupService();
}
/**
* @return string
*/
public function ServiceSocialFacebook()
{
return $this->oActions->Social()->FacebookPopupService();
}
/**
* @return string
*/
public function ServiceSocialTwitter()
{
return $this->oActions->Social()->TwitterPopupService();
}
/**
* @return string
*/
public function ServiceAppData()
{
return $this->localAppData(false);
}
/**
* @return string
*/
public function ServiceAdminAppData()
{
return $this->localAppData(true);
}
/**
* @return string
*/
public function ServiceNoScript()
{
return $this->localError($this->oActions->StaticI18N('STATIC/NO_SCRIPT_TITLE'), $this->oActions->StaticI18N('STATIC/NO_SCRIPT_DESC'));
}
/**
* @return string
*/
public function ServiceNoCookie()
{
return $this->localError($this->oActions->StaticI18N('STATIC/NO_COOKIE_TITLE'), $this->oActions->StaticI18N('STATIC/NO_COOKIE_DESC'));
}
/**
* @return string
*/
public function ServiceBadBrowser()
{
$sTitle = $this->oActions->StaticI18N('STATIC/BAD_BROWSER_TITLE');
$sDesc = \nl2br($this->oActions->StaticI18N('STATIC/BAD_BROWSER_DESC'));
@\header('Content-Type: text/html; charset=utf-8');
return \strtr(\file_get_contents(APP_VERSION_ROOT_PATH.'app/templates/BadBrowser.html'), array(
'{{BaseWebStaticPath}}' => \RainLoop\Utils::WebStaticPath(),
'{{ErrorTitle}}' => $sTitle,
'{{ErrorHeader}}' => $sTitle,
'{{ErrorDesc}}' => $sDesc
));
}
/**
* @return string
*/
public function ServiceMailto()
{
$sTo = \trim($this->oHttp->GetQuery('to', ''));
if (!empty($sTo) && \preg_match('/^mailto:/i', $sTo))
{
$oAccount = $this->oActions->GetAccountFromSignMeToken();
if ($oAccount)
{
$this->oActions->SetMailtoRequest($sTo);
}
}
$this->oActions->Location('./');
return '';
}
/**
* @return string
*/
public function ServicePing()
{
@\header('Content-Type: text/plain; charset=utf-8');
$this->oActions->Logger()->Write('Pong', \MailSo\Log\Enumerations\Type::INFO, 'PING');
return 'Pong';
}
/**
* @return string
*/
public function ServiceInfo()
{
if ($this->oActions->IsAdminLoggined(false))
{
@\header('Content-Type: text/html; charset=utf-8');
\phpinfo();
}
}
/**
* @return string
*/
public function ServiceSso()
{
$oException = null;
$oAccount = null;
$bLogout = true;
$sSsoHash = $this->oHttp->GetRequest('hash', '');
if (!empty($sSsoHash))
{
$mData = null;
$sSsoSubData = $this->Cacher()->Get(\RainLoop\KeyPathHelper::SsoCacherKey($sSsoHash));
if (!empty($sSsoSubData))
{
$mData = \RainLoop\Utils::DecodeKeyValues($sSsoSubData);
$this->Cacher()->Delete(\RainLoop\KeyPathHelper::SsoCacherKey($sSsoHash));
if (\is_array($mData) && !empty($mData['Email']) && isset($mData['Password'], $mData['Time']) &&
(0 === $mData['Time'] || \time() - 10 < $mData['Time']))
{
$sEmail = \trim($mData['Email']);
$sPassword = $mData['Password'];
$aAdditionalOptions = isset($mData['AdditionalOptions']) && \is_array($mData['AdditionalOptions']) &&
0 < \count($mData['AdditionalOptions']) ? $mData['AdditionalOptions'] : null;
try
{
$oAccount = $this->oActions->LoginProcess($sEmail, $sPassword);
if ($oAccount instanceof \RainLoop\Model\Account && $aAdditionalOptions)
{
$bNeedToSettings = false;
$oSettings = $this->SettingsProvider()->Load($oAccount);
if ($oSettings)
{
$sLanguage = isset($aAdditionalOptions['Language']) ?
$aAdditionalOptions['Language'] : '';
if ($sLanguage)
{
$sLanguage = $this->oActions->ValidateLanguage($sLanguage);
if ($sLanguage !== $oSettings->GetConf('Language', ''))
{
$bNeedToSettings = true;
$oSettings->SetConf('Language', $sLanguage);
}
}
}
if ($bNeedToSettings)
{
$this->SettingsProvider()->Save($oAccount, $oSettings);
}
}
$this->oActions->AuthToken($oAccount);
$bLogout = !($oAccount instanceof \RainLoop\Model\Account);
}
catch (\Exception $oException)
{
$this->oActions->Logger()->WriteException($oException);
}
}
}
}
if ($bLogout)
{
$this->oActions->SetAuthLogoutToken();
}
$this->oActions->Location('./');
return '';
}
/**
* @return string
*/
public function ServiceRemoteAutoLogin()
{
$oException = null;
$oAccount = null;
$bLogout = true;
$sEmail = $this->oHttp->GetEnv('REMOTE_USER', '');
$sPassword = $this->oHttp->GetEnv('REMOTE_PASSWORD', '');
if (0 < \strlen($sEmail) && 0 < \strlen(\trim($sPassword)))
{
try
{
$oAccount = $this->oActions->LoginProcess($sEmail, $sPassword);
$this->oActions->AuthToken($oAccount);
$bLogout = !($oAccount instanceof \RainLoop\Model\Account);
}
catch (\Exception $oException)
{
$this->oActions->Logger()->WriteException($oException);
}
}
if ($bLogout)
{
$this->oActions->SetAuthLogoutToken();
}
$this->oActions->Location('./');
return '';
}
/**
* @return string
*/
public function ServiceExternalLogin()
{
$oException = null;
$oAccount = null;
$bLogout = true;
if ($this->oActions->Config()->Get('labs', 'allow_external_login', false))
{
$sEmail = \trim($this->oHttp->GetRequest('Email', ''));
$sPassword = $this->oHttp->GetRequest('Password', '');
try
{
$oAccount = $this->oActions->LoginProcess($sEmail, $sPassword);
$this->oActions->AuthToken($oAccount);
$bLogout = !($oAccount instanceof \RainLoop\Model\Account);
}
catch (\Exception $oException)
{
$this->oActions->Logger()->WriteException($oException);
}
if ($bLogout)
{
$this->oActions->SetAuthLogoutToken();
}
}
switch (\strtolower($this->oHttp->GetRequest('Output', 'Redirect')))
{
case 'json':
@\header('Content-Type: application/json; charset=utf-8');
$aResult = array(
'Action' => 'ExternalLogin',
'Result' => $oAccount instanceof \RainLoop\Model\Account ? true : false,
'ErrorCode' => 0
);
if (!$aResult['Result'])
{
if ($oException instanceof \RainLoop\Exceptions\ClientException)
{
$aResult['ErrorCode'] = $oException->getCode();
}
else
{
$aResult['ErrorCode'] = \RainLoop\Notifications::AuthError;
}
}
return \MailSo\Base\Utils::Php2js($aResult, $this->Logger());
case 'redirect':
default:
$this->oActions->Location('./');
break;
}
return '';
}
/**
* @return string
*/
public function ServiceExternalSso()
{
$sResult = '';
$bLogout = true;
$sKey = $this->oActions->Config()->Get('labs', 'external_sso_key', '');
if ($this->oActions->Config()->Get('labs', 'allow_external_sso', false) &&
!empty($sKey) && $sKey === \trim($this->oHttp->GetRequest('SsoKey', '')))
{
$sEmail = \trim($this->oHttp->GetRequest('Email', ''));
$sPassword = $this->oHttp->GetRequest('Password', '');
$sResult = \RainLoop\Api::GetUserSsoHash($sEmail, $sPassword);
$bLogout = 0 === \strlen($sResult);
switch (\strtolower($this->oHttp->GetRequest('Output', 'Plain')))
{
case 'plain':
@\header('Content-Type: text/plain');
break;
case 'json':
@\header('Content-Type: application/json; charset=utf-8');
$sResult = \MailSo\Base\Utils::Php2js(array(
'Action' => 'ExternalSso',
'Result' => $sResult
), $this->Logger());
break;
}
}
if ($bLogout)
{
$this->oActions->SetAuthLogoutToken();
}
return $sResult;
}
/**
* @return string
*/
public function ServiceChange()
{
$oAccount = $this->oActions->GetAccount();
if ($oAccount && $this->oActions->GetCapa(false, \RainLoop\Enumerations\Capa::ADDITIONAL_ACCOUNTS, $oAccount))
{
$oAccountToLogin = null;
$sEmail = empty($this->aPaths[2]) ? '' : \urldecode(\trim($this->aPaths[2]));
if (!empty($sEmail))
{
$sEmail = \MailSo\Base\Utils::IdnToAscii($sEmail);
$aAccounts = $this->oActions->GetAccounts($oAccount);
if (isset($aAccounts[$sEmail]))
{
$oAccountToLogin = $this->oActions->GetAccountFromCustomToken($aAccounts[$sEmail], false, false);
}
}
if ($oAccountToLogin)
{
$this->oActions->AuthToken($oAccountToLogin);
}
}
$this->oActions->Location('./');
return '';
}
/**
* @param string $sTitle
* @param string $sDesc
*
* @return mixed
*/
public function ErrorTemplates($sTitle, $sDesc, $bShowBackLink = true)
{
return strtr(file_get_contents(APP_VERSION_ROOT_PATH.'app/templates/Error.html'), array(
'{{BaseWebStaticPath}}' => \RainLoop\Utils::WebStaticPath(),
'{{ErrorTitle}}' => $sTitle,
'{{ErrorHeader}}' => $sTitle,
'{{ErrorDesc}}' => $sDesc,
'{{BackLinkVisibilityStyle}}' => $bShowBackLink ? 'display:inline-block' : 'display:none',
'{{BackLink}}' => $this->oActions->StaticI18N('STATIC/BACK_LINK'),
'{{BackHref}}' => './'
));
}
/**
* @param string $sTitle
* @param string $sDesc
*
* @return string
*/
private function localError($sTitle, $sDesc)
{
@header('Content-Type: text/html; charset=utf-8');
return $this->ErrorTemplates($sTitle, \nl2br($sDesc));
}
/**
* @param bool $bAdmin = true
*
* @return string
*/
private function localAppData($bAdmin = false)
{
@\header('Content-Type: application/javascript; charset=utf-8');
$this->oHttp->ServerNoCache();
$sAuthAccountHash = '';
if (!$bAdmin && 0 === \strlen($this->oActions->GetSpecAuthLogoutTokenWithDeletion()))
{
$sAuthAccountHash = $this->oActions->GetSpecAuthTokenWithDeletion();
if (empty($sAuthAccountHash))
{
$sAuthAccountHash = $this->oActions->GetSpecAuthToken();
}
if (empty($sAuthAccountHash))
{
$oAccount = $this->oActions->GetAccountFromSignMeToken();
if ($oAccount)
{
try
{
$this->oActions->CheckMailConnection($oAccount);
$this->oActions->AuthToken($oAccount);
$sAuthAccountHash = $this->oActions->GetSpecAuthToken();
}
catch (\Exception $oException)
{
$oException = null;
$this->oActions->ClearSignMeData($oAccount);
}
}
}
$this->oActions->SetSpecAuthToken($sAuthAccountHash);
}
$sResult = $this->compileAppData($this->oActions->AppData($bAdmin, $sAuthAccountHash), false);
$this->Logger()->Write($sResult, \MailSo\Log\Enumerations\Type::INFO, 'APPDATA');
return $sResult;
}
/**
* @param bool $bAdmin = false
* @param bool $bJsOutput = true
*
* @return string
*/
public function compileTemplates($bAdmin = false, $bJsOutput = true)
{
$sHtml =
\RainLoop\Utils::CompileTemplates(APP_VERSION_ROOT_PATH.'app/templates/Views/Components', $this->oActions, 'Component').
\RainLoop\Utils::CompileTemplates(APP_VERSION_ROOT_PATH.'app/templates/Views/'.($bAdmin ? 'Admin' : 'User'), $this->oActions).
\RainLoop\Utils::CompileTemplates(APP_VERSION_ROOT_PATH.'app/templates/Views/Common', $this->oActions).
$this->oActions->Plugins()->CompileTemplate($bAdmin);
return $bJsOutput ? 'window.rainloopTEMPLATES='.\MailSo\Base\Utils::Php2js(array($sHtml), $this->Logger()).';' : $sHtml;
}
/**
* @param string $sLanguage
*
* @return string
*/
private function convertLanguageNameToMomentLanguageName($sLanguage)
{
switch ($sLanguage)
{
case 'pt-pt':
$sLanguage = 'pt';
break;
case 'ja-jp':
$sLanguage = 'ja';
break;
case 'ko-kr':
$sLanguage = 'ko';
break;
}
return $sLanguage;
}
/**
* @param string $sLanguage
* @param bool $bWrapByScriptTag = true
*
* @return string
*/
private function compileLanguage($sLanguage, $bWrapByScriptTag = true)
{
$aResultLang = array();
$sMoment = 'window.moment && window.moment.lang && window.moment.lang(\'en\');';
$sMomentFileName = APP_VERSION_ROOT_PATH.'app/i18n/moment/'.
$this->convertLanguageNameToMomentLanguageName($sLanguage).'.js';
if (\file_exists($sMomentFileName))
{
$sMoment = \file_get_contents($sMomentFileName);
$sMoment = \preg_replace('/\/\/[^\n]+\n/', '', $sMoment);
}
\RainLoop\Utils::ReadAndAddLang(APP_VERSION_ROOT_PATH.'app/i18n/langs.ini', $aResultLang);
\RainLoop\Utils::ReadAndAddLang(APP_VERSION_ROOT_PATH.'langs/'.$sLanguage.'.ini', $aResultLang);
$this->Plugins()->ReadLang($sLanguage, $aResultLang);
$sLangJs = '';
$aLangKeys = \array_keys($aResultLang);
foreach ($aLangKeys as $sKey)
{
$sString = isset($aResultLang[$sKey]) ? $aResultLang[$sKey] : $sKey;
$sLangJs .= '"'.\str_replace('"', '\\"', \str_replace('\\', '\\\\', $sKey)).'":'
.'"'.\str_replace(array("\r", "\n", "\t"), array('\r', '\n', '\t'),
\str_replace('"', '\\"', \str_replace('\\', '\\\\', $sString))).'",';
}
$sResult = empty($sLangJs) ? 'null' : '{'.\substr($sLangJs, 0, -1).'}';
return
($bWrapByScriptTag ? '' : '')
;
}
/**
* @param array $aAppData
* @param bool $bWrapByScriptTag = true
*
* @return string
*/
private function compileAppData($aAppData, $bWrapByScriptTag = true)
{
return
($bWrapByScriptTag ? '' : '')
;
}
}