1414use OCP \Cache \CappedMemoryCache ;
1515use OCP \EventDispatcher \IEventDispatcher ;
1616use OCP \Files \Config \IMountProvider ;
17+ use OCP \Files \Config \IMountProviderArgs ;
18+ use OCP \Files \Config \IPartialMountProvider ;
1719use OCP \Files \Mount \IMountManager ;
1820use OCP \Files \Mount \IMountPoint ;
1921use OCP \Files \Storage \IStorageFactory ;
2628use Psr \Log \LoggerInterface ;
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,19 @@ 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 ($ this ->getMountsFromSuperShares ($ userId ,
68+ $ superShares ,
69+ $ loader , $ user ));
6670 }
6771
6872 /**
6973 * Groups shares by path (nodeId) and target path
7074 *
71- * @param IShare[] $shares
75+ * @param iterable< IShare> $shares
7276 * @return IShare[][] array of grouped shares, each element in the
7377 * array is a group which itself is an array of shares
7478 */
75- private function groupShares (array $ shares ) {
79+ private function groupShares (iterable $ shares ): array {
7680 $ tmp = [];
7781
7882 foreach ($ shares as $ share ) {
@@ -108,11 +112,11 @@ private function groupShares(array $shares) {
108112 * the shares in the group, forming the most permissive combination
109113 * possible.
110114 *
111- * @param IShare[] $allShares
115+ * @param iterable< IShare> $allShares
112116 * @param IUser $user user
113117 * @return list<array{IShare, array<IShare>}> Tuple of [superShare, groupedShares]
114118 */
115- private function buildSuperShares (array $ allShares , IUser $ user ) {
119+ private function buildSuperShares (iterable $ allShares , IUser $ user ): array {
116120 $ result = [];
117121
118122 $ groupedShares = $ this ->groupShares ($ allShares );
@@ -248,7 +252,7 @@ private function adjustTarget(
248252 * @param array $superShares
249253 * @param IStorageFactory $loader
250254 * @param IUser $user
251- * @return array
255+ * @return array IMountPoint indexed by mount point
252256 * @throws Exception
253257 */
254258 private function getMountsFromSuperShares (
@@ -333,24 +337,102 @@ 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 ($ share ->getPermissions () > 0 && $ share ->getShareOwner ()
353+ !== $ userId && $ share ->getSharedBy () !== $ userId ) {
354+ yield $ share ;
355+ }
356+ }
357+ }
358+
359+ /**
360+ * @inheritdoc
361+ */
362+ public function getMountsForPath (
363+ string $ path ,
364+ bool $ forChildren ,
365+ array $ mountProviderArgs ,
366+ IStorageFactory $ loader ,
367+ ): array {
368+ if (empty ($ mountProviderArgs )) {
369+ return [];
370+ }
371+
372+ $ limit = -1 ;
373+ $ userId = null ;
374+ $ user = null ;
375+ foreach ($ mountProviderArgs as $ mountProviderArg ) {
376+ if ($ userId === null ) {
377+ $ user = $ mountProviderArg ->mountInfo ->getUser ();
378+ $ userId = $ user ->getUID ();
379+ } elseif ($ userId !== $ mountProviderArg ->mountInfo ->getUser ()->getUID ()) {
380+ throw new \LogicException ('Mounts must belong to the same user! ' );
353381 }
382+ }
383+
384+ if (!$ forChildren ) {
385+ // override path with mount point when fetching without children
386+ $ path = $ mountProviderArgs [0 ]->mountInfo ->getMountPoint ();
387+ }
388+
389+ // remove /uid/files and the trailing slash as the target is stored
390+ // without it
391+ $ path = \rtrim (\substr ($ path , \strlen ('/ ' . $ userId . '/files ' )), '/ ' );
392+
393+ $ shares = $ this ->mergeIterables (
394+ $ this ->shareManager ->getSharedWithByPath ($ userId ,
395+ IShare::TYPE_USER , $ path , $ forChildren , $ limit ),
396+ $ this ->shareManager ->getSharedWithByPath ($ userId ,
397+ IShare::TYPE_GROUP , $ path , $ forChildren , $ limit ),
398+ $ this ->shareManager ->getSharedWithByPath ($ userId ,
399+ IShare::TYPE_CIRCLE , $ path , $ forChildren , $ limit ),
400+ $ this ->shareManager ->getSharedWithByPath ($ userId ,
401+ IShare::TYPE_ROOM , $ path , $ forChildren , $ limit ),
402+ $ this ->shareManager ->getSharedWithByPath ($ userId ,
403+ IShare::TYPE_DECK , $ path , $ forChildren , $ limit ),
404+ $ this ->shareManager ->getSharedWithByPath ($ userId ,
405+ IShare::TYPE_SCIENCEMESH , $ path , $ forChildren , $ limit ),
354406 );
407+
408+ $ shares = $ this ->filterShares ($ shares , $ userId );
409+ $ superShares = $ this ->buildSuperShares ($ shares , $ user );
410+
411+ // remove unrequested shares
412+ $ superShares = \array_filter ($ superShares , function (array $ shares ) use ($ mountProviderArgs ) {
413+ $ superShare = $ shares [0 ];
414+
415+ return array_any ($ mountProviderArgs ,
416+ function (IMountProviderArgs $ mountProviderArg ) use ($ superShare ) {
417+ return $ superShare ->getNodeId () === $ mountProviderArg ->mountInfo ->getRootId ();
418+ });
419+ });
420+
421+ return $ this ->getMountsFromSuperShares ($ userId ,
422+ $ superShares ,
423+ $ loader ,
424+ $ user );
425+ }
426+
427+ /**
428+ * @param iterable ...$iterables
429+ * @return iterable
430+ */
431+ private function mergeIterables (...$ iterables ): iterable {
432+ foreach ($ iterables as $ iterable ) {
433+ foreach ($ iterable as $ value ) {
434+ yield $ value ;
435+ }
436+ }
355437 }
356438}
0 commit comments