Completed
Push — stable10 ( 482a72...d896d4 )
by Björn
35:56 queued 35:33
created

Share20OCS::canAccessShare()   D

Complexity

Conditions 9
Paths 6

Size

Total Lines 28
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 9
eloc 14
c 1
b 0
f 0
nc 6
nop 2
dl 0
loc 28
rs 4.909
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Joas Schilling <[email protected]>
6
 * @author Roeland Jago Douma <[email protected]>
7
 * @author Vincent Petry <[email protected]>
8
 *
9
 * @license AGPL-3.0
10
 *
11
 * This code is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU Affero General Public License, version 3,
13
 * as published by the Free Software Foundation.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
 * GNU Affero General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Affero General Public License, version 3,
21
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
22
 *
23
 */
24
namespace OCA\Files_Sharing\API;
25
26
use OCP\Files\NotFoundException;
27
use OCP\IGroupManager;
28
use OCP\IL10N;
29
use OCP\IUserManager;
30
use OCP\IRequest;
31
use OCP\IURLGenerator;
32
use OCP\IUser;
33
use OCP\Files\IRootFolder;
34
use OCP\Lock\LockedException;
35
use OCP\Share;
36
use OCP\Share\IManager;
37
use OCP\Share\Exceptions\ShareNotFound;
38
use OCP\Share\Exceptions\GenericShareException;
39
use OCP\Lock\ILockingProvider;
40
41
/**
42
 * Class Share20OCS
43
 *
44
 * @package OCA\Files_Sharing\API
45
 */
46
class Share20OCS {
47
48
	/** @var IManager */
49
	private $shareManager;
50
	/** @var IGroupManager */
51
	private $groupManager;
52
	/** @var IUserManager */
53
	private $userManager;
54
	/** @var IRequest */
55
	private $request;
56
	/** @var IRootFolder */
57
	private $rootFolder;
58
	/** @var IURLGenerator */
59
	private $urlGenerator;
60
	/** @var IUser */
61
	private $currentUser;
62
	/** @var IL10N */
63
	private $l;
64
65
	/**
66
	 * Share20OCS constructor.
67
	 *
68
	 * @param IManager $shareManager
69
	 * @param IGroupManager $groupManager
70
	 * @param IUserManager $userManager
71
	 * @param IRequest $request
72
	 * @param IRootFolder $rootFolder
73
	 * @param IURLGenerator $urlGenerator
74
	 * @param IUser $currentUser
75
	 */
76
	public function __construct(
77
			IManager $shareManager,
78
			IGroupManager $groupManager,
79
			IUserManager $userManager,
80
			IRequest $request,
81
			IRootFolder $rootFolder,
82
			IURLGenerator $urlGenerator,
83
			IUser $currentUser,
84
			IL10N $l10n
85
	) {
86
		$this->shareManager = $shareManager;
87
		$this->userManager = $userManager;
88
		$this->groupManager = $groupManager;
89
		$this->request = $request;
90
		$this->rootFolder = $rootFolder;
91
		$this->urlGenerator = $urlGenerator;
92
		$this->currentUser = $currentUser;
93
		$this->l = $l10n;
94
	}
95
96
	/**
97
	 * Convert an IShare to an array for OCS output
98
	 *
99
	 * @param \OCP\Share\IShare $share
100
	 * @return array
101
	 * @throws NotFoundException In case the node can't be resolved.
102
	 */
103
	protected function formatShare(\OCP\Share\IShare $share) {
104
		$sharedBy = $this->userManager->get($share->getSharedBy());
105
		$shareOwner = $this->userManager->get($share->getShareOwner());
106
107
		$result = [
108
			'id' => $share->getId(),
109
			'share_type' => $share->getShareType(),
110
			'uid_owner' => $share->getSharedBy(),
111
			'displayname_owner' => $sharedBy !== null ? $sharedBy->getDisplayName() : $share->getSharedBy(),
112
			'permissions' => $share->getPermissions(),
113
			'stime' => $share->getShareTime()->getTimestamp(),
114
			'parent' => null,
115
			'expiration' => null,
116
			'token' => null,
117
			'uid_file_owner' => $share->getShareOwner(),
118
			'displayname_file_owner' => $shareOwner !== null ? $shareOwner->getDisplayName() : $share->getShareOwner(),
119
		];
120
121
		$userFolder = $this->rootFolder->getUserFolder($this->currentUser->getUID());
122
		$nodes = $userFolder->getById($share->getNodeId());
123
124
		if (empty($nodes)) {
125
			throw new NotFoundException();
126
		}
127
128
		$node = $nodes[0];
129
130
		$result['path'] = $userFolder->getRelativePath($node->getPath());
131
		if ($node instanceOf \OCP\Files\Folder) {
132
			$result['item_type'] = 'folder';
133
		} else {
134
			$result['item_type'] = 'file';
135
		}
136
		$result['mimetype'] = $node->getMimeType();
137
		$result['storage_id'] = $node->getStorage()->getId();
138
		$result['storage'] = $node->getStorage()->getCache()->getNumericStorageId();
139
		$result['item_source'] = $node->getId();
140
		$result['file_source'] = $node->getId();
141
		$result['file_parent'] = $node->getParent()->getId();
142
		$result['file_target'] = $share->getTarget();
143
144
		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
145
			$sharedWith = $this->userManager->get($share->getSharedWith());
146
			$result['share_with'] = $share->getSharedWith();
147
			$result['share_with_displayname'] = $sharedWith !== null ? $sharedWith->getDisplayName() : $share->getSharedWith();
148
		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
149
			$result['share_with'] = $share->getSharedWith();
150
			$result['share_with_displayname'] = $share->getSharedWith();
151
		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
152
153
			$result['share_with'] = $share->getPassword();
154
			$result['share_with_displayname'] = $share->getPassword();
155
156
			$result['token'] = $share->getToken();
157
			$result['url'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $share->getToken()]);
158
159
			$expiration = $share->getExpirationDate();
160
			if ($expiration !== null) {
161
				$result['expiration'] = $expiration->format('Y-m-d 00:00:00');
162
			}
163
164
		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_REMOTE) {
165
			$result['share_with'] = $share->getSharedWith();
166
			$result['share_with_displayname'] = $share->getSharedWith();
167
			$result['token'] = $share->getToken();
168
		}
169
170
		$result['mail_send'] = $share->getMailSend() ? 1 : 0;
171
172
		return $result;
173
	}
174
175
	/**
176
	 * Get a specific share by id
177
	 *
178
	 * @param string $id
179
	 * @return \OC_OCS_Result
180
	 */
181
	public function getShare($id) {
182
		if (!$this->shareManager->shareApiEnabled()) {
183
			return new \OC_OCS_Result(null, 404, $this->l->t('Share API is disabled'));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
184
		}
185
186
		try {
187
			$share = $this->getShareById($id);
188
		} catch (ShareNotFound $e) {
189
			return new \OC_OCS_Result(null, 404, $this->l->t('Wrong share ID, share doesn\'t exist'));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
190
		}
191
192
		if ($this->canAccessShare($share)) {
193
			try {
194
				$share = $this->formatShare($share);
195
				return new \OC_OCS_Result([$share]);
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
196
			} catch (NotFoundException $e) {
197
				//Fall trough
198
			}
199
		}
200
201
		return new \OC_OCS_Result(null, 404, $this->l->t('Wrong share ID, share doesn\'t exist'));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
202
	}
203
204
	/**
205
	 * Delete a share
206
	 *
207
	 * @param string $id
208
	 * @return \OC_OCS_Result
209
	 */
210
	public function deleteShare($id) {
211
		if (!$this->shareManager->shareApiEnabled()) {
212
			return new \OC_OCS_Result(null, 404, $this->l->t('Share API is disabled'));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
213
		}
214
215
		try {
216
			$share = $this->getShareById($id);
217
		} catch (ShareNotFound $e) {
218
			return new \OC_OCS_Result(null, 404, $this->l->t('Wrong share ID, share doesn\'t exist'));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
219
		}
220
221
		try {
222
			$share->getNode()->lock(ILockingProvider::LOCK_SHARED);
223
		} catch (LockedException $e) {
224
			return new \OC_OCS_Result(null, 404, 'could not delete share');
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
225
		}
226
227 View Code Duplication
		if (!$this->canAccessShare($share, false)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
228
			$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
229
			return new \OC_OCS_Result(null, 404, $this->l->t('Could not delete share'));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
230
		}
231
232
		$this->shareManager->deleteShare($share);
233
234
		$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
235
236
		return new \OC_OCS_Result();
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
237
	}
238
239
	/**
240
	 * @return \OC_OCS_Result
241
	 */
242
	public function createShare() {
243
		$share = $this->shareManager->newShare();
244
245
		if (!$this->shareManager->shareApiEnabled()) {
246
			return new \OC_OCS_Result(null, 404, $this->l->t('Share API is disabled'));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
247
		}
248
249
		// Verify path
250
		$path = $this->request->getParam('path', null);
251
		if ($path === null) {
252
			return new \OC_OCS_Result(null, 404, $this->l->t('Please specify a file or folder path'));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
253
		}
254
255
		$userFolder = $this->rootFolder->getUserFolder($this->currentUser->getUID());
256
		try {
257
			$path = $userFolder->get($path);
258
		} catch (NotFoundException $e) {
259
			return new \OC_OCS_Result(null, 404, $this->l->t('Wrong path, file/folder doesn\'t exist'));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
260
		}
261
262
		$share->setNode($path);
263
264
		try {
265
			$share->getNode()->lock(ILockingProvider::LOCK_SHARED);
266
		} catch (LockedException $e) {
267
			return new \OC_OCS_Result(null, 404, 'Could not create share');
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
268
		}
269
270
		// Parse permissions (if available)
271
		$permissions = $this->request->getParam('permissions', null);
272
		if ($permissions === null) {
273
			$permissions = \OCP\Constants::PERMISSION_ALL;
274
		} else {
275
			$permissions = (int)$permissions;
276
		}
277
278
		if ($permissions < 0 || $permissions > \OCP\Constants::PERMISSION_ALL) {
279
			$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
280
			return new \OC_OCS_Result(null, 404, 'invalid permissions');
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
281
		}
282
283
		// Shares always require read permissions
284
		$permissions |= \OCP\Constants::PERMISSION_READ;
285
286
		if ($path instanceof \OCP\Files\File) {
287
			// Single file shares should never have delete or create permissions
288
			$permissions &= ~\OCP\Constants::PERMISSION_DELETE;
289
			$permissions &= ~\OCP\Constants::PERMISSION_CREATE;
290
		}
291
292
		/*
293
		 * Hack for https://github.com/owncloud/core/issues/22587
294
		 * We check the permissions via webdav. But the permissions of the mount point
295
		 * do not equal the share permissions. Here we fix that for federated mounts.
296
		 */
297
		if ($path->getStorage()->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
298
			$permissions &= ~($permissions & ~$path->getPermissions());
299
		}
300
301
		$shareWith = $this->request->getParam('shareWith', null);
302
		$shareType = (int)$this->request->getParam('shareType', '-1');
303
304
		if ($shareType === \OCP\Share::SHARE_TYPE_USER) {
305
			// Valid user is required to share
306 View Code Duplication
			if ($shareWith === null || !$this->userManager->userExists($shareWith)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
307
				$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
308
				return new \OC_OCS_Result(null, 404, $this->l->t('Please specify a valid user'));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
309
			}
310
			$share->setSharedWith($shareWith);
311
			$share->setPermissions($permissions);
312
		} else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) {
313 View Code Duplication
			if (!$this->shareManager->allowGroupSharing()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
314
				$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
315
				return new \OC_OCS_Result(null, 404, $this->l->t('Group sharing is disabled by the administrator'));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
316
			}
317
318
			// Valid group is required to share
319 View Code Duplication
			if ($shareWith === null || !$this->groupManager->groupExists($shareWith)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
320
				$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
321
				return new \OC_OCS_Result(null, 404, $this->l->t('Please specify a valid group'));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
322
			}
323
			$share->setSharedWith($shareWith);
324
			$share->setPermissions($permissions);
325
		} else if ($shareType === \OCP\Share::SHARE_TYPE_LINK) {
326
			//Can we even share links?
327 View Code Duplication
			if (!$this->shareManager->shareApiAllowLinks()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
328
				$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
329
				return new \OC_OCS_Result(null, 404, $this->l->t('Public link sharing is disabled by the administrator'));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
330
			}
331
332
			/*
333
			 * For now we only allow 1 link share.
334
			 * Return the existing link share if this is a duplicate
335
			 */
336
			$existingShares = $this->shareManager->getSharesBy($this->currentUser->getUID(), \OCP\Share::SHARE_TYPE_LINK, $path, false, 1, 0);
337
			if (!empty($existingShares)) {
338
				$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
339
				return new \OC_OCS_Result($this->formatShare($existingShares[0]));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
340
			}
341
342
			$publicUpload = $this->request->getParam('publicUpload', null);
343
			if ($publicUpload === 'true') {
344
				// Check if public upload is allowed
345 View Code Duplication
				if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
346
					$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
347
					return new \OC_OCS_Result(null, 403, $this->l->t('Public upload disabled by the administrator'));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
348
				}
349
350
				// Public upload can only be set for folders
351 View Code Duplication
				if ($path instanceof \OCP\Files\File) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
352
					$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
353
					return new \OC_OCS_Result(null, 404, $this->l->t('Public upload is only possible for publicly shared folders'));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
354
				}
355
356
				$share->setPermissions(
357
					\OCP\Constants::PERMISSION_READ |
358
					\OCP\Constants::PERMISSION_CREATE |
359
					\OCP\Constants::PERMISSION_UPDATE |
360
					\OCP\Constants::PERMISSION_DELETE
361
				);
362
			} else {
363
				$share->setPermissions(\OCP\Constants::PERMISSION_READ);
364
			}
365
366
			// Set password
367
			$password = $this->request->getParam('password', '');
368
369
			if ($password !== '') {
370
				$share->setPassword($password);
371
			}
372
373
			//Expire date
374
			$expireDate = $this->request->getParam('expireDate', '');
375
376 View Code Duplication
			if ($expireDate !== '') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
377
				try {
378
					$expireDate = $this->parseDate($expireDate);
379
					$share->setExpirationDate($expireDate);
380
				} catch (\Exception $e) {
381
					$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
382
					return new \OC_OCS_Result(null, 404, $this->l->t('Invalid date, date format must be YYYY-MM-DD'));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
383
				}
384
			}
385
386
		} else if ($shareType === \OCP\Share::SHARE_TYPE_REMOTE) {
387
			if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
388
				$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
389
				return new \OC_OCS_Result(null, 403, $this->l->t('Sharing %s failed because the back end does not allow shares from type %s', [$path->getPath(), $shareType]));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
390
			}
391
392
			$share->setSharedWith($shareWith);
393
			$share->setPermissions($permissions);
394 View Code Duplication
		} else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
395
			$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
396
			return new \OC_OCS_Result(null, 400, $this->l->t('Unknown share type'));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
397
		}
398
399
		$share->setShareType($shareType);
400
		$share->setSharedBy($this->currentUser->getUID());
401
402
		try {
403
			$share = $this->shareManager->createShare($share);
404
		} catch (GenericShareException $e) {
405
			$code = $e->getCode() === 0 ? 403 : $e->getCode();
406
			$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
407
			return new \OC_OCS_Result(null, $code, $e->getHint());
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
408
		}catch (\Exception $e) {
409
			$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
410
			return new \OC_OCS_Result(null, 403, $e->getMessage());
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
411
		}
412
413
		$output = $this->formatShare($share);
414
415
		$share->getNode()->unlock(\OCP\Lock\ILockingProvider::LOCK_SHARED);
416
417
		return new \OC_OCS_Result($output);
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
418
	}
419
420
	/**
421
	 * @param \OCP\Files\File|\OCP\Files\Folder $node
422
	 * @return \OC_OCS_Result
423
	 */
424
	private function getSharedWithMe($node = null) {
425
		$userShares = $this->shareManager->getSharedWith($this->currentUser->getUID(), \OCP\Share::SHARE_TYPE_USER, $node, -1, 0);
426
		$groupShares = $this->shareManager->getSharedWith($this->currentUser->getUID(), \OCP\Share::SHARE_TYPE_GROUP, $node, -1, 0);
427
428
		$shares = array_merge($userShares, $groupShares);
429
430
		$formatted = [];
431
		foreach ($shares as $share) {
432
			if ($this->canAccessShare($share)) {
433
				try {
434
					$formatted[] = $this->formatShare($share);
435
				} catch (NotFoundException $e) {
436
					// Ignore this share
437
				}
438
			}
439
		}
440
441
		return new \OC_OCS_Result($formatted);
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
442
	}
443
444
	/**
445
	 * @param \OCP\Files\Folder $folder
446
	 * @return \OC_OCS_Result
447
	 */
448
	private function getSharesInDir($folder) {
449
		if (!($folder instanceof \OCP\Files\Folder)) {
450
			return new \OC_OCS_Result(null, 400, $this->l->t('Not a directory'));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
451
		}
452
453
		$nodes = $folder->getDirectoryListing();
454
		/** @var \OCP\Share\IShare[] $shares */
455
		$shares = [];
456
		foreach ($nodes as $node) {
457
			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser->getUID(), \OCP\Share::SHARE_TYPE_USER, $node, false, -1, 0));
458
			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser->getUID(), \OCP\Share::SHARE_TYPE_GROUP, $node, false, -1, 0));
459
			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser->getUID(), \OCP\Share::SHARE_TYPE_LINK, $node, false, -1, 0));
460
			if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
461
				$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser->getUID(), \OCP\Share::SHARE_TYPE_REMOTE, $node, false, -1, 0));
462
			}
463
		}
464
465
		$formatted = [];
466
		foreach ($shares as $share) {
467
			try {
468
				$formatted[] = $this->formatShare($share);
469
			} catch (NotFoundException $e) {
470
				//Ignore this share
471
			}
472
		}
473
474
		return new \OC_OCS_Result($formatted);
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
475
	}
476
477
	/**
478
	 * The getShares function.
479
	 *
480
	 * - Get shares by the current user
481
	 * - Get shares by the current user and reshares (?reshares=true)
482
	 * - Get shares with the current user (?shared_with_me=true)
483
	 * - Get shares for a specific path (?path=...)
484
	 * - Get all shares in a folder (?subfiles=true&path=..)
485
	 *
486
	 * @return \OC_OCS_Result
487
	 */
488
	public function getShares() {
489
		if (!$this->shareManager->shareApiEnabled()) {
490
			return new \OC_OCS_Result();
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
491
		}
492
493
		$sharedWithMe = $this->request->getParam('shared_with_me', null);
494
		$reshares = $this->request->getParam('reshares', null);
495
		$subfiles = $this->request->getParam('subfiles');
496
		$path = $this->request->getParam('path', null);
497
498
		if ($path !== null) {
499
			$userFolder = $this->rootFolder->getUserFolder($this->currentUser->getUID());
500
			try {
501
				$path = $userFolder->get($path);
502
				$path->lock(ILockingProvider::LOCK_SHARED);
503
			} catch (\OCP\Files\NotFoundException $e) {
504
				return new \OC_OCS_Result(null, 404, $this->l->t('Wrong path, file/folder doesn\'t exist'));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
505
			} catch (LockedException $e) {
506
				return new \OC_OCS_Result(null, 404, $this->l->t('Could not lock path'));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
507
			}
508
		}
509
510
		if ($sharedWithMe === 'true') {
511
			$result = $this->getSharedWithMe($path);
0 ignored issues
show
Bug introduced by
It seems like $path can also be of type object<OCP\Files\Node>; however, OCA\Files_Sharing\API\Sh...0OCS::getSharedWithMe() does only seem to accept object<OCP\Files\File>|o...<OCP\Files\Folder>|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
512
			if ($path !== null) {
513
				$path->unlock(ILockingProvider::LOCK_SHARED);
514
			}
515
			return $result;
516
		}
517
518
		if ($subfiles === 'true') {
519
			$result = $this->getSharesInDir($path);
0 ignored issues
show
Documentation introduced by
$path is of type object<OCP\Files\Node>|null, but the function expects a object<OCP\Files\Folder>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
520
			if ($path !== null) {
521
				$path->unlock(ILockingProvider::LOCK_SHARED);
522
			}
523
			return $result;
524
		}
525
526
		if ($reshares === 'true') {
527
			$reshares = true;
528
		} else {
529
			$reshares = false;
530
		}
531
532
		// Get all shares
533
		$userShares = $this->shareManager->getSharesBy($this->currentUser->getUID(), \OCP\Share::SHARE_TYPE_USER, $path, $reshares, -1, 0);
534
		$groupShares = $this->shareManager->getSharesBy($this->currentUser->getUID(), \OCP\Share::SHARE_TYPE_GROUP, $path, $reshares, -1, 0);
535
		$linkShares = $this->shareManager->getSharesBy($this->currentUser->getUID(), \OCP\Share::SHARE_TYPE_LINK, $path, $reshares, -1, 0);
536
		$shares = array_merge($userShares, $groupShares, $linkShares);
537
538
		if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
539
			$federatedShares = $this->shareManager->getSharesBy($this->currentUser->getUID(), \OCP\Share::SHARE_TYPE_REMOTE, $path, $reshares, -1, 0);
540
			$shares = array_merge($shares, $federatedShares);
541
		}
542
543
		$formatted = [];
544
		foreach ($shares as $share) {
545
			try {
546
				$formatted[] = $this->formatShare($share);
547
			} catch (NotFoundException $e) {
548
				//Ignore share
549
			}
550
		}
551
552
		if ($path !== null) {
553
			$path->unlock(ILockingProvider::LOCK_SHARED);
554
		}
555
556
		return new \OC_OCS_Result($formatted);
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
557
	}
558
559
	/**
560
	 * @param int $id
561
	 * @return \OC_OCS_Result
562
	 */
563
	public function updateShare($id) {
564
		if (!$this->shareManager->shareApiEnabled()) {
565
			return new \OC_OCS_Result(null, 404, $this->l->t('Share API is disabled'));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
566
		}
567
568
		try {
569
			$share = $this->getShareById($id);
570
		} catch (ShareNotFound $e) {
571
			return new \OC_OCS_Result(null, 404, $this->l->t('Wrong share ID, share doesn\'t exist'));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
572
		}
573
574
		$share->getNode()->lock(\OCP\Lock\ILockingProvider::LOCK_SHARED);
575
576 View Code Duplication
		if (!$this->canAccessShare($share, false)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
577
			$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
578
			return new \OC_OCS_Result(null, 404, $this->l->t('Wrong share ID, share doesn\'t exist'));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
579
		}
580
581
		$permissions = $this->request->getParam('permissions', null);
582
		$password = $this->request->getParam('password', null);
583
		$publicUpload = $this->request->getParam('publicUpload', null);
584
		$expireDate = $this->request->getParam('expireDate', null);
585
586
		/*
587
		 * expirationdate, password and publicUpload only make sense for link shares
588
		 */
589
		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
590
			if ($permissions === null && $password === null && $publicUpload === null && $expireDate === null) {
591
				$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
592
				return new \OC_OCS_Result(null, 400, 'Wrong or no update parameter given');
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
593
			}
594
595
			$newPermissions = null;
596
			if ($publicUpload === 'true') {
597
				$newPermissions = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE;
598
			} else if ($publicUpload === 'false') {
599
				$newPermissions = \OCP\Constants::PERMISSION_READ;
600
			}
601
602
			if ($permissions !== null) {
603
				$newPermissions = (int)$permissions;
604
			}
605
606
			if ($newPermissions !== null &&
607
				!in_array($newPermissions, [
608
					\OCP\Constants::PERMISSION_READ,
609
					\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE, // legacy
610
					\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE, // correct
611
					\OCP\Constants::PERMISSION_CREATE, // hidden file list
612
				])
613
			) {
614
				$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
615
				return new \OC_OCS_Result(null, 400, $this->l->t('Can\'t change permissions for public share links'));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
616
			}
617
618
			if (
619
				// legacy
620
				$newPermissions === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE) ||
621
				// correct
622
				$newPermissions === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE)
623
			) {
624 View Code Duplication
				if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
625
					$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
626
					return new \OC_OCS_Result(null, 403, $this->l->t('Public upload disabled by the administrator'));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
627
				}
628
629 View Code Duplication
				if (!($share->getNode() instanceof \OCP\Files\Folder)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
630
					$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
631
					return new \OC_OCS_Result(null, 400, $this->l->t('Public upload is only possible for publicly shared folders'));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
632
				}
633
634
				// normalize to correct public upload permissions
635
				$newPermissions = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE;
636
			}
637
638
			if ($newPermissions !== null) {
639
				$share->setPermissions($newPermissions);
640
			}
641
642
			if ($expireDate === '') {
643
				$share->setExpirationDate(null);
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a object<DateTime>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
644 View Code Duplication
			} else if ($expireDate !== null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
645
				try {
646
					$expireDate = $this->parseDate($expireDate);
647
				} catch (\Exception $e) {
648
					$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
649
					return new \OC_OCS_Result(null, 400, $e->getMessage());
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
650
				}
651
				$share->setExpirationDate($expireDate);
652
			}
653
654
			if ($password === '') {
655
				$share->setPassword(null);
656
			} else if ($password !== null) {
657
				$share->setPassword($password);
658
			}
659
660
		} else {
661
			// For other shares only permissions is valid.
662
			if ($permissions === null) {
663
				$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
664
				return new \OC_OCS_Result(null, 400, $this->l->t('Wrong or no update parameter given'));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
665
			} else {
666
				$permissions = (int)$permissions;
667
				$share->setPermissions($permissions);
668
			}
669
		}
670
671
		if ($permissions !== null) {
672
			/* Check if this is an incomming share */
673
			$incomingShares = $this->shareManager->getSharedWith($this->currentUser->getUID(), \OCP\Share::SHARE_TYPE_USER, $share->getNode(), -1, 0);
674
			$incomingShares = array_merge($incomingShares, $this->shareManager->getSharedWith($this->currentUser->getUID(), \OCP\Share::SHARE_TYPE_GROUP, $share->getNode(), -1, 0));
675
676
			if (!empty($incomingShares)) {
677
				$maxPermissions = 0;
678
				foreach ($incomingShares as $incomingShare) {
679
					$maxPermissions |= $incomingShare->getPermissions();
680
				}
681
682 View Code Duplication
				if ($share->getPermissions() & ~$maxPermissions) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
683
					$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
684
					return new \OC_OCS_Result(null, 404, $this->l->t('Cannot increase permissions'));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
685
				}
686
			}
687
		}
688
689
690
		try {
691
			$share = $this->shareManager->updateShare($share);
692
		} catch (\Exception $e) {
693
			$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
694
			return new \OC_OCS_Result(null, 400, $e->getMessage());
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
695
		}
696
697
		$share->getNode()->unlock(\OCP\Lock\ILockingProvider::LOCK_SHARED);
698
699
		return new \OC_OCS_Result($this->formatShare($share));
0 ignored issues
show
Deprecated Code introduced by
The class OC_OCS_Result has been deprecated with message: Since 9.1.0 use \OC\OCS\Result

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

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

Loading history...
700
	}
701
702
	/**
703
	 * @param \OCP\Share\IShare $share
704
	 * @return bool
705
	 */
706
	protected function canAccessShare(\OCP\Share\IShare $share, $checkGroups = true) {
707
		// A file with permissions 0 can't be accessed by us. So Don't show it
708
		if ($share->getPermissions() === 0) {
709
			return false;
710
		}
711
712
		// Owner of the file and the sharer of the file can always get share
713
		if ($share->getShareOwner() === $this->currentUser->getUID() ||
714
			$share->getSharedBy() === $this->currentUser->getUID()
715
		) {
716
			return true;
717
		}
718
719
		// If the share is shared with you (or a group you are a member of)
720
		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
721
			$share->getSharedWith() === $this->currentUser->getUID()) {
722
			return true;
723
		}
724
725
		if ($checkGroups && $share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
726
			$sharedWith = $this->groupManager->get($share->getSharedWith());
727
			if ($sharedWith->inGroup($this->currentUser)) {
728
				return true;
729
			}
730
		}
731
732
		return false;
733
	}
734
735
	/**
736
	 * Make sure that the passed date is valid ISO 8601
737
	 * So YYYY-MM-DD
738
	 * If not throw an exception
739
	 *
740
	 * @param string $expireDate
741
	 *
742
	 * @throws \Exception
743
	 * @return \DateTime
744
	 */
745
	private function parseDate($expireDate) {
746
		try {
747
			$date = new \DateTime($expireDate);
748
		} catch (\Exception $e) {
749
			throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
750
		}
751
752
		if ($date === false) {
753
			throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
754
		}
755
756
		$date->setTime(0,0,0);
757
758
		return $date;
759
	}
760
761
	/**
762
	 * Since we have multiple providers but the OCS Share API v1 does
763
	 * not support this we need to check all backends.
764
	 *
765
	 * @param string $id
766
	 * @return \OCP\Share\IShare
767
	 * @throws ShareNotFound
768
	 */
769
	private function getShareById($id) {
770
		$share = null;
771
772
		// First check if it is an internal share.
773
		try {
774
			$share = $this->shareManager->getShareById('ocinternal:'.$id);
775
		} catch (ShareNotFound $e) {
776
			if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
777
				throw new ShareNotFound();
778
			}
779
780
			$share = $this->shareManager->getShareById('ocFederatedSharing:' . $id);
781
		}
782
783
		return $share;
784
	}
785
}
786