1: <?php
2: /**
3: * This code is licensed under AGPLv3 license or Afterlogic Software License
4: * if commercial version of the product was purchased.
5: * For full statements of the licenses see LICENSE-AFTERLOGIC and LICENSE-AGPL3 files.
6: */
7:
8: namespace Aurora\Modules\Ios;
9:
10: /**
11: * @license https://www.gnu.org/licenses/agpl-3.0.html AGPL-3.0
12: * @license https://afterlogic.com/products/common-licensing Afterlogic Software License
13: * @copyright Copyright (c) 2023, Afterlogic Corp.
14: */
15: class Manager extends \Aurora\System\Managers\AbstractManager
16: {
17: /*
18: * @var $oDavModule \Aurora\Modules\Dav\Module
19: */
20: private $oDavModule;
21:
22: /**
23: * @param \Aurora\System\Module\AbstractModule $oModule
24: */
25: public function __construct($oModule = null)
26: {
27: parent::__construct($oModule);
28:
29: /*
30: * @var $oApiDavManager CApiDavManager
31: */
32: $this->oDavModule = \Aurora\System\Api::GetModule('Dav');
33: }
34:
35: /**
36: *
37: * @param type $oXmlDocument
38: * @param array $aPayload
39: *
40: * @return DOMElement
41: */
42: private function _generateDict($oXmlDocument, $aPayload)
43: {
44: $oDictElement = $oXmlDocument->createElement('dict');
45:
46: foreach ($aPayload as $sKey => $mValue) {
47: $oDictElement->appendChild($oXmlDocument->createElement('key', $sKey));
48:
49: if (is_int($mValue)) {
50: $oDictElement->appendChild($oXmlDocument->createElement('integer', $mValue));
51: } elseif (is_bool($mValue)) {
52: $oDictElement->appendChild($oXmlDocument->createElement($mValue ? 'true' : 'false'));
53: } else {
54: $oDictElement->appendChild($oXmlDocument->createElement('string', $mValue));
55: }
56: }
57: return $oDictElement;
58: }
59:
60: /**
61: *
62: * @param type $oXmlDocument
63: * @param string $sPayloadId
64: * @param \Aurora\Modules\StandardAuth\Classes\Account $oAccount
65: * @param bool $bIsDemo Default false
66: *
67: * @return boolean
68: */
69: private function _generateEmailDict($oXmlDocument, $sPayloadId, $oAccount, $bIsDemo = false)
70: {
71: $oModuleManager = \Aurora\System\Api::GetModuleManager();
72:
73: $oServer = $oAccount->GetServer();
74:
75: $sIncomingServer = $oServer->IncomingServer;
76: $iIncomingPort = $oServer->IncomingPort;
77: $bIncomingUseSsl = $oServer->IncomingUseSsl;
78:
79: if ($sIncomingServer == 'localhost' || $sIncomingServer == '127.0.0.1') {
80: $sIncomingServer = $oServer->ExternalAccessImapServer;
81:
82: if (!empty($sIncomingServer)) {
83: $iIncomingPort = $oServer->ExternalAccessImapPort;
84: $bIncomingUseSsl = $oServer->ExternalAccessImapUseSsl;
85: }
86: }
87:
88: $sOutgoingServer = $oServer->OutgoingServer;
89: $iOutgoingPort = $oServer->OutgoingPort;
90: $bOutgoingUseSsl = $oServer->OutgoingUseSsl;
91:
92: if ($sOutgoingServer == 'localhost' || $sOutgoingServer == '127.0.0.1') {
93: $sOutgoingServer = $oServer->ExternalAccessSmtpServer;
94:
95: if (!empty($sOutgoingServer)) {
96: $iOutgoingPort = $oServer->ExternalAccessSmtpPort;
97: $bOutgoingUseSsl = $oServer->ExternalAccessSmtpUseSsl;
98: }
99: }
100:
101: if (empty($sIncomingServer) || empty($sOutgoingServer)) {
102: return false;
103: }
104:
105: $bIncludePasswordInProfile = $this->GetModule()->getConfig('IncludePasswordInProfile', true);
106: $sOutgoingMailServerUsername = $oAccount->IncomingLogin;
107: $sOutgoingPassword = $oAccount->getPassword();
108: $sOutgoingMailServerAuthentication = 'EmailAuthPassword';
109: if (class_exists('\Aurora\Modules\Mail\Enums\SmtpAuthType')) {
110: if ($oServer->SmtpAuthType === \Aurora\Modules\Mail\Enums\SmtpAuthType::UseSpecifiedCredentials) {
111: $sOutgoingMailServerUsername = $oServer->SmtpLogin;
112: $sOutgoingPassword = $oServer->SmtpLogin;
113: }
114: if ($oServer->SmtpAuthType === \Aurora\Modules\Mail\Enums\SmtpAuthType::NoAuthentication) {
115: $sOutgoingMailServerAuthentication = 'EmailAuthNone';
116: }
117: }
118:
119: $aEmail = array(
120: 'PayloadVersion' => 1,
121: 'PayloadUUID' => \Sabre\DAV\UUIDUtil::getUUID(),
122: 'PayloadType' => 'com.apple.mail.managed',
123: 'PayloadIdentifier' => $sPayloadId.'.' . $oAccount->Email . '.email',
124: 'PayloadDisplayName' => $oAccount->Email . ' Email Account',
125: 'PayloadOrganization' => $oModuleManager->getModuleConfigValue('Core', 'SiteName'),
126: 'PayloadDescription' => 'Configures email account',
127: 'EmailAddress' => $oAccount->Email,
128: 'EmailAccountType' => 'EmailTypeIMAP',
129: 'EmailAccountDescription' => $oAccount->Email,
130: 'EmailAccountName' => 0 === strlen($oAccount->FriendlyName)
131: ? $oAccount->Email : $oAccount->FriendlyName,
132: 'IncomingMailServerHostName' => $sIncomingServer,
133: 'IncomingMailServerPortNumber' => $iIncomingPort,
134: 'IncomingMailServerUseSSL' => $bIncomingUseSsl,
135: 'IncomingMailServerUsername' => $oAccount->IncomingLogin,
136: 'IncomingPassword' => $bIsDemo ? 'demo' : ($bIncludePasswordInProfile ? $oAccount->getPassword() : ''),
137: 'IncomingMailServerAuthentication' => 'EmailAuthPassword',
138: 'OutgoingMailServerHostName' => $sOutgoingServer,
139: 'OutgoingMailServerPortNumber' => $iOutgoingPort,
140: 'OutgoingMailServerUseSSL' => $bOutgoingUseSsl,
141: 'OutgoingMailServerUsername' => $sOutgoingMailServerUsername,
142: 'OutgoingPassword' => $bIsDemo ? 'demo' : ($bIncludePasswordInProfile ? $sOutgoingPassword : ''),
143: 'OutgoingMailServerAuthentication' => $sOutgoingMailServerAuthentication,
144: );
145:
146: return $this->_generateDict($oXmlDocument, $aEmail);
147: }
148:
149: private function getAuthenticatedAccountPassword()
150: {
151: $aUserInfo = \Aurora\System\Api::getAuthenticatedUserInfo();
152:
153: $sAccountPassword = '';
154:
155: if (isset($aUserInfo['account']) && isset($aUserInfo['accountType'])) {
156: $oAccount = call_user_func_array([$aUserInfo['accountType'], 'find'], [(int)$aUserInfo['account']]);
157: if ($oAccount) {
158: $sAccountPassword = $oAccount->getPassword();
159: }
160: }
161:
162: return $sAccountPassword;
163: }
164:
165: /**
166: *
167: * @param type $oXmlDocument
168: * @param string $sPayloadId
169: * @param \Aurora\Modules\Core\Classes\User $oUser
170: * @param bool $bIsDemo Default false
171: *
172: * @return DOMElement
173: */
174: private function _generateCaldavDict($oXmlDocument, $sPayloadId, $oUser, $bIsDemo = false)
175: {
176: $oModuleManager = \Aurora\System\Api::GetModuleManager();
177: $bIncludePasswordInProfile = $this->GetModule()->getConfig('IncludePasswordInProfile', true);
178: $aCaldav = array(
179: 'PayloadVersion' => 1,
180: 'PayloadUUID' => \Sabre\DAV\UUIDUtil::getUUID(),
181: 'PayloadType' => 'com.apple.caldav.account',
182: 'PayloadIdentifier' => $sPayloadId.'.caldav',
183: 'PayloadDisplayName' => $oUser->PublicId . ' - CalDAV Account',
184: 'PayloadOrganization' => $oModuleManager->getModuleConfigValue('Core', 'SiteName'),
185: 'PayloadDescription' => 'Configures CalDAV Account',
186: 'CalDAVAccountDescription' => $oModuleManager->getModuleConfigValue('Core', 'SiteName') . ' Calendars',
187: 'CalDAVHostName' => $this->oDavModule ? $this->oDavModule->GetServerHost() : '',
188: 'CalDAVUsername' => $oUser->PublicId,
189: 'CalDAVPassword' => $bIsDemo ? 'demo' : ($bIncludePasswordInProfile ? $this->getAuthenticatedAccountPassword() : ''),
190: 'CalDAVUseSSL' => $this->oDavModule ? $this->oDavModule->IsSsl() : '',
191: 'CalDAVPort' => $this->oDavModule ? $this->oDavModule->GetServerPort() : '',
192: 'CalDAVPrincipalURL' => $this->oDavModule ? $this->oDavModule->GetPrincipalUrl() : '',
193: );
194:
195: return $this->_generateDict($oXmlDocument, $aCaldav);
196: }
197:
198: /**
199: *
200: * @param type $oXmlDocument
201: * @param string $sPayloadId
202: * @param \Aurora\Modules\Core\Classes\User $oUser
203: * @param bool $bIsDemo Default false
204: *
205: * @return DOMElement
206: */
207:
208: private function _generateCarddavDict($oXmlDocument, $sPayloadId, $oUser, $bIsDemo = false)
209: {
210: $oModuleManager = \Aurora\System\Api::GetModuleManager();
211: $bIncludePasswordInProfile = $this->GetModule()->getConfig('IncludePasswordInProfile', true);
212: $aCarddav = array(
213: 'PayloadVersion' => 1,
214: 'PayloadUUID' => \Sabre\DAV\UUIDUtil::getUUID(),
215: 'PayloadType' => 'com.apple.carddav.account',
216: 'PayloadIdentifier' => $sPayloadId.'.carddav',
217: 'PayloadDisplayName' => $oUser->PublicId . ' - CardDAV Account',
218: 'PayloadOrganization' => $oModuleManager->getModuleConfigValue('Core', 'SiteName'),
219: 'PayloadDescription' => 'Configures CardDAV Account',
220: 'CardDAVAccountDescription' => $oModuleManager->getModuleConfigValue('Core', 'SiteName') . ' Contacts',
221: 'CardDAVHostName' => $this->oDavModule ? $this->oDavModule->GetServerHost() : '',
222: 'CardDAVUsername' => $oUser->PublicId,
223: 'CardDAVPassword' => $bIsDemo ? 'demo' : ($bIncludePasswordInProfile ? $this->getAuthenticatedAccountPassword() : ''),
224: 'CardDAVUseSSL' => $this->oDavModule ? $this->oDavModule->IsSsl() : '',
225: 'CardDAVPort' => $this->oDavModule ? $this->oDavModule->GetServerPort() : '',
226: 'CardDAVPrincipalURL' => $this->oDavModule ? $this->oDavModule->GetPrincipalUrl() : '',
227: );
228:
229: return $this->_generateDict($oXmlDocument, $aCarddav);
230: }
231:
232: /**
233: * @param \Aurora\Modules\Core\Models\User $oUser
234: * @return string
235: */
236: public function generateXMLProfile($oUser)
237: {
238: $mResult = false;
239:
240: if ($oUser) {
241: $oDomImplementation = new \DOMImplementation();
242: $oDocumentType = $oDomImplementation->createDocumentType(
243: 'plist',
244: '-//Apple//DTD PLIST 1.0//EN',
245: 'http://www.apple.com/DTDs/PropertyList-1.0.dtd'
246: );
247:
248: $oXmlDocument = $oDomImplementation->createDocument('', '', $oDocumentType);
249: $oXmlDocument->xmlVersion = '1.0';
250: $oXmlDocument->encoding = 'UTF-8';
251: $oXmlDocument->formatOutput = true;
252:
253: $oPlist = $oXmlDocument->createElement('plist');
254: $oPlist->setAttribute('version', '1.0');
255:
256: $sPayloadId = $this->oDavModule ? 'afterlogic.'.$this->oDavModule->GetServerHost() . '.' . $oUser->PublicId : '';
257:
258: $oModuleManager = \Aurora\System\Api::GetModuleManager();
259: $aPayload = array(
260: 'PayloadVersion' => 1,
261: 'PayloadUUID' => \Sabre\DAV\UUIDUtil::getUUID(),
262: 'PayloadType' => 'Configuration',
263: 'PayloadRemovalDisallowed' => false,
264: 'PayloadIdentifier' => $sPayloadId,
265: 'PayloadOrganization' => $oModuleManager->getModuleConfigValue('Core', 'SiteName'),
266: 'PayloadDescription' => $oModuleManager->getModuleConfigValue('Core', 'SiteName') . ' Mobile',
267: 'PayloadDisplayName' => $oModuleManager->getModuleConfigValue('Core', 'SiteName') . ' (' . $oUser->PublicId . ') Mobile Profile',
268: );
269:
270: $oArrayElement = $oXmlDocument->createElement('array');
271:
272: $oDemoModePlugin = \Aurora\System\Api::GetModule('DemoModePlugin');
273: $bIsDemo = false;
274: if (!($oDemoModePlugin && $oDemoModePlugin->IsDemoUser())) {
275: $oMailModule = \Aurora\System\Api::GetModule('Mail');
276: if ($oMailModule) {
277: $aAccounts = $oMailModule->GetAccounts($oUser->Id);
278: if (is_array($aAccounts) && 0 < count($aAccounts)) {
279: foreach ($aAccounts as $oAccountItem) {
280: $oEmailDictElement = $this->_generateEmailDict($oXmlDocument, $sPayloadId, $oAccountItem, $bIsDemo);
281:
282: if ($oEmailDictElement === false) {
283: return false;
284: } else {
285: $oArrayElement->appendChild($oEmailDictElement);
286: }
287:
288: unset($oAccountItem);
289: unset($oEmailDictElement);
290: }
291: }
292: }
293: } else {
294: $bIsDemo = true;
295: }
296:
297:
298: $oMobileSyncModule = \Aurora\System\Api::GetModule('MobileSync');
299: if ($oMobileSyncModule && !$oMobileSyncModule->getConfig('Disabled', false)) {
300: // Calendars
301: $oCaldavDictElement = $this->_generateCaldavDict($oXmlDocument, $sPayloadId, $oUser, $bIsDemo);
302: $oArrayElement->appendChild($oCaldavDictElement);
303:
304: // Contacts
305: $oCarddavDictElement = $this->_generateCarddavDict($oXmlDocument, $sPayloadId, $oUser, $bIsDemo);
306: $oArrayElement->appendChild($oCarddavDictElement);
307: }
308:
309: $oDictElement = $this->_generateDict($oXmlDocument, $aPayload);
310: $oPayloadContentElement = $oXmlDocument->createElement('key', 'PayloadContent');
311: $oDictElement->appendChild($oPayloadContentElement);
312: $oDictElement->appendChild($oArrayElement);
313: $oPlist->appendChild($oDictElement);
314:
315: $oXmlDocument->appendChild($oPlist);
316: $mResult = $oXmlDocument->saveXML();
317: }
318:
319: return $mResult;
320: }
321: }
322: