Passed
Push — master ( 62399c...5c21d1 )
by John
10:04
created

ShareAPIController::canDeleteShare()   A

Complexity

Conditions 6
Paths 4

Size

Total Lines 23
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 9
nc 4
nop 1
dl 0
loc 23
rs 9.2222
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
/**
4
 * @copyright Copyright (c) 2016, ownCloud, Inc.
5
 *
6
 * @author Bjoern Schiessle <[email protected]>
7
 * @author Joas Schilling <[email protected]>
8
 * @author Lukas Reschke <[email protected]>
9
 * @author Maxence Lange <[email protected]>
10
 * @author Michael Jobst <[email protected]>
11
 * @author Robin Appelman <[email protected]>
12
 * @author Roeland Jago Douma <[email protected]>
13
 * @author Vincent Petry <[email protected]>
14
 * @author John Molakvoæ <[email protected]>
15
 *
16
 * @license AGPL-3.0
17
 *
18
 * This code is free software: you can redistribute it and/or modify
19
 * it under the terms of the GNU Affero General Public License, version 3,
20
 * as published by the Free Software Foundation.
21
 *
22
 * This program is distributed in the hope that it will be useful,
23
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25
 * GNU Affero General Public License for more details.
26
 *
27
 * You should have received a copy of the GNU Affero General Public License, version 3,
28
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
29
 *
30
 */
31
32
namespace OCA\Files_Sharing\Controller;
33
34
use OCA\Files\Helper;
35
use OCP\App\IAppManager;
36
use OCP\AppFramework\Http\DataResponse;
37
use OCP\AppFramework\OCS\OCSBadRequestException;
38
use OCP\AppFramework\OCS\OCSException;
39
use OCP\AppFramework\OCS\OCSForbiddenException;
40
use OCP\AppFramework\OCS\OCSNotFoundException;
41
use OCP\AppFramework\OCSController;
42
use OCP\AppFramework\QueryException;
43
use OCP\Constants;
44
use OCP\Files\Node;
45
use OCP\Files\NotFoundException;
46
use OCP\IConfig;
47
use OCP\IGroupManager;
48
use OCP\IL10N;
49
use OCP\IUserManager;
50
use OCP\IRequest;
51
use OCP\IServerContainer;
52
use OCP\IURLGenerator;
53
use OCP\Files\IRootFolder;
54
use OCP\Lock\LockedException;
55
use OCP\Share;
56
use OCP\Share\IManager;
57
use OCP\Share\Exceptions\ShareNotFound;
58
use OCP\Share\Exceptions\GenericShareException;
59
use OCP\Lock\ILockingProvider;
60
use OCP\Share\IShare;
61
use OCA\Files_Sharing\External\Storage;
62
63
/**
64
 * Class Share20OCS
65
 *
66
 * @package OCA\Files_Sharing\API
67
 */
68
class ShareAPIController extends OCSController {
69
70
	/** @var IManager */
71
	private $shareManager;
72
	/** @var IGroupManager */
73
	private $groupManager;
74
	/** @var IUserManager */
75
	private $userManager;
76
	/** @var IRootFolder */
77
	private $rootFolder;
78
	/** @var IURLGenerator */
79
	private $urlGenerator;
80
	/** @var string */
81
	private $currentUser;
82
	/** @var IL10N */
83
	private $l;
84
	/** @var \OCP\Files\Node */
85
	private $lockedNode;
86
	/** @var IConfig */
87
	private $config;
88
	/** @var IAppManager */
89
	private $appManager;
90
	/** @var IServerContainer */
91
	private $serverContainer;
92
93
	/**
94
	 * Share20OCS constructor.
95
	 *
96
	 * @param string $appName
97
	 * @param IRequest $request
98
	 * @param IManager $shareManager
99
	 * @param IGroupManager $groupManager
100
	 * @param IUserManager $userManager
101
	 * @param IRootFolder $rootFolder
102
	 * @param IURLGenerator $urlGenerator
103
	 * @param string $userId
104
	 * @param IL10N $l10n
105
	 * @param IConfig $config
106
	 * @param IAppManager $appManager
107
	 * @param IServerContainer $serverContainer
108
	 */
109
	public function __construct(
110
		string $appName,
111
		IRequest $request,
112
		IManager $shareManager,
113
		IGroupManager $groupManager,
114
		IUserManager $userManager,
115
		IRootFolder $rootFolder,
116
		IURLGenerator $urlGenerator,
117
		string $userId = null,
118
		IL10N $l10n,
119
		IConfig $config,
120
		IAppManager $appManager,
121
		IServerContainer $serverContainer
122
	) {
123
		parent::__construct($appName, $request);
124
125
		$this->shareManager = $shareManager;
126
		$this->userManager = $userManager;
127
		$this->groupManager = $groupManager;
128
		$this->request = $request;
129
		$this->rootFolder = $rootFolder;
130
		$this->urlGenerator = $urlGenerator;
131
		$this->currentUser = $userId;
132
		$this->l = $l10n;
133
		$this->config = $config;
134
		$this->appManager = $appManager;
135
		$this->serverContainer = $serverContainer;
136
	}
137
138
	/**
139
	 * Convert an IShare to an array for OCS output
140
	 *
141
	 * @param \OCP\Share\IShare $share
142
	 * @param Node|null $recipientNode
143
	 * @return array
144
	 * @throws NotFoundException In case the node can't be resolved.
145
	 *
146
	 * @suppress PhanUndeclaredClassMethod
147
	 */
148
	protected function formatShare(\OCP\Share\IShare $share, Node $recipientNode = null): array {
149
		$sharedBy = $this->userManager->get($share->getSharedBy());
150
		$shareOwner = $this->userManager->get($share->getShareOwner());
151
152
		$result = [
153
			'id' => $share->getId(),
154
			'share_type' => $share->getShareType(),
155
			'uid_owner' => $share->getSharedBy(),
156
			'displayname_owner' => $sharedBy !== null ? $sharedBy->getDisplayName() : $share->getSharedBy(),
157
			'permissions' => $share->getPermissions(),
158
			'stime' => $share->getShareTime()->getTimestamp(),
159
			'parent' => null,
160
			'expiration' => null,
161
			'token' => null,
162
			'uid_file_owner' => $share->getShareOwner(),
163
			'note' => $share->getNote(),
164
			'label' => $share->getLabel(),
165
			'displayname_file_owner' => $shareOwner !== null ? $shareOwner->getDisplayName() : $share->getShareOwner(),
166
		];
167
168
		$userFolder = $this->rootFolder->getUserFolder($this->currentUser);
169
		if ($recipientNode) {
170
			$node = $recipientNode;
171
		} else {
172
			$nodes = $userFolder->getById($share->getNodeId());
173
			if (empty($nodes)) {
174
				// fallback to guessing the path
175
				$node = $userFolder->get($share->getTarget());
176
				if ($node === null || $share->getTarget() === '') {
177
					throw new NotFoundException();
178
				}
179
			} else {
180
				$node = $nodes[0];
181
			}
182
		}
183
184
		$result['path'] = $userFolder->getRelativePath($node->getPath());
185
		if ($node instanceof \OCP\Files\Folder) {
186
			$result['item_type'] = 'folder';
187
		} else {
188
			$result['item_type'] = 'file';
189
		}
190
191
		$result['mimetype'] = $node->getMimetype();
192
		$result['storage_id'] = $node->getStorage()->getId();
193
		$result['storage'] = $node->getStorage()->getCache()->getNumericStorageId();
194
		$result['item_source'] = $node->getId();
195
		$result['file_source'] = $node->getId();
196
		$result['file_parent'] = $node->getParent()->getId();
197
		$result['file_target'] = $share->getTarget();
198
199
		$expiration = $share->getExpirationDate();
200
		if ($expiration !== null) {
201
			$result['expiration'] = $expiration->format('Y-m-d 00:00:00');
202
		}
203
204
		if ($share->getShareType() === Share::SHARE_TYPE_USER) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_USER has been deprecated: 17.0.0 - use IShare::TYPE_USER instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

204
		if ($share->getShareType() === /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_USER) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
205
			$sharedWith = $this->userManager->get($share->getSharedWith());
206
			$result['share_with'] = $share->getSharedWith();
207
			$result['share_with_displayname'] = $sharedWith !== null ? $sharedWith->getDisplayName() : $share->getSharedWith();
208
		} else if ($share->getShareType() === Share::SHARE_TYPE_GROUP) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_GROUP has been deprecated: 17.0.0 - use IShare::TYPE_GROUP instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

208
		} else if ($share->getShareType() === /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_GROUP) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
209
			$group = $this->groupManager->get($share->getSharedWith());
210
			$result['share_with'] = $share->getSharedWith();
211
			$result['share_with_displayname'] = $group !== null ? $group->getDisplayName() : $share->getSharedWith();
212
		} else if ($share->getShareType() === Share::SHARE_TYPE_LINK) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_LINK has been deprecated: 17.0.0 - use IShare::TYPE_LINK instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

212
		} else if ($share->getShareType() === /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_LINK) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
213
214
			// "share_with" and "share_with_displayname" for passwords of link
215
			// shares was deprecated in Nextcloud 15, use "password" instead.
216
			$result['share_with'] = $share->getPassword();
217
			$result['share_with_displayname'] = $share->getPassword();
218
219
			$result['password'] = $share->getPassword();
220
221
			$result['send_password_by_talk'] = $share->getSendPasswordByTalk();
222
223
			$result['token'] = $share->getToken();
224
			$result['url'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $share->getToken()]);
225
		} else if ($share->getShareType() === Share::SHARE_TYPE_REMOTE || $share->getShareType() === Share::SHARE_TYPE_REMOTE_GROUP) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_REMOTE has been deprecated: 17.0.0 - use IShare::TYPE_REMOTE instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

225
		} else if ($share->getShareType() === /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_REMOTE || $share->getShareType() === Share::SHARE_TYPE_REMOTE_GROUP) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_REMOTE_GROUP has been deprecated: 17.0.0 - use IShare::REMOTE_GROUP instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

225
		} else if ($share->getShareType() === Share::SHARE_TYPE_REMOTE || $share->getShareType() === /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_REMOTE_GROUP) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
226
			$result['share_with'] = $share->getSharedWith();
227
			$result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'CLOUD');
228
			$result['token'] = $share->getToken();
229
		} else if ($share->getShareType() === Share::SHARE_TYPE_EMAIL) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_EMAIL has been deprecated: 17.0.0 - use IShare::TYPE_EMAIL instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

229
		} else if ($share->getShareType() === /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_EMAIL) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
230
			$result['share_with'] = $share->getSharedWith();
231
			$result['password'] = $share->getPassword();
232
			$result['send_password_by_talk'] = $share->getSendPasswordByTalk();
233
			$result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'EMAIL');
234
			$result['token'] = $share->getToken();
235
		} else if ($share->getShareType() === Share::SHARE_TYPE_CIRCLE) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_CIRCLE has been deprecated: 17.0.0 - use IShare::TYPE_CIRCLE instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

235
		} else if ($share->getShareType() === /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_CIRCLE) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
236
			// getSharedWith() returns either "name (type, owner)" or
237
			// "name (type, owner) [id]", depending on the Circles app version.
238
			$hasCircleId = (substr($share->getSharedWith(), -1) === ']');
239
240
			$result['share_with_displayname'] = $share->getSharedWithDisplayName();
241
			if (empty($result['share_with_displayname'])) {
242
				$displayNameLength = ($hasCircleId ? strrpos($share->getSharedWith(), ' ') : strlen($share->getSharedWith()));
243
				$result['share_with_displayname'] = substr($share->getSharedWith(), 0, $displayNameLength);
244
			}
245
246
			$result['share_with_avatar'] = $share->getSharedWithAvatar();
247
248
			$shareWithStart = ($hasCircleId ? strrpos($share->getSharedWith(), '[') + 1 : 0);
249
			$shareWithLength = ($hasCircleId ? -1 : strpos($share->getSharedWith(), ' '));
250
			if (is_bool($shareWithLength)) {
0 ignored issues
show
introduced by
The condition is_bool($shareWithLength) is always false.
Loading history...
251
				$shareWithLength = -1;
252
			}
253
			$result['share_with'] = substr($share->getSharedWith(), $shareWithStart, $shareWithLength);
254
		} else if ($share->getShareType() === Share::SHARE_TYPE_ROOM) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_ROOM has been deprecated: 17.0.0 - use IShare::TYPE_ROOM instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

254
		} else if ($share->getShareType() === /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_ROOM) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
255
			$result['share_with'] = $share->getSharedWith();
256
			$result['share_with_displayname'] = '';
257
258
			try {
259
				$result = array_merge($result, $this->getRoomShareHelper()->formatShare($share));
260
			} catch (QueryException $e) {}
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
261
		}
262
263
264
		$result['mail_send'] = $share->getMailSend() ? 1 : 0;
265
		$result['hide_download'] = $share->getHideDownload() ? 1 : 0;
266
267
		return $result;
268
	}
269
270
	/**
271
	 * Check if one of the users address books knows the exact property, if
272
	 * yes we return the full name.
273
	 *
274
	 * @param string $query
275
	 * @param string $property
276
	 * @return string
277
	 */
278
	private function getDisplayNameFromAddressBook(string $query, string $property): string {
279
		// FIXME: If we inject the contacts manager it gets initialized bofore any address books are registered
280
		$result = \OC::$server->getContactsManager()->search($query, [$property]);
281
		foreach ($result as $r) {
282
			foreach ($r[$property] as $value) {
283
				if ($value === $query) {
284
					return $r['FN'];
285
				}
286
			}
287
		}
288
289
		return $query;
290
	}
291
292
	/**
293
	 * Get a specific share by id
294
	 *
295
	 * @NoAdminRequired
296
	 *
297
	 * @param string $id
298
	 * @return DataResponse
299
	 * @throws OCSNotFoundException
300
	 */
301
	public function getShare(string $id): DataResponse {
302
		try {
303
			$share = $this->getShareById($id);
304
		} catch (ShareNotFound $e) {
305
			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
306
		}
307
308
		try {
309
			if ($this->canAccessShare($share)) {
310
				$share = $this->formatShare($share);
311
				return new DataResponse([$share]);
312
			}
313
		} catch (NotFoundException $e) {
314
			// Fall trough
315
		}
316
317
		throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
318
	}
319
320
	/**
321
	 * Delete a share
322
	 *
323
	 * @NoAdminRequired
324
	 *
325
	 * @param string $id
326
	 * @return DataResponse
327
	 * @throws OCSNotFoundException
328
	 */
329
	public function deleteShare(string $id): DataResponse {
330
		try {
331
			$share = $this->getShareById($id);
332
		} catch (ShareNotFound $e) {
333
			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
334
		}
335
336
		try {
337
			$this->lock($share->getNode());
338
		} catch (LockedException $e) {
339
			throw new OCSNotFoundException($this->l->t('Could not delete share'));
340
		}
341
342
		if (!$this->canAccessShare($share)) {
343
			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
344
		}
345
346
		// if it's a group share or a room share
347
		// we don't delete the share, but only the
348
		// mount point. Allowing it to be restored
349
		// from the deleted shares
350
		if ($this->canDeleteShareFromSelf($share)) {
351
			$this->shareManager->deleteFromSelf($share, $this->currentUser);
352
		} else {
353
			if (!$this->canDeleteShare($share)) {
354
				throw new OCSForbiddenException($this->l->t('Could not delete share'));
355
			}
356
357
			$this->shareManager->deleteShare($share);
358
		}
359
360
		return new DataResponse();
361
	}
362
363
	/**
364
	 * @NoAdminRequired
365
	 *
366
	 * @param string $path
367
	 * @param int $permissions
368
	 * @param int $shareType
369
	 * @param string $shareWith
370
	 * @param string $publicUpload
371
	 * @param string $password
372
	 * @param string $sendPasswordByTalk
373
	 * @param string $expireDate
374
	 * @param string $label
375
	 *
376
	 * @return DataResponse
377
	 * @throws NotFoundException
378
	 * @throws OCSBadRequestException
379
	 * @throws OCSException
380
	 * @throws OCSForbiddenException
381
	 * @throws OCSNotFoundException
382
	 * @throws \OCP\Files\InvalidPathException
383
	 * @suppress PhanUndeclaredClassMethod
384
	 */
385
	public function createShare(
386
		string $path = null,
387
		int $permissions = null,
388
		int $shareType = -1,
389
		string $shareWith = null,
390
		string $publicUpload = 'false',
391
		string $password = '',
392
		string $sendPasswordByTalk = null,
393
		string $expireDate = '',
394
		string $label = ''
395
	): DataResponse {
396
		$share = $this->shareManager->newShare();
397
398
		if ($permissions === null) {
399
			$permissions = $this->config->getAppValue('core', 'shareapi_default_permissions', Constants::PERMISSION_ALL);
400
		}
401
402
		// Verify path
403
		if ($path === null) {
404
			throw new OCSNotFoundException($this->l->t('Please specify a file or folder path'));
405
		}
406
407
		$userFolder = $this->rootFolder->getUserFolder($this->currentUser);
408
		try {
409
			$path = $userFolder->get($path);
410
		} catch (NotFoundException $e) {
411
			throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
412
		}
413
414
		$share->setNode($path);
415
416
		try {
417
			$this->lock($share->getNode());
418
		} catch (LockedException $e) {
419
			throw new OCSNotFoundException($this->l->t('Could not create share'));
420
		}
421
422
		if ($permissions < 0 || $permissions > Constants::PERMISSION_ALL) {
423
			throw new OCSNotFoundException($this->l->t('invalid permissions'));
424
		}
425
426
		// Shares always require read permissions
427
		$permissions |= Constants::PERMISSION_READ;
428
429
		if ($path instanceof \OCP\Files\File) {
430
			// Single file shares should never have delete or create permissions
431
			$permissions &= ~Constants::PERMISSION_DELETE;
432
			$permissions &= ~Constants::PERMISSION_CREATE;
433
		}
434
435
		/**
436
		 * Hack for https://github.com/owncloud/core/issues/22587
437
		 * We check the permissions via webdav. But the permissions of the mount point
438
		 * do not equal the share permissions. Here we fix that for federated mounts.
439
		 */
440
		if ($path->getStorage()->instanceOfStorage(Storage::class)) {
441
			$permissions &= ~($permissions & ~$path->getPermissions());
442
		}
443
444
		if ($shareType === Share::SHARE_TYPE_USER) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_USER has been deprecated: 17.0.0 - use IShare::TYPE_USER instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

444
		if ($shareType === /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_USER) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
445
			// Valid user is required to share
446
			if ($shareWith === null || !$this->userManager->userExists($shareWith)) {
447
				throw new OCSNotFoundException($this->l->t('Please specify a valid user'));
448
			}
449
			$share->setSharedWith($shareWith);
450
			$share->setPermissions($permissions);
451
		} else if ($shareType === Share::SHARE_TYPE_GROUP) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_GROUP has been deprecated: 17.0.0 - use IShare::TYPE_GROUP instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

451
		} else if ($shareType === /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_GROUP) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
452
			if (!$this->shareManager->allowGroupSharing()) {
453
				throw new OCSNotFoundException($this->l->t('Group sharing is disabled by the administrator'));
454
			}
455
456
			// Valid group is required to share
457
			if ($shareWith === null || !$this->groupManager->groupExists($shareWith)) {
458
				throw new OCSNotFoundException($this->l->t('Please specify a valid group'));
459
			}
460
			$share->setSharedWith($shareWith);
461
			$share->setPermissions($permissions);
462
		} else if ($shareType === Share::SHARE_TYPE_LINK
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_LINK has been deprecated: 17.0.0 - use IShare::TYPE_LINK instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

462
		} else if ($shareType === /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_LINK

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
463
			|| $shareType === Share::SHARE_TYPE_EMAIL) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_EMAIL has been deprecated: 17.0.0 - use IShare::TYPE_EMAIL instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

463
			|| $shareType === /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_EMAIL) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
464
465
			// Can we even share links?
466
			if (!$this->shareManager->shareApiAllowLinks()) {
467
				throw new OCSNotFoundException($this->l->t('Public link sharing is disabled by the administrator'));
468
			}
469
470
			if ($publicUpload === 'true') {
471
				// Check if public upload is allowed
472
				if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
473
					throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
474
				}
475
476
				// Public upload can only be set for folders
477
				if ($path instanceof \OCP\Files\File) {
478
					throw new OCSNotFoundException($this->l->t('Public upload is only possible for publicly shared folders'));
479
				}
480
481
				$share->setPermissions(
482
					Constants::PERMISSION_READ |
483
					Constants::PERMISSION_CREATE |
484
					Constants::PERMISSION_UPDATE |
485
					Constants::PERMISSION_DELETE
486
				);
487
			} else {
488
				$share->setPermissions(Constants::PERMISSION_READ);
489
			}
490
491
			// Set password
492
			if ($password !== '') {
493
				$share->setPassword($password);
494
			}
495
496
			// Only share by mail have a recipient
497
			if ($shareType === Share::SHARE_TYPE_EMAIL) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_EMAIL has been deprecated: 17.0.0 - use IShare::TYPE_EMAIL instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

497
			if ($shareType === /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_EMAIL) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
498
				$share->setSharedWith($shareWith);
499
			} else {
500
				// Only link share have a label
501
				if (!empty($label)) {
502
					$share->setLabel($label);
503
				}
504
			}
505
506
			if ($sendPasswordByTalk === 'true') {
507
				if (!$this->appManager->isEnabledForUser('spreed')) {
508
					throw new OCSForbiddenException($this->l->t('Sharing %s sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled', [$path->getPath()]));
509
				}
510
511
				$share->setSendPasswordByTalk(true);
512
			}
513
514
			//Expire date
515
			if ($expireDate !== '') {
516
				try {
517
					$expireDate = $this->parseDate($expireDate);
518
					$share->setExpirationDate($expireDate);
519
				} catch (\Exception $e) {
520
					throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD'));
521
				}
522
			}
523
		} else if ($shareType === Share::SHARE_TYPE_REMOTE) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_REMOTE has been deprecated: 17.0.0 - use IShare::TYPE_REMOTE instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

523
		} else if ($shareType === /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_REMOTE) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
524
			if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
525
				throw new OCSForbiddenException($this->l->t('Sharing %1$s failed because the back end does not allow shares from type %2$s', [$path->getPath(), $shareType]));
526
			}
527
528
			$share->setSharedWith($shareWith);
529
			$share->setPermissions($permissions);
530
		} else if ($shareType === Share::SHARE_TYPE_REMOTE_GROUP) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_REMOTE_GROUP has been deprecated: 17.0.0 - use IShare::REMOTE_GROUP instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

530
		} else if ($shareType === /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_REMOTE_GROUP) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
531
			if (!$this->shareManager->outgoingServer2ServerGroupSharesAllowed()) {
532
				throw new OCSForbiddenException($this->l->t('Sharing %1$s failed because the back end does not allow shares from type %2$s', [$path->getPath(), $shareType]));
533
			}
534
535
			$share->setSharedWith($shareWith);
536
			$share->setPermissions($permissions);
537
		} else if ($shareType === Share::SHARE_TYPE_CIRCLE) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_CIRCLE has been deprecated: 17.0.0 - use IShare::TYPE_CIRCLE instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

537
		} else if ($shareType === /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_CIRCLE) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
538
			if (!\OC::$server->getAppManager()->isEnabledForUser('circles') || !class_exists('\OCA\Circles\ShareByCircleProvider')) {
539
				throw new OCSNotFoundException($this->l->t('You cannot share to a Circle if the app is not enabled'));
540
			}
541
542
			$circle = \OCA\Circles\Api\v1\Circles::detailsCircle($shareWith);
0 ignored issues
show
Bug introduced by
The type OCA\Circles\Api\v1\Circles was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
543
544
			// Valid circle is required to share
545
			if ($circle === null) {
546
				throw new OCSNotFoundException($this->l->t('Please specify a valid circle'));
547
			}
548
			$share->setSharedWith($shareWith);
549
			$share->setPermissions($permissions);
550
		} else if ($shareType === Share::SHARE_TYPE_ROOM) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_ROOM has been deprecated: 17.0.0 - use IShare::TYPE_ROOM instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

550
		} else if ($shareType === /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_ROOM) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
551
			try {
552
				$this->getRoomShareHelper()->createShare($share, $shareWith, $permissions, $expireDate);
553
			} catch (QueryException $e) {
554
				throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not support room shares', [$path->getPath()]));
555
			}
556
		} else {
557
			throw new OCSBadRequestException($this->l->t('Unknown share type'));
558
		}
559
560
		$share->setShareType($shareType);
561
		$share->setSharedBy($this->currentUser);
562
563
		try {
564
			$share = $this->shareManager->createShare($share);
565
		} catch (GenericShareException $e) {
566
			$code = $e->getCode() === 0 ? 403 : $e->getCode();
567
			throw new OCSException($e->getHint(), $code);
568
		} catch (\Exception $e) {
569
			throw new OCSForbiddenException($e->getMessage(), $e);
570
		}
571
572
		$output = $this->formatShare($share);
573
574
		return new DataResponse($output);
575
	}
576
577
	/**
578
	 * @param \OCP\Files\File|\OCP\Files\Folder $node
579
	 * @param boolean $includeTags
580
	 * @return DataResponse
581
	 */
582
	private function getSharedWithMe($node = null, bool $includeTags): DataResponse {
583
584
		$userShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_USER, $node, -1, 0);
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_USER has been deprecated: 17.0.0 - use IShare::TYPE_USER instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

584
		$userShares = $this->shareManager->getSharedWith($this->currentUser, /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_USER, $node, -1, 0);

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
585
		$groupShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_GROUP, $node, -1, 0);
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_GROUP has been deprecated: 17.0.0 - use IShare::TYPE_GROUP instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

585
		$groupShares = $this->shareManager->getSharedWith($this->currentUser, /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_GROUP, $node, -1, 0);

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
586
		$circleShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_CIRCLE, $node, -1, 0);
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_CIRCLE has been deprecated: 17.0.0 - use IShare::TYPE_CIRCLE instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

586
		$circleShares = $this->shareManager->getSharedWith($this->currentUser, /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_CIRCLE, $node, -1, 0);

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
587
		$roomShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_ROOM, $node, -1, 0);
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_ROOM has been deprecated: 17.0.0 - use IShare::TYPE_ROOM instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

587
		$roomShares = $this->shareManager->getSharedWith($this->currentUser, /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_ROOM, $node, -1, 0);

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
588
589
		$shares = array_merge($userShares, $groupShares, $circleShares, $roomShares);
590
591
		$shares = array_filter($shares, function (IShare $share) {
592
			return $share->getShareOwner() !== $this->currentUser;
593
		});
594
595
		$formatted = [];
596
		foreach ($shares as $share) {
597
			if ($this->canAccessShare($share)) {
598
				try {
599
					$formatted[] = $this->formatShare($share);
600
				} catch (NotFoundException $e) {
601
					// Ignore this share
602
				}
603
			}
604
		}
605
606
		if ($includeTags) {
607
			$formatted = Helper::populateTags($formatted, 'file_source', \OC::$server->getTagManager());
608
		}
609
610
		return new DataResponse($formatted);
611
	}
612
613
	/**
614
	 * @param \OCP\Files\Folder $folder
615
	 * @return DataResponse
616
	 * @throws OCSBadRequestException
617
	 */
618
	private function getSharesInDir(Node $folder): DataResponse {
619
		if (!($folder instanceof \OCP\Files\Folder)) {
620
			throw new OCSBadRequestException($this->l->t('Not a directory'));
621
		}
622
623
		$nodes = $folder->getDirectoryListing();
624
		/** @var \OCP\Share\IShare[] $shares */
625
		$shares = [];
626
		foreach ($nodes as $node) {
627
628
			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_USER, $node, true, -1, 0));
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_USER has been deprecated: 17.0.0 - use IShare::TYPE_USER instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

628
			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_USER, $node, true, -1, 0));

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
629
			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_GROUP, $node, true, -1, 0));
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_GROUP has been deprecated: 17.0.0 - use IShare::TYPE_GROUP instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

629
			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_GROUP, $node, true, -1, 0));

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
630
			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_LINK, $node, true, -1, 0));
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_LINK has been deprecated: 17.0.0 - use IShare::TYPE_LINK instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

630
			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_LINK, $node, true, -1, 0));

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
631
			if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_EMAIL has been deprecated: 17.0.0 - use IShare::TYPE_EMAIL instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

631
			if ($this->shareManager->shareProviderExists(/** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_EMAIL)) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
632
				$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_EMAIL, $node, true, -1, 0));
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_EMAIL has been deprecated: 17.0.0 - use IShare::TYPE_EMAIL instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

632
				$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_EMAIL, $node, true, -1, 0));

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
633
			}
634
			if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
635
				$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_REMOTE, $node, true, -1, 0));
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_REMOTE has been deprecated: 17.0.0 - use IShare::TYPE_REMOTE instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

635
				$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_REMOTE, $node, true, -1, 0));

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
636
			}
637
			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_ROOM, $node, true, -1, 0));
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_ROOM has been deprecated: 17.0.0 - use IShare::TYPE_ROOM instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

637
			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_ROOM, $node, true, -1, 0));

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
638
		}
639
640
		$formatted = $miniFormatted = [];
641
		$resharingRight = false;
642
		$known = [];
643
		foreach ($shares as $share) {
644
			if (in_array($share->getId(), $known) || $share->getSharedWith() === $this->currentUser) {
645
				continue;
646
			}
647
648
			try {
649
				$format = $this->formatShare($share);
650
651
				$known[] = $share->getId();
652
				$formatted[] = $format;
653
				if ($share->getSharedBy() === $this->currentUser) {
654
					$miniFormatted[] = $format;
655
				}
656
				if (!$resharingRight && $this->shareProviderResharingRights($this->currentUser, $share, $folder)) {
657
					$resharingRight = true;
658
				}
659
			} catch (\Exception $e) {
660
				//Ignore this share
661
			}
662
		}
663
664
		if (!$resharingRight) {
665
			$formatted = $miniFormatted;
666
		}
667
668
		return new DataResponse($formatted);
669
	}
670
671
	/**
672
	 * The getShares function.
673
	 *
674
	 * @NoAdminRequired
675
	 *
676
	 * @param string $shared_with_me
677
	 * @param string $reshares
678
	 * @param string $subfiles
679
	 * @param string $path
680
	 *
681
	 * - Get shares by the current user
682
	 * - Get shares by the current user and reshares (?reshares=true)
683
	 * - Get shares with the current user (?shared_with_me=true)
684
	 * - Get shares for a specific path (?path=...)
685
	 * - Get all shares in a folder (?subfiles=true&path=..)
686
	 *
687
	 * @return DataResponse
688
	 * @throws OCSNotFoundException
689
	 */
690
	public function getShares(
691
		string $shared_with_me = 'false',
692
		string $reshares = 'false',
693
		string $subfiles = 'false',
694
		string $path = null,
695
		string $include_tags = 'false'
696
	): DataResponse {
697
698
		if ($path !== null) {
699
			$userFolder = $this->rootFolder->getUserFolder($this->currentUser);
700
			try {
701
				$path = $userFolder->get($path);
702
				$this->lock($path);
703
			} catch (\OCP\Files\NotFoundException $e) {
704
				throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
705
			} catch (LockedException $e) {
706
				throw new OCSNotFoundException($this->l->t('Could not lock path'));
707
			}
708
		}
709
710
		$include_tags = $include_tags === 'true';
711
712
		if ($shared_with_me === 'true') {
713
			$result = $this->getSharedWithMe($path, $include_tags);
714
			return $result;
715
		}
716
717
		if ($subfiles === 'true') {
718
			$result = $this->getSharesInDir($path);
719
			return $result;
720
		}
721
722
		if ($reshares === 'true') {
723
			$reshares = true;
724
		} else {
725
			$reshares = false;
726
		}
727
728
		// Get all shares
729
		$userShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_USER, $path, $reshares, -1, 0);
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_USER has been deprecated: 17.0.0 - use IShare::TYPE_USER instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

729
		$userShares = $this->shareManager->getSharesBy($this->currentUser, /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_USER, $path, $reshares, -1, 0);

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
730
		$groupShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_GROUP, $path, $reshares, -1, 0);
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_GROUP has been deprecated: 17.0.0 - use IShare::TYPE_GROUP instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

730
		$groupShares = $this->shareManager->getSharesBy($this->currentUser, /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_GROUP, $path, $reshares, -1, 0);

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
731
		$linkShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_LINK, $path, $reshares, -1, 0);
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_LINK has been deprecated: 17.0.0 - use IShare::TYPE_LINK instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

731
		$linkShares = $this->shareManager->getSharesBy($this->currentUser, /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_LINK, $path, $reshares, -1, 0);

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
732
		if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_EMAIL has been deprecated: 17.0.0 - use IShare::TYPE_EMAIL instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

732
		if ($this->shareManager->shareProviderExists(/** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_EMAIL)) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
733
			$mailShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_EMAIL, $path, $reshares, -1, 0);
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_EMAIL has been deprecated: 17.0.0 - use IShare::TYPE_EMAIL instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

733
			$mailShares = $this->shareManager->getSharesBy($this->currentUser, /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_EMAIL, $path, $reshares, -1, 0);

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
734
		} else {
735
			$mailShares = [];
736
		}
737
		if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_CIRCLE)) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_CIRCLE has been deprecated: 17.0.0 - use IShare::TYPE_CIRCLE instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

737
		if ($this->shareManager->shareProviderExists(/** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_CIRCLE)) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
738
			$circleShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_CIRCLE, $path, $reshares, -1, 0);
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_CIRCLE has been deprecated: 17.0.0 - use IShare::TYPE_CIRCLE instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

738
			$circleShares = $this->shareManager->getSharesBy($this->currentUser, /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_CIRCLE, $path, $reshares, -1, 0);

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
739
		} else {
740
			$circleShares = [];
741
		}
742
		$roomShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_ROOM, $path, $reshares, -1, 0);
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_ROOM has been deprecated: 17.0.0 - use IShare::TYPE_ROOM instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

742
		$roomShares = $this->shareManager->getSharesBy($this->currentUser, /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_ROOM, $path, $reshares, -1, 0);

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
743
744
		$shares = array_merge($userShares, $groupShares, $linkShares, $mailShares, $circleShares, $roomShares);
745
746
		if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
747
			$federatedShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_REMOTE, $path, $reshares, -1, 0);
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_REMOTE has been deprecated: 17.0.0 - use IShare::TYPE_REMOTE instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

747
			$federatedShares = $this->shareManager->getSharesBy($this->currentUser, /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_REMOTE, $path, $reshares, -1, 0);

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
748
			$shares = array_merge($shares, $federatedShares);
749
		}
750
751
		if ($this->shareManager->outgoingServer2ServerGroupSharesAllowed()) {
752
			$federatedShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_REMOTE_GROUP, $path, $reshares, -1, 0);
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_REMOTE_GROUP has been deprecated: 17.0.0 - use IShare::REMOTE_GROUP instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

752
			$federatedShares = $this->shareManager->getSharesBy($this->currentUser, /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_REMOTE_GROUP, $path, $reshares, -1, 0);

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
753
			$shares = array_merge($shares, $federatedShares);
754
		}
755
756
		$formatted = $miniFormatted = [];
757
		$resharingRight = false;
758
		foreach ($shares as $share) {
759
			/** @var IShare $share */
760
			try {
761
				$format = $this->formatShare($share, $path);
762
				$formatted[] = $format;
763
				if ($share->getSharedBy() === $this->currentUser) {
764
					$miniFormatted[] = $format;
765
				}
766
767
				if (!$resharingRight && $this->shareProviderResharingRights($this->currentUser, $share, $path)) {
768
					$resharingRight = true;
769
				}
770
			} catch (\Exception $e) {
771
				//Ignore share
772
			}
773
		}
774
775
		if (!$resharingRight) {
776
			$formatted = $miniFormatted;
777
		}
778
779
		if ($include_tags) {
780
			$formatted = Helper::populateTags($formatted, 'file_source', \OC::$server->getTagManager());
781
		}
782
783
		return new DataResponse($formatted);
784
	}
785
786
	/**
787
	 * @NoAdminRequired
788
	 *
789
	 * @param string $id
790
	 * @param int $permissions
791
	 * @param string $password
792
	 * @param string $sendPasswordByTalk
793
	 * @param string $publicUpload
794
	 * @param string $expireDate
795
	 * @param string $note
796
	 * @param string $label
797
	 * @param string $hideDownload
798
	 * @return DataResponse
799
	 * @throws LockedException
800
	 * @throws NotFoundException
801
	 * @throws OCSBadRequestException
802
	 * @throws OCSForbiddenException
803
	 * @throws OCSNotFoundException
804
	 */
805
	public function updateShare(
806
		string $id,
807
		int $permissions = null,
808
		string $password = null,
809
		string $sendPasswordByTalk = null,
810
		string $publicUpload = null,
811
		string $expireDate = null,
812
		string $note = null,
813
		string $label = null,
814
		string $hideDownload = null
815
	): DataResponse {
816
		try {
817
			$share = $this->getShareById($id);
818
		} catch (ShareNotFound $e) {
819
			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
820
		}
821
822
		$this->lock($share->getNode());
823
824
		if (!$this->canAccessShare($share, false)) {
825
			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
826
		}
827
828
		if (!$this->canEditShare($share)) {
829
			throw new OCSForbiddenException('You are not allowed to edit incoming shares');
830
		}
831
832
		if (
833
			$permissions === null &&
834
			$password === null &&
835
			$sendPasswordByTalk === null &&
836
			$publicUpload === null &&
837
			$expireDate === null &&
838
			$note === null &&
839
			$label === null &&
840
			$hideDownload === null
841
		) {
842
			throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given'));
843
		}
844
845
		if ($note !== null) {
846
			$share->setNote($note);
847
		}
848
849
		/**
850
		 * expirationdate, password and publicUpload only make sense for link shares
851
		 */
852
		if ($share->getShareType() === Share::SHARE_TYPE_LINK
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_LINK has been deprecated: 17.0.0 - use IShare::TYPE_LINK instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

852
		if ($share->getShareType() === /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_LINK

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
853
			|| $share->getShareType() === Share::SHARE_TYPE_EMAIL) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_EMAIL has been deprecated: 17.0.0 - use IShare::TYPE_EMAIL instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

853
			|| $share->getShareType() === /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_EMAIL) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
854
855
			/**
856
			 * We do not allow editing link shares that the current user
857
			 * doesn't own. This is confusing and lead to errors when
858
			 * someone else edit a password or expiration date without
859
			 * the share owner knowing about it.
860
			 * We only allow deletion
861
			 */
862
863
			if ($share->getSharedBy() !== $this->currentUser) {
864
				throw new OCSForbiddenException('You are not allowed to edit link shares that you don\'t own');
865
			}
866
867
			// Update hide download state
868
			if ($hideDownload === 'true') {
869
				$share->setHideDownload(true);
870
			} else if ($hideDownload === 'false') {
871
				$share->setHideDownload(false);
872
			}
873
874
			$newPermissions = null;
875
			if ($publicUpload === 'true') {
876
				$newPermissions = Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE;
877
			} else if ($publicUpload === 'false') {
878
				$newPermissions = Constants::PERMISSION_READ;
879
			}
880
881
			if ($permissions !== null) {
882
				$newPermissions = (int) $permissions;
883
				$newPermissions = $newPermissions & ~Constants::PERMISSION_SHARE;
884
			}
885
886
			if ($newPermissions !== null &&
887
				!in_array($newPermissions, [
888
					Constants::PERMISSION_READ,
889
					Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE, // legacy
890
					Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE, // correct
891
					Constants::PERMISSION_CREATE, // hidden file list
892
					Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE, // allow to edit single files
893
				], true)
894
			) {
895
				throw new OCSBadRequestException($this->l->t('Can\'t change permissions for public share links'));
896
			}
897
898
			if (
899
				// legacy
900
				$newPermissions === (Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE) ||
901
				// correct
902
				$newPermissions === (Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE)
903
			) {
904
				if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
905
					throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
906
				}
907
908
				if (!($share->getNode() instanceof \OCP\Files\Folder)) {
909
					throw new OCSBadRequestException($this->l->t('Public upload is only possible for publicly shared folders'));
910
				}
911
912
				// normalize to correct public upload permissions
913
				$newPermissions = Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE;
914
			}
915
916
			if ($newPermissions !== null) {
917
				$share->setPermissions($newPermissions);
918
				$permissions = $newPermissions;
0 ignored issues
show
Unused Code introduced by
The assignment to $permissions is dead and can be removed.
Loading history...
919
			}
920
921
			if ($expireDate === '') {
922
				$share->setExpirationDate(null);
923
			} else if ($expireDate !== null) {
924
				try {
925
					$expireDate = $this->parseDate($expireDate);
926
				} catch (\Exception $e) {
927
					throw new OCSBadRequestException($e->getMessage(), $e);
928
				}
929
				$share->setExpirationDate($expireDate);
930
			}
931
932
			if ($password === '') {
933
				$share->setPassword(null);
934
			} else if ($password !== null) {
935
				$share->setPassword($password);
936
			}
937
938
			// only link shares have labels
939
			if ($share->getShareType() === Share::SHARE_TYPE_LINK && $label !== null) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_LINK has been deprecated: 17.0.0 - use IShare::TYPE_LINK instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

939
			if ($share->getShareType() === /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_LINK && $label !== null) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
940
				$share->setLabel($label);
941
			}
942
943
			if ($sendPasswordByTalk === 'true') {
944
				if (!$this->appManager->isEnabledForUser('spreed')) {
945
					throw new OCSForbiddenException($this->l->t('Sharing sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled'));
946
				}
947
948
				$share->setSendPasswordByTalk(true);
949
			} else if ($sendPasswordByTalk !== null) {
950
				$share->setSendPasswordByTalk(false);
951
			}
952
		}
953
954
		// NOT A LINK SHARE
955
		else {
956
			if ($permissions !== null) {
957
				$permissions = (int) $permissions;
958
				$share->setPermissions($permissions);
959
			}
960
961
			if ($expireDate === '') {
962
				$share->setExpirationDate(null);
963
			} else if ($expireDate !== null) {
964
				try {
965
					$expireDate = $this->parseDate($expireDate);
966
				} catch (\Exception $e) {
967
					throw new OCSBadRequestException($e->getMessage(), $e);
968
				}
969
				$share->setExpirationDate($expireDate);
970
			}
971
		}
972
973
		try {
974
			$share = $this->shareManager->updateShare($share);
975
		} catch (GenericShareException $e) {
976
			$code = $e->getCode() === 0 ? 403 : $e->getCode();
977
			throw new OCSException($e->getHint(), $code);
978
		} catch (\Exception $e) {
979
			throw new OCSBadRequestException($e->getMessage(), $e);
980
		}
981
982
		return new DataResponse($this->formatShare($share));
983
	}
984
985
	/**
986
	 * Does the user have read permission on the share
987
	 *
988
	 * @param \OCP\Share\IShare $share the share to check
989
	 * @param boolean $checkGroups check groups as well?
990
	 * @return boolean
991
	 * @throws NotFoundException
992
	 *
993
	 * @suppress PhanUndeclaredClassMethod
994
	 */
995
	protected function canAccessShare(\OCP\Share\IShare $share, bool $checkGroups = true): bool {
996
		// A file with permissions 0 can't be accessed by us. So Don't show it
997
		if ($share->getPermissions() === 0) {
998
			return false;
999
		}
1000
1001
		// Owner of the file and the sharer of the file can always get share
1002
		if ($share->getShareOwner() === $this->currentUser
1003
			|| $share->getSharedBy() === $this->currentUser) {
1004
			return true;
1005
		}
1006
1007
		// If the share is shared with you, you can access it!
1008
		if ($share->getShareType() === Share::SHARE_TYPE_USER
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_USER has been deprecated: 17.0.0 - use IShare::TYPE_USER instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1008
		if ($share->getShareType() === /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_USER

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
1009
			&& $share->getSharedWith() === $this->currentUser) {
1010
			return true;
1011
		}
1012
1013
		// Have reshare rights on the shared file/folder ?
1014
		// Does the currentUser have access to the shared file?
1015
		$userFolder = $this->rootFolder->getUserFolder($this->currentUser);
1016
		$files = $userFolder->getById($share->getNodeId());
1017
		if (!empty($files) && $this->shareProviderResharingRights($this->currentUser, $share, $files[0])) {
1018
			return true;
1019
		}
1020
1021
		// If in the recipient group, you can see the share
1022
		if ($checkGroups && $share->getShareType() === Share::SHARE_TYPE_GROUP) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_GROUP has been deprecated: 17.0.0 - use IShare::TYPE_GROUP instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1022
		if ($checkGroups && $share->getShareType() === /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_GROUP) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
1023
			$sharedWith = $this->groupManager->get($share->getSharedWith());
1024
			$user = $this->userManager->get($this->currentUser);
1025
			if ($user !== null && $sharedWith !== null && $sharedWith->inGroup($user)) {
1026
				return true;
1027
			}
1028
		}
1029
1030
		if ($share->getShareType() === Share::SHARE_TYPE_CIRCLE) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_CIRCLE has been deprecated: 17.0.0 - use IShare::TYPE_CIRCLE instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1030
		if ($share->getShareType() === /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_CIRCLE) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
1031
			// TODO: have a sanity check like above?
1032
			return true;
1033
		}
1034
1035
		if ($share->getShareType() === Share::SHARE_TYPE_ROOM) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_ROOM has been deprecated: 17.0.0 - use IShare::TYPE_ROOM instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1035
		if ($share->getShareType() === /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_ROOM) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
1036
			try {
1037
				return $this->getRoomShareHelper()->canAccessShare($share, $this->currentUser);
1038
			} catch (QueryException $e) {
1039
				return false;
1040
			}
1041
		}
1042
1043
		return false;
1044
	}
1045
1046
	/**
1047
	 * Does the user have edit permission on the share
1048
	 *
1049
	 * @param \OCP\Share\IShare $share the share to check
1050
	 * @return boolean
1051
	 */
1052
	protected function canEditShare(\OCP\Share\IShare $share): bool {
1053
		// A file with permissions 0 can't be accessed by us. So Don't show it
1054
		if ($share->getPermissions() === 0) {
1055
			return false;
1056
		}
1057
1058
		// The owner of the file and the creator of the share
1059
		// can always edit the share
1060
		if ($share->getShareOwner() === $this->currentUser ||
1061
			$share->getSharedBy() === $this->currentUser
1062
		) {
1063
			return true;
1064
		}
1065
1066
		//! we do NOT support some kind of `admin` in groups.
1067
		//! You cannot edit shares shared to a group you're
1068
		//! a member of if you're not the share owner or the file owner!
1069
1070
		return false;
1071
	}
1072
1073
	/**
1074
	 * Does the user have delete permission on the share
1075
	 *
1076
	 * @param \OCP\Share\IShare $share the share to check
1077
	 * @return boolean
1078
	 */
1079
	protected function canDeleteShare(\OCP\Share\IShare $share): bool {
1080
		// A file with permissions 0 can't be accessed by us. So Don't show it
1081
		if ($share->getPermissions() === 0) {
1082
			return false;
1083
		}
1084
1085
		// if the user is the recipient, i can unshare
1086
		// the share with self
1087
		if ($share->getShareType() === Share::SHARE_TYPE_USER &&
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_USER has been deprecated: 17.0.0 - use IShare::TYPE_USER instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1087
		if ($share->getShareType() === /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_USER &&

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
1088
			$share->getSharedWith() === $this->currentUser
1089
		) {
1090
			return true;
1091
		}
1092
1093
		// The owner of the file and the creator of the share
1094
		// can always delete the share
1095
		if ($share->getShareOwner() === $this->currentUser ||
1096
			$share->getSharedBy() === $this->currentUser
1097
		) {
1098
			return true;
1099
		}
1100
1101
		return false;
1102
	}
1103
1104
	/**
1105
	 * Does the user have delete permission on the share
1106
	 * This differs from the canDeleteShare function as it only
1107
	 * remove the share for the current user. It does NOT
1108
	 * completely delete the share but only the mount point.
1109
	 * It can then be restored from the deleted shares section.
1110
	 *
1111
	 * @param \OCP\Share\IShare $share the share to check
1112
	 * @return boolean
1113
	 *
1114
	 * @suppress PhanUndeclaredClassMethod
1115
	 */
1116
	protected function canDeleteShareFromSelf(\OCP\Share\IShare $share): bool {
1117
		if ($share->getShareType() !== Share::SHARE_TYPE_GROUP &&
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_GROUP has been deprecated: 17.0.0 - use IShare::TYPE_GROUP instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1117
		if ($share->getShareType() !== /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_GROUP &&

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
1118
			$share->getShareType() !== Share::SHARE_TYPE_ROOM
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_ROOM has been deprecated: 17.0.0 - use IShare::TYPE_ROOM instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1118
			$share->getShareType() !== /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_ROOM

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
1119
		) {
1120
			return false;
1121
		}
1122
1123
		if ($share->getShareOwner() === $this->currentUser ||
1124
			$share->getSharedBy() === $this->currentUser
1125
		) {
1126
			// Delete the whole share, not just for self
1127
			return false;
1128
		}
1129
1130
		// If in the recipient group, you can delete the share from self
1131
		if ($share->getShareType() === Share::SHARE_TYPE_GROUP) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_GROUP has been deprecated: 17.0.0 - use IShare::TYPE_GROUP instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1131
		if ($share->getShareType() === /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_GROUP) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
1132
			$sharedWith = $this->groupManager->get($share->getSharedWith());
1133
			$user = $this->userManager->get($this->currentUser);
1134
			if ($user !== null && $sharedWith !== null && $sharedWith->inGroup($user)) {
1135
				return true;
1136
			}
1137
		}
1138
1139
		if ($share->getShareType() === Share::SHARE_TYPE_ROOM) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_ROOM has been deprecated: 17.0.0 - use IShare::TYPE_ROOM instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1139
		if ($share->getShareType() === /** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_ROOM) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
1140
			try {
1141
				return $this->getRoomShareHelper()->canAccessShare($share, $this->currentUser);
1142
			} catch (QueryException $e) {
1143
				return false;
1144
			}
1145
		}
1146
1147
		return false;
1148
	}
1149
1150
	/**
1151
	 * Make sure that the passed date is valid ISO 8601
1152
	 * So YYYY-MM-DD
1153
	 * If not throw an exception
1154
	 *
1155
	 * @param string $expireDate
1156
	 *
1157
	 * @throws \Exception
1158
	 * @return \DateTime
1159
	 */
1160
	private function parseDate(string $expireDate): \DateTime {
1161
		try {
1162
			$date = new \DateTime($expireDate);
1163
		} catch (\Exception $e) {
1164
			throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
1165
		}
1166
1167
		if ($date === false) {
0 ignored issues
show
introduced by
The condition $date === false is always false.
Loading history...
1168
			throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
1169
		}
1170
1171
		$date->setTime(0, 0, 0);
1172
1173
		return $date;
1174
	}
1175
1176
	/**
1177
	 * Since we have multiple providers but the OCS Share API v1 does
1178
	 * not support this we need to check all backends.
1179
	 *
1180
	 * @param string $id
1181
	 * @return \OCP\Share\IShare
1182
	 * @throws ShareNotFound
1183
	 */
1184
	private function getShareById(string $id): IShare {
1185
		$share = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $share is dead and can be removed.
Loading history...
1186
1187
		// First check if it is an internal share.
1188
		try {
1189
			$share = $this->shareManager->getShareById('ocinternal:' . $id, $this->currentUser);
1190
			return $share;
1191
		} catch (ShareNotFound $e) {
1192
			// Do nothing, just try the other share type
1193
		}
1194
1195
1196
		try {
1197
			if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_CIRCLE)) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_CIRCLE has been deprecated: 17.0.0 - use IShare::TYPE_CIRCLE instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1197
			if ($this->shareManager->shareProviderExists(/** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_CIRCLE)) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
1198
				$share = $this->shareManager->getShareById('ocCircleShare:' . $id, $this->currentUser);
1199
				return $share;
1200
			}
1201
		} catch (ShareNotFound $e) {
1202
			// Do nothing, just try the other share type
1203
		}
1204
1205
		try {
1206
			if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_EMAIL has been deprecated: 17.0.0 - use IShare::TYPE_EMAIL instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1206
			if ($this->shareManager->shareProviderExists(/** @scrutinizer ignore-deprecated */ Share::SHARE_TYPE_EMAIL)) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
1207
				$share = $this->shareManager->getShareById('ocMailShare:' . $id, $this->currentUser);
1208
				return $share;
1209
			}
1210
		} catch (ShareNotFound $e) {
1211
			// Do nothing, just try the other share type
1212
		}
1213
1214
		try {
1215
			$share = $this->shareManager->getShareById('ocRoomShare:' . $id, $this->currentUser);
1216
			return $share;
1217
		} catch (ShareNotFound $e) {
1218
			// Do nothing, just try the other share type
1219
		}
1220
1221
		if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
1222
			throw new ShareNotFound();
1223
		}
1224
		$share = $this->shareManager->getShareById('ocFederatedSharing:' . $id, $this->currentUser);
1225
1226
		return $share;
1227
	}
1228
1229
	/**
1230
	 * Lock a Node
1231
	 *
1232
	 * @param \OCP\Files\Node $node
1233
	 * @throws LockedException
1234
	 */
1235
	private function lock(\OCP\Files\Node $node) {
1236
		$node->lock(ILockingProvider::LOCK_SHARED);
1237
		$this->lockedNode = $node;
1238
	}
1239
1240
	/**
1241
	 * Cleanup the remaining locks
1242
	 * @throws @LockedException
1243
	 */
1244
	public function cleanup() {
1245
		if ($this->lockedNode !== null) {
1246
			$this->lockedNode->unlock(ILockingProvider::LOCK_SHARED);
1247
		}
1248
	}
1249
1250
	/**
1251
	 * Returns the helper of ShareAPIController for room shares.
1252
	 *
1253
	 * If the Talk application is not enabled or the helper is not available
1254
	 * a QueryException is thrown instead.
1255
	 *
1256
	 * @return \OCA\Talk\Share\Helper\ShareAPIController
0 ignored issues
show
Bug introduced by
The type OCA\Talk\Share\Helper\ShareAPIController was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
1257
	 * @throws QueryException
1258
	 */
1259
	private function getRoomShareHelper() {
1260
		if (!$this->appManager->isEnabledForUser('spreed')) {
1261
			throw new QueryException();
1262
		}
1263
1264
		return $this->serverContainer->query('\OCA\Talk\Share\Helper\ShareAPIController');
1265
	}
1266
1267
1268
	/**
1269
	 * Returns if we can find resharing rights in an IShare object for a specific user.
1270
	 *
1271
	 * @suppress PhanUndeclaredClassMethod
1272
	 *
1273
	 * @param string $userId
1274
	 * @param IShare $share
1275
	 * @param Node $node
1276
	 * @return bool
1277
	 * @throws NotFoundException
1278
	 * @throws \OCP\Files\InvalidPathException
1279
	 */
1280
	private function shareProviderResharingRights(string $userId, IShare $share, $node): bool {
1281
1282
		if ($share->getShareOwner() === $userId) {
1283
			return true;
1284
		}
1285
1286
		// we check that current user have parent resharing rights on the current file
1287
		if ($node !== null && ($node->getPermissions() & \OCP\Constants::PERMISSION_SHARE) !== 0) {
1288
			return true;
1289
		}
1290
1291
		if ((\OCP\Constants::PERMISSION_SHARE & $share->getPermissions()) === 0) {
1292
			return false;
1293
		}
1294
1295
		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER && $share->getSharedWith() === $userId) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_USER has been deprecated: 17.0.0 - use IShare::TYPE_USER instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1295
		if ($share->getShareType() === /** @scrutinizer ignore-deprecated */ \OCP\Share::SHARE_TYPE_USER && $share->getSharedWith() === $userId) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
1296
			return true;
1297
		}
1298
1299
		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP && $this->groupManager->isInGroup($userId, $share->getSharedWith())) {
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_GROUP has been deprecated: 17.0.0 - use IShare::TYPE_GROUP instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1299
		if ($share->getShareType() === /** @scrutinizer ignore-deprecated */ \OCP\Share::SHARE_TYPE_GROUP && $this->groupManager->isInGroup($userId, $share->getSharedWith())) {

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
1300
			return true;
1301
		}
1302
1303
		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_CIRCLE && \OC::$server->getAppManager()->isEnabledForUser('circles')
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_CIRCLE has been deprecated: 17.0.0 - use IShare::TYPE_CIRCLE instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1303
		if ($share->getShareType() === /** @scrutinizer ignore-deprecated */ \OCP\Share::SHARE_TYPE_CIRCLE && \OC::$server->getAppManager()->isEnabledForUser('circles')

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
1304
			&& class_exists('\OCA\Circles\Api\v1\Circles')) {
1305
1306
			$hasCircleId = (substr($share->getSharedWith(), -1) === ']');
1307
			$shareWithStart = ($hasCircleId ? strrpos($share->getSharedWith(), '[') + 1 : 0);
1308
			$shareWithLength = ($hasCircleId ? -1 : strpos($share->getSharedWith(), ' '));
1309
			if (is_bool($shareWithLength)) {
0 ignored issues
show
introduced by
The condition is_bool($shareWithLength) is always false.
Loading history...
1310
				$shareWithLength = -1;
1311
			}
1312
			$sharedWith = substr($share->getSharedWith(), $shareWithStart, $shareWithLength);
1313
			try {
1314
				$member = \OCA\Circles\Api\v1\Circles::getMember($sharedWith, $userId, 1);
1315
				if ($member->getLevel() >= 4) {
1316
					return true;
1317
				}
1318
				return false;
1319
			} catch (QueryException $e) {
1320
				return false;
1321
			}
1322
		}
1323
1324
		return false;
1325
	}
1326
1327
}
1328