Completed
Push — master ( 86d952...cbfcfb )
by Morris
24:23
created
apps/files_sharing/lib/Controller/ShareAPIController.php 1 patch
Indentation   +889 added lines, -889 removed lines patch added patch discarded remove patch
@@ -62,902 +62,902 @@
 block discarded – undo
62 62
  */
63 63
 class ShareAPIController extends OCSController {
64 64
 
65
-	/** @var IManager */
66
-	private $shareManager;
67
-	/** @var IGroupManager */
68
-	private $groupManager;
69
-	/** @var IUserManager */
70
-	private $userManager;
71
-	/** @var IRootFolder */
72
-	private $rootFolder;
73
-	/** @var IURLGenerator */
74
-	private $urlGenerator;
75
-	/** @var string */
76
-	private $currentUser;
77
-	/** @var IL10N */
78
-	private $l;
79
-	/** @var \OCP\Files\Node */
80
-	private $lockedNode;
81
-	/** @var IConfig */
82
-	private $config;
83
-
84
-	/**
85
-	 * Share20OCS constructor.
86
-	 *
87
-	 * @param string $appName
88
-	 * @param IRequest $request
89
-	 * @param IManager $shareManager
90
-	 * @param IGroupManager $groupManager
91
-	 * @param IUserManager $userManager
92
-	 * @param IRootFolder $rootFolder
93
-	 * @param IURLGenerator $urlGenerator
94
-	 * @param string $userId
95
-	 * @param IL10N $l10n
96
-	 * @param IConfig $config
97
-	 */
98
-	public function __construct(
99
-		string $appName,
100
-		IRequest $request,
101
-		IManager $shareManager,
102
-		IGroupManager $groupManager,
103
-		IUserManager $userManager,
104
-		IRootFolder $rootFolder,
105
-		IURLGenerator $urlGenerator,
106
-		string $userId,
107
-		IL10N $l10n,
108
-		IConfig $config
109
-	) {
110
-		parent::__construct($appName, $request);
111
-
112
-		$this->shareManager = $shareManager;
113
-		$this->userManager = $userManager;
114
-		$this->groupManager = $groupManager;
115
-		$this->request = $request;
116
-		$this->rootFolder = $rootFolder;
117
-		$this->urlGenerator = $urlGenerator;
118
-		$this->currentUser = $userId;
119
-		$this->l = $l10n;
120
-		$this->config = $config;
121
-	}
122
-
123
-	/**
124
-	 * Convert an IShare to an array for OCS output
125
-	 *
126
-	 * @param \OCP\Share\IShare $share
127
-	 * @param Node|null $recipientNode
128
-	 * @return array
129
-	 * @throws NotFoundException In case the node can't be resolved.
130
-	 */
131
-	protected function formatShare(\OCP\Share\IShare $share, Node $recipientNode = null): array {
132
-		$sharedBy = $this->userManager->get($share->getSharedBy());
133
-		$shareOwner = $this->userManager->get($share->getShareOwner());
134
-
135
-		$result = [
136
-			'id' => $share->getId(),
137
-			'share_type' => $share->getShareType(),
138
-			'uid_owner' => $share->getSharedBy(),
139
-			'displayname_owner' => $sharedBy !== null ? $sharedBy->getDisplayName() : $share->getSharedBy(),
140
-			'permissions' => $share->getPermissions(),
141
-			'stime' => $share->getShareTime()->getTimestamp(),
142
-			'parent' => null,
143
-			'expiration' => null,
144
-			'token' => null,
145
-			'uid_file_owner' => $share->getShareOwner(),
146
-			'displayname_file_owner' => $shareOwner !== null ? $shareOwner->getDisplayName() : $share->getShareOwner(),
147
-		];
148
-
149
-		$userFolder = $this->rootFolder->getUserFolder($this->currentUser);
150
-		if ($recipientNode) {
151
-			$node = $recipientNode;
152
-		} else {
153
-			$nodes = $userFolder->getById($share->getNodeId());
154
-			if (empty($nodes)) {
155
-				// fallback to guessing the path
156
-				$node = $userFolder->get($share->getTarget());
157
-				if ($node === null || $share->getTarget() === '') {
158
-					throw new NotFoundException();
159
-				}
160
-			} else {
161
-				$node = $nodes[0];
162
-			}
163
-		}
164
-
165
-		$result['path'] = $userFolder->getRelativePath($node->getPath());
166
-		if ($node instanceOf \OCP\Files\Folder) {
167
-			$result['item_type'] = 'folder';
168
-		} else {
169
-			$result['item_type'] = 'file';
170
-		}
171
-		$result['mimetype'] = $node->getMimetype();
172
-		$result['storage_id'] = $node->getStorage()->getId();
173
-		$result['storage'] = $node->getStorage()->getCache()->getNumericStorageId();
174
-		$result['item_source'] = $node->getId();
175
-		$result['file_source'] = $node->getId();
176
-		$result['file_parent'] = $node->getParent()->getId();
177
-		$result['file_target'] = $share->getTarget();
178
-
179
-		$expiration = $share->getExpirationDate();
180
-		if ($expiration !== null) {
181
-			$result['expiration'] = $expiration->format('Y-m-d 00:00:00');
182
-		}
183
-
184
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
185
-			$sharedWith = $this->userManager->get($share->getSharedWith());
186
-			$result['share_with'] = $share->getSharedWith();
187
-			$result['share_with_displayname'] = $sharedWith !== null ? $sharedWith->getDisplayName() : $share->getSharedWith();
188
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
189
-			$group = $this->groupManager->get($share->getSharedWith());
190
-			$result['share_with'] = $share->getSharedWith();
191
-			$result['share_with_displayname'] = $group !== null ? $group->getDisplayName() : $share->getSharedWith();
192
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
193
-
194
-			$result['share_with'] = $share->getPassword();
195
-			$result['share_with_displayname'] = $share->getPassword();
196
-
197
-			$result['token'] = $share->getToken();
198
-			$result['url'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $share->getToken()]);
199
-
200
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_REMOTE) {
201
-			$result['share_with'] = $share->getSharedWith();
202
-			$result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'CLOUD');
203
-			$result['token'] = $share->getToken();
204
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
205
-			$result['share_with'] = $share->getSharedWith();
206
-			$result['password'] = $share->getPassword();
207
-			$result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'EMAIL');
208
-			$result['token'] = $share->getToken();
209
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_CIRCLE) {
210
-			// getSharedWith() returns either "name (type, owner)" or
211
-			// "name (type, owner) [id]", depending on the Circles app version.
212
-			$hasCircleId = (substr($share->getSharedWith(), -1) === ']');
213
-
214
-			$displayNameLength = ($hasCircleId? strrpos($share->getSharedWith(), ' '): strlen($share->getSharedWith()));
215
-			$result['share_with_displayname'] = substr($share->getSharedWith(), 0, $displayNameLength);
216
-
217
-			$shareWithStart = ($hasCircleId? strrpos($share->getSharedWith(), '[') + 1: 0);
218
-			$shareWithLength = ($hasCircleId? -1: strpos($share->getSharedWith(), ' '));
219
-			$result['share_with'] = substr($share->getSharedWith(), $shareWithStart, $shareWithLength);
220
-		}
221
-
222
-
223
-		$result['mail_send'] = $share->getMailSend() ? 1 : 0;
224
-
225
-		return $result;
226
-	}
227
-
228
-	/**
229
-	 * Check if one of the users address books knows the exact property, if
230
-	 * yes we return the full name.
231
-	 *
232
-	 * @param string $query
233
-	 * @param string $property
234
-	 * @return string
235
-	 */
236
-	private function getDisplayNameFromAddressBook(string $query, string $property): string {
237
-		// FIXME: If we inject the contacts manager it gets initialized bofore any address books are registered
238
-		$result = \OC::$server->getContactsManager()->search($query, [$property]);
239
-		foreach ($result as $r) {
240
-			foreach($r[$property] as $value) {
241
-				if ($value === $query) {
242
-					return $r['FN'];
243
-				}
244
-			}
245
-		}
246
-
247
-		return $query;
248
-	}
249
-
250
-	/**
251
-	 * Get a specific share by id
252
-	 *
253
-	 * @NoAdminRequired
254
-	 *
255
-	 * @param string $id
256
-	 * @return DataResponse
257
-	 * @throws OCSNotFoundException
258
-	 */
259
-	public function getShare(string $id): DataResponse {
260
-		try {
261
-			$share = $this->getShareById($id);
262
-		} catch (ShareNotFound $e) {
263
-			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
264
-		}
265
-
266
-		if ($this->canAccessShare($share)) {
267
-			try {
268
-				$share = $this->formatShare($share);
269
-				return new DataResponse([$share]);
270
-			} catch (NotFoundException $e) {
271
-				//Fall trough
272
-			}
273
-		}
274
-
275
-		throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
276
-	}
277
-
278
-	/**
279
-	 * Delete a share
280
-	 *
281
-	 * @NoAdminRequired
282
-	 *
283
-	 * @param string $id
284
-	 * @return DataResponse
285
-	 * @throws OCSNotFoundException
286
-	 */
287
-	public function deleteShare(string $id): DataResponse {
288
-		try {
289
-			$share = $this->getShareById($id);
290
-		} catch (ShareNotFound $e) {
291
-			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
292
-		}
293
-
294
-		try {
295
-			$this->lock($share->getNode());
296
-		} catch (LockedException $e) {
297
-			throw new OCSNotFoundException($this->l->t('could not delete share'));
298
-		}
299
-
300
-		if (!$this->canAccessShare($share)) {
301
-			throw new OCSNotFoundException($this->l->t('Could not delete share'));
302
-		}
303
-
304
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP &&
305
-			$share->getShareOwner() !== $this->currentUser &&
306
-			$share->getSharedBy() !== $this->currentUser) {
307
-			$this->shareManager->deleteFromSelf($share, $this->currentUser);
308
-		} else {
309
-			$this->shareManager->deleteShare($share);
310
-		}
311
-
312
-		return new DataResponse();
313
-	}
314
-
315
-	/**
316
-	 * @NoAdminRequired
317
-	 *
318
-	 * @param string $path
319
-	 * @param int $permissions
320
-	 * @param int $shareType
321
-	 * @param string $shareWith
322
-	 * @param string $publicUpload
323
-	 * @param string $password
324
-	 * @param string $expireDate
325
-	 *
326
-	 * @return DataResponse
327
-	 * @throws OCSNotFoundException
328
-	 * @throws OCSForbiddenException
329
-	 * @throws OCSBadRequestException
330
-	 * @throws OCSException
331
-	 *
332
-	 * @suppress PhanUndeclaredClassMethod
333
-	 */
334
-	public function createShare(
335
-		string $path = null,
336
-		int $permissions = null,
337
-		int $shareType = -1,
338
-		string $shareWith = null,
339
-		string $publicUpload = 'false',
340
-		string $password = '',
341
-		string $expireDate = ''
342
-	): DataResponse {
343
-		$share = $this->shareManager->newShare();
344
-
345
-		if ($permissions === null) {
346
-			$permissions = $this->config->getAppValue('core', 'shareapi_default_permissions', Constants::PERMISSION_ALL);
347
-		}
348
-
349
-		// Verify path
350
-		if ($path === null) {
351
-			throw new OCSNotFoundException($this->l->t('Please specify a file or folder path'));
352
-		}
353
-
354
-		$userFolder = $this->rootFolder->getUserFolder($this->currentUser);
355
-		try {
356
-			$path = $userFolder->get($path);
357
-		} catch (NotFoundException $e) {
358
-			throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
359
-		}
360
-
361
-		$share->setNode($path);
362
-
363
-		try {
364
-			$this->lock($share->getNode());
365
-		} catch (LockedException $e) {
366
-			throw new OCSNotFoundException($this->l->t('Could not create share'));
367
-		}
368
-
369
-		if ($permissions < 0 || $permissions > Constants::PERMISSION_ALL) {
370
-			throw new OCSNotFoundException($this->l->t('invalid permissions'));
371
-		}
372
-
373
-		// Shares always require read permissions
374
-		$permissions |= Constants::PERMISSION_READ;
375
-
376
-		if ($path instanceof \OCP\Files\File) {
377
-			// Single file shares should never have delete or create permissions
378
-			$permissions &= ~Constants::PERMISSION_DELETE;
379
-			$permissions &= ~Constants::PERMISSION_CREATE;
380
-		}
381
-
382
-		/*
65
+    /** @var IManager */
66
+    private $shareManager;
67
+    /** @var IGroupManager */
68
+    private $groupManager;
69
+    /** @var IUserManager */
70
+    private $userManager;
71
+    /** @var IRootFolder */
72
+    private $rootFolder;
73
+    /** @var IURLGenerator */
74
+    private $urlGenerator;
75
+    /** @var string */
76
+    private $currentUser;
77
+    /** @var IL10N */
78
+    private $l;
79
+    /** @var \OCP\Files\Node */
80
+    private $lockedNode;
81
+    /** @var IConfig */
82
+    private $config;
83
+
84
+    /**
85
+     * Share20OCS constructor.
86
+     *
87
+     * @param string $appName
88
+     * @param IRequest $request
89
+     * @param IManager $shareManager
90
+     * @param IGroupManager $groupManager
91
+     * @param IUserManager $userManager
92
+     * @param IRootFolder $rootFolder
93
+     * @param IURLGenerator $urlGenerator
94
+     * @param string $userId
95
+     * @param IL10N $l10n
96
+     * @param IConfig $config
97
+     */
98
+    public function __construct(
99
+        string $appName,
100
+        IRequest $request,
101
+        IManager $shareManager,
102
+        IGroupManager $groupManager,
103
+        IUserManager $userManager,
104
+        IRootFolder $rootFolder,
105
+        IURLGenerator $urlGenerator,
106
+        string $userId,
107
+        IL10N $l10n,
108
+        IConfig $config
109
+    ) {
110
+        parent::__construct($appName, $request);
111
+
112
+        $this->shareManager = $shareManager;
113
+        $this->userManager = $userManager;
114
+        $this->groupManager = $groupManager;
115
+        $this->request = $request;
116
+        $this->rootFolder = $rootFolder;
117
+        $this->urlGenerator = $urlGenerator;
118
+        $this->currentUser = $userId;
119
+        $this->l = $l10n;
120
+        $this->config = $config;
121
+    }
122
+
123
+    /**
124
+     * Convert an IShare to an array for OCS output
125
+     *
126
+     * @param \OCP\Share\IShare $share
127
+     * @param Node|null $recipientNode
128
+     * @return array
129
+     * @throws NotFoundException In case the node can't be resolved.
130
+     */
131
+    protected function formatShare(\OCP\Share\IShare $share, Node $recipientNode = null): array {
132
+        $sharedBy = $this->userManager->get($share->getSharedBy());
133
+        $shareOwner = $this->userManager->get($share->getShareOwner());
134
+
135
+        $result = [
136
+            'id' => $share->getId(),
137
+            'share_type' => $share->getShareType(),
138
+            'uid_owner' => $share->getSharedBy(),
139
+            'displayname_owner' => $sharedBy !== null ? $sharedBy->getDisplayName() : $share->getSharedBy(),
140
+            'permissions' => $share->getPermissions(),
141
+            'stime' => $share->getShareTime()->getTimestamp(),
142
+            'parent' => null,
143
+            'expiration' => null,
144
+            'token' => null,
145
+            'uid_file_owner' => $share->getShareOwner(),
146
+            'displayname_file_owner' => $shareOwner !== null ? $shareOwner->getDisplayName() : $share->getShareOwner(),
147
+        ];
148
+
149
+        $userFolder = $this->rootFolder->getUserFolder($this->currentUser);
150
+        if ($recipientNode) {
151
+            $node = $recipientNode;
152
+        } else {
153
+            $nodes = $userFolder->getById($share->getNodeId());
154
+            if (empty($nodes)) {
155
+                // fallback to guessing the path
156
+                $node = $userFolder->get($share->getTarget());
157
+                if ($node === null || $share->getTarget() === '') {
158
+                    throw new NotFoundException();
159
+                }
160
+            } else {
161
+                $node = $nodes[0];
162
+            }
163
+        }
164
+
165
+        $result['path'] = $userFolder->getRelativePath($node->getPath());
166
+        if ($node instanceOf \OCP\Files\Folder) {
167
+            $result['item_type'] = 'folder';
168
+        } else {
169
+            $result['item_type'] = 'file';
170
+        }
171
+        $result['mimetype'] = $node->getMimetype();
172
+        $result['storage_id'] = $node->getStorage()->getId();
173
+        $result['storage'] = $node->getStorage()->getCache()->getNumericStorageId();
174
+        $result['item_source'] = $node->getId();
175
+        $result['file_source'] = $node->getId();
176
+        $result['file_parent'] = $node->getParent()->getId();
177
+        $result['file_target'] = $share->getTarget();
178
+
179
+        $expiration = $share->getExpirationDate();
180
+        if ($expiration !== null) {
181
+            $result['expiration'] = $expiration->format('Y-m-d 00:00:00');
182
+        }
183
+
184
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
185
+            $sharedWith = $this->userManager->get($share->getSharedWith());
186
+            $result['share_with'] = $share->getSharedWith();
187
+            $result['share_with_displayname'] = $sharedWith !== null ? $sharedWith->getDisplayName() : $share->getSharedWith();
188
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
189
+            $group = $this->groupManager->get($share->getSharedWith());
190
+            $result['share_with'] = $share->getSharedWith();
191
+            $result['share_with_displayname'] = $group !== null ? $group->getDisplayName() : $share->getSharedWith();
192
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
193
+
194
+            $result['share_with'] = $share->getPassword();
195
+            $result['share_with_displayname'] = $share->getPassword();
196
+
197
+            $result['token'] = $share->getToken();
198
+            $result['url'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $share->getToken()]);
199
+
200
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_REMOTE) {
201
+            $result['share_with'] = $share->getSharedWith();
202
+            $result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'CLOUD');
203
+            $result['token'] = $share->getToken();
204
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
205
+            $result['share_with'] = $share->getSharedWith();
206
+            $result['password'] = $share->getPassword();
207
+            $result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'EMAIL');
208
+            $result['token'] = $share->getToken();
209
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_CIRCLE) {
210
+            // getSharedWith() returns either "name (type, owner)" or
211
+            // "name (type, owner) [id]", depending on the Circles app version.
212
+            $hasCircleId = (substr($share->getSharedWith(), -1) === ']');
213
+
214
+            $displayNameLength = ($hasCircleId? strrpos($share->getSharedWith(), ' '): strlen($share->getSharedWith()));
215
+            $result['share_with_displayname'] = substr($share->getSharedWith(), 0, $displayNameLength);
216
+
217
+            $shareWithStart = ($hasCircleId? strrpos($share->getSharedWith(), '[') + 1: 0);
218
+            $shareWithLength = ($hasCircleId? -1: strpos($share->getSharedWith(), ' '));
219
+            $result['share_with'] = substr($share->getSharedWith(), $shareWithStart, $shareWithLength);
220
+        }
221
+
222
+
223
+        $result['mail_send'] = $share->getMailSend() ? 1 : 0;
224
+
225
+        return $result;
226
+    }
227
+
228
+    /**
229
+     * Check if one of the users address books knows the exact property, if
230
+     * yes we return the full name.
231
+     *
232
+     * @param string $query
233
+     * @param string $property
234
+     * @return string
235
+     */
236
+    private function getDisplayNameFromAddressBook(string $query, string $property): string {
237
+        // FIXME: If we inject the contacts manager it gets initialized bofore any address books are registered
238
+        $result = \OC::$server->getContactsManager()->search($query, [$property]);
239
+        foreach ($result as $r) {
240
+            foreach($r[$property] as $value) {
241
+                if ($value === $query) {
242
+                    return $r['FN'];
243
+                }
244
+            }
245
+        }
246
+
247
+        return $query;
248
+    }
249
+
250
+    /**
251
+     * Get a specific share by id
252
+     *
253
+     * @NoAdminRequired
254
+     *
255
+     * @param string $id
256
+     * @return DataResponse
257
+     * @throws OCSNotFoundException
258
+     */
259
+    public function getShare(string $id): DataResponse {
260
+        try {
261
+            $share = $this->getShareById($id);
262
+        } catch (ShareNotFound $e) {
263
+            throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
264
+        }
265
+
266
+        if ($this->canAccessShare($share)) {
267
+            try {
268
+                $share = $this->formatShare($share);
269
+                return new DataResponse([$share]);
270
+            } catch (NotFoundException $e) {
271
+                //Fall trough
272
+            }
273
+        }
274
+
275
+        throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
276
+    }
277
+
278
+    /**
279
+     * Delete a share
280
+     *
281
+     * @NoAdminRequired
282
+     *
283
+     * @param string $id
284
+     * @return DataResponse
285
+     * @throws OCSNotFoundException
286
+     */
287
+    public function deleteShare(string $id): DataResponse {
288
+        try {
289
+            $share = $this->getShareById($id);
290
+        } catch (ShareNotFound $e) {
291
+            throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
292
+        }
293
+
294
+        try {
295
+            $this->lock($share->getNode());
296
+        } catch (LockedException $e) {
297
+            throw new OCSNotFoundException($this->l->t('could not delete share'));
298
+        }
299
+
300
+        if (!$this->canAccessShare($share)) {
301
+            throw new OCSNotFoundException($this->l->t('Could not delete share'));
302
+        }
303
+
304
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP &&
305
+            $share->getShareOwner() !== $this->currentUser &&
306
+            $share->getSharedBy() !== $this->currentUser) {
307
+            $this->shareManager->deleteFromSelf($share, $this->currentUser);
308
+        } else {
309
+            $this->shareManager->deleteShare($share);
310
+        }
311
+
312
+        return new DataResponse();
313
+    }
314
+
315
+    /**
316
+     * @NoAdminRequired
317
+     *
318
+     * @param string $path
319
+     * @param int $permissions
320
+     * @param int $shareType
321
+     * @param string $shareWith
322
+     * @param string $publicUpload
323
+     * @param string $password
324
+     * @param string $expireDate
325
+     *
326
+     * @return DataResponse
327
+     * @throws OCSNotFoundException
328
+     * @throws OCSForbiddenException
329
+     * @throws OCSBadRequestException
330
+     * @throws OCSException
331
+     *
332
+     * @suppress PhanUndeclaredClassMethod
333
+     */
334
+    public function createShare(
335
+        string $path = null,
336
+        int $permissions = null,
337
+        int $shareType = -1,
338
+        string $shareWith = null,
339
+        string $publicUpload = 'false',
340
+        string $password = '',
341
+        string $expireDate = ''
342
+    ): DataResponse {
343
+        $share = $this->shareManager->newShare();
344
+
345
+        if ($permissions === null) {
346
+            $permissions = $this->config->getAppValue('core', 'shareapi_default_permissions', Constants::PERMISSION_ALL);
347
+        }
348
+
349
+        // Verify path
350
+        if ($path === null) {
351
+            throw new OCSNotFoundException($this->l->t('Please specify a file or folder path'));
352
+        }
353
+
354
+        $userFolder = $this->rootFolder->getUserFolder($this->currentUser);
355
+        try {
356
+            $path = $userFolder->get($path);
357
+        } catch (NotFoundException $e) {
358
+            throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
359
+        }
360
+
361
+        $share->setNode($path);
362
+
363
+        try {
364
+            $this->lock($share->getNode());
365
+        } catch (LockedException $e) {
366
+            throw new OCSNotFoundException($this->l->t('Could not create share'));
367
+        }
368
+
369
+        if ($permissions < 0 || $permissions > Constants::PERMISSION_ALL) {
370
+            throw new OCSNotFoundException($this->l->t('invalid permissions'));
371
+        }
372
+
373
+        // Shares always require read permissions
374
+        $permissions |= Constants::PERMISSION_READ;
375
+
376
+        if ($path instanceof \OCP\Files\File) {
377
+            // Single file shares should never have delete or create permissions
378
+            $permissions &= ~Constants::PERMISSION_DELETE;
379
+            $permissions &= ~Constants::PERMISSION_CREATE;
380
+        }
381
+
382
+        /*
383 383
 		 * Hack for https://github.com/owncloud/core/issues/22587
384 384
 		 * We check the permissions via webdav. But the permissions of the mount point
385 385
 		 * do not equal the share permissions. Here we fix that for federated mounts.
386 386
 		 */
387
-		if ($path->getStorage()->instanceOfStorage(Storage::class)) {
388
-			$permissions &= ~($permissions & ~$path->getPermissions());
389
-		}
390
-
391
-		if ($shareType === \OCP\Share::SHARE_TYPE_USER) {
392
-			// Valid user is required to share
393
-			if ($shareWith === null || !$this->userManager->userExists($shareWith)) {
394
-				throw new OCSNotFoundException($this->l->t('Please specify a valid user'));
395
-			}
396
-			$share->setSharedWith($shareWith);
397
-			$share->setPermissions($permissions);
398
-		} else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) {
399
-			if (!$this->shareManager->allowGroupSharing()) {
400
-				throw new OCSNotFoundException($this->l->t('Group sharing is disabled by the administrator'));
401
-			}
402
-
403
-			// Valid group is required to share
404
-			if ($shareWith === null || !$this->groupManager->groupExists($shareWith)) {
405
-				throw new OCSNotFoundException($this->l->t('Please specify a valid group'));
406
-			}
407
-			$share->setSharedWith($shareWith);
408
-			$share->setPermissions($permissions);
409
-		} else if ($shareType === \OCP\Share::SHARE_TYPE_LINK) {
410
-			//Can we even share links?
411
-			if (!$this->shareManager->shareApiAllowLinks()) {
412
-				throw new OCSNotFoundException($this->l->t('Public link sharing is disabled by the administrator'));
413
-			}
414
-
415
-			/*
387
+        if ($path->getStorage()->instanceOfStorage(Storage::class)) {
388
+            $permissions &= ~($permissions & ~$path->getPermissions());
389
+        }
390
+
391
+        if ($shareType === \OCP\Share::SHARE_TYPE_USER) {
392
+            // Valid user is required to share
393
+            if ($shareWith === null || !$this->userManager->userExists($shareWith)) {
394
+                throw new OCSNotFoundException($this->l->t('Please specify a valid user'));
395
+            }
396
+            $share->setSharedWith($shareWith);
397
+            $share->setPermissions($permissions);
398
+        } else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) {
399
+            if (!$this->shareManager->allowGroupSharing()) {
400
+                throw new OCSNotFoundException($this->l->t('Group sharing is disabled by the administrator'));
401
+            }
402
+
403
+            // Valid group is required to share
404
+            if ($shareWith === null || !$this->groupManager->groupExists($shareWith)) {
405
+                throw new OCSNotFoundException($this->l->t('Please specify a valid group'));
406
+            }
407
+            $share->setSharedWith($shareWith);
408
+            $share->setPermissions($permissions);
409
+        } else if ($shareType === \OCP\Share::SHARE_TYPE_LINK) {
410
+            //Can we even share links?
411
+            if (!$this->shareManager->shareApiAllowLinks()) {
412
+                throw new OCSNotFoundException($this->l->t('Public link sharing is disabled by the administrator'));
413
+            }
414
+
415
+            /*
416 416
 			 * For now we only allow 1 link share.
417 417
 			 * Return the existing link share if this is a duplicate
418 418
 			 */
419
-			$existingShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_LINK, $path, false, 1, 0);
420
-			if (!empty($existingShares)) {
421
-				return new DataResponse($this->formatShare($existingShares[0]));
422
-			}
423
-
424
-			if ($publicUpload === 'true') {
425
-				// Check if public upload is allowed
426
-				if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
427
-					throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
428
-				}
429
-
430
-				// Public upload can only be set for folders
431
-				if ($path instanceof \OCP\Files\File) {
432
-					throw new OCSNotFoundException($this->l->t('Public upload is only possible for publicly shared folders'));
433
-				}
434
-
435
-				$share->setPermissions(
436
-					Constants::PERMISSION_READ |
437
-					Constants::PERMISSION_CREATE |
438
-					Constants::PERMISSION_UPDATE |
439
-					Constants::PERMISSION_DELETE
440
-				);
441
-			} else {
442
-				$share->setPermissions(Constants::PERMISSION_READ);
443
-			}
444
-
445
-			// Set password
446
-			if ($password !== '') {
447
-				$share->setPassword($password);
448
-			}
449
-
450
-			//Expire date
451
-			if ($expireDate !== '') {
452
-				try {
453
-					$expireDate = $this->parseDate($expireDate);
454
-					$share->setExpirationDate($expireDate);
455
-				} catch (\Exception $e) {
456
-					throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD'));
457
-				}
458
-			}
459
-
460
-		} else if ($shareType === \OCP\Share::SHARE_TYPE_REMOTE) {
461
-			if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
462
-				throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not allow shares from type %s', [$path->getPath(), $shareType]));
463
-			}
464
-
465
-			$share->setSharedWith($shareWith);
466
-			$share->setPermissions($permissions);
467
-		} else if ($shareType === \OCP\Share::SHARE_TYPE_EMAIL) {
468
-			if ($share->getNodeType() === 'file') {
469
-				$share->setPermissions(Constants::PERMISSION_READ);
470
-			} else {
471
-				$share->setPermissions($permissions);
472
-			}
473
-			$share->setSharedWith($shareWith);
474
-		} else if ($shareType === \OCP\Share::SHARE_TYPE_CIRCLE) {
475
-			if (!\OC::$server->getAppManager()->isEnabledForUser('circles') || !class_exists('\OCA\Circles\ShareByCircleProvider')) {
476
-				throw new OCSNotFoundException($this->l->t('You cannot share to a Circle if the app is not enabled'));
477
-			}
478
-
479
-			$circle = \OCA\Circles\Api\v1\Circles::detailsCircle($shareWith);
480
-
481
-			// Valid circle is required to share
482
-			if ($circle === null) {
483
-				throw new OCSNotFoundException($this->l->t('Please specify a valid circle'));
484
-			}
485
-			$share->setSharedWith($shareWith);
486
-			$share->setPermissions($permissions);
487
-		} else {
488
-			throw new OCSBadRequestException($this->l->t('Unknown share type'));
489
-		}
490
-
491
-		$share->setShareType($shareType);
492
-		$share->setSharedBy($this->currentUser);
493
-
494
-		try {
495
-			$share = $this->shareManager->createShare($share);
496
-		} catch (GenericShareException $e) {
497
-			$code = $e->getCode() === 0 ? 403 : $e->getCode();
498
-			throw new OCSException($e->getHint(), $code);
499
-		} catch (\Exception $e) {
500
-			throw new OCSForbiddenException($e->getMessage(), $e);
501
-		}
502
-
503
-		$output = $this->formatShare($share);
504
-
505
-		return new DataResponse($output);
506
-	}
507
-
508
-	/**
509
-	 * @param \OCP\Files\File|\OCP\Files\Folder $node
510
-	 * @param boolean $includeTags
511
-	 * @return DataResponse
512
-	 */
513
-	private function getSharedWithMe($node = null, bool $includeTags): DataResponse {
514
-
515
-		$userShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $node, -1, 0);
516
-		$groupShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $node, -1, 0);
517
-		$circleShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_CIRCLE, $node, -1, 0);
518
-
519
-		$shares = array_merge($userShares, $groupShares, $circleShares);
520
-
521
-		$shares = array_filter($shares, function (IShare $share) {
522
-			return $share->getShareOwner() !== $this->currentUser;
523
-		});
524
-
525
-		$formatted = [];
526
-		foreach ($shares as $share) {
527
-			if ($this->canAccessShare($share)) {
528
-				try {
529
-					$formatted[] = $this->formatShare($share);
530
-				} catch (NotFoundException $e) {
531
-					// Ignore this share
532
-				}
533
-			}
534
-		}
535
-
536
-		if ($includeTags) {
537
-			$formatted = Helper::populateTags($formatted, 'file_source', \OC::$server->getTagManager());
538
-		}
539
-
540
-		return new DataResponse($formatted);
541
-	}
542
-
543
-	/**
544
-	 * @param \OCP\Files\Folder $folder
545
-	 * @return DataResponse
546
-	 * @throws OCSBadRequestException
547
-	 */
548
-	private function getSharesInDir(Node $folder): DataResponse {
549
-		if (!($folder instanceof \OCP\Files\Folder)) {
550
-			throw new OCSBadRequestException($this->l->t('Not a directory'));
551
-		}
552
-
553
-		$nodes = $folder->getDirectoryListing();
554
-		/** @var \OCP\Share\IShare[] $shares */
555
-		$shares = [];
556
-		foreach ($nodes as $node) {
557
-			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $node, false, -1, 0));
558
-			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $node, false, -1, 0));
559
-			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_LINK, $node, false, -1, 0));
560
-			if($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
561
-				$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_EMAIL, $node, false, -1, 0));
562
-			}
563
-			if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
564
-				$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_REMOTE, $node, false, -1, 0));
565
-			}
566
-		}
567
-
568
-		$formatted = [];
569
-		foreach ($shares as $share) {
570
-			try {
571
-				$formatted[] = $this->formatShare($share);
572
-			} catch (NotFoundException $e) {
573
-				//Ignore this share
574
-			}
575
-		}
576
-
577
-		return new DataResponse($formatted);
578
-	}
579
-
580
-	/**
581
-	 * The getShares function.
582
-	 *
583
-	 * @NoAdminRequired
584
-	 *
585
-	 * @param string $shared_with_me
586
-	 * @param string $reshares
587
-	 * @param string $subfiles
588
-	 * @param string $path
589
-	 *
590
-	 * - Get shares by the current user
591
-	 * - Get shares by the current user and reshares (?reshares=true)
592
-	 * - Get shares with the current user (?shared_with_me=true)
593
-	 * - Get shares for a specific path (?path=...)
594
-	 * - Get all shares in a folder (?subfiles=true&path=..)
595
-	 *
596
-	 * @return DataResponse
597
-	 * @throws OCSNotFoundException
598
-	 */
599
-	public function getShares(
600
-		string $shared_with_me = 'false',
601
-		string $reshares = 'false',
602
-		string $subfiles = 'false',
603
-		string $path = null,
604
-		string $include_tags = 'false'
605
-	): DataResponse {
606
-
607
-		if ($path !== null) {
608
-			$userFolder = $this->rootFolder->getUserFolder($this->currentUser);
609
-			try {
610
-				$path = $userFolder->get($path);
611
-				$this->lock($path);
612
-			} catch (\OCP\Files\NotFoundException $e) {
613
-				throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
614
-			} catch (LockedException $e) {
615
-				throw new OCSNotFoundException($this->l->t('Could not lock path'));
616
-			}
617
-		}
618
-
619
-		$include_tags = $include_tags === 'true';
620
-
621
-		if ($shared_with_me === 'true') {
622
-			$result = $this->getSharedWithMe($path, $include_tags);
623
-			return $result;
624
-		}
625
-
626
-		if ($subfiles === 'true') {
627
-			$result = $this->getSharesInDir($path);
628
-			return $result;
629
-		}
630
-
631
-		if ($reshares === 'true') {
632
-			$reshares = true;
633
-		} else {
634
-			$reshares = false;
635
-		}
636
-
637
-		// Get all shares
638
-		$userShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $path, $reshares, -1, 0);
639
-		$groupShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $path, $reshares, -1, 0);
640
-		$linkShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_LINK, $path, $reshares, -1, 0);
641
-		if ($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
642
-			$mailShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_EMAIL, $path, $reshares, -1, 0);
643
-		} else {
644
-			$mailShares = [];
645
-		}
646
-		if ($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_CIRCLE)) {
647
-			$circleShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_CIRCLE, $path, $reshares, -1, 0);
648
-		} else {
649
-			$circleShares = [];
650
-		}
651
-
652
-		$shares = array_merge($userShares, $groupShares, $linkShares, $mailShares, $circleShares);
653
-
654
-		if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
655
-			$federatedShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_REMOTE, $path, $reshares, -1, 0);
656
-			$shares = array_merge($shares, $federatedShares);
657
-		}
658
-
659
-		$formatted = [];
660
-		foreach ($shares as $share) {
661
-			try {
662
-				$formatted[] = $this->formatShare($share, $path);
663
-			} catch (NotFoundException $e) {
664
-				//Ignore share
665
-			}
666
-		}
667
-
668
-		if ($include_tags) {
669
-			$formatted = Helper::populateTags($formatted, 'file_source', \OC::$server->getTagManager());
670
-		}
671
-
672
-		return new DataResponse($formatted);
673
-	}
674
-
675
-	/**
676
-	 * @NoAdminRequired
677
-	 *
678
-	 * @param string $id
679
-	 * @param int $permissions
680
-	 * @param string $password
681
-	 * @param string $publicUpload
682
-	 * @param string $expireDate
683
-	 * @return DataResponse
684
-	 * @throws OCSNotFoundException
685
-	 * @throws OCSBadRequestException
686
-	 * @throws OCSForbiddenException
687
-	 */
688
-	public function updateShare(
689
-		string $id,
690
-		int $permissions = null,
691
-		string $password = null,
692
-		string $publicUpload = null,
693
-		string $expireDate = null
694
-	): DataResponse {
695
-		try {
696
-			$share = $this->getShareById($id);
697
-		} catch (ShareNotFound $e) {
698
-			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
699
-		}
700
-
701
-		$this->lock($share->getNode());
702
-
703
-		if (!$this->canAccessShare($share, false)) {
704
-			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
705
-		}
706
-
707
-		if ($permissions === null && $password === null && $publicUpload === null && $expireDate === null) {
708
-			throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given'));
709
-		}
710
-
711
-		/*
419
+            $existingShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_LINK, $path, false, 1, 0);
420
+            if (!empty($existingShares)) {
421
+                return new DataResponse($this->formatShare($existingShares[0]));
422
+            }
423
+
424
+            if ($publicUpload === 'true') {
425
+                // Check if public upload is allowed
426
+                if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
427
+                    throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
428
+                }
429
+
430
+                // Public upload can only be set for folders
431
+                if ($path instanceof \OCP\Files\File) {
432
+                    throw new OCSNotFoundException($this->l->t('Public upload is only possible for publicly shared folders'));
433
+                }
434
+
435
+                $share->setPermissions(
436
+                    Constants::PERMISSION_READ |
437
+                    Constants::PERMISSION_CREATE |
438
+                    Constants::PERMISSION_UPDATE |
439
+                    Constants::PERMISSION_DELETE
440
+                );
441
+            } else {
442
+                $share->setPermissions(Constants::PERMISSION_READ);
443
+            }
444
+
445
+            // Set password
446
+            if ($password !== '') {
447
+                $share->setPassword($password);
448
+            }
449
+
450
+            //Expire date
451
+            if ($expireDate !== '') {
452
+                try {
453
+                    $expireDate = $this->parseDate($expireDate);
454
+                    $share->setExpirationDate($expireDate);
455
+                } catch (\Exception $e) {
456
+                    throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD'));
457
+                }
458
+            }
459
+
460
+        } else if ($shareType === \OCP\Share::SHARE_TYPE_REMOTE) {
461
+            if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
462
+                throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not allow shares from type %s', [$path->getPath(), $shareType]));
463
+            }
464
+
465
+            $share->setSharedWith($shareWith);
466
+            $share->setPermissions($permissions);
467
+        } else if ($shareType === \OCP\Share::SHARE_TYPE_EMAIL) {
468
+            if ($share->getNodeType() === 'file') {
469
+                $share->setPermissions(Constants::PERMISSION_READ);
470
+            } else {
471
+                $share->setPermissions($permissions);
472
+            }
473
+            $share->setSharedWith($shareWith);
474
+        } else if ($shareType === \OCP\Share::SHARE_TYPE_CIRCLE) {
475
+            if (!\OC::$server->getAppManager()->isEnabledForUser('circles') || !class_exists('\OCA\Circles\ShareByCircleProvider')) {
476
+                throw new OCSNotFoundException($this->l->t('You cannot share to a Circle if the app is not enabled'));
477
+            }
478
+
479
+            $circle = \OCA\Circles\Api\v1\Circles::detailsCircle($shareWith);
480
+
481
+            // Valid circle is required to share
482
+            if ($circle === null) {
483
+                throw new OCSNotFoundException($this->l->t('Please specify a valid circle'));
484
+            }
485
+            $share->setSharedWith($shareWith);
486
+            $share->setPermissions($permissions);
487
+        } else {
488
+            throw new OCSBadRequestException($this->l->t('Unknown share type'));
489
+        }
490
+
491
+        $share->setShareType($shareType);
492
+        $share->setSharedBy($this->currentUser);
493
+
494
+        try {
495
+            $share = $this->shareManager->createShare($share);
496
+        } catch (GenericShareException $e) {
497
+            $code = $e->getCode() === 0 ? 403 : $e->getCode();
498
+            throw new OCSException($e->getHint(), $code);
499
+        } catch (\Exception $e) {
500
+            throw new OCSForbiddenException($e->getMessage(), $e);
501
+        }
502
+
503
+        $output = $this->formatShare($share);
504
+
505
+        return new DataResponse($output);
506
+    }
507
+
508
+    /**
509
+     * @param \OCP\Files\File|\OCP\Files\Folder $node
510
+     * @param boolean $includeTags
511
+     * @return DataResponse
512
+     */
513
+    private function getSharedWithMe($node = null, bool $includeTags): DataResponse {
514
+
515
+        $userShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $node, -1, 0);
516
+        $groupShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $node, -1, 0);
517
+        $circleShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_CIRCLE, $node, -1, 0);
518
+
519
+        $shares = array_merge($userShares, $groupShares, $circleShares);
520
+
521
+        $shares = array_filter($shares, function (IShare $share) {
522
+            return $share->getShareOwner() !== $this->currentUser;
523
+        });
524
+
525
+        $formatted = [];
526
+        foreach ($shares as $share) {
527
+            if ($this->canAccessShare($share)) {
528
+                try {
529
+                    $formatted[] = $this->formatShare($share);
530
+                } catch (NotFoundException $e) {
531
+                    // Ignore this share
532
+                }
533
+            }
534
+        }
535
+
536
+        if ($includeTags) {
537
+            $formatted = Helper::populateTags($formatted, 'file_source', \OC::$server->getTagManager());
538
+        }
539
+
540
+        return new DataResponse($formatted);
541
+    }
542
+
543
+    /**
544
+     * @param \OCP\Files\Folder $folder
545
+     * @return DataResponse
546
+     * @throws OCSBadRequestException
547
+     */
548
+    private function getSharesInDir(Node $folder): DataResponse {
549
+        if (!($folder instanceof \OCP\Files\Folder)) {
550
+            throw new OCSBadRequestException($this->l->t('Not a directory'));
551
+        }
552
+
553
+        $nodes = $folder->getDirectoryListing();
554
+        /** @var \OCP\Share\IShare[] $shares */
555
+        $shares = [];
556
+        foreach ($nodes as $node) {
557
+            $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $node, false, -1, 0));
558
+            $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $node, false, -1, 0));
559
+            $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_LINK, $node, false, -1, 0));
560
+            if($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
561
+                $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_EMAIL, $node, false, -1, 0));
562
+            }
563
+            if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
564
+                $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_REMOTE, $node, false, -1, 0));
565
+            }
566
+        }
567
+
568
+        $formatted = [];
569
+        foreach ($shares as $share) {
570
+            try {
571
+                $formatted[] = $this->formatShare($share);
572
+            } catch (NotFoundException $e) {
573
+                //Ignore this share
574
+            }
575
+        }
576
+
577
+        return new DataResponse($formatted);
578
+    }
579
+
580
+    /**
581
+     * The getShares function.
582
+     *
583
+     * @NoAdminRequired
584
+     *
585
+     * @param string $shared_with_me
586
+     * @param string $reshares
587
+     * @param string $subfiles
588
+     * @param string $path
589
+     *
590
+     * - Get shares by the current user
591
+     * - Get shares by the current user and reshares (?reshares=true)
592
+     * - Get shares with the current user (?shared_with_me=true)
593
+     * - Get shares for a specific path (?path=...)
594
+     * - Get all shares in a folder (?subfiles=true&path=..)
595
+     *
596
+     * @return DataResponse
597
+     * @throws OCSNotFoundException
598
+     */
599
+    public function getShares(
600
+        string $shared_with_me = 'false',
601
+        string $reshares = 'false',
602
+        string $subfiles = 'false',
603
+        string $path = null,
604
+        string $include_tags = 'false'
605
+    ): DataResponse {
606
+
607
+        if ($path !== null) {
608
+            $userFolder = $this->rootFolder->getUserFolder($this->currentUser);
609
+            try {
610
+                $path = $userFolder->get($path);
611
+                $this->lock($path);
612
+            } catch (\OCP\Files\NotFoundException $e) {
613
+                throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
614
+            } catch (LockedException $e) {
615
+                throw new OCSNotFoundException($this->l->t('Could not lock path'));
616
+            }
617
+        }
618
+
619
+        $include_tags = $include_tags === 'true';
620
+
621
+        if ($shared_with_me === 'true') {
622
+            $result = $this->getSharedWithMe($path, $include_tags);
623
+            return $result;
624
+        }
625
+
626
+        if ($subfiles === 'true') {
627
+            $result = $this->getSharesInDir($path);
628
+            return $result;
629
+        }
630
+
631
+        if ($reshares === 'true') {
632
+            $reshares = true;
633
+        } else {
634
+            $reshares = false;
635
+        }
636
+
637
+        // Get all shares
638
+        $userShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $path, $reshares, -1, 0);
639
+        $groupShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $path, $reshares, -1, 0);
640
+        $linkShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_LINK, $path, $reshares, -1, 0);
641
+        if ($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
642
+            $mailShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_EMAIL, $path, $reshares, -1, 0);
643
+        } else {
644
+            $mailShares = [];
645
+        }
646
+        if ($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_CIRCLE)) {
647
+            $circleShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_CIRCLE, $path, $reshares, -1, 0);
648
+        } else {
649
+            $circleShares = [];
650
+        }
651
+
652
+        $shares = array_merge($userShares, $groupShares, $linkShares, $mailShares, $circleShares);
653
+
654
+        if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
655
+            $federatedShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_REMOTE, $path, $reshares, -1, 0);
656
+            $shares = array_merge($shares, $federatedShares);
657
+        }
658
+
659
+        $formatted = [];
660
+        foreach ($shares as $share) {
661
+            try {
662
+                $formatted[] = $this->formatShare($share, $path);
663
+            } catch (NotFoundException $e) {
664
+                //Ignore share
665
+            }
666
+        }
667
+
668
+        if ($include_tags) {
669
+            $formatted = Helper::populateTags($formatted, 'file_source', \OC::$server->getTagManager());
670
+        }
671
+
672
+        return new DataResponse($formatted);
673
+    }
674
+
675
+    /**
676
+     * @NoAdminRequired
677
+     *
678
+     * @param string $id
679
+     * @param int $permissions
680
+     * @param string $password
681
+     * @param string $publicUpload
682
+     * @param string $expireDate
683
+     * @return DataResponse
684
+     * @throws OCSNotFoundException
685
+     * @throws OCSBadRequestException
686
+     * @throws OCSForbiddenException
687
+     */
688
+    public function updateShare(
689
+        string $id,
690
+        int $permissions = null,
691
+        string $password = null,
692
+        string $publicUpload = null,
693
+        string $expireDate = null
694
+    ): DataResponse {
695
+        try {
696
+            $share = $this->getShareById($id);
697
+        } catch (ShareNotFound $e) {
698
+            throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
699
+        }
700
+
701
+        $this->lock($share->getNode());
702
+
703
+        if (!$this->canAccessShare($share, false)) {
704
+            throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
705
+        }
706
+
707
+        if ($permissions === null && $password === null && $publicUpload === null && $expireDate === null) {
708
+            throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given'));
709
+        }
710
+
711
+        /*
712 712
 		 * expirationdate, password and publicUpload only make sense for link shares
713 713
 		 */
714
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
715
-
716
-			$newPermissions = null;
717
-			if ($publicUpload === 'true') {
718
-				$newPermissions = Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE;
719
-			} else if ($publicUpload === 'false') {
720
-				$newPermissions = Constants::PERMISSION_READ;
721
-			}
722
-
723
-			if ($permissions !== null) {
724
-				$newPermissions = (int)$permissions;
725
-				$newPermissions = $newPermissions & ~Constants::PERMISSION_SHARE;
726
-			}
727
-
728
-			if ($newPermissions !== null &&
729
-				!in_array($newPermissions, [
730
-					Constants::PERMISSION_READ,
731
-					Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE, // legacy
732
-					Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE, // correct
733
-					Constants::PERMISSION_CREATE, // hidden file list
734
-					Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE, // allow to edit single files
735
-				], true)
736
-			) {
737
-				throw new OCSBadRequestException($this->l->t('Can\'t change permissions for public share links'));
738
-			}
739
-
740
-			if (
741
-				// legacy
742
-				$newPermissions === (Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE) ||
743
-				// correct
744
-				$newPermissions === (Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE)
745
-			) {
746
-				if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
747
-					throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
748
-				}
749
-
750
-				if (!($share->getNode() instanceof \OCP\Files\Folder)) {
751
-					throw new OCSBadRequestException($this->l->t('Public upload is only possible for publicly shared folders'));
752
-				}
753
-
754
-				// normalize to correct public upload permissions
755
-				$newPermissions = Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE;
756
-			}
757
-
758
-			if ($newPermissions !== null) {
759
-				$share->setPermissions($newPermissions);
760
-				$permissions = $newPermissions;
761
-			}
762
-
763
-			if ($expireDate === '') {
764
-				$share->setExpirationDate(null);
765
-			} else if ($expireDate !== null) {
766
-				try {
767
-					$expireDate = $this->parseDate($expireDate);
768
-				} catch (\Exception $e) {
769
-					throw new OCSBadRequestException($e->getMessage(), $e);
770
-				}
771
-				$share->setExpirationDate($expireDate);
772
-			}
773
-
774
-			if ($password === '') {
775
-				$share->setPassword(null);
776
-			} else if ($password !== null) {
777
-				$share->setPassword($password);
778
-			}
779
-
780
-		} else {
781
-			if ($permissions !== null) {
782
-				$permissions = (int)$permissions;
783
-				$share->setPermissions($permissions);
784
-			}
785
-
786
-			if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
787
-				if ($password === '') {
788
-					$share->setPassword(null);
789
-				} else if ($password !== null) {
790
-					$share->setPassword($password);
791
-				}
792
-			}
793
-
794
-			if ($expireDate === '') {
795
-				$share->setExpirationDate(null);
796
-			} else if ($expireDate !== null) {
797
-				try {
798
-					$expireDate = $this->parseDate($expireDate);
799
-				} catch (\Exception $e) {
800
-					throw new OCSBadRequestException($e->getMessage(), $e);
801
-				}
802
-				$share->setExpirationDate($expireDate);
803
-			}
804
-
805
-		}
806
-
807
-		if ($permissions !== null && $share->getShareOwner() !== $this->currentUser) {
808
-			/* Check if this is an incomming share */
809
-			$incomingShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $share->getNode(), -1, 0);
810
-			$incomingShares = array_merge($incomingShares, $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $share->getNode(), -1, 0));
811
-
812
-			/** @var \OCP\Share\IShare[] $incomingShares */
813
-			if (!empty($incomingShares)) {
814
-				$maxPermissions = 0;
815
-				foreach ($incomingShares as $incomingShare) {
816
-					$maxPermissions |= $incomingShare->getPermissions();
817
-				}
818
-
819
-				if ($share->getPermissions() & ~$maxPermissions) {
820
-					throw new OCSNotFoundException($this->l->t('Cannot increase permissions'));
821
-				}
822
-			}
823
-		}
824
-
825
-
826
-		try {
827
-			$share = $this->shareManager->updateShare($share);
828
-		} catch (\Exception $e) {
829
-			throw new OCSBadRequestException($e->getMessage(), $e);
830
-		}
831
-
832
-		return new DataResponse($this->formatShare($share));
833
-	}
834
-
835
-	protected function canAccessShare(\OCP\Share\IShare $share, bool $checkGroups = true): bool {
836
-		// A file with permissions 0 can't be accessed by us. So Don't show it
837
-		if ($share->getPermissions() === 0) {
838
-			return false;
839
-		}
840
-
841
-		// Owner of the file and the sharer of the file can always get share
842
-		if ($share->getShareOwner() === $this->currentUser ||
843
-			$share->getSharedBy() === $this->currentUser
844
-		) {
845
-			return true;
846
-		}
847
-
848
-		// If the share is shared with you (or a group you are a member of)
849
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
850
-			$share->getSharedWith() === $this->currentUser
851
-		) {
852
-			return true;
853
-		}
854
-
855
-		if ($checkGroups && $share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
856
-			$sharedWith = $this->groupManager->get($share->getSharedWith());
857
-			$user = $this->userManager->get($this->currentUser);
858
-			if ($user !== null && $sharedWith !== null && $sharedWith->inGroup($user)) {
859
-				return true;
860
-			}
861
-		}
862
-
863
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_CIRCLE) {
864
-			// TODO: have a sanity check like above?
865
-			return true;
866
-		}
867
-
868
-		return false;
869
-	}
870
-
871
-	/**
872
-	 * Make sure that the passed date is valid ISO 8601
873
-	 * So YYYY-MM-DD
874
-	 * If not throw an exception
875
-	 *
876
-	 * @param string $expireDate
877
-	 *
878
-	 * @throws \Exception
879
-	 * @return \DateTime
880
-	 */
881
-	private function parseDate(string $expireDate): \DateTime {
882
-		try {
883
-			$date = new \DateTime($expireDate);
884
-		} catch (\Exception $e) {
885
-			throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
886
-		}
887
-
888
-		if ($date === false) {
889
-			throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
890
-		}
891
-
892
-		$date->setTime(0, 0, 0);
893
-
894
-		return $date;
895
-	}
896
-
897
-	/**
898
-	 * Since we have multiple providers but the OCS Share API v1 does
899
-	 * not support this we need to check all backends.
900
-	 *
901
-	 * @param string $id
902
-	 * @return \OCP\Share\IShare
903
-	 * @throws ShareNotFound
904
-	 */
905
-	private function getShareById(string $id): IShare {
906
-		$share = null;
907
-
908
-		// First check if it is an internal share.
909
-		try {
910
-			$share = $this->shareManager->getShareById('ocinternal:' . $id, $this->currentUser);
911
-			return $share;
912
-		} catch (ShareNotFound $e) {
913
-			// Do nothing, just try the other share type
914
-		}
915
-
916
-
917
-		try {
918
-			if ($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_CIRCLE)) {
919
-				$share = $this->shareManager->getShareById('ocCircleShare:' . $id, $this->currentUser);
920
-				return $share;
921
-			}
922
-		} catch (ShareNotFound $e) {
923
-			// Do nothing, just try the other share type
924
-		}
925
-
926
-		try {
927
-			if ($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
928
-				$share = $this->shareManager->getShareById('ocMailShare:' . $id, $this->currentUser);
929
-				return $share;
930
-			}
931
-		} catch (ShareNotFound $e) {
932
-			// Do nothing, just try the other share type
933
-		}
934
-
935
-		if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
936
-			throw new ShareNotFound();
937
-		}
938
-		$share = $this->shareManager->getShareById('ocFederatedSharing:' . $id, $this->currentUser);
939
-
940
-		return $share;
941
-	}
942
-
943
-	/**
944
-	 * Lock a Node
945
-	 *
946
-	 * @param \OCP\Files\Node $node
947
-	 * @throws LockedException
948
-	 */
949
-	private function lock(\OCP\Files\Node $node) {
950
-		$node->lock(ILockingProvider::LOCK_SHARED);
951
-		$this->lockedNode = $node;
952
-	}
953
-
954
-	/**
955
-	 * Cleanup the remaining locks
956
-	 * @throws @LockedException
957
-	 */
958
-	public function cleanup() {
959
-		if ($this->lockedNode !== null) {
960
-			$this->lockedNode->unlock(ILockingProvider::LOCK_SHARED);
961
-		}
962
-	}
714
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
715
+
716
+            $newPermissions = null;
717
+            if ($publicUpload === 'true') {
718
+                $newPermissions = Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE;
719
+            } else if ($publicUpload === 'false') {
720
+                $newPermissions = Constants::PERMISSION_READ;
721
+            }
722
+
723
+            if ($permissions !== null) {
724
+                $newPermissions = (int)$permissions;
725
+                $newPermissions = $newPermissions & ~Constants::PERMISSION_SHARE;
726
+            }
727
+
728
+            if ($newPermissions !== null &&
729
+                !in_array($newPermissions, [
730
+                    Constants::PERMISSION_READ,
731
+                    Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE, // legacy
732
+                    Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE, // correct
733
+                    Constants::PERMISSION_CREATE, // hidden file list
734
+                    Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE, // allow to edit single files
735
+                ], true)
736
+            ) {
737
+                throw new OCSBadRequestException($this->l->t('Can\'t change permissions for public share links'));
738
+            }
739
+
740
+            if (
741
+                // legacy
742
+                $newPermissions === (Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE) ||
743
+                // correct
744
+                $newPermissions === (Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE)
745
+            ) {
746
+                if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
747
+                    throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
748
+                }
749
+
750
+                if (!($share->getNode() instanceof \OCP\Files\Folder)) {
751
+                    throw new OCSBadRequestException($this->l->t('Public upload is only possible for publicly shared folders'));
752
+                }
753
+
754
+                // normalize to correct public upload permissions
755
+                $newPermissions = Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE;
756
+            }
757
+
758
+            if ($newPermissions !== null) {
759
+                $share->setPermissions($newPermissions);
760
+                $permissions = $newPermissions;
761
+            }
762
+
763
+            if ($expireDate === '') {
764
+                $share->setExpirationDate(null);
765
+            } else if ($expireDate !== null) {
766
+                try {
767
+                    $expireDate = $this->parseDate($expireDate);
768
+                } catch (\Exception $e) {
769
+                    throw new OCSBadRequestException($e->getMessage(), $e);
770
+                }
771
+                $share->setExpirationDate($expireDate);
772
+            }
773
+
774
+            if ($password === '') {
775
+                $share->setPassword(null);
776
+            } else if ($password !== null) {
777
+                $share->setPassword($password);
778
+            }
779
+
780
+        } else {
781
+            if ($permissions !== null) {
782
+                $permissions = (int)$permissions;
783
+                $share->setPermissions($permissions);
784
+            }
785
+
786
+            if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
787
+                if ($password === '') {
788
+                    $share->setPassword(null);
789
+                } else if ($password !== null) {
790
+                    $share->setPassword($password);
791
+                }
792
+            }
793
+
794
+            if ($expireDate === '') {
795
+                $share->setExpirationDate(null);
796
+            } else if ($expireDate !== null) {
797
+                try {
798
+                    $expireDate = $this->parseDate($expireDate);
799
+                } catch (\Exception $e) {
800
+                    throw new OCSBadRequestException($e->getMessage(), $e);
801
+                }
802
+                $share->setExpirationDate($expireDate);
803
+            }
804
+
805
+        }
806
+
807
+        if ($permissions !== null && $share->getShareOwner() !== $this->currentUser) {
808
+            /* Check if this is an incomming share */
809
+            $incomingShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $share->getNode(), -1, 0);
810
+            $incomingShares = array_merge($incomingShares, $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $share->getNode(), -1, 0));
811
+
812
+            /** @var \OCP\Share\IShare[] $incomingShares */
813
+            if (!empty($incomingShares)) {
814
+                $maxPermissions = 0;
815
+                foreach ($incomingShares as $incomingShare) {
816
+                    $maxPermissions |= $incomingShare->getPermissions();
817
+                }
818
+
819
+                if ($share->getPermissions() & ~$maxPermissions) {
820
+                    throw new OCSNotFoundException($this->l->t('Cannot increase permissions'));
821
+                }
822
+            }
823
+        }
824
+
825
+
826
+        try {
827
+            $share = $this->shareManager->updateShare($share);
828
+        } catch (\Exception $e) {
829
+            throw new OCSBadRequestException($e->getMessage(), $e);
830
+        }
831
+
832
+        return new DataResponse($this->formatShare($share));
833
+    }
834
+
835
+    protected function canAccessShare(\OCP\Share\IShare $share, bool $checkGroups = true): bool {
836
+        // A file with permissions 0 can't be accessed by us. So Don't show it
837
+        if ($share->getPermissions() === 0) {
838
+            return false;
839
+        }
840
+
841
+        // Owner of the file and the sharer of the file can always get share
842
+        if ($share->getShareOwner() === $this->currentUser ||
843
+            $share->getSharedBy() === $this->currentUser
844
+        ) {
845
+            return true;
846
+        }
847
+
848
+        // If the share is shared with you (or a group you are a member of)
849
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
850
+            $share->getSharedWith() === $this->currentUser
851
+        ) {
852
+            return true;
853
+        }
854
+
855
+        if ($checkGroups && $share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
856
+            $sharedWith = $this->groupManager->get($share->getSharedWith());
857
+            $user = $this->userManager->get($this->currentUser);
858
+            if ($user !== null && $sharedWith !== null && $sharedWith->inGroup($user)) {
859
+                return true;
860
+            }
861
+        }
862
+
863
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_CIRCLE) {
864
+            // TODO: have a sanity check like above?
865
+            return true;
866
+        }
867
+
868
+        return false;
869
+    }
870
+
871
+    /**
872
+     * Make sure that the passed date is valid ISO 8601
873
+     * So YYYY-MM-DD
874
+     * If not throw an exception
875
+     *
876
+     * @param string $expireDate
877
+     *
878
+     * @throws \Exception
879
+     * @return \DateTime
880
+     */
881
+    private function parseDate(string $expireDate): \DateTime {
882
+        try {
883
+            $date = new \DateTime($expireDate);
884
+        } catch (\Exception $e) {
885
+            throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
886
+        }
887
+
888
+        if ($date === false) {
889
+            throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
890
+        }
891
+
892
+        $date->setTime(0, 0, 0);
893
+
894
+        return $date;
895
+    }
896
+
897
+    /**
898
+     * Since we have multiple providers but the OCS Share API v1 does
899
+     * not support this we need to check all backends.
900
+     *
901
+     * @param string $id
902
+     * @return \OCP\Share\IShare
903
+     * @throws ShareNotFound
904
+     */
905
+    private function getShareById(string $id): IShare {
906
+        $share = null;
907
+
908
+        // First check if it is an internal share.
909
+        try {
910
+            $share = $this->shareManager->getShareById('ocinternal:' . $id, $this->currentUser);
911
+            return $share;
912
+        } catch (ShareNotFound $e) {
913
+            // Do nothing, just try the other share type
914
+        }
915
+
916
+
917
+        try {
918
+            if ($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_CIRCLE)) {
919
+                $share = $this->shareManager->getShareById('ocCircleShare:' . $id, $this->currentUser);
920
+                return $share;
921
+            }
922
+        } catch (ShareNotFound $e) {
923
+            // Do nothing, just try the other share type
924
+        }
925
+
926
+        try {
927
+            if ($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
928
+                $share = $this->shareManager->getShareById('ocMailShare:' . $id, $this->currentUser);
929
+                return $share;
930
+            }
931
+        } catch (ShareNotFound $e) {
932
+            // Do nothing, just try the other share type
933
+        }
934
+
935
+        if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
936
+            throw new ShareNotFound();
937
+        }
938
+        $share = $this->shareManager->getShareById('ocFederatedSharing:' . $id, $this->currentUser);
939
+
940
+        return $share;
941
+    }
942
+
943
+    /**
944
+     * Lock a Node
945
+     *
946
+     * @param \OCP\Files\Node $node
947
+     * @throws LockedException
948
+     */
949
+    private function lock(\OCP\Files\Node $node) {
950
+        $node->lock(ILockingProvider::LOCK_SHARED);
951
+        $this->lockedNode = $node;
952
+    }
953
+
954
+    /**
955
+     * Cleanup the remaining locks
956
+     * @throws @LockedException
957
+     */
958
+    public function cleanup() {
959
+        if ($this->lockedNode !== null) {
960
+            $this->lockedNode->unlock(ILockingProvider::LOCK_SHARED);
961
+        }
962
+    }
963 963
 }
Please login to merge, or discard this patch.
apps/federatedfilesharing/lib/FederatedShareProvider.php 1 patch
Indentation   +970 added lines, -970 removed lines patch added patch discarded remove patch
@@ -54,984 +54,984 @@
 block discarded – undo
54 54
  */
55 55
 class FederatedShareProvider implements IShareProvider {
56 56
 
57
-	const SHARE_TYPE_REMOTE = 6;
58
-
59
-	/** @var IDBConnection */
60
-	private $dbConnection;
61
-
62
-	/** @var AddressHandler */
63
-	private $addressHandler;
64
-
65
-	/** @var Notifications */
66
-	private $notifications;
67
-
68
-	/** @var TokenHandler */
69
-	private $tokenHandler;
70
-
71
-	/** @var IL10N */
72
-	private $l;
73
-
74
-	/** @var ILogger */
75
-	private $logger;
76
-
77
-	/** @var IRootFolder */
78
-	private $rootFolder;
79
-
80
-	/** @var IConfig */
81
-	private $config;
82
-
83
-	/** @var string */
84
-	private $externalShareTable = 'share_external';
85
-
86
-	/** @var IUserManager */
87
-	private $userManager;
88
-
89
-	/** @var ICloudIdManager */
90
-	private $cloudIdManager;
91
-
92
-	/** @var \OCP\GlobalScale\IConfig */
93
-	private $gsConfig;
94
-
95
-	/**
96
-	 * DefaultShareProvider constructor.
97
-	 *
98
-	 * @param IDBConnection $connection
99
-	 * @param AddressHandler $addressHandler
100
-	 * @param Notifications $notifications
101
-	 * @param TokenHandler $tokenHandler
102
-	 * @param IL10N $l10n
103
-	 * @param ILogger $logger
104
-	 * @param IRootFolder $rootFolder
105
-	 * @param IConfig $config
106
-	 * @param IUserManager $userManager
107
-	 * @param ICloudIdManager $cloudIdManager
108
-	 * @param \OCP\GlobalScale\IConfig $globalScaleConfig
109
-	 */
110
-	public function __construct(
111
-			IDBConnection $connection,
112
-			AddressHandler $addressHandler,
113
-			Notifications $notifications,
114
-			TokenHandler $tokenHandler,
115
-			IL10N $l10n,
116
-			ILogger $logger,
117
-			IRootFolder $rootFolder,
118
-			IConfig $config,
119
-			IUserManager $userManager,
120
-			ICloudIdManager $cloudIdManager,
121
-			\OCP\GlobalScale\IConfig $globalScaleConfig
122
-	) {
123
-		$this->dbConnection = $connection;
124
-		$this->addressHandler = $addressHandler;
125
-		$this->notifications = $notifications;
126
-		$this->tokenHandler = $tokenHandler;
127
-		$this->l = $l10n;
128
-		$this->logger = $logger;
129
-		$this->rootFolder = $rootFolder;
130
-		$this->config = $config;
131
-		$this->userManager = $userManager;
132
-		$this->cloudIdManager = $cloudIdManager;
133
-		$this->gsConfig = $globalScaleConfig;
134
-	}
135
-
136
-	/**
137
-	 * Return the identifier of this provider.
138
-	 *
139
-	 * @return string Containing only [a-zA-Z0-9]
140
-	 */
141
-	public function identifier() {
142
-		return 'ocFederatedSharing';
143
-	}
144
-
145
-	/**
146
-	 * Share a path
147
-	 *
148
-	 * @param IShare $share
149
-	 * @return IShare The share object
150
-	 * @throws ShareNotFound
151
-	 * @throws \Exception
152
-	 */
153
-	public function create(IShare $share) {
154
-
155
-		$shareWith = $share->getSharedWith();
156
-		$itemSource = $share->getNodeId();
157
-		$itemType = $share->getNodeType();
158
-		$permissions = $share->getPermissions();
159
-		$sharedBy = $share->getSharedBy();
160
-
161
-		/*
57
+    const SHARE_TYPE_REMOTE = 6;
58
+
59
+    /** @var IDBConnection */
60
+    private $dbConnection;
61
+
62
+    /** @var AddressHandler */
63
+    private $addressHandler;
64
+
65
+    /** @var Notifications */
66
+    private $notifications;
67
+
68
+    /** @var TokenHandler */
69
+    private $tokenHandler;
70
+
71
+    /** @var IL10N */
72
+    private $l;
73
+
74
+    /** @var ILogger */
75
+    private $logger;
76
+
77
+    /** @var IRootFolder */
78
+    private $rootFolder;
79
+
80
+    /** @var IConfig */
81
+    private $config;
82
+
83
+    /** @var string */
84
+    private $externalShareTable = 'share_external';
85
+
86
+    /** @var IUserManager */
87
+    private $userManager;
88
+
89
+    /** @var ICloudIdManager */
90
+    private $cloudIdManager;
91
+
92
+    /** @var \OCP\GlobalScale\IConfig */
93
+    private $gsConfig;
94
+
95
+    /**
96
+     * DefaultShareProvider constructor.
97
+     *
98
+     * @param IDBConnection $connection
99
+     * @param AddressHandler $addressHandler
100
+     * @param Notifications $notifications
101
+     * @param TokenHandler $tokenHandler
102
+     * @param IL10N $l10n
103
+     * @param ILogger $logger
104
+     * @param IRootFolder $rootFolder
105
+     * @param IConfig $config
106
+     * @param IUserManager $userManager
107
+     * @param ICloudIdManager $cloudIdManager
108
+     * @param \OCP\GlobalScale\IConfig $globalScaleConfig
109
+     */
110
+    public function __construct(
111
+            IDBConnection $connection,
112
+            AddressHandler $addressHandler,
113
+            Notifications $notifications,
114
+            TokenHandler $tokenHandler,
115
+            IL10N $l10n,
116
+            ILogger $logger,
117
+            IRootFolder $rootFolder,
118
+            IConfig $config,
119
+            IUserManager $userManager,
120
+            ICloudIdManager $cloudIdManager,
121
+            \OCP\GlobalScale\IConfig $globalScaleConfig
122
+    ) {
123
+        $this->dbConnection = $connection;
124
+        $this->addressHandler = $addressHandler;
125
+        $this->notifications = $notifications;
126
+        $this->tokenHandler = $tokenHandler;
127
+        $this->l = $l10n;
128
+        $this->logger = $logger;
129
+        $this->rootFolder = $rootFolder;
130
+        $this->config = $config;
131
+        $this->userManager = $userManager;
132
+        $this->cloudIdManager = $cloudIdManager;
133
+        $this->gsConfig = $globalScaleConfig;
134
+    }
135
+
136
+    /**
137
+     * Return the identifier of this provider.
138
+     *
139
+     * @return string Containing only [a-zA-Z0-9]
140
+     */
141
+    public function identifier() {
142
+        return 'ocFederatedSharing';
143
+    }
144
+
145
+    /**
146
+     * Share a path
147
+     *
148
+     * @param IShare $share
149
+     * @return IShare The share object
150
+     * @throws ShareNotFound
151
+     * @throws \Exception
152
+     */
153
+    public function create(IShare $share) {
154
+
155
+        $shareWith = $share->getSharedWith();
156
+        $itemSource = $share->getNodeId();
157
+        $itemType = $share->getNodeType();
158
+        $permissions = $share->getPermissions();
159
+        $sharedBy = $share->getSharedBy();
160
+
161
+        /*
162 162
 		 * Check if file is not already shared with the remote user
163 163
 		 */
164
-		$alreadyShared = $this->getSharedWith($shareWith, self::SHARE_TYPE_REMOTE, $share->getNode(), 1, 0);
165
-		if (!empty($alreadyShared)) {
166
-			$message = 'Sharing %s failed, because this item is already shared with %s';
167
-			$message_t = $this->l->t('Sharing %s failed, because this item is already shared with %s', array($share->getNode()->getName(), $shareWith));
168
-			$this->logger->debug(sprintf($message, $share->getNode()->getName(), $shareWith), ['app' => 'Federated File Sharing']);
169
-			throw new \Exception($message_t);
170
-		}
171
-
172
-
173
-		// don't allow federated shares if source and target server are the same
174
-		$cloudId = $this->cloudIdManager->resolveCloudId($shareWith);
175
-		$currentServer = $this->addressHandler->generateRemoteURL();
176
-		$currentUser = $sharedBy;
177
-		if ($this->addressHandler->compareAddresses($cloudId->getUser(), $cloudId->getRemote(), $currentUser, $currentServer)) {
178
-			$message = 'Not allowed to create a federated share with the same user.';
179
-			$message_t = $this->l->t('Not allowed to create a federated share with the same user');
180
-			$this->logger->debug($message, ['app' => 'Federated File Sharing']);
181
-			throw new \Exception($message_t);
182
-		}
183
-
184
-
185
-		$share->setSharedWith($cloudId->getId());
186
-
187
-		try {
188
-			$remoteShare = $this->getShareFromExternalShareTable($share);
189
-		} catch (ShareNotFound $e) {
190
-			$remoteShare = null;
191
-		}
192
-
193
-		if ($remoteShare) {
194
-			try {
195
-				$ownerCloudId = $this->cloudIdManager->getCloudId($remoteShare['owner'], $remoteShare['remote']);
196
-				$shareId = $this->addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $ownerCloudId->getId(), $permissions, 'tmp_token_' . time());
197
-				$share->setId($shareId);
198
-				list($token, $remoteId) = $this->askOwnerToReShare($shareWith, $share, $shareId);
199
-				// remote share was create successfully if we get a valid token as return
200
-				$send = is_string($token) && $token !== '';
201
-			} catch (\Exception $e) {
202
-				// fall back to old re-share behavior if the remote server
203
-				// doesn't support flat re-shares (was introduced with Nextcloud 9.1)
204
-				$this->removeShareFromTable($share);
205
-				$shareId = $this->createFederatedShare($share);
206
-			}
207
-			if ($send) {
208
-				$this->updateSuccessfulReshare($shareId, $token);
209
-				$this->storeRemoteId($shareId, $remoteId);
210
-			} else {
211
-				$this->removeShareFromTable($share);
212
-				$message_t = $this->l->t('File is already shared with %s', [$shareWith]);
213
-				throw new \Exception($message_t);
214
-			}
215
-
216
-		} else {
217
-			$shareId = $this->createFederatedShare($share);
218
-		}
219
-
220
-		$data = $this->getRawShare($shareId);
221
-		return $this->createShareObject($data);
222
-	}
223
-
224
-	/**
225
-	 * create federated share and inform the recipient
226
-	 *
227
-	 * @param IShare $share
228
-	 * @return int
229
-	 * @throws ShareNotFound
230
-	 * @throws \Exception
231
-	 */
232
-	protected function createFederatedShare(IShare $share) {
233
-		$token = $this->tokenHandler->generateToken();
234
-		$shareId = $this->addShareToDB(
235
-			$share->getNodeId(),
236
-			$share->getNodeType(),
237
-			$share->getSharedWith(),
238
-			$share->getSharedBy(),
239
-			$share->getShareOwner(),
240
-			$share->getPermissions(),
241
-			$token
242
-		);
243
-
244
-		$failure = false;
245
-
246
-		try {
247
-			$sharedByFederatedId = $share->getSharedBy();
248
-			if ($this->userManager->userExists($sharedByFederatedId)) {
249
-				$cloudId = $this->cloudIdManager->getCloudId($sharedByFederatedId, $this->addressHandler->generateRemoteURL());
250
-				$sharedByFederatedId = $cloudId->getId();
251
-			}
252
-			$ownerCloudId = $this->cloudIdManager->getCloudId($share->getShareOwner(), $this->addressHandler->generateRemoteURL());
253
-			$send = $this->notifications->sendRemoteShare(
254
-				$token,
255
-				$share->getSharedWith(),
256
-				$share->getNode()->getName(),
257
-				$shareId,
258
-				$share->getShareOwner(),
259
-				$ownerCloudId->getId(),
260
-				$share->getSharedBy(),
261
-				$sharedByFederatedId
262
-			);
263
-
264
-			if ($send === false) {
265
-				$failure = true;
266
-			}
267
-		} catch (\Exception $e) {
268
-			$this->logger->logException($e, [
269
-				'message' => 'Failed to notify remote server of federated share, removing share.',
270
-				'level' => ILogger::ERROR,
271
-				'app' => 'federatedfilesharing',
272
-			]);
273
-			$failure = true;
274
-		}
275
-
276
-		if($failure) {
277
-			$this->removeShareFromTableById($shareId);
278
-			$message_t = $this->l->t('Sharing %s failed, could not find %s, maybe the server is currently unreachable or uses a self-signed certificate.',
279
-				[$share->getNode()->getName(), $share->getSharedWith()]);
280
-			throw new \Exception($message_t);
281
-		}
282
-
283
-		return $shareId;
284
-
285
-	}
286
-
287
-	/**
288
-	 * @param string $shareWith
289
-	 * @param IShare $share
290
-	 * @param string $shareId internal share Id
291
-	 * @return array
292
-	 * @throws \Exception
293
-	 */
294
-	protected function askOwnerToReShare($shareWith, IShare $share, $shareId) {
295
-
296
-		$remoteShare = $this->getShareFromExternalShareTable($share);
297
-		$token = $remoteShare['share_token'];
298
-		$remoteId = $remoteShare['remote_id'];
299
-		$remote = $remoteShare['remote'];
300
-
301
-		list($token, $remoteId) = $this->notifications->requestReShare(
302
-			$token,
303
-			$remoteId,
304
-			$shareId,
305
-			$remote,
306
-			$shareWith,
307
-			$share->getPermissions(),
308
-			$share->getNode()->getName()
309
-		);
310
-
311
-		return [$token, $remoteId];
312
-	}
313
-
314
-	/**
315
-	 * get federated share from the share_external table but exclude mounted link shares
316
-	 *
317
-	 * @param IShare $share
318
-	 * @return array
319
-	 * @throws ShareNotFound
320
-	 */
321
-	protected function getShareFromExternalShareTable(IShare $share) {
322
-		$query = $this->dbConnection->getQueryBuilder();
323
-		$query->select('*')->from($this->externalShareTable)
324
-			->where($query->expr()->eq('user', $query->createNamedParameter($share->getShareOwner())))
325
-			->andWhere($query->expr()->eq('mountpoint', $query->createNamedParameter($share->getTarget())));
326
-		$result = $query->execute()->fetchAll();
327
-
328
-		if (isset($result[0]) && (int)$result[0]['remote_id'] > 0) {
329
-			return $result[0];
330
-		}
331
-
332
-		throw new ShareNotFound('share not found in share_external table');
333
-	}
334
-
335
-	/**
336
-	 * add share to the database and return the ID
337
-	 *
338
-	 * @param int $itemSource
339
-	 * @param string $itemType
340
-	 * @param string $shareWith
341
-	 * @param string $sharedBy
342
-	 * @param string $uidOwner
343
-	 * @param int $permissions
344
-	 * @param string $token
345
-	 * @return int
346
-	 */
347
-	private function addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token) {
348
-		$qb = $this->dbConnection->getQueryBuilder();
349
-		$qb->insert('share')
350
-			->setValue('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE))
351
-			->setValue('item_type', $qb->createNamedParameter($itemType))
352
-			->setValue('item_source', $qb->createNamedParameter($itemSource))
353
-			->setValue('file_source', $qb->createNamedParameter($itemSource))
354
-			->setValue('share_with', $qb->createNamedParameter($shareWith))
355
-			->setValue('uid_owner', $qb->createNamedParameter($uidOwner))
356
-			->setValue('uid_initiator', $qb->createNamedParameter($sharedBy))
357
-			->setValue('permissions', $qb->createNamedParameter($permissions))
358
-			->setValue('token', $qb->createNamedParameter($token))
359
-			->setValue('stime', $qb->createNamedParameter(time()));
360
-
361
-		/*
164
+        $alreadyShared = $this->getSharedWith($shareWith, self::SHARE_TYPE_REMOTE, $share->getNode(), 1, 0);
165
+        if (!empty($alreadyShared)) {
166
+            $message = 'Sharing %s failed, because this item is already shared with %s';
167
+            $message_t = $this->l->t('Sharing %s failed, because this item is already shared with %s', array($share->getNode()->getName(), $shareWith));
168
+            $this->logger->debug(sprintf($message, $share->getNode()->getName(), $shareWith), ['app' => 'Federated File Sharing']);
169
+            throw new \Exception($message_t);
170
+        }
171
+
172
+
173
+        // don't allow federated shares if source and target server are the same
174
+        $cloudId = $this->cloudIdManager->resolveCloudId($shareWith);
175
+        $currentServer = $this->addressHandler->generateRemoteURL();
176
+        $currentUser = $sharedBy;
177
+        if ($this->addressHandler->compareAddresses($cloudId->getUser(), $cloudId->getRemote(), $currentUser, $currentServer)) {
178
+            $message = 'Not allowed to create a federated share with the same user.';
179
+            $message_t = $this->l->t('Not allowed to create a federated share with the same user');
180
+            $this->logger->debug($message, ['app' => 'Federated File Sharing']);
181
+            throw new \Exception($message_t);
182
+        }
183
+
184
+
185
+        $share->setSharedWith($cloudId->getId());
186
+
187
+        try {
188
+            $remoteShare = $this->getShareFromExternalShareTable($share);
189
+        } catch (ShareNotFound $e) {
190
+            $remoteShare = null;
191
+        }
192
+
193
+        if ($remoteShare) {
194
+            try {
195
+                $ownerCloudId = $this->cloudIdManager->getCloudId($remoteShare['owner'], $remoteShare['remote']);
196
+                $shareId = $this->addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $ownerCloudId->getId(), $permissions, 'tmp_token_' . time());
197
+                $share->setId($shareId);
198
+                list($token, $remoteId) = $this->askOwnerToReShare($shareWith, $share, $shareId);
199
+                // remote share was create successfully if we get a valid token as return
200
+                $send = is_string($token) && $token !== '';
201
+            } catch (\Exception $e) {
202
+                // fall back to old re-share behavior if the remote server
203
+                // doesn't support flat re-shares (was introduced with Nextcloud 9.1)
204
+                $this->removeShareFromTable($share);
205
+                $shareId = $this->createFederatedShare($share);
206
+            }
207
+            if ($send) {
208
+                $this->updateSuccessfulReshare($shareId, $token);
209
+                $this->storeRemoteId($shareId, $remoteId);
210
+            } else {
211
+                $this->removeShareFromTable($share);
212
+                $message_t = $this->l->t('File is already shared with %s', [$shareWith]);
213
+                throw new \Exception($message_t);
214
+            }
215
+
216
+        } else {
217
+            $shareId = $this->createFederatedShare($share);
218
+        }
219
+
220
+        $data = $this->getRawShare($shareId);
221
+        return $this->createShareObject($data);
222
+    }
223
+
224
+    /**
225
+     * create federated share and inform the recipient
226
+     *
227
+     * @param IShare $share
228
+     * @return int
229
+     * @throws ShareNotFound
230
+     * @throws \Exception
231
+     */
232
+    protected function createFederatedShare(IShare $share) {
233
+        $token = $this->tokenHandler->generateToken();
234
+        $shareId = $this->addShareToDB(
235
+            $share->getNodeId(),
236
+            $share->getNodeType(),
237
+            $share->getSharedWith(),
238
+            $share->getSharedBy(),
239
+            $share->getShareOwner(),
240
+            $share->getPermissions(),
241
+            $token
242
+        );
243
+
244
+        $failure = false;
245
+
246
+        try {
247
+            $sharedByFederatedId = $share->getSharedBy();
248
+            if ($this->userManager->userExists($sharedByFederatedId)) {
249
+                $cloudId = $this->cloudIdManager->getCloudId($sharedByFederatedId, $this->addressHandler->generateRemoteURL());
250
+                $sharedByFederatedId = $cloudId->getId();
251
+            }
252
+            $ownerCloudId = $this->cloudIdManager->getCloudId($share->getShareOwner(), $this->addressHandler->generateRemoteURL());
253
+            $send = $this->notifications->sendRemoteShare(
254
+                $token,
255
+                $share->getSharedWith(),
256
+                $share->getNode()->getName(),
257
+                $shareId,
258
+                $share->getShareOwner(),
259
+                $ownerCloudId->getId(),
260
+                $share->getSharedBy(),
261
+                $sharedByFederatedId
262
+            );
263
+
264
+            if ($send === false) {
265
+                $failure = true;
266
+            }
267
+        } catch (\Exception $e) {
268
+            $this->logger->logException($e, [
269
+                'message' => 'Failed to notify remote server of federated share, removing share.',
270
+                'level' => ILogger::ERROR,
271
+                'app' => 'federatedfilesharing',
272
+            ]);
273
+            $failure = true;
274
+        }
275
+
276
+        if($failure) {
277
+            $this->removeShareFromTableById($shareId);
278
+            $message_t = $this->l->t('Sharing %s failed, could not find %s, maybe the server is currently unreachable or uses a self-signed certificate.',
279
+                [$share->getNode()->getName(), $share->getSharedWith()]);
280
+            throw new \Exception($message_t);
281
+        }
282
+
283
+        return $shareId;
284
+
285
+    }
286
+
287
+    /**
288
+     * @param string $shareWith
289
+     * @param IShare $share
290
+     * @param string $shareId internal share Id
291
+     * @return array
292
+     * @throws \Exception
293
+     */
294
+    protected function askOwnerToReShare($shareWith, IShare $share, $shareId) {
295
+
296
+        $remoteShare = $this->getShareFromExternalShareTable($share);
297
+        $token = $remoteShare['share_token'];
298
+        $remoteId = $remoteShare['remote_id'];
299
+        $remote = $remoteShare['remote'];
300
+
301
+        list($token, $remoteId) = $this->notifications->requestReShare(
302
+            $token,
303
+            $remoteId,
304
+            $shareId,
305
+            $remote,
306
+            $shareWith,
307
+            $share->getPermissions(),
308
+            $share->getNode()->getName()
309
+        );
310
+
311
+        return [$token, $remoteId];
312
+    }
313
+
314
+    /**
315
+     * get federated share from the share_external table but exclude mounted link shares
316
+     *
317
+     * @param IShare $share
318
+     * @return array
319
+     * @throws ShareNotFound
320
+     */
321
+    protected function getShareFromExternalShareTable(IShare $share) {
322
+        $query = $this->dbConnection->getQueryBuilder();
323
+        $query->select('*')->from($this->externalShareTable)
324
+            ->where($query->expr()->eq('user', $query->createNamedParameter($share->getShareOwner())))
325
+            ->andWhere($query->expr()->eq('mountpoint', $query->createNamedParameter($share->getTarget())));
326
+        $result = $query->execute()->fetchAll();
327
+
328
+        if (isset($result[0]) && (int)$result[0]['remote_id'] > 0) {
329
+            return $result[0];
330
+        }
331
+
332
+        throw new ShareNotFound('share not found in share_external table');
333
+    }
334
+
335
+    /**
336
+     * add share to the database and return the ID
337
+     *
338
+     * @param int $itemSource
339
+     * @param string $itemType
340
+     * @param string $shareWith
341
+     * @param string $sharedBy
342
+     * @param string $uidOwner
343
+     * @param int $permissions
344
+     * @param string $token
345
+     * @return int
346
+     */
347
+    private function addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token) {
348
+        $qb = $this->dbConnection->getQueryBuilder();
349
+        $qb->insert('share')
350
+            ->setValue('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE))
351
+            ->setValue('item_type', $qb->createNamedParameter($itemType))
352
+            ->setValue('item_source', $qb->createNamedParameter($itemSource))
353
+            ->setValue('file_source', $qb->createNamedParameter($itemSource))
354
+            ->setValue('share_with', $qb->createNamedParameter($shareWith))
355
+            ->setValue('uid_owner', $qb->createNamedParameter($uidOwner))
356
+            ->setValue('uid_initiator', $qb->createNamedParameter($sharedBy))
357
+            ->setValue('permissions', $qb->createNamedParameter($permissions))
358
+            ->setValue('token', $qb->createNamedParameter($token))
359
+            ->setValue('stime', $qb->createNamedParameter(time()));
360
+
361
+        /*
362 362
 		 * Added to fix https://github.com/owncloud/core/issues/22215
363 363
 		 * Can be removed once we get rid of ajax/share.php
364 364
 		 */
365
-		$qb->setValue('file_target', $qb->createNamedParameter(''));
366
-
367
-		$qb->execute();
368
-		$id = $qb->getLastInsertId();
369
-
370
-		return (int)$id;
371
-	}
372
-
373
-	/**
374
-	 * Update a share
375
-	 *
376
-	 * @param IShare $share
377
-	 * @return IShare The share object
378
-	 */
379
-	public function update(IShare $share) {
380
-		/*
365
+        $qb->setValue('file_target', $qb->createNamedParameter(''));
366
+
367
+        $qb->execute();
368
+        $id = $qb->getLastInsertId();
369
+
370
+        return (int)$id;
371
+    }
372
+
373
+    /**
374
+     * Update a share
375
+     *
376
+     * @param IShare $share
377
+     * @return IShare The share object
378
+     */
379
+    public function update(IShare $share) {
380
+        /*
381 381
 		 * We allow updating the permissions of federated shares
382 382
 		 */
383
-		$qb = $this->dbConnection->getQueryBuilder();
384
-			$qb->update('share')
385
-				->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
386
-				->set('permissions', $qb->createNamedParameter($share->getPermissions()))
387
-				->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
388
-				->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
389
-				->execute();
390
-
391
-		// send the updated permission to the owner/initiator, if they are not the same
392
-		if ($share->getShareOwner() !== $share->getSharedBy()) {
393
-			$this->sendPermissionUpdate($share);
394
-		}
395
-
396
-		return $share;
397
-	}
398
-
399
-	/**
400
-	 * send the updated permission to the owner/initiator, if they are not the same
401
-	 *
402
-	 * @param IShare $share
403
-	 * @throws ShareNotFound
404
-	 * @throws \OC\HintException
405
-	 */
406
-	protected function sendPermissionUpdate(IShare $share) {
407
-		$remoteId = $this->getRemoteId($share);
408
-		// if the local user is the owner we send the permission change to the initiator
409
-		if ($this->userManager->userExists($share->getShareOwner())) {
410
-			list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy());
411
-		} else { // ... if not we send the permission change to the owner
412
-			list(, $remote) = $this->addressHandler->splitUserRemote($share->getShareOwner());
413
-		}
414
-		$this->notifications->sendPermissionChange($remote, $remoteId, $share->getToken(), $share->getPermissions());
415
-	}
416
-
417
-
418
-	/**
419
-	 * update successful reShare with the correct token
420
-	 *
421
-	 * @param int $shareId
422
-	 * @param string $token
423
-	 */
424
-	protected function updateSuccessfulReShare($shareId, $token) {
425
-		$query = $this->dbConnection->getQueryBuilder();
426
-		$query->update('share')
427
-			->where($query->expr()->eq('id', $query->createNamedParameter($shareId)))
428
-			->set('token', $query->createNamedParameter($token))
429
-			->execute();
430
-	}
431
-
432
-	/**
433
-	 * store remote ID in federated reShare table
434
-	 *
435
-	 * @param $shareId
436
-	 * @param $remoteId
437
-	 */
438
-	public function storeRemoteId($shareId, $remoteId) {
439
-		$query = $this->dbConnection->getQueryBuilder();
440
-		$query->insert('federated_reshares')
441
-			->values(
442
-				[
443
-					'share_id' =>  $query->createNamedParameter($shareId),
444
-					'remote_id' => $query->createNamedParameter($remoteId),
445
-				]
446
-			);
447
-		$query->execute();
448
-	}
449
-
450
-	/**
451
-	 * get share ID on remote server for federated re-shares
452
-	 *
453
-	 * @param IShare $share
454
-	 * @return int
455
-	 * @throws ShareNotFound
456
-	 */
457
-	public function getRemoteId(IShare $share) {
458
-		$query = $this->dbConnection->getQueryBuilder();
459
-		$query->select('remote_id')->from('federated_reshares')
460
-			->where($query->expr()->eq('share_id', $query->createNamedParameter((int)$share->getId())));
461
-		$data = $query->execute()->fetch();
462
-
463
-		if (!is_array($data) || !isset($data['remote_id'])) {
464
-			throw new ShareNotFound();
465
-		}
466
-
467
-		return (int)$data['remote_id'];
468
-	}
469
-
470
-	/**
471
-	 * @inheritdoc
472
-	 */
473
-	public function move(IShare $share, $recipient) {
474
-		/*
383
+        $qb = $this->dbConnection->getQueryBuilder();
384
+            $qb->update('share')
385
+                ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
386
+                ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
387
+                ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
388
+                ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
389
+                ->execute();
390
+
391
+        // send the updated permission to the owner/initiator, if they are not the same
392
+        if ($share->getShareOwner() !== $share->getSharedBy()) {
393
+            $this->sendPermissionUpdate($share);
394
+        }
395
+
396
+        return $share;
397
+    }
398
+
399
+    /**
400
+     * send the updated permission to the owner/initiator, if they are not the same
401
+     *
402
+     * @param IShare $share
403
+     * @throws ShareNotFound
404
+     * @throws \OC\HintException
405
+     */
406
+    protected function sendPermissionUpdate(IShare $share) {
407
+        $remoteId = $this->getRemoteId($share);
408
+        // if the local user is the owner we send the permission change to the initiator
409
+        if ($this->userManager->userExists($share->getShareOwner())) {
410
+            list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy());
411
+        } else { // ... if not we send the permission change to the owner
412
+            list(, $remote) = $this->addressHandler->splitUserRemote($share->getShareOwner());
413
+        }
414
+        $this->notifications->sendPermissionChange($remote, $remoteId, $share->getToken(), $share->getPermissions());
415
+    }
416
+
417
+
418
+    /**
419
+     * update successful reShare with the correct token
420
+     *
421
+     * @param int $shareId
422
+     * @param string $token
423
+     */
424
+    protected function updateSuccessfulReShare($shareId, $token) {
425
+        $query = $this->dbConnection->getQueryBuilder();
426
+        $query->update('share')
427
+            ->where($query->expr()->eq('id', $query->createNamedParameter($shareId)))
428
+            ->set('token', $query->createNamedParameter($token))
429
+            ->execute();
430
+    }
431
+
432
+    /**
433
+     * store remote ID in federated reShare table
434
+     *
435
+     * @param $shareId
436
+     * @param $remoteId
437
+     */
438
+    public function storeRemoteId($shareId, $remoteId) {
439
+        $query = $this->dbConnection->getQueryBuilder();
440
+        $query->insert('federated_reshares')
441
+            ->values(
442
+                [
443
+                    'share_id' =>  $query->createNamedParameter($shareId),
444
+                    'remote_id' => $query->createNamedParameter($remoteId),
445
+                ]
446
+            );
447
+        $query->execute();
448
+    }
449
+
450
+    /**
451
+     * get share ID on remote server for federated re-shares
452
+     *
453
+     * @param IShare $share
454
+     * @return int
455
+     * @throws ShareNotFound
456
+     */
457
+    public function getRemoteId(IShare $share) {
458
+        $query = $this->dbConnection->getQueryBuilder();
459
+        $query->select('remote_id')->from('federated_reshares')
460
+            ->where($query->expr()->eq('share_id', $query->createNamedParameter((int)$share->getId())));
461
+        $data = $query->execute()->fetch();
462
+
463
+        if (!is_array($data) || !isset($data['remote_id'])) {
464
+            throw new ShareNotFound();
465
+        }
466
+
467
+        return (int)$data['remote_id'];
468
+    }
469
+
470
+    /**
471
+     * @inheritdoc
472
+     */
473
+    public function move(IShare $share, $recipient) {
474
+        /*
475 475
 		 * This function does nothing yet as it is just for outgoing
476 476
 		 * federated shares.
477 477
 		 */
478
-		return $share;
479
-	}
480
-
481
-	/**
482
-	 * Get all children of this share
483
-	 *
484
-	 * @param IShare $parent
485
-	 * @return IShare[]
486
-	 */
487
-	public function getChildren(IShare $parent) {
488
-		$children = [];
489
-
490
-		$qb = $this->dbConnection->getQueryBuilder();
491
-		$qb->select('*')
492
-			->from('share')
493
-			->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
494
-			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE)))
495
-			->orderBy('id');
496
-
497
-		$cursor = $qb->execute();
498
-		while($data = $cursor->fetch()) {
499
-			$children[] = $this->createShareObject($data);
500
-		}
501
-		$cursor->closeCursor();
502
-
503
-		return $children;
504
-	}
505
-
506
-	/**
507
-	 * Delete a share (owner unShares the file)
508
-	 *
509
-	 * @param IShare $share
510
-	 * @throws ShareNotFound
511
-	 * @throws \OC\HintException
512
-	 */
513
-	public function delete(IShare $share) {
514
-
515
-		list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedWith());
516
-
517
-		// if the local user is the owner we can send the unShare request directly...
518
-		if ($this->userManager->userExists($share->getShareOwner())) {
519
-			$this->notifications->sendRemoteUnShare($remote, $share->getId(), $share->getToken());
520
-			$this->revokeShare($share, true);
521
-		} else { // ... if not we need to correct ID for the unShare request
522
-			$remoteId = $this->getRemoteId($share);
523
-			$this->notifications->sendRemoteUnShare($remote, $remoteId, $share->getToken());
524
-			$this->revokeShare($share, false);
525
-		}
526
-
527
-		// only remove the share when all messages are send to not lose information
528
-		// about the share to early
529
-		$this->removeShareFromTable($share);
530
-	}
531
-
532
-	/**
533
-	 * in case of a re-share we need to send the other use (initiator or owner)
534
-	 * a message that the file was unshared
535
-	 *
536
-	 * @param IShare $share
537
-	 * @param bool $isOwner the user can either be the owner or the user who re-sahred it
538
-	 * @throws ShareNotFound
539
-	 * @throws \OC\HintException
540
-	 */
541
-	protected function revokeShare($share, $isOwner) {
542
-		// also send a unShare request to the initiator, if this is a different user than the owner
543
-		if ($share->getShareOwner() !== $share->getSharedBy()) {
544
-			if ($isOwner) {
545
-				list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy());
546
-			} else {
547
-				list(, $remote) = $this->addressHandler->splitUserRemote($share->getShareOwner());
548
-			}
549
-			$remoteId = $this->getRemoteId($share);
550
-			$this->notifications->sendRevokeShare($remote, $remoteId, $share->getToken());
551
-		}
552
-	}
553
-
554
-	/**
555
-	 * remove share from table
556
-	 *
557
-	 * @param IShare $share
558
-	 */
559
-	public function removeShareFromTable(IShare $share) {
560
-		$this->removeShareFromTableById($share->getId());
561
-	}
562
-
563
-	/**
564
-	 * remove share from table
565
-	 *
566
-	 * @param string $shareId
567
-	 */
568
-	private function removeShareFromTableById($shareId) {
569
-		$qb = $this->dbConnection->getQueryBuilder();
570
-		$qb->delete('share')
571
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($shareId)));
572
-		$qb->execute();
573
-
574
-		$qb->delete('federated_reshares')
575
-			->where($qb->expr()->eq('share_id', $qb->createNamedParameter($shareId)));
576
-		$qb->execute();
577
-	}
578
-
579
-	/**
580
-	 * @inheritdoc
581
-	 */
582
-	public function deleteFromSelf(IShare $share, $recipient) {
583
-		// nothing to do here. Technically deleteFromSelf in the context of federated
584
-		// shares is a umount of a external storage. This is handled here
585
-		// apps/files_sharing/lib/external/manager.php
586
-		// TODO move this code over to this app
587
-	}
588
-
589
-	public function restore(IShare $share, string $recipient): IShare {
590
-		throw new GenericShareException('not implemented');
591
-	}
592
-
593
-
594
-	public function getSharesInFolder($userId, Folder $node, $reshares) {
595
-		$qb = $this->dbConnection->getQueryBuilder();
596
-		$qb->select('*')
597
-			->from('share', 's')
598
-			->andWhere($qb->expr()->orX(
599
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
600
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
601
-			))
602
-			->andWhere(
603
-				$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_REMOTE))
604
-			);
605
-
606
-		/**
607
-		 * Reshares for this user are shares where they are the owner.
608
-		 */
609
-		if ($reshares === false) {
610
-			$qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
611
-		} else {
612
-			$qb->andWhere(
613
-				$qb->expr()->orX(
614
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
615
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
616
-				)
617
-			);
618
-		}
619
-
620
-		$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
621
-		$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
622
-
623
-		$qb->orderBy('id');
624
-
625
-		$cursor = $qb->execute();
626
-		$shares = [];
627
-		while ($data = $cursor->fetch()) {
628
-			$shares[$data['fileid']][] = $this->createShareObject($data);
629
-		}
630
-		$cursor->closeCursor();
631
-
632
-		return $shares;
633
-	}
634
-
635
-	/**
636
-	 * @inheritdoc
637
-	 */
638
-	public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
639
-		$qb = $this->dbConnection->getQueryBuilder();
640
-		$qb->select('*')
641
-			->from('share');
642
-
643
-		$qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE)));
644
-
645
-		/**
646
-		 * Reshares for this user are shares where they are the owner.
647
-		 */
648
-		if ($reshares === false) {
649
-			//Special case for old shares created via the web UI
650
-			$or1 = $qb->expr()->andX(
651
-				$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
652
-				$qb->expr()->isNull('uid_initiator')
653
-			);
654
-
655
-			$qb->andWhere(
656
-				$qb->expr()->orX(
657
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)),
658
-					$or1
659
-				)
660
-			);
661
-		} else {
662
-			$qb->andWhere(
663
-				$qb->expr()->orX(
664
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
665
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
666
-				)
667
-			);
668
-		}
669
-
670
-		if ($node !== null) {
671
-			$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
672
-		}
673
-
674
-		if ($limit !== -1) {
675
-			$qb->setMaxResults($limit);
676
-		}
677
-
678
-		$qb->setFirstResult($offset);
679
-		$qb->orderBy('id');
680
-
681
-		$cursor = $qb->execute();
682
-		$shares = [];
683
-		while($data = $cursor->fetch()) {
684
-			$shares[] = $this->createShareObject($data);
685
-		}
686
-		$cursor->closeCursor();
687
-
688
-		return $shares;
689
-	}
690
-
691
-	/**
692
-	 * @inheritdoc
693
-	 */
694
-	public function getShareById($id, $recipientId = null) {
695
-		$qb = $this->dbConnection->getQueryBuilder();
696
-
697
-		$qb->select('*')
698
-			->from('share')
699
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
700
-			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE)));
701
-
702
-		$cursor = $qb->execute();
703
-		$data = $cursor->fetch();
704
-		$cursor->closeCursor();
705
-
706
-		if ($data === false) {
707
-			throw new ShareNotFound('Can not find share with ID: ' . $id);
708
-		}
709
-
710
-		try {
711
-			$share = $this->createShareObject($data);
712
-		} catch (InvalidShare $e) {
713
-			throw new ShareNotFound();
714
-		}
715
-
716
-		return $share;
717
-	}
718
-
719
-	/**
720
-	 * Get shares for a given path
721
-	 *
722
-	 * @param \OCP\Files\Node $path
723
-	 * @return IShare[]
724
-	 */
725
-	public function getSharesByPath(Node $path) {
726
-		$qb = $this->dbConnection->getQueryBuilder();
727
-
728
-		$cursor = $qb->select('*')
729
-			->from('share')
730
-			->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
731
-			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE)))
732
-			->execute();
733
-
734
-		$shares = [];
735
-		while($data = $cursor->fetch()) {
736
-			$shares[] = $this->createShareObject($data);
737
-		}
738
-		$cursor->closeCursor();
739
-
740
-		return $shares;
741
-	}
742
-
743
-	/**
744
-	 * @inheritdoc
745
-	 */
746
-	public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
747
-		/** @var IShare[] $shares */
748
-		$shares = [];
749
-
750
-		//Get shares directly with this user
751
-		$qb = $this->dbConnection->getQueryBuilder();
752
-		$qb->select('*')
753
-			->from('share');
754
-
755
-		// Order by id
756
-		$qb->orderBy('id');
757
-
758
-		// Set limit and offset
759
-		if ($limit !== -1) {
760
-			$qb->setMaxResults($limit);
761
-		}
762
-		$qb->setFirstResult($offset);
763
-
764
-		$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE)));
765
-		$qb->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)));
766
-
767
-		// Filter by node if provided
768
-		if ($node !== null) {
769
-			$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
770
-		}
771
-
772
-		$cursor = $qb->execute();
773
-
774
-		while($data = $cursor->fetch()) {
775
-			$shares[] = $this->createShareObject($data);
776
-		}
777
-		$cursor->closeCursor();
778
-
779
-
780
-		return $shares;
781
-	}
782
-
783
-	/**
784
-	 * Get a share by token
785
-	 *
786
-	 * @param string $token
787
-	 * @return IShare
788
-	 * @throws ShareNotFound
789
-	 */
790
-	public function getShareByToken($token) {
791
-		$qb = $this->dbConnection->getQueryBuilder();
792
-
793
-		$cursor = $qb->select('*')
794
-			->from('share')
795
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE)))
796
-			->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
797
-			->execute();
798
-
799
-		$data = $cursor->fetch();
800
-
801
-		if ($data === false) {
802
-			throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
803
-		}
804
-
805
-		try {
806
-			$share = $this->createShareObject($data);
807
-		} catch (InvalidShare $e) {
808
-			throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
809
-		}
810
-
811
-		return $share;
812
-	}
813
-
814
-	/**
815
-	 * get database row of a give share
816
-	 *
817
-	 * @param $id
818
-	 * @return array
819
-	 * @throws ShareNotFound
820
-	 */
821
-	private function getRawShare($id) {
822
-
823
-		// Now fetch the inserted share and create a complete share object
824
-		$qb = $this->dbConnection->getQueryBuilder();
825
-		$qb->select('*')
826
-			->from('share')
827
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
828
-
829
-		$cursor = $qb->execute();
830
-		$data = $cursor->fetch();
831
-		$cursor->closeCursor();
832
-
833
-		if ($data === false) {
834
-			throw new ShareNotFound;
835
-		}
836
-
837
-		return $data;
838
-	}
839
-
840
-	/**
841
-	 * Create a share object from an database row
842
-	 *
843
-	 * @param array $data
844
-	 * @return IShare
845
-	 * @throws InvalidShare
846
-	 * @throws ShareNotFound
847
-	 */
848
-	private function createShareObject($data) {
849
-
850
-		$share = new Share($this->rootFolder, $this->userManager);
851
-		$share->setId((int)$data['id'])
852
-			->setShareType((int)$data['share_type'])
853
-			->setPermissions((int)$data['permissions'])
854
-			->setTarget($data['file_target'])
855
-			->setMailSend((bool)$data['mail_send'])
856
-			->setToken($data['token']);
857
-
858
-		$shareTime = new \DateTime();
859
-		$shareTime->setTimestamp((int)$data['stime']);
860
-		$share->setShareTime($shareTime);
861
-		$share->setSharedWith($data['share_with']);
862
-
863
-		if ($data['uid_initiator'] !== null) {
864
-			$share->setShareOwner($data['uid_owner']);
865
-			$share->setSharedBy($data['uid_initiator']);
866
-		} else {
867
-			//OLD SHARE
868
-			$share->setSharedBy($data['uid_owner']);
869
-			$path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
870
-
871
-			$owner = $path->getOwner();
872
-			$share->setShareOwner($owner->getUID());
873
-		}
874
-
875
-		$share->setNodeId((int)$data['file_source']);
876
-		$share->setNodeType($data['item_type']);
877
-
878
-		$share->setProviderId($this->identifier());
879
-
880
-		return $share;
881
-	}
882
-
883
-	/**
884
-	 * Get the node with file $id for $user
885
-	 *
886
-	 * @param string $userId
887
-	 * @param int $id
888
-	 * @return \OCP\Files\File|\OCP\Files\Folder
889
-	 * @throws InvalidShare
890
-	 */
891
-	private function getNode($userId, $id) {
892
-		try {
893
-			$userFolder = $this->rootFolder->getUserFolder($userId);
894
-		} catch (NotFoundException $e) {
895
-			throw new InvalidShare();
896
-		}
897
-
898
-		$nodes = $userFolder->getById($id);
899
-
900
-		if (empty($nodes)) {
901
-			throw new InvalidShare();
902
-		}
903
-
904
-		return $nodes[0];
905
-	}
906
-
907
-	/**
908
-	 * A user is deleted from the system
909
-	 * So clean up the relevant shares.
910
-	 *
911
-	 * @param string $uid
912
-	 * @param int $shareType
913
-	 */
914
-	public function userDeleted($uid, $shareType) {
915
-		//TODO: probabaly a good idea to send unshare info to remote servers
916
-
917
-		$qb = $this->dbConnection->getQueryBuilder();
918
-
919
-		$qb->delete('share')
920
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_REMOTE)))
921
-			->andWhere($qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)))
922
-			->execute();
923
-	}
924
-
925
-	/**
926
-	 * This provider does not handle groups
927
-	 *
928
-	 * @param string $gid
929
-	 */
930
-	public function groupDeleted($gid) {
931
-		// We don't handle groups here
932
-	}
933
-
934
-	/**
935
-	 * This provider does not handle groups
936
-	 *
937
-	 * @param string $uid
938
-	 * @param string $gid
939
-	 */
940
-	public function userDeletedFromGroup($uid, $gid) {
941
-		// We don't handle groups here
942
-	}
943
-
944
-	/**
945
-	 * check if users from other Nextcloud instances are allowed to mount public links share by this instance
946
-	 *
947
-	 * @return bool
948
-	 */
949
-	public function isOutgoingServer2serverShareEnabled() {
950
-		if ($this->gsConfig->onlyInternalFederation()) {
951
-			return false;
952
-		}
953
-		$result = $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes');
954
-		return ($result === 'yes');
955
-	}
956
-
957
-	/**
958
-	 * check if users are allowed to mount public links from other Nextclouds
959
-	 *
960
-	 * @return bool
961
-	 */
962
-	public function isIncomingServer2serverShareEnabled() {
963
-		if ($this->gsConfig->onlyInternalFederation()) {
964
-			return false;
965
-		}
966
-		$result = $this->config->getAppValue('files_sharing', 'incoming_server2server_share_enabled', 'yes');
967
-		return ($result === 'yes');
968
-	}
969
-
970
-	/**
971
-	 * Check if querying sharees on the lookup server is enabled
972
-	 *
973
-	 * @return bool
974
-	 */
975
-	public function isLookupServerQueriesEnabled() {
976
-		// in a global scale setup we should always query the lookup server
977
-		if ($this->gsConfig->isGlobalScaleEnabled()) {
978
-			return true;
979
-		}
980
-		$result = $this->config->getAppValue('files_sharing', 'lookupServerEnabled', 'no');
981
-		return ($result === 'yes');
982
-	}
983
-
984
-
985
-	/**
986
-	 * Check if it is allowed to publish user specific data to the lookup server
987
-	 *
988
-	 * @return bool
989
-	 */
990
-	public function isLookupServerUploadEnabled() {
991
-		// in a global scale setup the admin is responsible to keep the lookup server up-to-date
992
-		if ($this->gsConfig->isGlobalScaleEnabled()) {
993
-			return false;
994
-		}
995
-		$result = $this->config->getAppValue('files_sharing', 'lookupServerUploadEnabled', 'yes');
996
-		return ($result === 'yes');
997
-	}
998
-
999
-	/**
1000
-	 * @inheritdoc
1001
-	 */
1002
-	public function getAccessList($nodes, $currentAccess) {
1003
-		$ids = [];
1004
-		foreach ($nodes as $node) {
1005
-			$ids[] = $node->getId();
1006
-		}
1007
-
1008
-		$qb = $this->dbConnection->getQueryBuilder();
1009
-		$qb->select('share_with', 'token', 'file_source')
1010
-			->from('share')
1011
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_REMOTE)))
1012
-			->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1013
-			->andWhere($qb->expr()->orX(
1014
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1015
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1016
-			));
1017
-		$cursor = $qb->execute();
1018
-
1019
-		if ($currentAccess === false) {
1020
-			$remote = $cursor->fetch() !== false;
1021
-			$cursor->closeCursor();
1022
-
1023
-			return ['remote' => $remote];
1024
-		}
1025
-
1026
-		$remote = [];
1027
-		while ($row = $cursor->fetch()) {
1028
-			$remote[$row['share_with']] = [
1029
-				'node_id' => $row['file_source'],
1030
-				'token' => $row['token'],
1031
-			];
1032
-		}
1033
-		$cursor->closeCursor();
1034
-
1035
-		return ['remote' => $remote];
1036
-	}
478
+        return $share;
479
+    }
480
+
481
+    /**
482
+     * Get all children of this share
483
+     *
484
+     * @param IShare $parent
485
+     * @return IShare[]
486
+     */
487
+    public function getChildren(IShare $parent) {
488
+        $children = [];
489
+
490
+        $qb = $this->dbConnection->getQueryBuilder();
491
+        $qb->select('*')
492
+            ->from('share')
493
+            ->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
494
+            ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE)))
495
+            ->orderBy('id');
496
+
497
+        $cursor = $qb->execute();
498
+        while($data = $cursor->fetch()) {
499
+            $children[] = $this->createShareObject($data);
500
+        }
501
+        $cursor->closeCursor();
502
+
503
+        return $children;
504
+    }
505
+
506
+    /**
507
+     * Delete a share (owner unShares the file)
508
+     *
509
+     * @param IShare $share
510
+     * @throws ShareNotFound
511
+     * @throws \OC\HintException
512
+     */
513
+    public function delete(IShare $share) {
514
+
515
+        list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedWith());
516
+
517
+        // if the local user is the owner we can send the unShare request directly...
518
+        if ($this->userManager->userExists($share->getShareOwner())) {
519
+            $this->notifications->sendRemoteUnShare($remote, $share->getId(), $share->getToken());
520
+            $this->revokeShare($share, true);
521
+        } else { // ... if not we need to correct ID for the unShare request
522
+            $remoteId = $this->getRemoteId($share);
523
+            $this->notifications->sendRemoteUnShare($remote, $remoteId, $share->getToken());
524
+            $this->revokeShare($share, false);
525
+        }
526
+
527
+        // only remove the share when all messages are send to not lose information
528
+        // about the share to early
529
+        $this->removeShareFromTable($share);
530
+    }
531
+
532
+    /**
533
+     * in case of a re-share we need to send the other use (initiator or owner)
534
+     * a message that the file was unshared
535
+     *
536
+     * @param IShare $share
537
+     * @param bool $isOwner the user can either be the owner or the user who re-sahred it
538
+     * @throws ShareNotFound
539
+     * @throws \OC\HintException
540
+     */
541
+    protected function revokeShare($share, $isOwner) {
542
+        // also send a unShare request to the initiator, if this is a different user than the owner
543
+        if ($share->getShareOwner() !== $share->getSharedBy()) {
544
+            if ($isOwner) {
545
+                list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy());
546
+            } else {
547
+                list(, $remote) = $this->addressHandler->splitUserRemote($share->getShareOwner());
548
+            }
549
+            $remoteId = $this->getRemoteId($share);
550
+            $this->notifications->sendRevokeShare($remote, $remoteId, $share->getToken());
551
+        }
552
+    }
553
+
554
+    /**
555
+     * remove share from table
556
+     *
557
+     * @param IShare $share
558
+     */
559
+    public function removeShareFromTable(IShare $share) {
560
+        $this->removeShareFromTableById($share->getId());
561
+    }
562
+
563
+    /**
564
+     * remove share from table
565
+     *
566
+     * @param string $shareId
567
+     */
568
+    private function removeShareFromTableById($shareId) {
569
+        $qb = $this->dbConnection->getQueryBuilder();
570
+        $qb->delete('share')
571
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($shareId)));
572
+        $qb->execute();
573
+
574
+        $qb->delete('federated_reshares')
575
+            ->where($qb->expr()->eq('share_id', $qb->createNamedParameter($shareId)));
576
+        $qb->execute();
577
+    }
578
+
579
+    /**
580
+     * @inheritdoc
581
+     */
582
+    public function deleteFromSelf(IShare $share, $recipient) {
583
+        // nothing to do here. Technically deleteFromSelf in the context of federated
584
+        // shares is a umount of a external storage. This is handled here
585
+        // apps/files_sharing/lib/external/manager.php
586
+        // TODO move this code over to this app
587
+    }
588
+
589
+    public function restore(IShare $share, string $recipient): IShare {
590
+        throw new GenericShareException('not implemented');
591
+    }
592
+
593
+
594
+    public function getSharesInFolder($userId, Folder $node, $reshares) {
595
+        $qb = $this->dbConnection->getQueryBuilder();
596
+        $qb->select('*')
597
+            ->from('share', 's')
598
+            ->andWhere($qb->expr()->orX(
599
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
600
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
601
+            ))
602
+            ->andWhere(
603
+                $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_REMOTE))
604
+            );
605
+
606
+        /**
607
+         * Reshares for this user are shares where they are the owner.
608
+         */
609
+        if ($reshares === false) {
610
+            $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
611
+        } else {
612
+            $qb->andWhere(
613
+                $qb->expr()->orX(
614
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
615
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
616
+                )
617
+            );
618
+        }
619
+
620
+        $qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
621
+        $qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
622
+
623
+        $qb->orderBy('id');
624
+
625
+        $cursor = $qb->execute();
626
+        $shares = [];
627
+        while ($data = $cursor->fetch()) {
628
+            $shares[$data['fileid']][] = $this->createShareObject($data);
629
+        }
630
+        $cursor->closeCursor();
631
+
632
+        return $shares;
633
+    }
634
+
635
+    /**
636
+     * @inheritdoc
637
+     */
638
+    public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
639
+        $qb = $this->dbConnection->getQueryBuilder();
640
+        $qb->select('*')
641
+            ->from('share');
642
+
643
+        $qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE)));
644
+
645
+        /**
646
+         * Reshares for this user are shares where they are the owner.
647
+         */
648
+        if ($reshares === false) {
649
+            //Special case for old shares created via the web UI
650
+            $or1 = $qb->expr()->andX(
651
+                $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
652
+                $qb->expr()->isNull('uid_initiator')
653
+            );
654
+
655
+            $qb->andWhere(
656
+                $qb->expr()->orX(
657
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)),
658
+                    $or1
659
+                )
660
+            );
661
+        } else {
662
+            $qb->andWhere(
663
+                $qb->expr()->orX(
664
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
665
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
666
+                )
667
+            );
668
+        }
669
+
670
+        if ($node !== null) {
671
+            $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
672
+        }
673
+
674
+        if ($limit !== -1) {
675
+            $qb->setMaxResults($limit);
676
+        }
677
+
678
+        $qb->setFirstResult($offset);
679
+        $qb->orderBy('id');
680
+
681
+        $cursor = $qb->execute();
682
+        $shares = [];
683
+        while($data = $cursor->fetch()) {
684
+            $shares[] = $this->createShareObject($data);
685
+        }
686
+        $cursor->closeCursor();
687
+
688
+        return $shares;
689
+    }
690
+
691
+    /**
692
+     * @inheritdoc
693
+     */
694
+    public function getShareById($id, $recipientId = null) {
695
+        $qb = $this->dbConnection->getQueryBuilder();
696
+
697
+        $qb->select('*')
698
+            ->from('share')
699
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
700
+            ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE)));
701
+
702
+        $cursor = $qb->execute();
703
+        $data = $cursor->fetch();
704
+        $cursor->closeCursor();
705
+
706
+        if ($data === false) {
707
+            throw new ShareNotFound('Can not find share with ID: ' . $id);
708
+        }
709
+
710
+        try {
711
+            $share = $this->createShareObject($data);
712
+        } catch (InvalidShare $e) {
713
+            throw new ShareNotFound();
714
+        }
715
+
716
+        return $share;
717
+    }
718
+
719
+    /**
720
+     * Get shares for a given path
721
+     *
722
+     * @param \OCP\Files\Node $path
723
+     * @return IShare[]
724
+     */
725
+    public function getSharesByPath(Node $path) {
726
+        $qb = $this->dbConnection->getQueryBuilder();
727
+
728
+        $cursor = $qb->select('*')
729
+            ->from('share')
730
+            ->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
731
+            ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE)))
732
+            ->execute();
733
+
734
+        $shares = [];
735
+        while($data = $cursor->fetch()) {
736
+            $shares[] = $this->createShareObject($data);
737
+        }
738
+        $cursor->closeCursor();
739
+
740
+        return $shares;
741
+    }
742
+
743
+    /**
744
+     * @inheritdoc
745
+     */
746
+    public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
747
+        /** @var IShare[] $shares */
748
+        $shares = [];
749
+
750
+        //Get shares directly with this user
751
+        $qb = $this->dbConnection->getQueryBuilder();
752
+        $qb->select('*')
753
+            ->from('share');
754
+
755
+        // Order by id
756
+        $qb->orderBy('id');
757
+
758
+        // Set limit and offset
759
+        if ($limit !== -1) {
760
+            $qb->setMaxResults($limit);
761
+        }
762
+        $qb->setFirstResult($offset);
763
+
764
+        $qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE)));
765
+        $qb->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)));
766
+
767
+        // Filter by node if provided
768
+        if ($node !== null) {
769
+            $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
770
+        }
771
+
772
+        $cursor = $qb->execute();
773
+
774
+        while($data = $cursor->fetch()) {
775
+            $shares[] = $this->createShareObject($data);
776
+        }
777
+        $cursor->closeCursor();
778
+
779
+
780
+        return $shares;
781
+    }
782
+
783
+    /**
784
+     * Get a share by token
785
+     *
786
+     * @param string $token
787
+     * @return IShare
788
+     * @throws ShareNotFound
789
+     */
790
+    public function getShareByToken($token) {
791
+        $qb = $this->dbConnection->getQueryBuilder();
792
+
793
+        $cursor = $qb->select('*')
794
+            ->from('share')
795
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_REMOTE)))
796
+            ->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
797
+            ->execute();
798
+
799
+        $data = $cursor->fetch();
800
+
801
+        if ($data === false) {
802
+            throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
803
+        }
804
+
805
+        try {
806
+            $share = $this->createShareObject($data);
807
+        } catch (InvalidShare $e) {
808
+            throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
809
+        }
810
+
811
+        return $share;
812
+    }
813
+
814
+    /**
815
+     * get database row of a give share
816
+     *
817
+     * @param $id
818
+     * @return array
819
+     * @throws ShareNotFound
820
+     */
821
+    private function getRawShare($id) {
822
+
823
+        // Now fetch the inserted share and create a complete share object
824
+        $qb = $this->dbConnection->getQueryBuilder();
825
+        $qb->select('*')
826
+            ->from('share')
827
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
828
+
829
+        $cursor = $qb->execute();
830
+        $data = $cursor->fetch();
831
+        $cursor->closeCursor();
832
+
833
+        if ($data === false) {
834
+            throw new ShareNotFound;
835
+        }
836
+
837
+        return $data;
838
+    }
839
+
840
+    /**
841
+     * Create a share object from an database row
842
+     *
843
+     * @param array $data
844
+     * @return IShare
845
+     * @throws InvalidShare
846
+     * @throws ShareNotFound
847
+     */
848
+    private function createShareObject($data) {
849
+
850
+        $share = new Share($this->rootFolder, $this->userManager);
851
+        $share->setId((int)$data['id'])
852
+            ->setShareType((int)$data['share_type'])
853
+            ->setPermissions((int)$data['permissions'])
854
+            ->setTarget($data['file_target'])
855
+            ->setMailSend((bool)$data['mail_send'])
856
+            ->setToken($data['token']);
857
+
858
+        $shareTime = new \DateTime();
859
+        $shareTime->setTimestamp((int)$data['stime']);
860
+        $share->setShareTime($shareTime);
861
+        $share->setSharedWith($data['share_with']);
862
+
863
+        if ($data['uid_initiator'] !== null) {
864
+            $share->setShareOwner($data['uid_owner']);
865
+            $share->setSharedBy($data['uid_initiator']);
866
+        } else {
867
+            //OLD SHARE
868
+            $share->setSharedBy($data['uid_owner']);
869
+            $path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
870
+
871
+            $owner = $path->getOwner();
872
+            $share->setShareOwner($owner->getUID());
873
+        }
874
+
875
+        $share->setNodeId((int)$data['file_source']);
876
+        $share->setNodeType($data['item_type']);
877
+
878
+        $share->setProviderId($this->identifier());
879
+
880
+        return $share;
881
+    }
882
+
883
+    /**
884
+     * Get the node with file $id for $user
885
+     *
886
+     * @param string $userId
887
+     * @param int $id
888
+     * @return \OCP\Files\File|\OCP\Files\Folder
889
+     * @throws InvalidShare
890
+     */
891
+    private function getNode($userId, $id) {
892
+        try {
893
+            $userFolder = $this->rootFolder->getUserFolder($userId);
894
+        } catch (NotFoundException $e) {
895
+            throw new InvalidShare();
896
+        }
897
+
898
+        $nodes = $userFolder->getById($id);
899
+
900
+        if (empty($nodes)) {
901
+            throw new InvalidShare();
902
+        }
903
+
904
+        return $nodes[0];
905
+    }
906
+
907
+    /**
908
+     * A user is deleted from the system
909
+     * So clean up the relevant shares.
910
+     *
911
+     * @param string $uid
912
+     * @param int $shareType
913
+     */
914
+    public function userDeleted($uid, $shareType) {
915
+        //TODO: probabaly a good idea to send unshare info to remote servers
916
+
917
+        $qb = $this->dbConnection->getQueryBuilder();
918
+
919
+        $qb->delete('share')
920
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_REMOTE)))
921
+            ->andWhere($qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)))
922
+            ->execute();
923
+    }
924
+
925
+    /**
926
+     * This provider does not handle groups
927
+     *
928
+     * @param string $gid
929
+     */
930
+    public function groupDeleted($gid) {
931
+        // We don't handle groups here
932
+    }
933
+
934
+    /**
935
+     * This provider does not handle groups
936
+     *
937
+     * @param string $uid
938
+     * @param string $gid
939
+     */
940
+    public function userDeletedFromGroup($uid, $gid) {
941
+        // We don't handle groups here
942
+    }
943
+
944
+    /**
945
+     * check if users from other Nextcloud instances are allowed to mount public links share by this instance
946
+     *
947
+     * @return bool
948
+     */
949
+    public function isOutgoingServer2serverShareEnabled() {
950
+        if ($this->gsConfig->onlyInternalFederation()) {
951
+            return false;
952
+        }
953
+        $result = $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes');
954
+        return ($result === 'yes');
955
+    }
956
+
957
+    /**
958
+     * check if users are allowed to mount public links from other Nextclouds
959
+     *
960
+     * @return bool
961
+     */
962
+    public function isIncomingServer2serverShareEnabled() {
963
+        if ($this->gsConfig->onlyInternalFederation()) {
964
+            return false;
965
+        }
966
+        $result = $this->config->getAppValue('files_sharing', 'incoming_server2server_share_enabled', 'yes');
967
+        return ($result === 'yes');
968
+    }
969
+
970
+    /**
971
+     * Check if querying sharees on the lookup server is enabled
972
+     *
973
+     * @return bool
974
+     */
975
+    public function isLookupServerQueriesEnabled() {
976
+        // in a global scale setup we should always query the lookup server
977
+        if ($this->gsConfig->isGlobalScaleEnabled()) {
978
+            return true;
979
+        }
980
+        $result = $this->config->getAppValue('files_sharing', 'lookupServerEnabled', 'no');
981
+        return ($result === 'yes');
982
+    }
983
+
984
+
985
+    /**
986
+     * Check if it is allowed to publish user specific data to the lookup server
987
+     *
988
+     * @return bool
989
+     */
990
+    public function isLookupServerUploadEnabled() {
991
+        // in a global scale setup the admin is responsible to keep the lookup server up-to-date
992
+        if ($this->gsConfig->isGlobalScaleEnabled()) {
993
+            return false;
994
+        }
995
+        $result = $this->config->getAppValue('files_sharing', 'lookupServerUploadEnabled', 'yes');
996
+        return ($result === 'yes');
997
+    }
998
+
999
+    /**
1000
+     * @inheritdoc
1001
+     */
1002
+    public function getAccessList($nodes, $currentAccess) {
1003
+        $ids = [];
1004
+        foreach ($nodes as $node) {
1005
+            $ids[] = $node->getId();
1006
+        }
1007
+
1008
+        $qb = $this->dbConnection->getQueryBuilder();
1009
+        $qb->select('share_with', 'token', 'file_source')
1010
+            ->from('share')
1011
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_REMOTE)))
1012
+            ->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1013
+            ->andWhere($qb->expr()->orX(
1014
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1015
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1016
+            ));
1017
+        $cursor = $qb->execute();
1018
+
1019
+        if ($currentAccess === false) {
1020
+            $remote = $cursor->fetch() !== false;
1021
+            $cursor->closeCursor();
1022
+
1023
+            return ['remote' => $remote];
1024
+        }
1025
+
1026
+        $remote = [];
1027
+        while ($row = $cursor->fetch()) {
1028
+            $remote[$row['share_with']] = [
1029
+                'node_id' => $row['file_source'],
1030
+                'token' => $row['token'],
1031
+            ];
1032
+        }
1033
+        $cursor->closeCursor();
1034
+
1035
+        return ['remote' => $remote];
1036
+    }
1037 1037
 }
Please login to merge, or discard this patch.