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\SharedFiles;
9:
10: use Afterlogic\DAV\Constants;
11: use Afterlogic\DAV\FS\Directory as Directory;
12: use Afterlogic\DAV\FS\File;
13: use Afterlogic\DAV\FS\Permission;
14: use Afterlogic\DAV\Server;
15: use Aurora\Api;
16: use Aurora\Modules\Core\Module as CoreModule;
17: use Aurora\Modules\Files\Module as FilesModule;
18: use Aurora\Modules\SharedFiles\Enums\ErrorCodes;
19: use Aurora\System\Enums\FileStorageType;
20: use Aurora\System\Enums\UserRole;
21: use Aurora\System\Exceptions\ApiException;
22: use Afterlogic\DAV\FS\Shared\File as SharedFile;
23: use Afterlogic\DAV\FS\Shared\Directory as SharedDirectory;
24: use Aurora\Modules\Core\Models\User;
25: use Aurora\Modules\SharedFiles\Enums\Access;
26: use Aurora\System\Router;
27:
28: use function Sabre\Uri\split;
29:
30: /**
31: * @license https://www.gnu.org/licenses/agpl-3.0.html AGPL-3.0
32: * @license https://afterlogic.com/products/common-licensing Afterlogic Software License
33: * @copyright Copyright (c) 2023, Afterlogic Corp.
34: *
35: * @package Modules
36: */
37: class Module extends \Aurora\Modules\PersonalFiles\Module
38: {
39: /**
40: *
41: */
42: protected static $sStorageType = 'shared';
43:
44: /**
45: *
46: * @var integer
47: */
48: protected static $iStorageOrder = 30;
49:
50: /**
51: * Indicates if it's allowed to move files/folders to this storage.
52: * @var bool
53: */
54: protected static $bIsDroppable = false;
55:
56: /**
57: *
58: * @var \Afterlogic\DAV\FS\Backend\PDO
59: */
60: protected $oBackend;
61:
62: protected $oBeforeDeleteUser = null;
63:
64: public function getManager()
65: {
66: if ($this->oManager === null) {
67: $this->oManager = new Manager($this);
68: }
69:
70: return $this->oManager;
71: }
72:
73: public function init()
74: {
75: parent::init();
76:
77: $this->oBackend = new \Afterlogic\DAV\FS\Backend\PDO();
78:
79: $this->aErrors = [
80: Enums\ErrorCodes::NotPossibleToShareWithYourself => $this->i18N('ERROR_NOT_POSSIBLE_TO_SHARE_WITH_YOURSELF'),
81: Enums\ErrorCodes::UnknownError => $this->i18N('ERROR_UNKNOWN_ERROR'),
82: Enums\ErrorCodes::UserNotExists => $this->i18N('ERROR_USER_NOT_EXISTS'),
83: Enums\ErrorCodes::DuplicatedUsers => $this->i18N('ERROR_DUPLICATE_USERS_BACKEND'),
84: Enums\ErrorCodes::NotPossibleToShareDirectoryInEcryptedStorage => $this->i18N('CANNOT_SHARE_DIRECTORY_IN_ECRYPTED_STORAGE'),
85: Enums\ErrorCodes::IncorrectFilename => $this->i18N('INCORRECT_FILE_NAME'),
86: ];
87:
88: $this->subscribeEvent('Files::GetFiles::after', [$this, 'onAfterGetFiles']);
89: $this->subscribeEvent('Files::GetItems::after', [$this, 'onAfterGetItems'], 10000);
90:
91: $this->subscribeEvent('Core::AddUsersToGroup::after', [$this, 'onAfterAddUsersToGroup']);
92: $this->subscribeEvent('Core::RemoveUsersFromGroup::after', [$this, 'onAfterRemoveUsersFromGroup']);
93: $this->subscribeEvent('Core::CreateUser::after', [$this, 'onAfterCreateUser']);
94: $this->subscribeEvent('Core::UpdateUser::after', [$this, 'onAfterUpdateUser']);
95: $this->subscribeEvent('Core::DeleteGroup::after', [$this, 'onAfterDeleteGroup']);
96: $this->subscribeEvent('Files::PopulateExtendedProps', [$this, 'onPopulateExtendedProps'], 10000);
97: $this->subscribeEvent('Files::LeaveShare', [$this, 'onLeaveShare']);
98:
99: $this->denyMethodsCallByWebApi([
100: 'getNonExistentFileName'
101: ]);
102: }
103:
104: protected function populateExtendedProps($userId, $type, $path, &$aExtendedProps)
105: {
106: $bSharedWithMe = isset($aExtendedProps['SharedWithMeAccess']) ? $aExtendedProps['SharedWithMeAccess'] === Permission::Reshare : false;
107: $aExtendedProps['Shares'] = $this->GetShares(
108: $userId,
109: $type,
110: $path,
111: $bSharedWithMe
112: );
113: }
114:
115: /**
116: * @ignore
117: * @param array $aArgs Arguments of event.
118: * @param mixed $mResult Is passed by reference.
119: */
120: public function onAfterGetItems($aArgs, &$mResult)
121: {
122: if (is_array($mResult)) {
123: foreach ($mResult as $oItem) {
124: $aExtendedProps = $oItem->ExtendedProps;
125: $this->populateExtendedProps($aArgs['UserId'], $aArgs['Type'], \rtrim($oItem->Path, '/') . '/' . $oItem->Id, $aExtendedProps);
126: $oItem->ExtendedProps = $aExtendedProps;
127: }
128: }
129: }
130:
131: protected function isNeedToReturnBody()
132: {
133: $sMethod = $this->oHttp->GetPost('Method', null);
134:
135: return ((string) Router::getItemByIndex(2, '') === 'thumb' ||
136: $sMethod === 'SaveFilesAsTempFiles' ||
137: $sMethod === 'GetFilesForUpload'
138: );
139: }
140:
141: protected function isNeedToReturnWithContectDisposition()
142: {
143: $sAction = (string) Router::getItemByIndex(2, 'download');
144: return $sAction === 'download';
145: }
146:
147: public function GetShares($UserId, $Storage, $Path, $SharedWithMe = false)
148: {
149: $aResult = [];
150:
151: Api::checkUserRoleIsAtLeast(UserRole::NormalUser);
152:
153: Api::CheckAccess($UserId);
154:
155: $sUserPublicId = Api::getUserPublicIdById($UserId);
156: $oUser = Api::getUserById($UserId);
157: $sFullPath = 'files/' . $Storage . '/' . \ltrim($Path, '/');
158: $oNode = Server::getNodeForPath($sFullPath, $sUserPublicId);
159:
160: $aShares = [];
161: if ($oNode instanceof File || $oNode instanceof Directory) {
162: if ($oNode->getAccess() === Enums\Access::Reshare) {
163: Server::checkPrivileges('files/' . $Storage . '/' . \ltrim($Path, '/'), '{DAV:}write-acl');
164: if ($oNode instanceof SharedFile || $oNode instanceof SharedDirectory) {
165: $aShares = $this->oBackend->getShares(Constants::PRINCIPALS_PREFIX . $oNode->getNode()->getUser(), $oNode->getStorage(), '/' . \ltrim($Path, '/'));
166: }
167: } else {
168: $aShares = $this->oBackend->getShares(Constants::PRINCIPALS_PREFIX . $sUserPublicId, $Storage, '/' . \ltrim($Path, '/'));
169: }
170:
171: if (count($aShares) === 0 && ($oNode instanceof SharedFile || $oNode instanceof SharedDirectory) && $SharedWithMe && !$oNode->isInherited()) {
172: $aSharedFile = $this->oBackend->getSharedFileByUidWithPath(
173: Constants::PRINCIPALS_PREFIX . $sUserPublicId,
174: $oNode->getName(),
175: $oNode->getSharePath()
176: );
177: if ($aSharedFile) {
178: $aShares = $this->oBackend->getShares(
179: $aSharedFile['owner'],
180: $aSharedFile['storage'],
181: $aSharedFile['path']
182: );
183: }
184: }
185: $aGroups = [];
186: foreach ($aShares as $aShare) {
187: if ($aShare['group_id'] != 0) {
188: if (!in_array($aShare['group_id'], $aGroups)) {
189: $oGroup = CoreModule::Decorator()->GetGroup($oUser->IdTenant, (int) $aShare['group_id']);
190: if ($oGroup) {
191: $aGroups[] = $aShare['group_id'];
192: $aResult[] = [
193: 'PublicId' => $oGroup->getName(),
194: 'Access' => $aShare['access'],
195: 'IsGroup' => true,
196: 'IsAll' => !!$oGroup->IsAll,
197: 'GroupId' => (int) $aShare['group_id']
198: ];
199: }
200: }
201: } else {
202: $aResult[] = [
203: 'PublicId' => basename($aShare['principaluri']),
204: 'Access' => $aShare['access']
205: ];
206: }
207: }
208: }
209:
210: return $aResult;
211: }
212:
213: /**
214: * @param \Aurora\Modules\StandardAuth\Classes\Account $oAccount
215: * @param int $iType
216: * @param string $sPath
217: * @param string $sFileName
218: *
219: * @return string
220: */
221: public function getNonExistentFileName($principalUri, $sFileName, $sPath = '', $bWithoutGroup = false)
222: {
223: $iIndex = 1;
224: $sFileNamePathInfo = pathinfo($sFileName);
225: $sExt = isset($sFileNamePathInfo['extension']) ? '.'.$sFileNamePathInfo['extension'] : '';
226: $sNameWOExt = isset($sFileNamePathInfo['filename']) ? $sFileNamePathInfo['filename'] : $sFileName;
227:
228: while ($this->oBackend->getSharedFileByUidWithPath($principalUri, $sFileName, $sPath, $bWithoutGroup)) {
229: $sFileName = $sNameWOExt.' ('.$iIndex.')'.$sExt;
230: $iIndex++;
231: }
232: list(, $sUserPublicId) = \Sabre\Uri\split($principalUri);
233: $oUser = CoreModule::getInstance()->GetUserByPublicId($sUserPublicId);
234:
235: if ($oUser) {
236: $sPrevState = Api::skipCheckUserRole(true);
237: $sFileName = FilesModule::Decorator()->GetNonExistentFileName(
238: $oUser->Id,
239: FileStorageType::Personal,
240: $sPath,
241: $sFileName,
242: $bWithoutGroup
243: );
244: Api::skipCheckUserRole($sPrevState);
245: }
246:
247: return $sFileName;
248: }
249:
250: public function UpdateShare($UserId, $Storage, $Path, $Id, $Shares, $IsDir = false)
251: {
252: $mResult = true;
253: $aGuests = [];
254: $aOwners = [];
255: $aReshare = [];
256: $aUpdateShares = [];
257:
258: Api::checkUserRoleIsAtLeast(UserRole::NormalUser);
259: Api::CheckAccess($UserId);
260:
261: $oUser = Api::getAuthenticatedUser();
262: if ($oUser instanceof User) {
263: $sUserPublicId = Api::getUserPublicIdById($UserId);
264: $sInitiator = $sUserPrincipalUri = Constants::PRINCIPALS_PREFIX . $sUserPublicId;
265: $FullPath = $Path . '/' . $Id;
266: Server::checkPrivileges('files/' . $Storage . '/' . \ltrim($FullPath, '/'), '{DAV:}write-acl');
267: $oNode = Server::getNodeForPath('files/' . $Storage . '/' . \ltrim($FullPath, '/'));
268: $bIsEncrypted = false;
269: if ($oNode instanceof File || $oNode instanceof Directory) {
270: $aExtendedProps = $oNode->getProperty('ExtendedProps');
271: $bIsEncrypted = (is_array($aExtendedProps) && isset($aExtendedProps['InitializationVector']));
272:
273: $aSharePublicIds = array_map(function ($share) {
274: return strtolower($share['PublicId']);
275: }, $Shares);
276: if (in_array(strtolower($oNode->getOwner()), $aSharePublicIds)) {
277: throw new ApiException(Enums\ErrorCodes::NotPossibleToShareWithYourself);
278: }
279: }
280: $bIsShared = false;
281: if (($oNode instanceof SharedFile || $oNode instanceof SharedDirectory)) {
282: $bIsShared = true;
283: $aSharedFile = $this->oBackend->getSharedFileByUidWithPath(
284: $sUserPrincipalUri,
285: $oNode->getName(),
286: $oNode->getSharePath()
287: );
288: if ($aSharedFile) {
289: $sUserPrincipalUri = $aSharedFile['owner'];
290: } else {
291: $sUserPrincipalUri = 'principals/' . $oNode->getOwner();
292: }
293: $ParentNode = $oNode->getNode();
294: $FullPath = $ParentNode->getRelativePath() . '/' . $ParentNode->getName();
295: $Storage = $oNode->getStorage();
296: }
297:
298: $aResultShares = [];
299: foreach ($Shares as $item) {
300: if (isset($item['GroupId'])) {
301: $aUsers = CoreModule::Decorator()->GetGroupUsers($oUser->IdTenant, (int) $item['GroupId']);
302: foreach ($aUsers as $aUser) {
303: $aResultShares[] = [
304: 'PublicId' => $aUser['PublicId'],
305: 'Access' => (int) $item['Access'],
306: 'GroupId' => (int) $item['GroupId'],
307: ];
308: }
309: } else {
310: $item['GroupId'] = 0;
311: $aResultShares[] = $item;
312: }
313: }
314:
315: $aDbShares = $this->oBackend->getShares(
316: $sUserPrincipalUri,
317: $Storage,
318: '/' . \ltrim($FullPath, '/')
319: );
320:
321: $aOldSharePrincipals = array_map(function ($aShareItem) {
322: if (isset($aShareItem['principaluri'])) {
323: return \json_encode([
324: $aShareItem['principaluri'],
325: $aShareItem['group_id']
326: ]);
327: }
328: }, $aDbShares);
329:
330: $aNewSharePrincipals = array_map(function ($aShareItem) {
331: if (isset($aShareItem['PublicId'])) {
332: return \json_encode([
333: Constants::PRINCIPALS_PREFIX . $aShareItem['PublicId'],
334: $aShareItem['GroupId']
335: ]);
336: }
337: }, $aResultShares);
338:
339: $aItemsToDelete = array_diff($aOldSharePrincipals, $aNewSharePrincipals);
340: $aItemsToCreate = array_diff($aNewSharePrincipals, $aOldSharePrincipals);
341: $aItemsToUpdate = array_intersect($aOldSharePrincipals, $aNewSharePrincipals);
342:
343: foreach ($aItemsToDelete as $aItem) {
344: $aItem = \json_decode($aItem);
345: $mResult = $this->oBackend->deleteSharedFileByPrincipalUri(
346: $aItem[0],
347: $Storage,
348: $FullPath,
349: $aItem[1]
350: );
351: }
352:
353: foreach ($aResultShares as $Share) {
354: if (!$bIsShared && $oUser->PublicId === $Share['PublicId'] && $Share['GroupId'] == 0) {
355: throw new ApiException(Enums\ErrorCodes::NotPossibleToShareWithYourself);
356: }
357: if (!CoreModule::Decorator()->GetUserByPublicId($Share['PublicId'])) {
358: throw new ApiException(Enums\ErrorCodes::UserNotExists);
359: }
360: if ($Share['Access'] === Enums\Access::Read) {
361: $aGuests[] = $Share['PublicId'];
362: } elseif ($Share['Access'] === Enums\Access::Write) {
363: $aOwners[] = $Share['PublicId'];
364: } elseif ($Share['Access'] === Enums\Access::Reshare) {
365: $aReshare[] = $Share['PublicId'];
366: }
367: $aUpdateShares[] = $Share['PublicId'];
368: }
369:
370: $aDuplicatedUsers = array_intersect($aOwners, $aGuests, $aReshare);
371: if (!empty($aDuplicatedUsers)) {
372: // throw new ApiException(Enums\ErrorCodes::DuplicatedUsers);
373: }
374:
375: $aGuestPublicIds = [];
376: foreach ($aResultShares as $aShare) {
377: $sPrincipalUri = Constants::PRINCIPALS_PREFIX . $aShare['PublicId'];
378:
379: $groupId = (int) $aShare['GroupId'];
380:
381: try {
382: $bCreate = false;
383: foreach ($aItemsToCreate as $aItemToCreate) {
384: $aItemToCreate = \json_decode($aItemToCreate);
385: if ($sPrincipalUri === $aItemToCreate[0] && $groupId == $aItemToCreate[1]) {
386: $bCreate = true;
387: break;
388: }
389: }
390: if ($bCreate) {
391: if ($groupId == 0) {
392: $sNonExistentFileName = $this->getNonExistentFileName($sPrincipalUri, $Id, '', true);
393: } else {
394: $sNonExistentFileName = $Id;
395: }
396: $mCreateResult = $this->oBackend->createSharedFile(
397: $sUserPrincipalUri,
398: $Storage,
399: $FullPath,
400: $sNonExistentFileName,
401: $sPrincipalUri,
402: $aShare['Access'],
403: $IsDir,
404: '',
405: $groupId,
406: $sInitiator
407: );
408: if ($mCreateResult) {
409: $aArgs = [
410: 'UserPrincipalUri' => $sUserPrincipalUri,
411: 'Storage' => $Storage,
412: 'FullPath' => $FullPath,
413: 'Share' => $aShare,
414: ];
415: $this->broadcastEvent($this->GetName() . '::CreateSharedFile', $aArgs);
416: }
417: $mResult = $mResult && $mCreateResult;
418: } else {
419: $bUpdate = false;
420: foreach ($aItemsToUpdate as $aItemToUpdate) {
421: $aItemToUpdate = \json_decode($aItemToUpdate);
422: if ($sPrincipalUri === $aItemToUpdate[0] && $groupId == $aItemToUpdate[1]) {
423: $bUpdate = true;
424: break;
425: }
426: }
427: if ($bUpdate) {
428: $mUpdateResult = $this->oBackend->updateSharedFile(
429: $sUserPrincipalUri,
430: $Storage,
431: $FullPath,
432: $sPrincipalUri,
433: $aShare['Access'],
434: $groupId
435: );
436: if ($mUpdateResult) {
437: $aArgs = [
438: 'UserPrincipalUri' => $sUserPrincipalUri,
439: 'Storage' => $Storage,
440: 'FullPath' => $FullPath,
441: 'Share' => $aShare,
442: ];
443: $this->broadcastEvent($this->GetName() . '::UpdateSharedFile', $aArgs);
444: }
445: $mResult = $mResult && $mUpdateResult;
446: }
447: }
448: } catch (\PDOException $oEx) {
449: if (isset($oEx->errorInfo[1]) && $oEx->errorInfo[1] === 1366) {
450: throw new ApiException(ErrorCodes::IncorrectFilename, $oEx);
451: } else {
452: throw $oEx;
453: }
454: }
455:
456: if ($mResult) {
457: switch ((int) $aShare['Access']) {
458: case Enums\Access::Read:
459: $sAccess = '(r)';
460: break;
461: case Enums\Access::Write:
462: $sAccess = '(r/w)';
463: break;
464: case Enums\Access::Reshare:
465: $sAccess = '(r/w/s)';
466: break;
467: default:
468: $sAccess = '(r/w)';
469: break;
470: }
471: $aGuestPublicIds[] = $aShare['PublicId'] . ' - ' . $sAccess;
472: }
473: }
474:
475: $sResourceId = $Storage . '/' . \ltrim(\ltrim($FullPath, '/'));
476: $aArgs = [
477: 'UserId' => $UserId,
478: 'ResourceType' => 'file',
479: 'ResourceId' => $sResourceId,
480: 'Action' => 'update-share',
481: 'GuestPublicId' => \implode(', ', $aGuestPublicIds)
482: ];
483: $this->broadcastEvent('AddToActivityHistory', $aArgs);
484: }
485:
486: return $mResult;
487: }
488:
489: /**
490: *
491: */
492: public function onAfterGetFiles(&$aArgs, &$mResult)
493: {
494: if ($mResult) {
495: try {
496: $oNode = Server::getNodeForPath('files/' . $aArgs['Type'] . $aArgs['Path']);
497: if ($oNode instanceof SharedFile || $oNode instanceof SharedDirectory) {
498: $mResult['Access'] = $oNode->getAccess();
499: }
500: if ($oNode instanceof SharedDirectory) {
501: $sResourceId = $oNode->getStorage() . '/' . \ltrim(\ltrim($oNode->getRelativeNodePath(), '/') . '/' . \ltrim($oNode->getName(), '/'), '/');
502: $oUser = CoreModule::Decorator()->GetUserByPublicId($oNode->getOwnerPublicId());
503: if ($oUser) {
504: $aArgs = [
505: 'UserId' => $oUser->Id,
506: 'ResourceType' => 'file',
507: 'ResourceId' => $sResourceId,
508: 'Action' => 'list-share'
509: ];
510: $this->broadcastEvent('AddToActivityHistory', $aArgs);
511: }
512: }
513: } catch (\Exception $oEx) {
514: }
515: }
516: }
517:
518: /**
519: * @ignore
520: * @param array $aArgs Arguments of event.
521: * @param mixed $mResult Is passed by reference.
522: */
523: public function onAfterDeleteUser($aArgs, $mResult)
524: {
525: if ($mResult && $this->oBeforeDeleteUser instanceof User) {
526: $this->oBackend->deleteSharesByPrincipal(Constants::PRINCIPALS_PREFIX . $this->oBeforeDeleteUser->PublicId);
527: }
528: }
529:
530: /**
531: * @ignore
532: * @param array $aArgs Arguments of event.
533: * @param mixed $mResult Is passed by reference.
534: */
535: public function onAfterGetSubModules($aArgs, &$mResult)
536: {
537: array_unshift($mResult, self::$sStorageType);
538: }
539:
540: public function onAfterAddUsersToGroup($aArgs, &$mResult)
541: {
542: if ($mResult) {
543: foreach ($aArgs['UserIds'] as $iUserId) {
544: $userPublicId = Api::getUserPublicIdById($iUserId);
545: $sUserPrincipalUri = 'principals/' . $userPublicId;
546: $aDbShares = $this->oBackend->getSharesByPrincipalUriAndGroupId($sUserPrincipalUri, $aArgs['GroupId']);
547:
548: foreach ($aDbShares as $aDbShare) {
549: $mResult = $mResult && $this->oBackend->createSharedFile(
550: $aDbShare['owner'],
551: $aDbShare['storage'],
552: $aDbShare['path'],
553: basename($aDbShare['path']),
554: $sUserPrincipalUri,
555: $aDbShare['access'],
556: $aDbShare['isdir'],
557: '',
558: $aDbShare['group_id'],
559: $aDbShare['initiator']
560: );
561: }
562: }
563: }
564: }
565:
566: public function onAfterUpdateUser($aArgs, &$mResult)
567: {
568: if ($mResult) {
569: $groupIds = $aArgs['GroupIds'];
570: $userId = $aArgs['UserId'];
571:
572: $userPublicId = Api::getUserPublicIdById($userId);
573: $sUserPrincipalUri = 'principals/' . $userPublicId;
574:
575: if ($groupIds !== null) {
576: if (count($groupIds) > 0) {
577: $aDbCreateShares = [];
578: foreach ($groupIds as $groupId) {
579: $aDbCreateShares = array_merge(
580: $aDbCreateShares,
581: $this->oBackend->getSharesByPrincipalUriAndGroupId($sUserPrincipalUri, $groupId)
582: );
583: }
584:
585: foreach ($aDbCreateShares as $aShare) {
586: $mResult && $this->oBackend->createSharedFile(
587: $aShare['owner'],
588: $aShare['storage'],
589: $aShare['path'],
590: basename($aShare['path']),
591: $sUserPrincipalUri,
592: $aShare['access'],
593: $aShare['isdir'],
594: '',
595: $aShare['group_id'],
596: $aShare['initiator']
597: );
598: }
599: } else {
600: $groupIds[] = 0;
601: }
602: $this->oBackend->deleteShareNotInGroups($sUserPrincipalUri, $groupIds);
603: }
604: }
605: }
606:
607: public function onAfterRemoveUsersFromGroup($aArgs, &$mResult)
608: {
609: if ($mResult) {
610: foreach ($aArgs['UserIds'] as $iUserId) {
611: $oUser = Api::getUserById($iUserId);
612: $this->oBackend->deleteShareByPrincipaluriAndGroupId('principals/' . $oUser->PublicId, $aArgs['GroupId']);
613: }
614: }
615: }
616:
617: public function onAfterDeleteGroup($aArgs, &$mResult)
618: {
619: if ($mResult) {
620: $this->oBackend->deleteSharesByGroupId($aArgs['GroupId']);
621: }
622: }
623:
624: public function onPopulateExtendedProps(&$aArgs, &$mResult)
625: {
626: $oItem = $aArgs['Item'];
627: if ($oItem instanceof SharedFile || $oItem instanceof SharedDirectory) {
628: $mResult['SharedWithMeAccess'] = $oItem->getAccess();
629: }
630:
631: $this->populateExtendedProps(
632: $aArgs['UserId'],
633: $aArgs['Type'],
634: \rtrim($aArgs['Path'], '/') . '/' . $aArgs['Name'],
635: $mResult
636: );
637: }
638:
639: public function onLeaveShare(&$aArgs, &$mResult)
640: {
641: $UserId = $aArgs['UserId'];
642: Api::checkUserRoleIsAtLeast(UserRole::NormalUser);
643: Api::CheckAccess($UserId);
644:
645: $oUser = Api::getAuthenticatedUser();
646: if ($oUser instanceof User) {
647: $sUserPublicId = Api::getUserPublicIdById($UserId);
648: $sUserPrincipalUri = Constants::PRINCIPALS_PREFIX . $sUserPublicId;
649:
650: foreach ($aArgs['Items'] as $aItem) {
651: if ($aItem->getGroupId() > 0) {
652: $this->oBackend->createSharedFile(
653: 'principals/' . $aItem->getOwnerPublicId(),
654: $aItem->getStorage(),
655: $aItem->getNode()->getRelativePath() . '/' . $aItem->getNode()->getName(),
656: $aItem->getName(),
657: $sUserPrincipalUri,
658: Access::NoAccess,
659: ($aItem instanceof SharedDirectory),
660: '',
661: 0,
662: 'principals/' . $aItem->getOwnerPublicId()
663: );
664: } else {
665: $this->oBackend->updateSharedFile(
666: 'principals/' . $aItem->getOwnerPublicId(),
667: $aItem->getStorage(),
668: $aItem->getNode()->getRelativePath() . '/' . $aItem->getNode()->getName(),
669: $sUserPrincipalUri,
670: Access::NoAccess,
671: 0,
672: 'principals/' . $aItem->getOwnerPublicId()
673: );
674: }
675: }
676:
677: $mResult = true;
678: }
679: }
680:
681: public function onAfterCreateUser($aArgs, &$mResult)
682: {
683: if ($mResult) {
684: $oUser = User::find($mResult);
685: if ($oUser) {
686: $oGroup = CoreModule::getInstance()->GetAllGroup($oUser->IdTenant);
687: if ($oGroup) {
688: $newArgs = [
689: 'GroupId' => $oGroup->Id,
690: 'UserIds' => [$mResult]
691: ];
692: $newResult = true;
693: $this->onAfterAddUsersToGroup($newArgs, $newResult);
694: }
695: }
696: }
697: }
698: }
699: