@@ -86,6 +86,9 @@ class Share20OcsController extends OCSController {
8686 */
8787 private $ additionalInfoField ;
8888
89+ /** @var Folder[] */
90+ private $ currentUserFolder ;
91+
8992 public function __construct (
9093 $ appName ,
9194 IRequest $ request ,
@@ -132,6 +135,21 @@ private function getAdditionalUserInfo(IUser $user) {
132135 return null ;
133136 }
134137
138+ /**
139+ * Returns root folder of the current user
140+ *
141+ * @return Folder
142+ */
143+ private function getCurrentUserFolder () {
144+ // cache only one key, but be sure to check current user session id in case
145+ // current user folder changes
146+ $ userSessionId = $ this ->userSession ->getUser ()->getUID ();
147+ if (!isset ($ this ->currentUserFolder [$ userSessionId ])) {
148+ $ this ->currentUserFolder = [$ userSessionId => $ this ->rootFolder ->getUserFolder ($ userSessionId )];
149+ }
150+ return $ this ->currentUserFolder [$ userSessionId ];
151+ }
152+
135153 /**
136154 * Convert an IShare to an array for OCS output
137155 *
@@ -172,34 +190,33 @@ protected function formatShare(IShare $share, $received = false) {
172190
173191 // can only fetch path info if mounted already or if owner
174192 if ($ share ->getState () === Share::STATE_ACCEPTED || $ share ->getShareOwner () === $ this ->userSession ->getUser ()->getUID ()) {
175- $ userFolder = $ this ->rootFolder -> getUserFolder ( $ this -> userSession -> getUser ()-> getUID () );
193+ $ userFolder = $ this ->getCurrentUserFolder ( );
176194 } else {
177195 // need to go through owner user for pending shares
178196 $ userFolder = $ this ->rootFolder ->getUserFolder ($ share ->getShareOwner ());
179197 }
180198 } else {
181- $ userFolder = $ this ->rootFolder -> getUserFolder ( $ this -> userSession -> getUser ()-> getUID () );
199+ $ userFolder = $ this ->getCurrentUserFolder ( );
182200 }
183201
184- $ nodes = $ userFolder ->getById ($ share ->getNodeId (), true );
185- $ node = $ nodes [0 ] ?? null ;
186- if ($ node === null ) {
202+ // we need to retrieve a share mountpoint node for the userfolder,
203+ // we cannot use share->getNode() as it retrieves the original node and
204+ // not a user folder mount. Share node will be needed to retrieve e.g.
205+ // shared storage details
206+ $ shareNodes = $ userFolder ->getById ($ share ->getNodeId (), true );
207+ $ shareNode = $ shareNodes [0 ] ?? null ;
208+ if ($ shareNode === null ) {
187209 throw new NotFoundException ();
188210 }
189- $ node = $ nodes [0 ];
190211
191- $ result ['path ' ] = $ userFolder ->getRelativePath ($ node ->getPath ());
192- if ($ node instanceof Folder) {
193- $ result ['item_type ' ] = 'folder ' ;
194- } else {
195- $ result ['item_type ' ] = 'file ' ;
196- }
197- $ result ['mimetype ' ] = $ node ->getMimeType ();
198- $ result ['storage_id ' ] = $ node ->getStorage ()->getId ();
199- $ result ['storage ' ] = $ node ->getStorage ()->getCache ()->getNumericStorageId ();
200- $ result ['item_source ' ] = $ node ->getId ();
201- $ result ['file_source ' ] = $ node ->getId ();
202- $ result ['file_parent ' ] = $ node ->getParent ()->getId ();
212+ $ result ['path ' ] = $ userFolder ->getRelativePath ($ shareNode ->getPath ());
213+ $ result ['mimetype ' ] = $ shareNode ->getMimeType ();
214+ $ result ['storage_id ' ] = $ shareNode ->getStorage ()->getId ();
215+ $ result ['storage ' ] = $ shareNode ->getStorage ()->getCache ()->getNumericStorageId ();
216+ $ result ['item_type ' ] = $ share ->getNodeType ();
217+ $ result ['item_source ' ] = $ shareNode ->getId ();
218+ $ result ['file_source ' ] = $ shareNode ->getId ();
219+ $ result ['file_parent ' ] = $ shareNode ->getParent ()->getId ();
203220 $ result ['file_target ' ] = $ share ->getTarget ();
204221
205222 $ expiration = $ share ->getExpirationDate ();
@@ -341,7 +358,7 @@ public function createShare() {
341358 return new Result (null , 404 , $ this ->l ->t ('Please specify a file or folder path ' ));
342359 }
343360
344- $ userFolder = $ this ->rootFolder -> getUserFolder ( $ this -> userSession -> getUser ()-> getUID () );
361+ $ userFolder = $ this ->getCurrentUserFolder ( );
345362
346363 try {
347364 $ path = $ userFolder ->get ($ path );
@@ -668,7 +685,7 @@ public function getShares() {
668685 // (with "true" value), without duplicate elements, and only valid share types
669686
670687 if ($ path !== null ) {
671- $ userFolder = $ this ->rootFolder -> getUserFolder ( $ this -> userSession -> getUser ()-> getUID () );
688+ $ userFolder = $ this ->getCurrentUserFolder ( );
672689 try {
673690 $ path = $ userFolder ->get ($ path );
674691 $ path ->lock (ILockingProvider::LOCK_SHARED );
@@ -999,6 +1016,8 @@ private function updateShareState($id, $state) {
9991016
10001017 $ node ->unlock (ILockingProvider::LOCK_SHARED );
10011018
1019+ // refresh the mounts by teardown of existing user mounts and remounting
1020+ // by retrieving current user folder
10021021 // FIXME: needs public API!
10031022 Filesystem::tearDown ();
10041023 // FIXME: trigger mount for user to make sure the new node is mounted already
@@ -1021,7 +1040,7 @@ private function updateShareState($id, $state) {
10211040 * @return IShare same share with target updated if necessary
10221041 */
10231042 private function deduplicateShareTarget (IShare $ share ) {
1024- $ userFolder = $ this ->rootFolder -> getUserFolder ( $ this -> userSession -> getUser ()-> getUID () );
1043+ $ userFolder = $ this ->getCurrentUserFolder ( );
10251044 $ parentDir = \dirname ($ share ->getTarget ());
10261045 if (!$ userFolder ->nodeExists ($ parentDir )) {
10271046 // assume the parent folder matches the configured shared folder
0 commit comments