1414use OCP \Cache \CappedMemoryCache ;
1515use OCP \EventDispatcher \IEventDispatcher ;
1616use OCP \Files \Config \IMountProvider ;
17+ use OCP \Files \Config \IPartialMountProvider ;
1718use OCP \Files \Mount \IMountManager ;
1819use OCP \Files \Mount \IMountPoint ;
1920use OCP \Files \Storage \IStorageFactory ;
2425use OCP \Share \IManager ;
2526use OCP \Share \IShare ;
2627use Psr \Log \LoggerInterface ;
28+
2729use function count ;
2830
29- class MountProvider implements IMountProvider {
31+ class MountProvider implements IMountProvider, IPartialMountProvider {
3032 /**
3133 * @param IConfig $config
3234 * @param IManager $shareManager
@@ -51,7 +53,7 @@ public function __construct(
5153 */
5254 public function getMountsForUser (IUser $ user , IStorageFactory $ loader ) {
5355 $ userId = $ user ->getUID ();
54- $ shares = array_merge (
56+ $ shares = $ this -> mergeIterables (
5557 $ this ->shareManager ->getSharedWith ($ userId , IShare::TYPE_USER , null , -1 ),
5658 $ this ->shareManager ->getSharedWith ($ userId , IShare::TYPE_GROUP , null , -1 ),
5759 $ this ->shareManager ->getSharedWith ($ userId , IShare::TYPE_CIRCLE , null , -1 ),
@@ -62,17 +64,24 @@ public function getMountsForUser(IUser $user, IStorageFactory $loader) {
6264 $ shares = $ this ->filterShares ($ shares , $ userId );
6365 $ superShares = $ this ->buildSuperShares ($ shares , $ user );
6466
65- return $ this ->getMountsFromSuperShares ($ userId , $ superShares , $ loader , $ user );
67+ return array_values (
68+ $ this ->getMountsFromSuperShares (
69+ $ userId ,
70+ $ superShares ,
71+ $ loader ,
72+ $ user ,
73+ ),
74+ );
6675 }
6776
6877 /**
6978 * Groups shares by path (nodeId) and target path
7079 *
71- * @param IShare[] $shares
80+ * @param iterable< IShare> $shares
7281 * @return IShare[][] array of grouped shares, each element in the
7382 * array is a group which itself is an array of shares
7483 */
75- private function groupShares (array $ shares ) {
84+ private function groupShares (iterable $ shares ): array {
7685 $ tmp = [];
7786
7887 foreach ($ shares as $ share ) {
@@ -108,11 +117,11 @@ private function groupShares(array $shares) {
108117 * the shares in the group, forming the most permissive combination
109118 * possible.
110119 *
111- * @param IShare[] $allShares
120+ * @param iterable< IShare> $allShares
112121 * @param IUser $user user
113122 * @return list<array{IShare, array<IShare>}> Tuple of [superShare, groupedShares]
114123 */
115- private function buildSuperShares (array $ allShares , IUser $ user ) {
124+ private function buildSuperShares (iterable $ allShares , IUser $ user ): array {
116125 $ result = [];
117126
118127 $ groupedShares = $ this ->groupShares ($ allShares );
@@ -237,8 +246,7 @@ private function adjustTarget(
237246 // null groups which usually appear with group backend
238247 // caching inconsistencies
239248 $ this ->logger ->debug (
240- 'Could not adjust share target for share ' . $ share ->getId (
241- ) . ' to make it consistent: ' . $ e ->getMessage (),
249+ 'Could not adjust share target for share ' . $ share ->getId () . ' to make it consistent: ' . $ e ->getMessage (),
242250 ['app ' => 'files_sharing ' ]
243251 );
244252 }
@@ -248,7 +256,7 @@ private function adjustTarget(
248256 * @param array $superShares
249257 * @param IStorageFactory $loader
250258 * @param IUser $user
251- * @return array
259+ * @return array IMountPoint indexed by mount point
252260 * @throws Exception
253261 */
254262 private function getMountsFromSuperShares (
@@ -261,13 +269,11 @@ private function getMountsFromSuperShares(
261269 $ mounts = [];
262270 $ view = new View ('/ ' . $ userId . '/files ' );
263271 $ ownerViews = [];
264- $ sharingDisabledForUser
265- = $ this ->shareManager ->sharingDisabledForUser ($ userId );
272+ $ sharingDisabledForUser = $ this ->shareManager ->sharingDisabledForUser ($ userId );
266273 /** @var CappedMemoryCache<bool> $folderExistCache */
267274 $ foldersExistCache = new CappedMemoryCache ();
268275
269- $ validShareCache
270- = $ this ->cacheFactory ->createLocal ('share-valid-mountpoint-max ' );
276+ $ validShareCache = $ this ->cacheFactory ->createLocal ('share-valid-mountpoint-max ' );
271277 $ maxValidatedShare = $ validShareCache ->get ($ userId ) ?? 0 ;
272278 $ newMaxValidatedShare = $ maxValidatedShare ;
273279
@@ -312,12 +318,10 @@ private function getMountsFromSuperShares(
312318 $ event = new ShareMountedEvent ($ mount );
313319 $ this ->eventDispatcher ->dispatchTyped ($ event );
314320
315- $ mounts [$ mount ->getMountPoint ()]
316- = $ allMounts [$ mount ->getMountPoint ()] = $ mount ;
321+ $ mounts [$ mount ->getMountPoint ()] = $ allMounts [$ mount ->getMountPoint ()] = $ mount ;
317322 foreach ($ event ->getAdditionalMounts () as $ additionalMount ) {
318- $ allMounts [$ additionalMount ->getMountPoint ()]
319- = $ mounts [$ additionalMount ->getMountPoint ()]
320- = $ additionalMount ;
323+ $ mounts [$ additionalMount ->getMountPoint ()] = $ additionalMount ;
324+ $ allMounts [$ additionalMount ->getMountPoint ()] = $ additionalMount ;
321325 }
322326 } catch (Exception $ e ) {
323327 $ this ->logger ->error (
@@ -333,24 +337,74 @@ private function getMountsFromSuperShares(
333337 $ validShareCache ->set ($ userId , $ newMaxValidatedShare , 24 * 60 * 60 );
334338
335339 // array_filter removes the null values from the array
336- return array_values ( array_filter ($ mounts) );
340+ return array_filter ($ mounts );
337341 }
338342
339343 /**
340344 * Filters out shares owned or shared by the user and ones for which the
341345 * user has no permissions.
342346 *
343- * @param IShare[] $shares
344- * @return IShare[]
347+ * @param iterable< IShare> $shares
348+ * @return iterable< IShare>
345349 */
346- private function filterShares (array $ shares , string $ userId ): array {
347- return array_filter (
348- $ shares ,
349- static function (IShare $ share ) use ($ userId ) {
350- return $ share ->getPermissions () > 0
351- && $ share ->getShareOwner () !== $ userId
352- && $ share ->getSharedBy () !== $ userId ;
350+ private function filterShares (iterable $ shares , string $ userId ): iterable {
351+ foreach ($ shares as $ share ) {
352+ if (
353+ $ share ->getPermissions () > 0
354+ && $ share ->getShareOwner () !== $ userId
355+ && $ share ->getSharedBy () !== $ userId
356+ ) {
357+ yield $ share ;
353358 }
359+ }
360+ }
361+
362+ public function getMountsForPath (
363+ string $ setupPathHint ,
364+ bool $ forChildren ,
365+ array $ mountProviderArgs ,
366+ IStorageFactory $ loader ,
367+ ): array {
368+ $ limit = -1 ;
369+ $ user = $ mountProviderArgs [0 ]->mountInfo ->getUser ();
370+ $ userId = $ user ->getUID ();
371+
372+ if (!$ forChildren ) {
373+ // override path with mount point when fetching without children
374+ $ setupPathHint = $ mountProviderArgs [0 ]->mountInfo ->getMountPoint ();
375+ }
376+
377+ // remove /uid/files as the target is stored without
378+ $ setupPathHint = \substr ($ setupPathHint , \strlen ('/ ' . $ userId . '/files ' ));
379+ // remove trailing slash
380+ $ setupPathHint = \rtrim ($ setupPathHint , '/ ' );
381+
382+ // make sure trailing slash is present when loading children
383+ if ($ forChildren || $ setupPathHint === '' ) {
384+ $ setupPathHint .= '/ ' ;
385+ }
386+
387+ $ shares = $ this ->mergeIterables (
388+ $ this ->shareManager ->getSharedWithByPath ($ userId , IShare::TYPE_USER , $ setupPathHint , $ forChildren , $ limit ),
389+ $ this ->shareManager ->getSharedWithByPath ($ userId , IShare::TYPE_GROUP , $ setupPathHint , $ forChildren , $ limit ),
390+ $ this ->shareManager ->getSharedWithByPath ($ userId , IShare::TYPE_CIRCLE , $ setupPathHint , $ forChildren , $ limit ),
391+ $ this ->shareManager ->getSharedWithByPath ($ userId , IShare::TYPE_ROOM , $ setupPathHint , $ forChildren , $ limit ),
392+ $ this ->shareManager ->getSharedWithByPath ($ userId , IShare::TYPE_DECK , $ setupPathHint , $ forChildren , $ limit ),
354393 );
394+
395+ $ shares = $ this ->filterShares ($ shares , $ userId );
396+ $ superShares = $ this ->buildSuperShares ($ shares , $ user );
397+
398+ return $ this ->getMountsFromSuperShares ($ userId , $ superShares , $ loader , $ user );
399+ }
400+
401+ /**
402+ * @param iterable ...$iterables
403+ * @return iterable
404+ */
405+ private function mergeIterables (...$ iterables ): iterable {
406+ foreach ($ iterables as $ iterable ) {
407+ yield from $ iterable ;
408+ }
355409 }
356410}
0 commit comments