2828use OCP \Files \Folder ;
2929use OCP \Files \IRootFolder ;
3030use OCP \Files \Mount \IMountManager ;
31- use OCP \Files \Mount \IMovableMount ;
3231use OCP \Files \Mount \IShareOwnerlessMount ;
3332use OCP \Files \Node ;
3433use OCP \Files \NotFoundException ;
3938use OCP \IDBConnection ;
4039use OCP \IGroupManager ;
4140use OCP \IL10N ;
41+ use OCP \Interaction \Actions \ShareAction ;
42+ use OCP \Interaction \Receivers \CircleReceiver ;
43+ use OCP \Interaction \Receivers \DeckReceiver ;
44+ use OCP \Interaction \Receivers \EmailReceiver ;
45+ use OCP \Interaction \Receivers \GroupReceiver ;
46+ use OCP \Interaction \Receivers \LinkReceiver ;
47+ use OCP \Interaction \Receivers \RemoteGroupReceiver ;
48+ use OCP \Interaction \Receivers \RemoteUserReceiver ;
49+ use OCP \Interaction \Receivers \RoomReceiver ;
50+ use OCP \Interaction \Receivers \UserReceiver ;
51+ use OCP \Interaction \Resources \NodeResource ;
52+ use OCP \Interaction \RestrictInteractionEvent ;
4253use OCP \IUser ;
4354use OCP \IUserManager ;
4455use OCP \IUserSession ;
@@ -149,7 +160,7 @@ protected function verifyPassword(?string $password): void {
149160 *
150161 * @suppress PhanUndeclaredClassMethod
151162 */
152- protected function generalCreateChecks (IShare $ share, bool $ isUpdate = false ): void {
163+ protected function generalChecks (IShare $ share ): void {
153164 if ($ share ->getShareType () === IShare::TYPE_USER ) {
154165 // We expect a valid user as sharedWith for user shares
155166 if (!$ this ->userManager ->userExists ($ share ->getSharedWith ())) {
@@ -212,21 +223,6 @@ protected function generalCreateChecks(IShare $share, bool $isUpdate = false): v
212223 throw new \InvalidArgumentException ($ this ->l ->t ('Shared path must be either a file or a folder ' ));
213224 }
214225
215- // And you cannot share your rootfolder
216- if ($ this ->userManager ->userExists ($ share ->getSharedBy ())) {
217- $ userFolder = $ this ->rootFolder ->getUserFolder ($ share ->getSharedBy ());
218- } else {
219- $ userFolder = $ this ->rootFolder ->getUserFolder ($ share ->getShareOwner ());
220- }
221- if ($ userFolder ->getId () === $ share ->getNode ()->getId ()) {
222- throw new \InvalidArgumentException ($ this ->l ->t ('You cannot share your root folder ' ));
223- }
224-
225- // Check if we actually have share permissions
226- if (!$ share ->getNode ()->isShareable ()) {
227- throw new GenericShareException ($ this ->l ->t ('You are not allowed to share %s ' , [$ share ->getNode ()->getName ()]), code: 404 );
228- }
229-
230226 // Permissions should be set
231227 if ($ share ->getPermissions () === null ) {
232228 throw new \InvalidArgumentException ($ this ->l ->t ('Valid permissions are required for sharing ' ));
@@ -237,45 +233,32 @@ protected function generalCreateChecks(IShare $share, bool $isUpdate = false): v
237233 throw new \InvalidArgumentException ($ this ->l ->t ('Valid permissions are required for sharing ' ));
238234 }
239235
240- // Single file shares should never have delete or create permissions
241- if (($ share ->getNode () instanceof File)
242- && (($ share ->getPermissions () & (Constants::PERMISSION_CREATE | Constants::PERMISSION_DELETE )) !== 0 )) {
243- throw new \InvalidArgumentException ($ this ->l ->t ('File shares cannot have create or delete permissions ' ));
244- }
236+ $ action = new ShareAction ($ share ->getPermissions ());
237+ $ receiver = match ($ share ->getShareType ()) {
238+ IShare::TYPE_USER => new UserReceiver ($ share ->getSharedWith ()),
239+ IShare::TYPE_GROUP => new GroupReceiver ($ share ->getSharedWith ()),
240+ IShare::TYPE_LINK => new LinkReceiver (),
241+ IShare::TYPE_EMAIL => new EmailReceiver ($ share ->getSharedWith ()),
242+ IShare::TYPE_REMOTE => new RemoteUserReceiver ($ share ->getSharedWith ()),
243+ IShare::TYPE_CIRCLE => new CircleReceiver ($ share ->getSharedWith ()),
244+ IShare::TYPE_REMOTE_GROUP => new RemoteGroupReceiver ($ share ->getSharedWith ()),
245+ IShare::TYPE_ROOM => new RoomReceiver ($ share ->getSharedWith ()),
246+ IShare::TYPE_DECK => new DeckReceiver ((int )$ share ->getSharedWith ()),
247+ default => throw new \InvalidArgumentException ('Unknown share type. ' ),
248+ };
245249
246- $ permissions = 0 ;
247- $ nodesForUser = $ userFolder ->getById ($ share ->getNodeId ());
248- foreach ($ nodesForUser as $ node ) {
249- if ($ node ->getInternalPath () === '' && !$ node ->getMountPoint () instanceof IMovableMount) {
250- // for the root of non-movable mount, the permissions we see if limited by the mount itself,
251- // so we instead use the "raw" permissions from the storage
252- $ permissions |= $ node ->getStorage ()->getPermissions ('' );
253- } else {
254- $ permissions |= $ node ->getPermissions ();
255- }
256- }
257-
258- // Check that we do not share with more permissions than we have
259- if ($ share ->getPermissions () & ~$ permissions ) {
260- $ path = $ userFolder ->getRelativePath ($ share ->getNode ()->getPath ());
261- throw new GenericShareException ($ this ->l ->t ('Cannot increase permissions of %s ' , [$ path ]), code: 404 );
250+ $ userIds = [];
251+ if ($ share ->getShareOwner () !== null && $ this ->userManager ->userExists ($ share ->getShareOwner ())) {
252+ $ userIds [] = $ share ->getShareOwner ();
262253 }
263-
264- // Check that read permissions are always set
265- // Link shares are allowed to have no read permissions to allow upload to hidden folders
266- $ noReadPermissionRequired = $ share ->getShareType () === IShare::TYPE_LINK
267- || $ share ->getShareType () === IShare::TYPE_EMAIL ;
268- if (!$ noReadPermissionRequired
269- && ($ share ->getPermissions () & Constants::PERMISSION_READ ) === 0 ) {
270- throw new \InvalidArgumentException ($ this ->l ->t ('Shares need at least read permissions ' ));
254+ if ($ share ->getSharedBy () !== $ share ->getShareOwner () && $ this ->userManager ->userExists ($ share ->getSharedBy ())) {
255+ $ userIds [] = $ share ->getSharedBy ();
271256 }
272257
273- if ($ share ->getNode () instanceof File) {
274- if ($ share ->getPermissions () & Constants::PERMISSION_DELETE ) {
275- throw new GenericShareException ($ this ->l ->t ('Files cannot be shared with delete permissions ' ));
276- }
277- if ($ share ->getPermissions () & Constants::PERMISSION_CREATE ) {
278- throw new GenericShareException ($ this ->l ->t ('Files cannot be shared with create permissions ' ));
258+ foreach ($ userIds as $ userId ) {
259+ $ resource = new NodeResource ($ share ->getNodeId (), $ userId );
260+ if ((new RestrictInteractionEvent ($ userId , null , $ resource , $ action , $ receiver ))->isInteractionRestricted ()) {
261+ throw new GenericShareException ($ this ->l ->t ('You are not allowed to share %s ' , [$ share ->getNode ()->getName ()]), code: 403 );
279262 }
280263 }
281264 }
@@ -432,25 +415,6 @@ protected function validateExpirationDateLink(IShare $share): IShare {
432415 * @throws \Exception
433416 */
434417 protected function userCreateChecks (IShare $ share ): void {
435- // Check if we can share with group members only
436- if ($ this ->shareWithGroupMembersOnly ()) {
437- $ sharedBy = $ this ->userManager ->get ($ share ->getSharedBy ());
438- $ sharedWith = $ this ->userManager ->get ($ share ->getSharedWith ());
439- // Verify we can share with this user
440- $ groups = array_intersect (
441- $ this ->groupManager ->getUserGroupIds ($ sharedBy ),
442- $ this ->groupManager ->getUserGroupIds ($ sharedWith )
443- );
444-
445- // optional excluded groups
446- $ excludedGroups = $ this ->shareWithGroupMembersOnlyExcludeGroupsList ();
447- $ groups = array_diff ($ groups , $ excludedGroups );
448-
449- if (empty ($ groups )) {
450- throw new \Exception ($ this ->l ->t ('Sharing is only allowed with group members ' ));
451- }
452- }
453-
454418 /*
455419 * TODO: Could be costly, fix
456420 *
@@ -493,23 +457,6 @@ protected function userCreateChecks(IShare $share): void {
493457 * @throws \Exception
494458 */
495459 protected function groupCreateChecks (IShare $ share ): void {
496- // Verify group shares are allowed
497- if (!$ this ->allowGroupSharing ()) {
498- throw new \Exception ($ this ->l ->t ('Group sharing is now allowed ' ));
499- }
500-
501- // Verify if the user can share with this group
502- if ($ this ->shareWithGroupMembersOnly ()) {
503- $ sharedBy = $ this ->userManager ->get ($ share ->getSharedBy ());
504- $ sharedWith = $ this ->groupManager ->get ($ share ->getSharedWith ());
505-
506- // optional excluded groups
507- $ excludedGroups = $ this ->shareWithGroupMembersOnlyExcludeGroupsList ();
508- if (is_null ($ sharedWith ) || in_array ($ share ->getSharedWith (), $ excludedGroups ) || !$ sharedWith ->inGroup ($ sharedBy )) {
509- throw new \Exception ($ this ->l ->t ('Sharing is only allowed within your own groups ' ));
510- }
511- }
512-
513460 /*
514461 * TODO: Could be costly, fix
515462 *
@@ -532,24 +479,6 @@ protected function groupCreateChecks(IShare $share): void {
532479 }
533480 }
534481
535- /**
536- * Check for pre share requirements for link shares
537- *
538- * @throws \Exception
539- */
540- protected function linkCreateChecks (IShare $ share ): void {
541- // Are link shares allowed?
542- if (!$ this ->shareApiAllowLinks ()) {
543- throw new \Exception ($ this ->l ->t ('Link sharing is not allowed ' ));
544- }
545-
546- // Check if public upload is allowed
547- if ($ share ->getNodeType () === 'folder ' && !$ this ->shareApiLinkAllowPublicUpload ()
548- && ($ share ->getPermissions () & (Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE ))) {
549- throw new \InvalidArgumentException ($ this ->l ->t ('Public upload is not allowed ' ));
550- }
551- }
552-
553482 /**
554483 * To make sure we don't get invisible link shares we set the parent
555484 * of a link if it is a reshare. This is a quick word around
@@ -600,10 +529,7 @@ protected function canShare(IShare $share): void {
600529
601530 #[Override]
602531 public function createShare (IShare $ share ): IShare {
603- // TODO: handle link share permissions or check them
604- $ this ->canShare ($ share );
605-
606- $ this ->generalCreateChecks ($ share );
532+ $ this ->generalChecks ($ share );
607533
608534 // Verify if there are any issues with the path
609535 $ this ->pathCreateChecks ($ share ->getNode ());
@@ -644,7 +570,6 @@ public function createShare(IShare $share): IShare {
644570 $ share = $ this ->validateExpirationDateInternal ($ share );
645571 } elseif ($ share ->getShareType () === IShare::TYPE_LINK
646572 || $ share ->getShareType () === IShare::TYPE_EMAIL ) {
647- $ this ->linkCreateChecks ($ share );
648573 $ this ->setLinkParent ($ share );
649574
650575 $ token = $ this ->generateToken ();
@@ -737,8 +662,6 @@ public function createShare(IShare $share): IShare {
737662 public function updateShare (IShare $ share , bool $ onlyValid = true ): IShare {
738663 $ expirationDateUpdated = false ;
739664
740- $ this ->canShare ($ share );
741-
742665 try {
743666 $ originalShare = $ this ->getShareById ($ share ->getFullId (), onlyValid: $ onlyValid );
744667 } catch (\UnexpectedValueException $ e ) {
@@ -762,7 +685,7 @@ public function updateShare(IShare $share, bool $onlyValid = true): IShare {
762685 throw new \InvalidArgumentException ($ this ->l ->t ('Cannot share with the share owner ' ));
763686 }
764687
765- $ this ->generalCreateChecks ($ share, true );
688+ $ this ->generalChecks ($ share );
766689
767690 if ($ share ->getShareType () === IShare::TYPE_USER ) {
768691 $ this ->userCreateChecks ($ share );
@@ -782,7 +705,6 @@ public function updateShare(IShare $share, bool $onlyValid = true): IShare {
782705 }
783706 } elseif ($ share ->getShareType () === IShare::TYPE_LINK
784707 || $ share ->getShareType () === IShare::TYPE_EMAIL ) {
785- $ this ->linkCreateChecks ($ share );
786708
787709 // The new password is not set again if it is the same as the old
788710 // one, unless when switching from sending by Talk to sending by
@@ -1096,7 +1018,7 @@ protected function promoteReshares(IShare $share): void {
10961018 foreach ($ reshareRecords as $ child ) {
10971019 try {
10981020 /* Check if the share is still valid (means the resharer still has access to the file through another mean) */
1099- $ this ->generalCreateChecks ($ child );
1021+ $ this ->generalChecks ($ child );
11001022 } catch (GenericShareException $ e ) {
11011023 /* The check is invalid, promote it to a direct share from the sharer of parent share */
11021024 $ this ->logger ->debug ('Promote reshare because of exception ' . $ e ->getMessage (), ['exception ' => $ e , 'fullId ' => $ child ->getFullId ()]);
@@ -1486,7 +1408,7 @@ private function checkShare(IShare $share, int &$added = 1): void {
14861408 throw new ShareNotFound ($ this ->l ->t ('The requested share does not exist anymore ' ));
14871409 }
14881410 if ($ this ->config ->getAppValue ('files_sharing ' , 'hide_disabled_user_shares ' , 'no ' ) === 'yes ' ) {
1489- $ uids = array_unique ([$ share ->getShareOwner (),$ share ->getSharedBy ()]);
1411+ $ uids = array_unique ([$ share ->getShareOwner (), $ share ->getSharedBy ()]);
14901412 foreach ($ uids as $ uid ) {
14911413 $ user = $ this ->userManager ->get ($ uid );
14921414 if ($ user ?->isEnabled() === false ) {
0 commit comments