3333use OCP \IUser ;
3434use OCP \IUserManager ;
3535use OCP \Server ;
36+ use OCP \Share \IManager ;
37+ use OCP \Share \IShare ;
3638use PHPUnit \Framework \Attributes \Group ;
3739use Test \TestCase ;
3840
3941#[Group('DB ' )]
4042final class RestrictInteractionListenerTest extends TestCase {
4143 private IUser $ user ;
44+ private ?IUser $ recipient = null ;
4245
4346 #[\Override]
4447 protected function setUp (): void {
@@ -54,6 +57,10 @@ protected function setUp(): void {
5457 protected function tearDown (): void {
5558 Server::get (ISetupManager::class)->tearDown ();
5659
60+ if ($ this ->recipient !== null ) {
61+ $ this ->assertTrue ($ this ->recipient ->delete ());
62+ }
63+
5764 $ this ->assertTrue ($ this ->user ->delete ());
5865
5966 parent ::tearDown ();
@@ -79,25 +86,83 @@ public function testNodeResourceShareActionMissingSharePermission(): void {
7986 }
8087
8188 public function testNodeResourceShareActionSharePermissionOnOtherPath (): void {
82- $ userFolder = Server::get (IRootFolder::class)->getUserFolder ($ this ->user ->getUID ());
89+ $ userManager = Server::get (IUserManager::class);
90+ $ shareManager = Server::get (IManager::class);
91+ $ setupManager = Server::get (ISetupManager::class);
8392
84- $ fileNode = $ userFolder ->newFile ('foo.txt ' , 'bar ' );
85- $ fileNode ->getStorage ()->getCache ()->update ($ fileNode ->getId (), ['permissions ' => Constants::PERMISSION_ALL & ~Constants::PERMISSION_SHARE ]);
86- $ fileNode = $ userFolder ->getFirstNodeById ($ fileNode ->getId ());
87- $ this ->assertNotNull ($ fileNode );
93+ $ recipient = $ userManager ->createUser ('recipient ' , 'password ' );
94+ $ this ->assertInstanceOf (IUser::class, $ recipient );
95+ $ this ->recipient = $ recipient ;
8896
89- $ folderNode = $ userFolder ->newFolder ('foo ' );
90- $ folderNode ->getStorage ()->getCache ()->update ($ folderNode ->getId (), ['permissions ' => Constants::PERMISSION_ALL & ~Constants::PERMISSION_SHARE ]);
91- $ folderNode = $ userFolder ->getFirstNodeById ($ folderNode ->getId ());
92- $ this ->assertNotNull ($ folderNode );
93-
94- // The node found first has no share permission, but another path to the same file id has,
95- // which is reflected by the merged permissions of the resource.
96- foreach ([$ fileNode , $ folderNode ] as $ node ) {
97- $ resource = new NodeResource ($ node ->getId (), $ this ->user ->getUID (), $ node , Constants::PERMISSION_ALL );
98- $ event = new RestrictInteractionEvent ($ this ->user ->getUID (), $ this ->user , [$ resource ], new ShareAction (), []);
99- $ this ->assertFalse ($ event ->isInteractionRestricted ());
97+ $ userFolder = Server::get (IRootFolder::class)->getUserFolder ($ this ->user ->getUID ());
98+ $ parentNode = $ userFolder ->newFolder ('parent ' );
99+ $ childNode = $ parentNode ->newFolder ('child ' );
100+
101+ // The recipient reaches the child through both a shareable parent mount and a read-only direct mount.
102+ $ parentShare = $ shareManager ->newShare ()
103+ ->setShareType (IShare::TYPE_USER )
104+ ->setSharedWith ($ recipient ->getUID ())
105+ ->setSharedBy ($ this ->user ->getUID ())
106+ ->setShareOwner ($ this ->user ->getUID ())
107+ ->setNode ($ parentNode )
108+ ->setPermissions (Constants::PERMISSION_ALL );
109+ $ parentShare = $ shareManager ->createShare ($ parentShare );
110+ $ shareManager ->acceptShare ($ parentShare , $ recipient ->getUID ());
111+
112+ $ childShare = $ shareManager ->newShare ()
113+ ->setShareType (IShare::TYPE_USER )
114+ ->setSharedWith ($ recipient ->getUID ())
115+ ->setSharedBy ($ this ->user ->getUID ())
116+ ->setShareOwner ($ this ->user ->getUID ())
117+ ->setNode ($ childNode )
118+ ->setPermissions (Constants::PERMISSION_READ );
119+ $ childShare = $ shareManager ->createShare ($ childShare );
120+ $ shareManager ->acceptShare ($ childShare , $ recipient ->getUID ());
121+
122+ $ setupManager ->tearDown ();
123+ $ setupManager ->setupForUser ($ recipient );
124+
125+ $ recipientFolder = Server::get (IRootFolder::class)->getUserFolder ($ recipient ->getUID ());
126+ $ nodes = $ recipientFolder ->getById ($ childNode ->getId ());
127+
128+ $ this ->assertCount (2 , $ nodes );
129+
130+ $ readOnlyNode = null ;
131+ $ shareableNode = null ;
132+ foreach ($ nodes as $ node ) {
133+ if (($ node ->getPermissions () & Constants::PERMISSION_SHARE ) === 0 ) {
134+ $ readOnlyNode = $ node ;
135+ } else {
136+ $ shareableNode = $ node ;
137+ }
100138 }
139+
140+ $ this ->assertNotNull ($ readOnlyNode );
141+ $ this ->assertNotNull ($ shareableNode );
142+ $ this ->assertNotSame ($ readOnlyNode ->getPath (), $ shareableNode ->getPath ());
143+ $ this ->assertSame (0 , $ readOnlyNode ->getPermissions () & Constants::PERMISSION_SHARE );
144+ $ this ->assertSame (Constants::PERMISSION_SHARE , $ shareableNode ->getPermissions () & Constants::PERMISSION_SHARE );
145+
146+ $ resource = new NodeResource (
147+ $ childNode ->getId (),
148+ $ recipient ->getUID (),
149+ $ readOnlyNode ,
150+ );
151+
152+ $ this ->assertSame (
153+ Constants::PERMISSION_SHARE ,
154+ $ resource ->getNodePermissions () & Constants::PERMISSION_SHARE ,
155+ );
156+
157+ $ event = new RestrictInteractionEvent (
158+ $ recipient ->getUID (),
159+ $ recipient ,
160+ [$ resource ],
161+ new ShareAction (),
162+ [],
163+ );
164+
165+ $ this ->assertFalse ($ event ->isInteractionRestricted ());
101166 }
102167
103168 public function testNodeResourceShareActionNotHomeFolder (): void {
0 commit comments