1: | <?php |
2: | |
3: | |
4: | |
5: | |
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: | |
32: | |
33: | |
34: | |
35: | |
36: | |
37: | class Module extends \Aurora\Modules\PersonalFiles\Module |
38: | { |
39: | |
40: | |
41: | |
42: | protected static $sStorageType = 'shared'; |
43: | |
44: | |
45: | |
46: | |
47: | |
48: | protected static $iStorageOrder = 30; |
49: | |
50: | |
51: | |
52: | |
53: | |
54: | protected static $bIsDroppable = false; |
55: | |
56: | |
57: | |
58: | |
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: | |
117: | |
118: | |
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: | |
215: | |
216: | |
217: | |
218: | |
219: | |
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: | |
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: | |
520: | |
521: | |
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: | |
532: | |
533: | |
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: | |