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\Dav;
9:
10: /**
11: * Integrate SabreDav framework into Aurora platform.
12: *
13: * @license https://www.gnu.org/licenses/agpl-3.0.html AGPL-3.0
14: * @license https://afterlogic.com/products/common-licensing Afterlogic Software License
15: * @copyright Copyright (c) 2023, Afterlogic Corp.
16: *
17: * @package Modules
18: */
19: class Module extends \Aurora\System\Module\AbstractModule
20: {
21: public $oManager = null;
22:
23: public function getManager()
24: {
25: if ($this->oManager === null) {
26: $this->oManager = new Manager($this);
27: }
28:
29: return $this->oManager;
30: }
31:
32: public function GetModuleManager()
33: {
34: return parent::GetModuleManager();
35: }
36:
37: /***** private functions *****/
38: /**
39: * Initializes DAV Module.
40: *
41: * @ignore
42: */
43: public function init()
44: {
45: $this->AddEntry('dav', 'EntryDav');
46:
47: $this->subscribeEvent('Calendar::GetCalendars::after', array($this, 'onAfterGetCalendars'));
48: $this->subscribeEvent('MobileSync::GetInfo', array($this, 'onGetMobileSyncInfo'));
49: }
50:
51: /**
52: * Writes in $aParameters DAV server URL.
53: *
54: * @ignore
55: * @param array $aArgs
56: */
57: public function onAfterGetCalendars(&$aArgs, &$mResult)
58: {
59: if (isset($mResult) && $mResult !== false) {
60: $mResult['ServerUrl'] = $this->GetServerUrl();
61: }
62: }
63:
64: /**
65: * Writes in $aData information about DAV server.
66: *
67: * @ignore
68: * @param array $mResult
69: */
70: public function onGetMobileSyncInfo($aArgs, &$mResult)
71: {
72: $mResult['EnableDav'] = true;
73: $mResult['Dav']['Login'] = $this->GetLogin();
74: $mResult['Dav']['Server'] = $this->GetServerUrl();
75: $mResult['Dav']['PrincipalUrl'] = $this->GetPrincipalUrl();
76: }
77:
78: /**
79: * Creates tables required for module work. Called by event subscribe.
80: *
81: * @ignore
82: * @param array $aArgs Parameters
83: * @param mixed $mResult
84: */
85: public function onAfterCreateTables($aArgs, &$mResult)
86: {
87: // if ($mResult)
88: // {
89: // $mResult = self::Decorator()->CreateTables();
90: // }
91: }
92: /***** private functions *****/
93:
94: /***** public functions *****/
95:
96: /**
97: * @ignore
98: * @return void
99: */
100: public function EntryDav()
101: {
102: set_error_handler(function ($errno, $errstr, $errfile, $errline) {
103: throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
104: });
105:
106: @set_time_limit(3000);
107:
108: $sRequestUri = empty($_SERVER['REQUEST_URI']) ? '' : \trim($_SERVER['REQUEST_URI']);
109:
110: $oServer = \Afterlogic\DAV\Server::getInstance();
111: $oServer->setBaseUri($sRequestUri);
112:
113: \Afterlogic\DAV\Server::getInstance()->exec();
114: }
115:
116: /**
117: * Returns DAV client.
118: *
119: * @return \Aurora\Modules\Dav\Client|false
120: */
121: public function GetDavClient()
122: {
123: \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser);
124:
125: return $this->getManager()->GetDAVClient(\Aurora\System\Api::getAuthenticatedUserId());
126: }
127:
128: /**
129: * Returns VCARD object.
130: *
131: * @param string|resource $Data
132: * @return Document
133: */
134: public function GetVCardObject($Data)
135: {
136: \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser);
137:
138: return $this->getManager()->getVCardObject($Data);
139: }
140: /***** public functions *****/
141:
142: /***** public functions might be called with web API *****/
143: /**
144: * @apiDefine Dav Dav Module
145: * Integrate SabreDav framework into Aurora platform
146: */
147:
148: /**
149: * @api {post} ?/Api/ GetSettings
150: * @apiName GetSettings
151: * @apiGroup Dav
152: * @apiDescription Obtains list of module settings for authenticated user.
153: *
154: * @apiHeader {string} [Authorization] "Bearer " + Authentication token which was received as the result of Core.Login method.
155: * @apiHeaderExample {json} Header-Example:
156: * {
157: * "Authorization": "Bearer 32b2ecd4a4016fedc4abee880425b6b8"
158: * }
159: *
160: * @apiParam {string=Dav} Module Module name.
161: * @apiParam {string=GetSettings} Method Method name.
162: *
163: * @apiParamExample {json} Request-Example:
164: * {
165: * Module: 'Dav',
166: * Method: 'GetSettings'
167: * }
168: *
169: * @apiSuccess {object[]} Result Array of response objects.
170: * @apiSuccess {string} Result.Module Module name.
171: * @apiSuccess {string} Result.Method Method name.
172: * @apiSuccess {mixed} Result.Result Object in case of success, otherwise **false**.
173: * @apiSuccess {string} Result.Result.ExternalHostNameOfDAVServer External host name of DAV server.
174: * @apiSuccess {int} [Result.ErrorCode] Error code.
175: *
176: * @apiSuccessExample {json} Success response example:
177: * {
178: * Module: 'Dav',
179: * Method: 'GetSettings',
180: * Result: [{ExternalHostNameOfDAVServer: 'host_value'}]
181: * }
182: *
183: * @apiSuccessExample {json} Error response example:
184: * {
185: * Module: 'Dav',
186: * Method: 'GetSettings',
187: * Result: false,
188: * ErrorCode: 102
189: * }
190: */
191: /**
192: * Obtains list of module settings for authenticated user.
193: *
194: * @return array
195: */
196: public function GetSettings()
197: {
198: \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous);
199:
200: return array(
201: 'ExternalHostNameOfDAVServer' => $this->GetServerUrl()
202: );
203: }
204:
205: /**
206: * @api {post} ?/Api/ UpdateSettings
207: * @apiName UpdateSettings
208: * @apiGroup Dav
209: * @apiDescription Updates module's settings - saves them to config.json file.
210: *
211: * @apiHeader {string} Authorization "Bearer " + Authentication token which was received as the result of Core.Login method.
212: * @apiHeaderExample {json} Header-Example:
213: * {
214: * "Authorization": "Bearer 32b2ecd4a4016fedc4abee880425b6b8"
215: * }
216: *
217: * @apiParam {string=Dav} Module Module name.
218: * @apiParam {string=UpdateSettings} Method Method name.
219: * @apiParam {string} Parameters JSON.stringified object <br>
220: * {<br>
221: * &emsp; **ExternalHostNameOfDAVServer** *string* External host name of DAV server.<br>
222: * }
223: *
224: * @apiParamExample {json} Request-Example:
225: * {
226: * Module: 'Dav',
227: * Method: 'UpdateSettings',
228: * Parameters: '{ ExternalHostNameOfDAVServer: "host_value" }'
229: * }
230: *
231: * @apiSuccess {object[]} Result Array of response objects.
232: * @apiSuccess {string} Result.Module Module name.
233: * @apiSuccess {string} Result.Method Method name.
234: * @apiSuccess {bool} Result.Result Indicates if settings were updated successfully.
235: * @apiSuccess {int} [Result.ErrorCode] Error code.
236: *
237: * @apiSuccessExample {json} Success response example:
238: * {
239: * Module: 'Dav',
240: * Method: 'UpdateSettings',
241: * Result: true
242: * }
243: *
244: * @apiSuccessExample {json} Error response example:
245: * {
246: * Module: 'Dav',
247: * Method: 'UpdateSettings',
248: * Result: false,
249: * ErrorCode: 102
250: * }
251: */
252: /**
253: * Updates module's settings - saves them to config.json file.
254: *
255: * @param string $ExternalHostNameOfDAVServer External host name of DAV server.
256: * @return bool
257: */
258: public function UpdateSettings($ExternalHostNameOfDAVServer)
259: {
260: \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::TenantAdmin);
261:
262: if (!empty($ExternalHostNameOfDAVServer)) {
263: $this->setConfig('ExternalHostNameOfDAVServer', $ExternalHostNameOfDAVServer);
264: $this->saveModuleConfig();
265: return true;
266: }
267:
268: return false;
269: }
270:
271: /**
272: * @api {post} ?/Api/ GetServerUrl
273: * @apiName GetServerUrl
274: * @apiGroup Dav
275: * @apiDescription Returns DAV server URL.
276: *
277: * @apiParam {string=Dav} Module Module name.
278: * @apiParam {string=GetServerUrl} Method Method name.
279: *
280: * @apiParamExample {json} Request-Example:
281: * {
282: * Module: 'Dav',
283: * Method: 'GetServerUrl'
284: * }
285: *
286: * @apiSuccess {object[]} Result Array of response objects.
287: * @apiSuccess {string} Result.Module Module name.
288: * @apiSuccess {string} Result.Method Method name.
289: * @apiSuccess {mixed} Result.Result DAV server URL in case of success, otherwise **false**.
290: * @apiSuccess {int} [Result.ErrorCode] Error code.
291: *
292: * @apiSuccessExample {json} Success response example:
293: * {
294: * Module: 'Dav',
295: * Method: 'GetServerUrl',
296: * Result: 'url_value'
297: * }
298: *
299: * @apiSuccessExample {json} Error response example:
300: * {
301: * Module: 'Dav',
302: * Method: 'GetServerUrl',
303: * Result: false,
304: * ErrorCode: 102
305: * }
306: */
307: /**
308: * Returns DAV server URL.
309: *
310: * @return string
311: */
312: public function GetServerUrl()
313: {
314: \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous);
315:
316: return $this->getManager()->getServerUrl();
317: }
318:
319: /**
320: * @api {post} ?/Api/ GetServerHost
321: * @apiName GetServerHost
322: * @apiGroup Dav
323: * @apiDescription Returns DAV server host.
324: *
325: * @apiParam {string=Dav} Module Module name.
326: * @apiParam {string=GetServerHost} Method Method name.
327: *
328: * @apiParamExample {json} Request-Example:
329: * {
330: * Module: 'Dav',
331: * Method: 'GetServerHost'
332: * }
333: *
334: * @apiSuccess {object[]} Result Array of response objects.
335: * @apiSuccess {string} Result.Module Module name.
336: * @apiSuccess {string} Result.Method Method name.
337: * @apiSuccess {mixed} Result.Result DAV server host in case of success, otherwise **false**.
338: * @apiSuccess {int} [Result.ErrorCode] Error code.
339: *
340: * @apiSuccessExample {json} Success response example:
341: * {
342: * Module: 'Dav',
343: * Method: 'GetServerHost',
344: * Result: 'host_value'
345: * }
346: *
347: * @apiSuccessExample {json} Error response example:
348: * {
349: * Module: 'Dav',
350: * Method: 'GetServerHost',
351: * Result: false,
352: * ErrorCode: 102
353: * }
354: */
355: /**
356: * Returns DAV server host.
357: *
358: * @return string
359: */
360: public function GetServerHost()
361: {
362: \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous);
363:
364: return $this->getManager()->getServerHost();
365: }
366:
367: /**
368: * @api {post} ?/Api/ GetServerPort
369: * @apiName GetServerPort
370: * @apiGroup Dav
371: * @apiDescription Returns DAV server port.
372: *
373: * @apiParam {string=Dav} Module Module name.
374: * @apiParam {string=GetServerPort} Method Method name.
375: *
376: * @apiParamExample {json} Request-Example:
377: * {
378: * Module: 'Dav',
379: * Method: 'GetServerPort'
380: * }
381: *
382: * @apiSuccess {object[]} Result Array of response objects.
383: * @apiSuccess {string} Result.Module Module name.
384: * @apiSuccess {string} Result.Method Method name.
385: * @apiSuccess {mixed} Result.Result DAV server post in case of success, otherwise **false**.
386: * @apiSuccess {int} [Result.ErrorCode] Error code.
387: *
388: * @apiSuccessExample {json} Success response example:
389: * {
390: * Module: 'Dav',
391: * Method: 'GetServerPort',
392: * Result: 'port_value'
393: * }
394: *
395: * @apiSuccessExample {json} Error response example:
396: * {
397: * Module: 'Dav',
398: * Method: 'GetServerPort',
399: * Result: false,
400: * ErrorCode: 102
401: * }
402: */
403: /**
404: * Returns DAV server port.
405: *
406: * @return int
407: */
408: public function GetServerPort()
409: {
410: \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous);
411:
412: return $this->getManager()->getServerPort();
413: }
414:
415: /**
416: * Returns DAV principal URL.
417: *
418: * @return string
419: */
420: public function GetPrincipalUrl()
421: {
422: \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser);
423: $mResult = null;
424:
425: $oUser = \Aurora\System\Api::getAuthenticatedUser();
426: if ($oUser) {
427: $mResult = $this->getManager()->getPrincipalUrl($oUser->PublicId);
428: }
429: return $mResult;
430: }
431:
432: /**
433: * Returns **true** if connection to DAV should use SSL.
434: *
435: * @return bool
436: */
437: public function IsSsl()
438: {
439: \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser);
440:
441: return $this->getManager()->isSsl();
442: }
443:
444: /**
445: * Returns DAV login.
446: *
447: * @return string
448: */
449: public function GetLogin()
450: {
451: \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser);
452: $mResult = null;
453: $oEntity = \Aurora\Modules\Core\Models\User::find(\Aurora\System\Api::getAuthenticatedUserId());
454: if (!empty($oEntity)) {
455: $mResult = $oEntity->PublicId;
456: }
457:
458: return $mResult;
459: }
460:
461: /**
462: * Returns **true** if mobile sync enabled.
463: *
464: * @return bool
465: */
466: public function IsMobileSyncEnabled()
467: {
468: \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser);
469:
470: return $this->getManager()->isMobileSyncEnabled();
471: }
472:
473: /**
474: * Sets mobile sync enabled/disabled.
475: *
476: * @param bool $MobileSyncEnable Indicates if mobile sync should be enabled.
477: * @return bool
478: */
479: public function SetMobileSyncEnable($MobileSyncEnable)
480: {
481: \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser);
482:
483: $oMobileSyncModule = \Aurora\System\Api::GetModule('MobileSync');
484: $oMobileSyncModule->setConfig('Disabled', !$MobileSyncEnable);
485: return $oMobileSyncModule->saveModuleConfig();
486: }
487:
488: /**
489: * Tests connection and returns **true** if connection was successful.
490: *
491: * @return bool
492: */
493: public function TestConnection()
494: {
495: \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser);
496:
497: return $this->getManager()->testConnection(
498: \Aurora\System\Api::getAuthenticatedUserId()
499: );
500: }
501:
502: /**
503: * Deletes principal.
504: *
505: * @return bool
506: */
507: public function DeletePrincipal()
508: {
509: \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser);
510:
511: return $this->getManager()->deletePrincipal(
512: \Aurora\System\Api::getAuthenticatedUserId()
513: );
514: }
515:
516: /**
517: * Returns public user.
518: *
519: * @return string
520: */
521: public function GetPublicUser()
522: {
523: \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser);
524:
525: return \Afterlogic\DAV\Constants::DAV_PUBLIC_PRINCIPAL;
526: }
527:
528: /**
529: *
530: */
531: public function Login($Login, $Password)
532: {
533: \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous);
534:
535: $oTenant = \Aurora\System\Api::getTenantByWebDomain();
536:
537: if (!$this->getConfig('UseFullEmailForLogin', true)) {
538: $Login = $Login . '@' . $this->getConfig('DomainForLoginWithoutEmail', '');
539: }
540:
541: $mResult = \Aurora\Modules\Core\Module::Decorator()->Login($Login, $Password, '', false);
542:
543: if (is_array($mResult) && isset($mResult['AuthToken'])) {
544: $sAuthToken = $mResult['AuthToken'];
545:
546: //this will store user data in static variable of Api class for later usage
547: $oUser = \Aurora\System\Api::getAuthenticatedUser($sAuthToken);
548:
549: return array(
550: 'AuthToken' => $sAuthToken
551: );
552: }
553:
554: \Aurora\System\Api::LogEvent('login-failed: ' . $Login, self::GetName());
555: if (!is_writable(\Aurora\System\Api::DataPath())) {
556: throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::SystemNotConfigured);
557: }
558: throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::AuthError);
559: }
560: /***** public functions might be called with web API *****/
561: }
562: