/rainloop/v/0.0.0/app/libraries/RainLoop/Model/Account.php

https://gitlab.com/wuhang2003/rainloop-webmail · PHP · 576 lines · 328 code · 78 blank · 170 comment · 16 complexity · 737b60181ca8791293018171aefccf8d MD5 · raw file

  1. <?php
  2. namespace RainLoop\Model;
  3. class Account extends \RainLoop\Account // for backward compatibility
  4. {
  5. /**
  6. * @var string
  7. */
  8. private $sEmail;
  9. /**
  10. * @var string
  11. */
  12. private $sLogin;
  13. /**
  14. * @var int
  15. */
  16. private $sPassword;
  17. /**
  18. * @var string
  19. */
  20. private $sProxyAuthUser;
  21. /**
  22. * @var string
  23. */
  24. private $sProxyAuthPassword;
  25. /**
  26. * @var string
  27. */
  28. private $sSignMeToken;
  29. /**
  30. * @var \RainLoop\Model\Domain
  31. */
  32. private $oDomain;
  33. /**
  34. * @var string
  35. */
  36. private $sParentEmail;
  37. /**
  38. * @param string $sEmail
  39. * @param string $sLogin
  40. * @param string $sPassword
  41. * @param \RainLoop\Model\Domain $oDomain
  42. * @param string $sSignMeToken = ''
  43. * @param string $sProxyAuthUser = ''
  44. * @param string $sProxyAuthPassword = ''
  45. *
  46. * @return void
  47. */
  48. protected function __construct($sEmail, $sLogin, $sPassword, \RainLoop\Model\Domain $oDomain,
  49. $sSignMeToken = '', $sProxyAuthUser = '', $sProxyAuthPassword = '')
  50. {
  51. $this->sEmail = \MailSo\Base\Utils::IdnToAscii($sEmail, true);
  52. $this->sLogin = \MailSo\Base\Utils::IdnToAscii($sLogin);
  53. $this->sPassword = $sPassword;
  54. $this->oDomain = $oDomain;
  55. $this->sSignMeToken = $sSignMeToken;
  56. $this->sProxyAuthUser = $sProxyAuthUser;
  57. $this->sProxyAuthPassword = $sProxyAuthPassword;
  58. $this->sParentEmail = '';
  59. }
  60. /**
  61. * @param string $sEmail
  62. * @param string $sLogin
  63. * @param string $sPassword
  64. * @param \RainLoop\Model\Domain $oDomain
  65. * @param string $sSignMeToken = ''
  66. * @param string $sProxyAuthUser = ''
  67. * @param string $sProxyAuthPassword = ''
  68. *
  69. * @return \RainLoop\Model\Account
  70. */
  71. public static function NewInstance($sEmail, $sLogin, $sPassword, \RainLoop\Model\Domain $oDomain,
  72. $sSignMeToken = '', $sProxyAuthUser = '', $sProxyAuthPassword = '')
  73. {
  74. return new self($sEmail, $sLogin, $sPassword, $oDomain, $sSignMeToken, $sProxyAuthUser, $sProxyAuthPassword);
  75. }
  76. /**
  77. * @return string
  78. */
  79. public function Email()
  80. {
  81. return $this->sEmail;
  82. }
  83. /**
  84. * @return string
  85. */
  86. public function ParentEmail()
  87. {
  88. return $this->sParentEmail;
  89. }
  90. /**
  91. * @return string
  92. */
  93. public function ProxyAuthUser()
  94. {
  95. return $this->sProxyAuthUser;
  96. }
  97. /**
  98. * @return string
  99. */
  100. public function ProxyAuthPassword()
  101. {
  102. return $this->sProxyAuthPassword;
  103. }
  104. /**
  105. * @return string
  106. */
  107. public function ParentEmailHelper()
  108. {
  109. return 0 < \strlen($this->sParentEmail) ? $this->sParentEmail : $this->sEmail;
  110. }
  111. /**
  112. * @return string
  113. */
  114. public function IsAdditionalAccount()
  115. {
  116. return 0 < \strlen($this->sParentEmail);
  117. }
  118. /**
  119. * @return string
  120. */
  121. public function IncLogin()
  122. {
  123. $sLogin = $this->sLogin;
  124. if ($this->oDomain->IncShortLogin())
  125. {
  126. $sLogin = \MailSo\Base\Utils::GetAccountNameFromEmail($this->sLogin);
  127. }
  128. return $sLogin;
  129. }
  130. /**
  131. * @return string
  132. */
  133. public function IncPassword()
  134. {
  135. return $this->sPassword;
  136. }
  137. /**
  138. * @return string
  139. */
  140. public function OutLogin()
  141. {
  142. $sLogin = $this->sLogin;
  143. if ($this->oDomain->OutShortLogin())
  144. {
  145. $sLogin = \MailSo\Base\Utils::GetAccountNameFromEmail($this->sLogin);
  146. }
  147. return $sLogin;
  148. }
  149. /**
  150. * @return string
  151. */
  152. public function Login()
  153. {
  154. return $this->IncLogin();
  155. }
  156. /**
  157. * @return string
  158. */
  159. public function Password()
  160. {
  161. return $this->IncPassword();
  162. }
  163. /**
  164. * @return bool
  165. */
  166. public function SignMe()
  167. {
  168. return 0 < \strlen($this->sSignMeToken);
  169. }
  170. /**
  171. * @return string
  172. */
  173. public function SignMeToken()
  174. {
  175. return $this->sSignMeToken;
  176. }
  177. /**
  178. * @return \RainLoop\Model\Domain
  179. */
  180. public function Domain()
  181. {
  182. return $this->oDomain;
  183. }
  184. /**
  185. * @return string
  186. */
  187. public function Hash()
  188. {
  189. return md5(APP_SALT.$this->Email().APP_SALT.$this->DomainIncHost().
  190. APP_SALT.$this->DomainIncPort().APP_SALT.$this->Password().APP_SALT.'0'.APP_SALT.$this->ParentEmail().APP_SALT);
  191. }
  192. /**
  193. * @param string $sPassword
  194. *
  195. * @return void
  196. */
  197. public function SetPassword($sPassword)
  198. {
  199. $this->sPassword = $sPassword;
  200. }
  201. /**
  202. * @param string $sParentEmail
  203. *
  204. * @return void
  205. */
  206. public function SetParentEmail($sParentEmail)
  207. {
  208. $this->sParentEmail = \trim(\MailSo\Base\Utils::IdnToAscii($sParentEmail, true));
  209. }
  210. /**
  211. * @param string $sProxyAuthUser
  212. *
  213. * @return void
  214. */
  215. public function SetProxyAuthUser($sProxyAuthUser)
  216. {
  217. return $this->sProxyAuthUser = $sProxyAuthUser;
  218. }
  219. /**
  220. * @param string $sProxyAuthPassword
  221. *
  222. * @return void
  223. */
  224. public function SetProxyAuthPassword($sProxyAuthPassword)
  225. {
  226. return $this->sProxyAuthPassword = $sProxyAuthPassword;
  227. }
  228. /**
  229. * @return string
  230. */
  231. public function DomainIncHost()
  232. {
  233. return $this->Domain()->IncHost();
  234. }
  235. /**
  236. * @return int
  237. */
  238. public function DomainIncPort()
  239. {
  240. return $this->Domain()->IncPort();
  241. }
  242. /**
  243. * @return int
  244. */
  245. public function DomainIncSecure()
  246. {
  247. return $this->Domain()->IncSecure();
  248. }
  249. /**
  250. * @return string
  251. */
  252. public function DomainOutHost()
  253. {
  254. return $this->Domain()->OutHost();
  255. }
  256. /**
  257. * @return int
  258. */
  259. public function DomainOutPort()
  260. {
  261. return $this->Domain()->OutPort();
  262. }
  263. /**
  264. * @return int
  265. */
  266. public function DomainOutSecure()
  267. {
  268. return $this->Domain()->OutSecure();
  269. }
  270. /**
  271. * @return bool
  272. */
  273. public function DomainOutAuth()
  274. {
  275. return $this->Domain()->OutAuth();
  276. }
  277. /**
  278. * @return string
  279. */
  280. public function DomainSieveHost()
  281. {
  282. return $this->Domain()->SieveHost();
  283. }
  284. /**
  285. * @return int
  286. */
  287. public function DomainSievePort()
  288. {
  289. return $this->Domain()->SievePort();
  290. }
  291. /**
  292. * @return int
  293. */
  294. public function DomainSieveSecure()
  295. {
  296. return $this->Domain()->SieveSecure();
  297. }
  298. /**
  299. * @return bool
  300. */
  301. public function DomainSieveAllowRaw()
  302. {
  303. return $this->Domain()->SieveAllowRaw();
  304. }
  305. /**
  306. * @return string
  307. */
  308. public function GetAuthToken()
  309. {
  310. return \RainLoop\Utils::EncodeKeyValues(array(
  311. 'token', // 0
  312. $this->sEmail, // 1
  313. $this->sLogin, // 2
  314. $this->sPassword, // 3
  315. \RainLoop\Utils::Fingerprint(), // 4
  316. $this->sSignMeToken, // 5
  317. $this->sParentEmail, // 6
  318. \RainLoop\Utils::GetShortToken(), // 7
  319. $this->sProxyAuthUser, // 8
  320. $this->sProxyAuthPassword, // 9
  321. 0 // 10 // timelife
  322. ));
  323. }
  324. /**
  325. * @return string
  326. */
  327. public function GetAuthTokenQ()
  328. {
  329. return \RainLoop\Utils::EncodeKeyValuesQ(array(
  330. 'token', // 0
  331. $this->sEmail, // 1
  332. $this->sLogin, // 2
  333. $this->sPassword, // 3
  334. \RainLoop\Utils::Fingerprint(), // 4
  335. $this->sSignMeToken, // 5
  336. $this->sParentEmail, // 6
  337. \RainLoop\Utils::GetShortToken(), // 7
  338. $this->sProxyAuthUser, // 8
  339. $this->sProxyAuthPassword, // 9
  340. 0 // 10 // timelife
  341. ));
  342. }
  343. /**
  344. * @param \RainLoop\Plugins\Manager $oPlugins
  345. * @param \MailSo\Mail\MailClient $oMailClient
  346. * @param \RainLoop\Application $oConfig
  347. *
  348. * @return bool
  349. */
  350. public function IncConnectAndLoginHelper($oPlugins, $oMailClient, $oConfig)
  351. {
  352. $bLogin = false;
  353. $aImapCredentials = array(
  354. 'UseConnect' => true,
  355. 'UseAuth' => true,
  356. 'Host' => $this->DomainIncHost(),
  357. 'Port' => $this->DomainIncPort(),
  358. 'Secure' => $this->DomainIncSecure(),
  359. 'Login' => $this->IncLogin(),
  360. 'Password' => $this->Password(),
  361. 'ProxyAuthUser' => $this->ProxyAuthUser(),
  362. 'ProxyAuthPassword' => $this->ProxyAuthPassword(),
  363. 'VerifySsl' => !!$oConfig->Get('ssl', 'verify_certificate', false),
  364. 'AllowSelfSigned' => !!$oConfig->Get('ssl', 'allow_self_signed', true),
  365. 'UseAuthPlainIfSupported' => !!$oConfig->Get('labs', 'use_imap_auth_plain'),
  366. 'UseAuthCramMd5IfSupported' => !!$oConfig->Get('labs', 'use_imap_auth_cram_md5')
  367. );
  368. $oPlugins->RunHook('filter.imap-credentials', array($this, &$aImapCredentials));
  369. $oPlugins->RunHook('event.imap-pre-connect', array($this, $aImapCredentials['UseConnect'], $aImapCredentials));
  370. if ($aImapCredentials['UseConnect'])
  371. {
  372. $oMailClient
  373. ->Connect($aImapCredentials['Host'], $aImapCredentials['Port'],
  374. $aImapCredentials['Secure'], $aImapCredentials['VerifySsl'], $aImapCredentials['AllowSelfSigned']);
  375. }
  376. $oPlugins->RunHook('event.imap-pre-login', array($this, $aImapCredentials['UseAuth'], $aImapCredentials));
  377. if ($aImapCredentials['UseAuth'])
  378. {
  379. if (0 < \strlen($aImapCredentials['ProxyAuthUser']) &&
  380. 0 < \strlen($aImapCredentials['ProxyAuthPassword']))
  381. {
  382. $oMailClient
  383. ->Login($aImapCredentials['ProxyAuthUser'], $aImapCredentials['ProxyAuthPassword'],
  384. $aImapCredentials['Login'], $aImapCredentials['UseAuthPlainIfSupported'], $aImapCredentials['UseAuthCramMd5IfSupported']);
  385. }
  386. else
  387. {
  388. $iGatLen = \strlen(APP_GOOGLE_ACCESS_TOKEN_PREFIX);
  389. $sPassword = $aImapCredentials['Password'];
  390. if (APP_GOOGLE_ACCESS_TOKEN_PREFIX === \substr($sPassword, 0, $iGatLen))
  391. {
  392. $oMailClient->LoginWithXOauth2(
  393. \base64_encode('user='.$aImapCredentials['Login']."\1".'auth=Bearer '.\substr($sPassword, $iGatLen)."\1\1"));
  394. }
  395. else
  396. {
  397. $oMailClient->Login($aImapCredentials['Login'], $aImapCredentials['Password'], '',
  398. $aImapCredentials['UseAuthPlainIfSupported'], $aImapCredentials['UseAuthCramMd5IfSupported']);
  399. }
  400. }
  401. $bLogin = true;
  402. }
  403. $oPlugins->RunHook('event.imap-post-login', array($this, $aImapCredentials['UseAuth'], $bLogin, $aImapCredentials));
  404. return $bLogin;
  405. }
  406. /**
  407. * @param \RainLoop\Plugins\Manager $oPlugins
  408. * @param \MailSo\Smtp\SmtpClient|null $oSmtpClient
  409. * @param \RainLoop\Application $oConfig
  410. * @param bool $bUsePhpMail = false
  411. *
  412. * @return bool
  413. */
  414. public function OutConnectAndLoginHelper($oPlugins, $oSmtpClient, $oConfig, &$bUsePhpMail = false)
  415. {
  416. $bLogin = false;
  417. $aSmtpCredentials = array(
  418. 'UseConnect' => true,
  419. 'UseAuth' => $this->DomainOutAuth(),
  420. 'UsePhpMail' => $bUsePhpMail,
  421. 'Ehlo' => \MailSo\Smtp\SmtpClient::EhloHelper(),
  422. 'Host' => $this->DomainOutHost(),
  423. 'Port' => $this->DomainOutPort(),
  424. 'Secure' => $this->DomainOutSecure(),
  425. 'Login' => $this->OutLogin(),
  426. 'Password' => $this->Password(),
  427. 'ProxyAuthUser' => $this->ProxyAuthUser(),
  428. 'ProxyAuthPassword' => $this->ProxyAuthPassword(),
  429. 'VerifySsl' => !!$oConfig->Get('ssl', 'verify_certificate', false),
  430. 'AllowSelfSigned' => !!$oConfig->Get('ssl', 'allow_self_signed', true)
  431. );
  432. $oPlugins->RunHook('filter.smtp-credentials', array($this, &$aSmtpCredentials));
  433. $bUsePhpMail = $aSmtpCredentials['UsePhpMail'];
  434. $oPlugins->RunHook('event.smtp-pre-connect', array($this, $aSmtpCredentials['UseConnect'], $aSmtpCredentials));
  435. if ($aSmtpCredentials['UseConnect'] && !$aSmtpCredentials['UsePhpMail'] && $oSmtpClient)
  436. {
  437. $oSmtpClient->Connect($aSmtpCredentials['Host'], $aSmtpCredentials['Port'], $aSmtpCredentials['Ehlo'],
  438. $aSmtpCredentials['Secure'], $aSmtpCredentials['VerifySsl'], $aSmtpCredentials['AllowSelfSigned']
  439. );
  440. }
  441. $oPlugins->RunHook('event.smtp-post-connect', array($this, $aSmtpCredentials['UseConnect'], $aSmtpCredentials));
  442. $oPlugins->RunHook('event.smtp-pre-login', array($this, $aSmtpCredentials['UseAuth'], $aSmtpCredentials));
  443. if ($aSmtpCredentials['UseAuth'] && !$aSmtpCredentials['UsePhpMail'] && $oSmtpClient)
  444. {
  445. $iGatLen = \strlen(APP_GOOGLE_ACCESS_TOKEN_PREFIX);
  446. $sPassword = $aSmtpCredentials['Password'];
  447. if (APP_GOOGLE_ACCESS_TOKEN_PREFIX === \substr($sPassword, 0, $iGatLen))
  448. {
  449. $oSmtpClient->LoginWithXOauth2(
  450. \base64_encode('user='.$aSmtpCredentials['Login']."\1".'auth=Bearer '.\substr($sPassword, $iGatLen)."\1\1"));
  451. }
  452. else
  453. {
  454. $oSmtpClient->Login($aSmtpCredentials['Login'], $aSmtpCredentials['Password']);
  455. }
  456. $bLogin = true;
  457. }
  458. $oPlugins->RunHook('event.smtp-post-login', array($this, $aSmtpCredentials['UseAuth'], $bLogin, $aSmtpCredentials));
  459. return $bLogin;
  460. }
  461. /**
  462. * @param \RainLoop\Plugins\Manager $oPlugins
  463. * @param \MailSo\Sieve\ManageSieveClient $oSieveClient
  464. * @param \RainLoop\Application $oConfig
  465. */
  466. public function SieveConnectAndLoginHelper($oPlugins, $oSieveClient, $oConfig)
  467. {
  468. $bLogin = false;
  469. $aSieveCredentials = array(
  470. 'UseConnect' => true,
  471. 'UseAuth' => true,
  472. 'Host' => $this->DomainSieveHost(),
  473. 'Port' => $this->DomainSievePort(),
  474. 'Secure' => $this->DomainSieveSecure(),
  475. 'Login' => $this->IncLogin(),
  476. 'Password' => $this->Password(),
  477. 'VerifySsl' => !!$oConfig->Get('ssl', 'verify_certificate', false),
  478. 'AllowSelfSigned' => !!$oConfig->Get('ssl', 'allow_self_signed', true)
  479. );
  480. $oPlugins->RunHook('filter.sieve-credentials', array($this, &$aSieveCredentials));
  481. $oPlugins->RunHook('event.sieve-pre-connect', array($this, $aSieveCredentials['UseConnect'], $aSieveCredentials));
  482. if ($aSieveCredentials['UseConnect'] && $oSieveClient)
  483. {
  484. $oSieveClient->Connect($aSieveCredentials['Host'], $aSieveCredentials['Port'],
  485. $aSieveCredentials['Secure'], $aSieveCredentials['VerifySsl'], $aSieveCredentials['AllowSelfSigned']
  486. );
  487. }
  488. $oPlugins->RunHook('event.sieve-post-connect', array($this, $aSieveCredentials['UseConnect'], $aSieveCredentials));
  489. $oPlugins->RunHook('event.sieve-pre-login', array($this, $aSieveCredentials['UseAuth'], $aSieveCredentials));
  490. if ($aSieveCredentials['UseAuth'])
  491. {
  492. $oSieveClient->Login($aSieveCredentials['Login'], $aSieveCredentials['Password']);
  493. $bLogin = true;
  494. }
  495. $oPlugins->RunHook('event.sieve-post-login', array($this, $aSieveCredentials['UseAuth'], $bLogin, $aSieveCredentials));
  496. return $bLogin;
  497. }
  498. }