Completed
Pull Request — master (#3813)
by Maxence
20:55 queued 09:41
created
apps/files_sharing/lib/Controller/ShareAPIController.php 2 patches
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -215,7 +215,7 @@  discard block
 block discarded – undo
215 215
 		// FIXME: If we inject the contacts manager it gets initialized bofore any address books are registered
216 216
 		$result = \OC::$server->getContactsManager()->search($query, [$property]);
217 217
 		foreach ($result as $r) {
218
-			foreach($r[$property] as $value) {
218
+			foreach ($r[$property] as $value) {
219 219
 				if ($value === $query) {
220 220
 					return $r['FN'];
221 221
 				}
@@ -490,7 +490,7 @@  discard block
 block discarded – undo
490 490
 
491 491
 		$shares = array_merge($userShares, $groupShares, $circleShares);
492 492
 
493
-		$shares = array_filter($shares, function (IShare $share) {
493
+		$shares = array_filter($shares, function(IShare $share) {
494 494
 			return $share->getShareOwner() !== $this->currentUser;
495 495
 		});
496 496
 
@@ -525,7 +525,7 @@  discard block
 block discarded – undo
525 525
 			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $node, false, -1, 0));
526 526
 			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $node, false, -1, 0));
527 527
 			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_LINK, $node, false, -1, 0));
528
-			if($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
528
+			if ($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
529 529
 				$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_EMAIL, $node, false, -1, 0));
530 530
 			}
531 531
 			if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
@@ -682,7 +682,7 @@  discard block
 block discarded – undo
682 682
 			}
683 683
 
684 684
 			if ($permissions !== null) {
685
-				$newPermissions = (int)$permissions;
685
+				$newPermissions = (int) $permissions;
686 686
 			}
687 687
 
688 688
 			if ($newPermissions !== null &&
@@ -742,7 +742,7 @@  discard block
 block discarded – undo
742 742
 			if ($permissions === null) {
743 743
 				throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given'));
744 744
 			} else {
745
-				$permissions = (int)$permissions;
745
+				$permissions = (int) $permissions;
746 746
 				$share->setPermissions($permissions);
747 747
 			}
748 748
 		}
@@ -849,7 +849,7 @@  discard block
 block discarded – undo
849 849
 
850 850
 		// First check if it is an internal share.
851 851
 		try {
852
-			$share = $this->shareManager->getShareById('ocinternal:' . $id);
852
+			$share = $this->shareManager->getShareById('ocinternal:'.$id);
853 853
 			return $share;
854 854
 		} catch (ShareNotFound $e) {
855 855
 			// Do nothing, just try the other share type
@@ -858,7 +858,7 @@  discard block
 block discarded – undo
858 858
 
859 859
 		try {
860 860
 			if ($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_CIRCLE)) {
861
-				$share = $this->shareManager->getShareById('ocCircleShare:' . $id);
861
+				$share = $this->shareManager->getShareById('ocCircleShare:'.$id);
862 862
 				return $share;
863 863
 			}
864 864
 		} catch (ShareNotFound $e) {
@@ -867,7 +867,7 @@  discard block
 block discarded – undo
867 867
 
868 868
 		try {
869 869
 			if ($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
870
-				$share = $this->shareManager->getShareById('ocMailShare:' . $id);
870
+				$share = $this->shareManager->getShareById('ocMailShare:'.$id);
871 871
 				return $share;
872 872
 			}
873 873
 		} catch (ShareNotFound $e) {
@@ -877,7 +877,7 @@  discard block
 block discarded – undo
877 877
 		if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
878 878
 			throw new ShareNotFound();
879 879
 		}
880
-		$share = $this->shareManager->getShareById('ocFederatedSharing:' . $id);
880
+		$share = $this->shareManager->getShareById('ocFederatedSharing:'.$id);
881 881
 
882 882
 		return $share;
883 883
 	}
Please login to merge, or discard this patch.
Indentation   +847 added lines, -847 removed lines patch added patch discarded remove patch
@@ -51,860 +51,860 @@
 block discarded – undo
51 51
  */
52 52
 class ShareAPIController extends OCSController {
53 53
 
54
-	/** @var IManager */
55
-	private $shareManager;
56
-	/** @var IGroupManager */
57
-	private $groupManager;
58
-	/** @var IUserManager */
59
-	private $userManager;
60
-	/** @var IRequest */
61
-	protected $request;
62
-	/** @var IRootFolder */
63
-	private $rootFolder;
64
-	/** @var IURLGenerator */
65
-	private $urlGenerator;
66
-	/** @var string */
67
-	private $currentUser;
68
-	/** @var IL10N */
69
-	private $l;
70
-	/** @var \OCP\Files\Node */
71
-	private $lockedNode;
72
-
73
-	/**
74
-	 * Share20OCS constructor.
75
-	 *
76
-	 * @param string $appName
77
-	 * @param IRequest $request
78
-	 * @param IManager $shareManager
79
-	 * @param IGroupManager $groupManager
80
-	 * @param IUserManager $userManager
81
-	 * @param IRootFolder $rootFolder
82
-	 * @param IURLGenerator $urlGenerator
83
-	 * @param string $userId
84
-	 * @param IL10N $l10n
85
-	 */
86
-	public function __construct(
87
-		$appName,
88
-		IRequest $request,
89
-		IManager $shareManager,
90
-		IGroupManager $groupManager,
91
-		IUserManager $userManager,
92
-		IRootFolder $rootFolder,
93
-		IURLGenerator $urlGenerator,
94
-		$userId,
95
-		IL10N $l10n
96
-	) {
97
-		parent::__construct($appName, $request);
98
-
99
-		$this->shareManager = $shareManager;
100
-		$this->userManager = $userManager;
101
-		$this->groupManager = $groupManager;
102
-		$this->request = $request;
103
-		$this->rootFolder = $rootFolder;
104
-		$this->urlGenerator = $urlGenerator;
105
-		$this->currentUser = $userId;
106
-		$this->l = $l10n;
107
-	}
108
-
109
-	/**
110
-	 * Convert an IShare to an array for OCS output
111
-	 *
112
-	 * @param \OCP\Share\IShare $share
113
-	 * @param Node|null $recipientNode
114
-	 * @return array
115
-	 * @throws NotFoundException In case the node can't be resolved.
116
-	 */
117
-	protected function formatShare(\OCP\Share\IShare $share, Node $recipientNode = null) {
118
-		$sharedBy = $this->userManager->get($share->getSharedBy());
119
-		$shareOwner = $this->userManager->get($share->getShareOwner());
120
-
121
-		$result = [
122
-			'id' => $share->getId(),
123
-			'share_type' => $share->getShareType(),
124
-			'uid_owner' => $share->getSharedBy(),
125
-			'displayname_owner' => $sharedBy !== null ? $sharedBy->getDisplayName() : $share->getSharedBy(),
126
-			'permissions' => $share->getPermissions(),
127
-			'stime' => $share->getShareTime()->getTimestamp(),
128
-			'parent' => null,
129
-			'expiration' => null,
130
-			'token' => null,
131
-			'uid_file_owner' => $share->getShareOwner(),
132
-			'displayname_file_owner' => $shareOwner !== null ? $shareOwner->getDisplayName() : $share->getShareOwner(),
133
-		];
134
-
135
-		$userFolder = $this->rootFolder->getUserFolder($this->currentUser);
136
-		if ($recipientNode) {
137
-			$node = $recipientNode;
138
-		} else {
139
-			$nodes = $userFolder->getById($share->getNodeId());
140
-
141
-			if (empty($nodes)) {
142
-				// fallback to guessing the path
143
-				$node = $userFolder->get($share->getTarget());
144
-				if ($node === null) {
145
-					throw new NotFoundException();
146
-				}
147
-			} else {
148
-				$node = $nodes[0];
149
-			}
150
-		}
151
-
152
-		$result['path'] = $userFolder->getRelativePath($node->getPath());
153
-		if ($node instanceOf \OCP\Files\Folder) {
154
-			$result['item_type'] = 'folder';
155
-		} else {
156
-			$result['item_type'] = 'file';
157
-		}
158
-		$result['mimetype'] = $node->getMimetype();
159
-		$result['storage_id'] = $node->getStorage()->getId();
160
-		$result['storage'] = $node->getStorage()->getCache()->getNumericStorageId();
161
-		$result['item_source'] = $node->getId();
162
-		$result['file_source'] = $node->getId();
163
-		$result['file_parent'] = $node->getParent()->getId();
164
-		$result['file_target'] = $share->getTarget();
165
-
166
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
167
-			$sharedWith = $this->userManager->get($share->getSharedWith());
168
-			$result['share_with'] = $share->getSharedWith();
169
-			$result['share_with_displayname'] = $sharedWith !== null ? $sharedWith->getDisplayName() : $share->getSharedWith();
170
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
171
-			$group = $this->groupManager->get($share->getSharedWith());
172
-			$result['share_with'] = $share->getSharedWith();
173
-			$result['share_with_displayname'] = $group !== null ? $group->getDisplayName() : $share->getSharedWith();
174
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
175
-
176
-			$result['share_with'] = $share->getPassword();
177
-			$result['share_with_displayname'] = $share->getPassword();
178
-
179
-			$result['token'] = $share->getToken();
180
-			$result['url'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $share->getToken()]);
181
-
182
-			$expiration = $share->getExpirationDate();
183
-			if ($expiration !== null) {
184
-				$result['expiration'] = $expiration->format('Y-m-d 00:00:00');
185
-			}
186
-
187
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_REMOTE) {
188
-			$result['share_with'] = $share->getSharedWith();
189
-			$result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'CLOUD');
190
-			$result['token'] = $share->getToken();
191
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
192
-			$result['share_with'] = $share->getSharedWith();
193
-			$result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'EMAIL');
194
-			$result['token'] = $share->getToken();
195
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_CIRCLE) {
196
-			$result['share_with_displayname'] = $share->getSharedWith();
197
-			$result['share_with'] = explode(' ', $share->getSharedWith(), 2)[0];
198
-		}
199
-
200
-
201
-		$result['mail_send'] = $share->getMailSend() ? 1 : 0;
202
-
203
-		return $result;
204
-	}
205
-
206
-	/**
207
-	 * Check if one of the users address books knows the exact property, if
208
-	 * yes we return the full name.
209
-	 *
210
-	 * @param string $query
211
-	 * @param string $property
212
-	 * @return string
213
-	 */
214
-	private function getDisplayNameFromAddressBook($query, $property) {
215
-		// FIXME: If we inject the contacts manager it gets initialized bofore any address books are registered
216
-		$result = \OC::$server->getContactsManager()->search($query, [$property]);
217
-		foreach ($result as $r) {
218
-			foreach($r[$property] as $value) {
219
-				if ($value === $query) {
220
-					return $r['FN'];
221
-				}
222
-			}
223
-		}
224
-
225
-		return $query;
226
-	}
227
-
228
-	/**
229
-	 * Get a specific share by id
230
-	 *
231
-	 * @NoAdminRequired
232
-	 *
233
-	 * @param string $id
234
-	 * @return DataResponse
235
-	 * @throws OCSNotFoundException
236
-	 */
237
-	public function getShare($id) {
238
-		try {
239
-			$share = $this->getShareById($id);
240
-		} catch (ShareNotFound $e) {
241
-			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
242
-		}
243
-
244
-		if ($this->canAccessShare($share)) {
245
-			try {
246
-				$share = $this->formatShare($share);
247
-				return new DataResponse([$share]);
248
-			} catch (NotFoundException $e) {
249
-				//Fall trough
250
-			}
251
-		}
252
-
253
-		throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
254
-	}
255
-
256
-	/**
257
-	 * Delete a share
258
-	 *
259
-	 * @NoAdminRequired
260
-	 *
261
-	 * @param string $id
262
-	 * @return DataResponse
263
-	 * @throws OCSNotFoundException
264
-	 */
265
-	public function deleteShare($id) {
266
-		try {
267
-			$share = $this->getShareById($id);
268
-		} catch (ShareNotFound $e) {
269
-			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
270
-		}
271
-
272
-		try {
273
-			$this->lock($share->getNode());
274
-		} catch (LockedException $e) {
275
-			throw new OCSNotFoundException($this->l->t('could not delete share'));
276
-		}
277
-
278
-		if (!$this->canAccessShare($share)) {
279
-			throw new OCSNotFoundException($this->l->t('Could not delete share'));
280
-		}
281
-
282
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP &&
283
-			$share->getShareOwner() !== $this->currentUser &&
284
-			$share->getSharedBy() !== $this->currentUser) {
285
-			$this->shareManager->deleteFromSelf($share, $this->currentUser);
286
-		} else {
287
-			$this->shareManager->deleteShare($share);
288
-		}
289
-
290
-		return new DataResponse();
291
-	}
292
-
293
-	/**
294
-	 * @NoAdminRequired
295
-	 *
296
-	 * @param string $path
297
-	 * @param int $permissions
298
-	 * @param int $shareType
299
-	 * @param string $shareWith
300
-	 * @param string $publicUpload
301
-	 * @param string $password
302
-	 * @param string $expireDate
303
-	 *
304
-	 * @return DataResponse
305
-	 * @throws OCSNotFoundException
306
-	 * @throws OCSForbiddenException
307
-	 * @throws OCSBadRequestException
308
-	 * @throws OCSException
309
-	 */
310
-	public function createShare(
311
-		$path = null,
312
-		$permissions = \OCP\Constants::PERMISSION_ALL,
313
-		$shareType = -1,
314
-		$shareWith = null,
315
-		$publicUpload = 'false',
316
-		$password = '',
317
-		$expireDate = ''
318
-	) {
319
-		$share = $this->shareManager->newShare();
320
-
321
-		// Verify path
322
-		if ($path === null) {
323
-			throw new OCSNotFoundException($this->l->t('Please specify a file or folder path'));
324
-		}
325
-
326
-		$userFolder = $this->rootFolder->getUserFolder($this->currentUser);
327
-		try {
328
-			$path = $userFolder->get($path);
329
-		} catch (NotFoundException $e) {
330
-			throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
331
-		}
332
-
333
-		$share->setNode($path);
334
-
335
-		try {
336
-			$this->lock($share->getNode());
337
-		} catch (LockedException $e) {
338
-			throw new OCSNotFoundException($this->l->t('Could not create share'));
339
-		}
340
-
341
-		if ($permissions < 0 || $permissions > \OCP\Constants::PERMISSION_ALL) {
342
-			throw new OCSNotFoundException($this->l->t('invalid permissions'));
343
-		}
344
-
345
-		// Shares always require read permissions
346
-		$permissions |= \OCP\Constants::PERMISSION_READ;
347
-
348
-		if ($path instanceof \OCP\Files\File) {
349
-			// Single file shares should never have delete or create permissions
350
-			$permissions &= ~\OCP\Constants::PERMISSION_DELETE;
351
-			$permissions &= ~\OCP\Constants::PERMISSION_CREATE;
352
-		}
353
-
354
-		/*
54
+    /** @var IManager */
55
+    private $shareManager;
56
+    /** @var IGroupManager */
57
+    private $groupManager;
58
+    /** @var IUserManager */
59
+    private $userManager;
60
+    /** @var IRequest */
61
+    protected $request;
62
+    /** @var IRootFolder */
63
+    private $rootFolder;
64
+    /** @var IURLGenerator */
65
+    private $urlGenerator;
66
+    /** @var string */
67
+    private $currentUser;
68
+    /** @var IL10N */
69
+    private $l;
70
+    /** @var \OCP\Files\Node */
71
+    private $lockedNode;
72
+
73
+    /**
74
+     * Share20OCS constructor.
75
+     *
76
+     * @param string $appName
77
+     * @param IRequest $request
78
+     * @param IManager $shareManager
79
+     * @param IGroupManager $groupManager
80
+     * @param IUserManager $userManager
81
+     * @param IRootFolder $rootFolder
82
+     * @param IURLGenerator $urlGenerator
83
+     * @param string $userId
84
+     * @param IL10N $l10n
85
+     */
86
+    public function __construct(
87
+        $appName,
88
+        IRequest $request,
89
+        IManager $shareManager,
90
+        IGroupManager $groupManager,
91
+        IUserManager $userManager,
92
+        IRootFolder $rootFolder,
93
+        IURLGenerator $urlGenerator,
94
+        $userId,
95
+        IL10N $l10n
96
+    ) {
97
+        parent::__construct($appName, $request);
98
+
99
+        $this->shareManager = $shareManager;
100
+        $this->userManager = $userManager;
101
+        $this->groupManager = $groupManager;
102
+        $this->request = $request;
103
+        $this->rootFolder = $rootFolder;
104
+        $this->urlGenerator = $urlGenerator;
105
+        $this->currentUser = $userId;
106
+        $this->l = $l10n;
107
+    }
108
+
109
+    /**
110
+     * Convert an IShare to an array for OCS output
111
+     *
112
+     * @param \OCP\Share\IShare $share
113
+     * @param Node|null $recipientNode
114
+     * @return array
115
+     * @throws NotFoundException In case the node can't be resolved.
116
+     */
117
+    protected function formatShare(\OCP\Share\IShare $share, Node $recipientNode = null) {
118
+        $sharedBy = $this->userManager->get($share->getSharedBy());
119
+        $shareOwner = $this->userManager->get($share->getShareOwner());
120
+
121
+        $result = [
122
+            'id' => $share->getId(),
123
+            'share_type' => $share->getShareType(),
124
+            'uid_owner' => $share->getSharedBy(),
125
+            'displayname_owner' => $sharedBy !== null ? $sharedBy->getDisplayName() : $share->getSharedBy(),
126
+            'permissions' => $share->getPermissions(),
127
+            'stime' => $share->getShareTime()->getTimestamp(),
128
+            'parent' => null,
129
+            'expiration' => null,
130
+            'token' => null,
131
+            'uid_file_owner' => $share->getShareOwner(),
132
+            'displayname_file_owner' => $shareOwner !== null ? $shareOwner->getDisplayName() : $share->getShareOwner(),
133
+        ];
134
+
135
+        $userFolder = $this->rootFolder->getUserFolder($this->currentUser);
136
+        if ($recipientNode) {
137
+            $node = $recipientNode;
138
+        } else {
139
+            $nodes = $userFolder->getById($share->getNodeId());
140
+
141
+            if (empty($nodes)) {
142
+                // fallback to guessing the path
143
+                $node = $userFolder->get($share->getTarget());
144
+                if ($node === null) {
145
+                    throw new NotFoundException();
146
+                }
147
+            } else {
148
+                $node = $nodes[0];
149
+            }
150
+        }
151
+
152
+        $result['path'] = $userFolder->getRelativePath($node->getPath());
153
+        if ($node instanceOf \OCP\Files\Folder) {
154
+            $result['item_type'] = 'folder';
155
+        } else {
156
+            $result['item_type'] = 'file';
157
+        }
158
+        $result['mimetype'] = $node->getMimetype();
159
+        $result['storage_id'] = $node->getStorage()->getId();
160
+        $result['storage'] = $node->getStorage()->getCache()->getNumericStorageId();
161
+        $result['item_source'] = $node->getId();
162
+        $result['file_source'] = $node->getId();
163
+        $result['file_parent'] = $node->getParent()->getId();
164
+        $result['file_target'] = $share->getTarget();
165
+
166
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
167
+            $sharedWith = $this->userManager->get($share->getSharedWith());
168
+            $result['share_with'] = $share->getSharedWith();
169
+            $result['share_with_displayname'] = $sharedWith !== null ? $sharedWith->getDisplayName() : $share->getSharedWith();
170
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
171
+            $group = $this->groupManager->get($share->getSharedWith());
172
+            $result['share_with'] = $share->getSharedWith();
173
+            $result['share_with_displayname'] = $group !== null ? $group->getDisplayName() : $share->getSharedWith();
174
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
175
+
176
+            $result['share_with'] = $share->getPassword();
177
+            $result['share_with_displayname'] = $share->getPassword();
178
+
179
+            $result['token'] = $share->getToken();
180
+            $result['url'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $share->getToken()]);
181
+
182
+            $expiration = $share->getExpirationDate();
183
+            if ($expiration !== null) {
184
+                $result['expiration'] = $expiration->format('Y-m-d 00:00:00');
185
+            }
186
+
187
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_REMOTE) {
188
+            $result['share_with'] = $share->getSharedWith();
189
+            $result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'CLOUD');
190
+            $result['token'] = $share->getToken();
191
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
192
+            $result['share_with'] = $share->getSharedWith();
193
+            $result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'EMAIL');
194
+            $result['token'] = $share->getToken();
195
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_CIRCLE) {
196
+            $result['share_with_displayname'] = $share->getSharedWith();
197
+            $result['share_with'] = explode(' ', $share->getSharedWith(), 2)[0];
198
+        }
199
+
200
+
201
+        $result['mail_send'] = $share->getMailSend() ? 1 : 0;
202
+
203
+        return $result;
204
+    }
205
+
206
+    /**
207
+     * Check if one of the users address books knows the exact property, if
208
+     * yes we return the full name.
209
+     *
210
+     * @param string $query
211
+     * @param string $property
212
+     * @return string
213
+     */
214
+    private function getDisplayNameFromAddressBook($query, $property) {
215
+        // FIXME: If we inject the contacts manager it gets initialized bofore any address books are registered
216
+        $result = \OC::$server->getContactsManager()->search($query, [$property]);
217
+        foreach ($result as $r) {
218
+            foreach($r[$property] as $value) {
219
+                if ($value === $query) {
220
+                    return $r['FN'];
221
+                }
222
+            }
223
+        }
224
+
225
+        return $query;
226
+    }
227
+
228
+    /**
229
+     * Get a specific share by id
230
+     *
231
+     * @NoAdminRequired
232
+     *
233
+     * @param string $id
234
+     * @return DataResponse
235
+     * @throws OCSNotFoundException
236
+     */
237
+    public function getShare($id) {
238
+        try {
239
+            $share = $this->getShareById($id);
240
+        } catch (ShareNotFound $e) {
241
+            throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
242
+        }
243
+
244
+        if ($this->canAccessShare($share)) {
245
+            try {
246
+                $share = $this->formatShare($share);
247
+                return new DataResponse([$share]);
248
+            } catch (NotFoundException $e) {
249
+                //Fall trough
250
+            }
251
+        }
252
+
253
+        throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
254
+    }
255
+
256
+    /**
257
+     * Delete a share
258
+     *
259
+     * @NoAdminRequired
260
+     *
261
+     * @param string $id
262
+     * @return DataResponse
263
+     * @throws OCSNotFoundException
264
+     */
265
+    public function deleteShare($id) {
266
+        try {
267
+            $share = $this->getShareById($id);
268
+        } catch (ShareNotFound $e) {
269
+            throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
270
+        }
271
+
272
+        try {
273
+            $this->lock($share->getNode());
274
+        } catch (LockedException $e) {
275
+            throw new OCSNotFoundException($this->l->t('could not delete share'));
276
+        }
277
+
278
+        if (!$this->canAccessShare($share)) {
279
+            throw new OCSNotFoundException($this->l->t('Could not delete share'));
280
+        }
281
+
282
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP &&
283
+            $share->getShareOwner() !== $this->currentUser &&
284
+            $share->getSharedBy() !== $this->currentUser) {
285
+            $this->shareManager->deleteFromSelf($share, $this->currentUser);
286
+        } else {
287
+            $this->shareManager->deleteShare($share);
288
+        }
289
+
290
+        return new DataResponse();
291
+    }
292
+
293
+    /**
294
+     * @NoAdminRequired
295
+     *
296
+     * @param string $path
297
+     * @param int $permissions
298
+     * @param int $shareType
299
+     * @param string $shareWith
300
+     * @param string $publicUpload
301
+     * @param string $password
302
+     * @param string $expireDate
303
+     *
304
+     * @return DataResponse
305
+     * @throws OCSNotFoundException
306
+     * @throws OCSForbiddenException
307
+     * @throws OCSBadRequestException
308
+     * @throws OCSException
309
+     */
310
+    public function createShare(
311
+        $path = null,
312
+        $permissions = \OCP\Constants::PERMISSION_ALL,
313
+        $shareType = -1,
314
+        $shareWith = null,
315
+        $publicUpload = 'false',
316
+        $password = '',
317
+        $expireDate = ''
318
+    ) {
319
+        $share = $this->shareManager->newShare();
320
+
321
+        // Verify path
322
+        if ($path === null) {
323
+            throw new OCSNotFoundException($this->l->t('Please specify a file or folder path'));
324
+        }
325
+
326
+        $userFolder = $this->rootFolder->getUserFolder($this->currentUser);
327
+        try {
328
+            $path = $userFolder->get($path);
329
+        } catch (NotFoundException $e) {
330
+            throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
331
+        }
332
+
333
+        $share->setNode($path);
334
+
335
+        try {
336
+            $this->lock($share->getNode());
337
+        } catch (LockedException $e) {
338
+            throw new OCSNotFoundException($this->l->t('Could not create share'));
339
+        }
340
+
341
+        if ($permissions < 0 || $permissions > \OCP\Constants::PERMISSION_ALL) {
342
+            throw new OCSNotFoundException($this->l->t('invalid permissions'));
343
+        }
344
+
345
+        // Shares always require read permissions
346
+        $permissions |= \OCP\Constants::PERMISSION_READ;
347
+
348
+        if ($path instanceof \OCP\Files\File) {
349
+            // Single file shares should never have delete or create permissions
350
+            $permissions &= ~\OCP\Constants::PERMISSION_DELETE;
351
+            $permissions &= ~\OCP\Constants::PERMISSION_CREATE;
352
+        }
353
+
354
+        /*
355 355
 		 * Hack for https://github.com/owncloud/core/issues/22587
356 356
 		 * We check the permissions via webdav. But the permissions of the mount point
357 357
 		 * do not equal the share permissions. Here we fix that for federated mounts.
358 358
 		 */
359
-		if ($path->getStorage()->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
360
-			$permissions &= ~($permissions & ~$path->getPermissions());
361
-		}
362
-
363
-		if ($shareType === \OCP\Share::SHARE_TYPE_USER) {
364
-			// Valid user is required to share
365
-			if ($shareWith === null || !$this->userManager->userExists($shareWith)) {
366
-				throw new OCSNotFoundException($this->l->t('Please specify a valid user'));
367
-			}
368
-			$share->setSharedWith($shareWith);
369
-			$share->setPermissions($permissions);
370
-		} else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) {
371
-			if (!$this->shareManager->allowGroupSharing()) {
372
-				throw new OCSNotFoundException($this->l->t('Group sharing is disabled by the administrator'));
373
-			}
374
-
375
-			// Valid group is required to share
376
-			if ($shareWith === null || !$this->groupManager->groupExists($shareWith)) {
377
-				throw new OCSNotFoundException($this->l->t('Please specify a valid group'));
378
-			}
379
-			$share->setSharedWith($shareWith);
380
-			$share->setPermissions($permissions);
381
-		} else if ($shareType === \OCP\Share::SHARE_TYPE_LINK) {
382
-			//Can we even share links?
383
-			if (!$this->shareManager->shareApiAllowLinks()) {
384
-				throw new OCSNotFoundException($this->l->t('Public link sharing is disabled by the administrator'));
385
-			}
386
-
387
-			/*
359
+        if ($path->getStorage()->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
360
+            $permissions &= ~($permissions & ~$path->getPermissions());
361
+        }
362
+
363
+        if ($shareType === \OCP\Share::SHARE_TYPE_USER) {
364
+            // Valid user is required to share
365
+            if ($shareWith === null || !$this->userManager->userExists($shareWith)) {
366
+                throw new OCSNotFoundException($this->l->t('Please specify a valid user'));
367
+            }
368
+            $share->setSharedWith($shareWith);
369
+            $share->setPermissions($permissions);
370
+        } else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) {
371
+            if (!$this->shareManager->allowGroupSharing()) {
372
+                throw new OCSNotFoundException($this->l->t('Group sharing is disabled by the administrator'));
373
+            }
374
+
375
+            // Valid group is required to share
376
+            if ($shareWith === null || !$this->groupManager->groupExists($shareWith)) {
377
+                throw new OCSNotFoundException($this->l->t('Please specify a valid group'));
378
+            }
379
+            $share->setSharedWith($shareWith);
380
+            $share->setPermissions($permissions);
381
+        } else if ($shareType === \OCP\Share::SHARE_TYPE_LINK) {
382
+            //Can we even share links?
383
+            if (!$this->shareManager->shareApiAllowLinks()) {
384
+                throw new OCSNotFoundException($this->l->t('Public link sharing is disabled by the administrator'));
385
+            }
386
+
387
+            /*
388 388
 			 * For now we only allow 1 link share.
389 389
 			 * Return the existing link share if this is a duplicate
390 390
 			 */
391
-			$existingShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_LINK, $path, false, 1, 0);
392
-			if (!empty($existingShares)) {
393
-				return new DataResponse($this->formatShare($existingShares[0]));
394
-			}
395
-
396
-			if ($publicUpload === 'true') {
397
-				// Check if public upload is allowed
398
-				if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
399
-					throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
400
-				}
401
-
402
-				// Public upload can only be set for folders
403
-				if ($path instanceof \OCP\Files\File) {
404
-					throw new OCSNotFoundException($this->l->t('Public upload is only possible for publicly shared folders'));
405
-				}
406
-
407
-				$share->setPermissions(
408
-					\OCP\Constants::PERMISSION_READ |
409
-					\OCP\Constants::PERMISSION_CREATE |
410
-					\OCP\Constants::PERMISSION_UPDATE |
411
-					\OCP\Constants::PERMISSION_DELETE
412
-				);
413
-			} else {
414
-				$share->setPermissions(\OCP\Constants::PERMISSION_READ);
415
-			}
416
-
417
-			// Set password
418
-			if ($password !== '') {
419
-				$share->setPassword($password);
420
-			}
421
-
422
-			//Expire date
423
-			if ($expireDate !== '') {
424
-				try {
425
-					$expireDate = $this->parseDate($expireDate);
426
-					$share->setExpirationDate($expireDate);
427
-				} catch (\Exception $e) {
428
-					throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD'));
429
-				}
430
-			}
431
-
432
-		} else if ($shareType === \OCP\Share::SHARE_TYPE_REMOTE) {
433
-			if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
434
-				throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not allow shares from type %s', [$path->getPath(), $shareType]));
435
-			}
436
-
437
-			$share->setSharedWith($shareWith);
438
-			$share->setPermissions($permissions);
439
-		} else if ($shareType === \OCP\Share::SHARE_TYPE_EMAIL) {
440
-			if ($share->getNodeType() === 'file') {
441
-				$share->setPermissions(\OCP\Constants::PERMISSION_READ);
442
-			} else {
443
-				$share->setPermissions(
444
-					\OCP\Constants::PERMISSION_READ |
445
-					\OCP\Constants::PERMISSION_CREATE |
446
-					\OCP\Constants::PERMISSION_UPDATE |
447
-					\OCP\Constants::PERMISSION_DELETE);
448
-			}
449
-			$share->setSharedWith($shareWith);
450
-		} else if ($shareType === \OCP\Share::SHARE_TYPE_CIRCLE) {
451
-			if (!\OCP\App::isEnabled('circles')) {
452
-				throw new OCSNotFoundException($this->l->t('You cannot share to a Circle if the app is not enabled'));
453
-			}
454
-
455
-			$circle = \OCA\Circles\Api\Circles::detailsCircle($shareWith);
456
-
457
-			// Valid circle is required to share
458
-			if ($circle === null) {
459
-				throw new OCSNotFoundException($this->l->t('Please specify a valid circle'));
460
-			}
461
-			$share->setSharedWith($shareWith);
462
-			$share->setPermissions($permissions);
463
-		} else {
464
-			throw new OCSBadRequestException($this->l->t('Unknown share type'));
465
-		}
466
-
467
-		$share->setShareType($shareType);
468
-		$share->setSharedBy($this->currentUser);
469
-
470
-		try {
471
-			$share = $this->shareManager->createShare($share);
472
-		} catch (GenericShareException $e) {
473
-			$code = $e->getCode() === 0 ? 403 : $e->getCode();
474
-			throw new OCSException($e->getHint(), $code);
475
-		} catch (\Exception $e) {
476
-			throw new OCSForbiddenException($e->getMessage());
477
-		}
478
-
479
-		$output = $this->formatShare($share);
480
-
481
-		return new DataResponse($output);
482
-	}
483
-
484
-	/**
485
-	 * @param \OCP\Files\File|\OCP\Files\Folder $node
486
-	 * @return DataResponse
487
-	 */
488
-	private function getSharedWithMe($node = null) {
489
-
490
-		$userShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $node, -1, 0);
491
-		$groupShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $node, -1, 0);
492
-		$circleShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_CIRCLE, $node, -1, 0);
493
-
494
-		$shares = array_merge($userShares, $groupShares, $circleShares);
495
-
496
-		$shares = array_filter($shares, function (IShare $share) {
497
-			return $share->getShareOwner() !== $this->currentUser;
498
-		});
499
-
500
-		$formatted = [];
501
-		foreach ($shares as $share) {
502
-			if ($this->canAccessShare($share)) {
503
-				try {
504
-					$formatted[] = $this->formatShare($share);
505
-				} catch (NotFoundException $e) {
506
-					// Ignore this share
507
-				}
508
-			}
509
-		}
510
-
511
-		return new DataResponse($formatted);
512
-	}
513
-
514
-	/**
515
-	 * @param \OCP\Files\Folder $folder
516
-	 * @return DataResponse
517
-	 * @throws OCSBadRequestException
518
-	 */
519
-	private function getSharesInDir($folder) {
520
-		if (!($folder instanceof \OCP\Files\Folder)) {
521
-			throw new OCSBadRequestException($this->l->t('Not a directory'));
522
-		}
523
-
524
-		$nodes = $folder->getDirectoryListing();
525
-		/** @var \OCP\Share\IShare[] $shares */
526
-		$shares = [];
527
-		foreach ($nodes as $node) {
528
-			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $node, false, -1, 0));
529
-			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $node, false, -1, 0));
530
-			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_LINK, $node, false, -1, 0));
531
-			if($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
532
-				$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_EMAIL, $node, false, -1, 0));
533
-			}
534
-			if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
535
-				$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_REMOTE, $node, false, -1, 0));
536
-			}
537
-		}
538
-
539
-		$formatted = [];
540
-		foreach ($shares as $share) {
541
-			try {
542
-				$formatted[] = $this->formatShare($share);
543
-			} catch (NotFoundException $e) {
544
-				//Ignore this share
545
-			}
546
-		}
547
-
548
-		return new DataResponse($formatted);
549
-	}
550
-
551
-	/**
552
-	 * The getShares function.
553
-	 *
554
-	 * @NoAdminRequired
555
-	 *
556
-	 * @param string $shared_with_me
557
-	 * @param string $reshares
558
-	 * @param string $subfiles
559
-	 * @param string $path
560
-	 *
561
-	 * - Get shares by the current user
562
-	 * - Get shares by the current user and reshares (?reshares=true)
563
-	 * - Get shares with the current user (?shared_with_me=true)
564
-	 * - Get shares for a specific path (?path=...)
565
-	 * - Get all shares in a folder (?subfiles=true&path=..)
566
-	 *
567
-	 * @return DataResponse
568
-	 * @throws OCSNotFoundException
569
-	 */
570
-	public function getShares(
571
-		$shared_with_me = 'false',
572
-		$reshares = 'false',
573
-		$subfiles = 'false',
574
-		$path = null
575
-	) {
576
-
577
-		if ($path !== null) {
578
-			$userFolder = $this->rootFolder->getUserFolder($this->currentUser);
579
-			try {
580
-				$path = $userFolder->get($path);
581
-				$this->lock($path);
582
-			} catch (\OCP\Files\NotFoundException $e) {
583
-				throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
584
-			} catch (LockedException $e) {
585
-				throw new OCSNotFoundException($this->l->t('Could not lock path'));
586
-			}
587
-		}
588
-
589
-		if ($shared_with_me === 'true') {
590
-			$result = $this->getSharedWithMe($path);
591
-			return $result;
592
-		}
593
-
594
-		if ($subfiles === 'true') {
595
-			$result = $this->getSharesInDir($path);
596
-			return $result;
597
-		}
598
-
599
-		if ($reshares === 'true') {
600
-			$reshares = true;
601
-		} else {
602
-			$reshares = false;
603
-		}
604
-
605
-		// Get all shares
606
-		$userShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $path, $reshares, -1, 0);
607
-		$groupShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $path, $reshares, -1, 0);
608
-		$linkShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_LINK, $path, $reshares, -1, 0);
609
-		if ($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
610
-			$mailShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_EMAIL, $path, $reshares, -1, 0);
611
-		} else {
612
-			$mailShares = [];
613
-		}
614
-		if ($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_CIRCLE)) {
615
-			$circleShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_CIRCLE, $path, $reshares, -1, 0);
616
-		} else {
617
-			$circleShares = [];
618
-		}
619
-
620
-		$shares = array_merge($userShares, $groupShares, $linkShares, $mailShares, $circleShares);
621
-
622
-		if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
623
-			$federatedShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_REMOTE, $path, $reshares, -1, 0);
624
-			$shares = array_merge($shares, $federatedShares);
625
-		}
626
-
627
-		$formatted = [];
628
-		foreach ($shares as $share) {
629
-			try {
630
-				$formatted[] = $this->formatShare($share, $path);
631
-			} catch (NotFoundException $e) {
632
-				//Ignore share
633
-			}
634
-		}
635
-
636
-		return new DataResponse($formatted);
637
-	}
638
-
639
-	/**
640
-	 * @NoAdminRequired
641
-	 *
642
-	 * @param int $id
643
-	 * @param int $permissions
644
-	 * @param string $password
645
-	 * @param string $publicUpload
646
-	 * @param string $expireDate
647
-	 * @return DataResponse
648
-	 * @throws OCSNotFoundException
649
-	 * @throws OCSBadRequestException
650
-	 * @throws OCSForbiddenException
651
-	 */
652
-	public function updateShare(
653
-		$id,
654
-		$permissions = null,
655
-		$password = null,
656
-		$publicUpload = null,
657
-		$expireDate = null
658
-	) {
659
-		try {
660
-			$share = $this->getShareById($id);
661
-		} catch (ShareNotFound $e) {
662
-			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
663
-		}
664
-
665
-		$this->lock($share->getNode());
666
-
667
-		if (!$this->canAccessShare($share, false)) {
668
-			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
669
-		}
670
-
671
-		/*
391
+            $existingShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_LINK, $path, false, 1, 0);
392
+            if (!empty($existingShares)) {
393
+                return new DataResponse($this->formatShare($existingShares[0]));
394
+            }
395
+
396
+            if ($publicUpload === 'true') {
397
+                // Check if public upload is allowed
398
+                if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
399
+                    throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
400
+                }
401
+
402
+                // Public upload can only be set for folders
403
+                if ($path instanceof \OCP\Files\File) {
404
+                    throw new OCSNotFoundException($this->l->t('Public upload is only possible for publicly shared folders'));
405
+                }
406
+
407
+                $share->setPermissions(
408
+                    \OCP\Constants::PERMISSION_READ |
409
+                    \OCP\Constants::PERMISSION_CREATE |
410
+                    \OCP\Constants::PERMISSION_UPDATE |
411
+                    \OCP\Constants::PERMISSION_DELETE
412
+                );
413
+            } else {
414
+                $share->setPermissions(\OCP\Constants::PERMISSION_READ);
415
+            }
416
+
417
+            // Set password
418
+            if ($password !== '') {
419
+                $share->setPassword($password);
420
+            }
421
+
422
+            //Expire date
423
+            if ($expireDate !== '') {
424
+                try {
425
+                    $expireDate = $this->parseDate($expireDate);
426
+                    $share->setExpirationDate($expireDate);
427
+                } catch (\Exception $e) {
428
+                    throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD'));
429
+                }
430
+            }
431
+
432
+        } else if ($shareType === \OCP\Share::SHARE_TYPE_REMOTE) {
433
+            if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
434
+                throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not allow shares from type %s', [$path->getPath(), $shareType]));
435
+            }
436
+
437
+            $share->setSharedWith($shareWith);
438
+            $share->setPermissions($permissions);
439
+        } else if ($shareType === \OCP\Share::SHARE_TYPE_EMAIL) {
440
+            if ($share->getNodeType() === 'file') {
441
+                $share->setPermissions(\OCP\Constants::PERMISSION_READ);
442
+            } else {
443
+                $share->setPermissions(
444
+                    \OCP\Constants::PERMISSION_READ |
445
+                    \OCP\Constants::PERMISSION_CREATE |
446
+                    \OCP\Constants::PERMISSION_UPDATE |
447
+                    \OCP\Constants::PERMISSION_DELETE);
448
+            }
449
+            $share->setSharedWith($shareWith);
450
+        } else if ($shareType === \OCP\Share::SHARE_TYPE_CIRCLE) {
451
+            if (!\OCP\App::isEnabled('circles')) {
452
+                throw new OCSNotFoundException($this->l->t('You cannot share to a Circle if the app is not enabled'));
453
+            }
454
+
455
+            $circle = \OCA\Circles\Api\Circles::detailsCircle($shareWith);
456
+
457
+            // Valid circle is required to share
458
+            if ($circle === null) {
459
+                throw new OCSNotFoundException($this->l->t('Please specify a valid circle'));
460
+            }
461
+            $share->setSharedWith($shareWith);
462
+            $share->setPermissions($permissions);
463
+        } else {
464
+            throw new OCSBadRequestException($this->l->t('Unknown share type'));
465
+        }
466
+
467
+        $share->setShareType($shareType);
468
+        $share->setSharedBy($this->currentUser);
469
+
470
+        try {
471
+            $share = $this->shareManager->createShare($share);
472
+        } catch (GenericShareException $e) {
473
+            $code = $e->getCode() === 0 ? 403 : $e->getCode();
474
+            throw new OCSException($e->getHint(), $code);
475
+        } catch (\Exception $e) {
476
+            throw new OCSForbiddenException($e->getMessage());
477
+        }
478
+
479
+        $output = $this->formatShare($share);
480
+
481
+        return new DataResponse($output);
482
+    }
483
+
484
+    /**
485
+     * @param \OCP\Files\File|\OCP\Files\Folder $node
486
+     * @return DataResponse
487
+     */
488
+    private function getSharedWithMe($node = null) {
489
+
490
+        $userShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $node, -1, 0);
491
+        $groupShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $node, -1, 0);
492
+        $circleShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_CIRCLE, $node, -1, 0);
493
+
494
+        $shares = array_merge($userShares, $groupShares, $circleShares);
495
+
496
+        $shares = array_filter($shares, function (IShare $share) {
497
+            return $share->getShareOwner() !== $this->currentUser;
498
+        });
499
+
500
+        $formatted = [];
501
+        foreach ($shares as $share) {
502
+            if ($this->canAccessShare($share)) {
503
+                try {
504
+                    $formatted[] = $this->formatShare($share);
505
+                } catch (NotFoundException $e) {
506
+                    // Ignore this share
507
+                }
508
+            }
509
+        }
510
+
511
+        return new DataResponse($formatted);
512
+    }
513
+
514
+    /**
515
+     * @param \OCP\Files\Folder $folder
516
+     * @return DataResponse
517
+     * @throws OCSBadRequestException
518
+     */
519
+    private function getSharesInDir($folder) {
520
+        if (!($folder instanceof \OCP\Files\Folder)) {
521
+            throw new OCSBadRequestException($this->l->t('Not a directory'));
522
+        }
523
+
524
+        $nodes = $folder->getDirectoryListing();
525
+        /** @var \OCP\Share\IShare[] $shares */
526
+        $shares = [];
527
+        foreach ($nodes as $node) {
528
+            $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $node, false, -1, 0));
529
+            $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $node, false, -1, 0));
530
+            $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_LINK, $node, false, -1, 0));
531
+            if($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
532
+                $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_EMAIL, $node, false, -1, 0));
533
+            }
534
+            if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
535
+                $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_REMOTE, $node, false, -1, 0));
536
+            }
537
+        }
538
+
539
+        $formatted = [];
540
+        foreach ($shares as $share) {
541
+            try {
542
+                $formatted[] = $this->formatShare($share);
543
+            } catch (NotFoundException $e) {
544
+                //Ignore this share
545
+            }
546
+        }
547
+
548
+        return new DataResponse($formatted);
549
+    }
550
+
551
+    /**
552
+     * The getShares function.
553
+     *
554
+     * @NoAdminRequired
555
+     *
556
+     * @param string $shared_with_me
557
+     * @param string $reshares
558
+     * @param string $subfiles
559
+     * @param string $path
560
+     *
561
+     * - Get shares by the current user
562
+     * - Get shares by the current user and reshares (?reshares=true)
563
+     * - Get shares with the current user (?shared_with_me=true)
564
+     * - Get shares for a specific path (?path=...)
565
+     * - Get all shares in a folder (?subfiles=true&path=..)
566
+     *
567
+     * @return DataResponse
568
+     * @throws OCSNotFoundException
569
+     */
570
+    public function getShares(
571
+        $shared_with_me = 'false',
572
+        $reshares = 'false',
573
+        $subfiles = 'false',
574
+        $path = null
575
+    ) {
576
+
577
+        if ($path !== null) {
578
+            $userFolder = $this->rootFolder->getUserFolder($this->currentUser);
579
+            try {
580
+                $path = $userFolder->get($path);
581
+                $this->lock($path);
582
+            } catch (\OCP\Files\NotFoundException $e) {
583
+                throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
584
+            } catch (LockedException $e) {
585
+                throw new OCSNotFoundException($this->l->t('Could not lock path'));
586
+            }
587
+        }
588
+
589
+        if ($shared_with_me === 'true') {
590
+            $result = $this->getSharedWithMe($path);
591
+            return $result;
592
+        }
593
+
594
+        if ($subfiles === 'true') {
595
+            $result = $this->getSharesInDir($path);
596
+            return $result;
597
+        }
598
+
599
+        if ($reshares === 'true') {
600
+            $reshares = true;
601
+        } else {
602
+            $reshares = false;
603
+        }
604
+
605
+        // Get all shares
606
+        $userShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $path, $reshares, -1, 0);
607
+        $groupShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $path, $reshares, -1, 0);
608
+        $linkShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_LINK, $path, $reshares, -1, 0);
609
+        if ($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
610
+            $mailShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_EMAIL, $path, $reshares, -1, 0);
611
+        } else {
612
+            $mailShares = [];
613
+        }
614
+        if ($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_CIRCLE)) {
615
+            $circleShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_CIRCLE, $path, $reshares, -1, 0);
616
+        } else {
617
+            $circleShares = [];
618
+        }
619
+
620
+        $shares = array_merge($userShares, $groupShares, $linkShares, $mailShares, $circleShares);
621
+
622
+        if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
623
+            $federatedShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_REMOTE, $path, $reshares, -1, 0);
624
+            $shares = array_merge($shares, $federatedShares);
625
+        }
626
+
627
+        $formatted = [];
628
+        foreach ($shares as $share) {
629
+            try {
630
+                $formatted[] = $this->formatShare($share, $path);
631
+            } catch (NotFoundException $e) {
632
+                //Ignore share
633
+            }
634
+        }
635
+
636
+        return new DataResponse($formatted);
637
+    }
638
+
639
+    /**
640
+     * @NoAdminRequired
641
+     *
642
+     * @param int $id
643
+     * @param int $permissions
644
+     * @param string $password
645
+     * @param string $publicUpload
646
+     * @param string $expireDate
647
+     * @return DataResponse
648
+     * @throws OCSNotFoundException
649
+     * @throws OCSBadRequestException
650
+     * @throws OCSForbiddenException
651
+     */
652
+    public function updateShare(
653
+        $id,
654
+        $permissions = null,
655
+        $password = null,
656
+        $publicUpload = null,
657
+        $expireDate = null
658
+    ) {
659
+        try {
660
+            $share = $this->getShareById($id);
661
+        } catch (ShareNotFound $e) {
662
+            throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
663
+        }
664
+
665
+        $this->lock($share->getNode());
666
+
667
+        if (!$this->canAccessShare($share, false)) {
668
+            throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
669
+        }
670
+
671
+        /*
672 672
 		 * expirationdate, password and publicUpload only make sense for link shares
673 673
 		 */
674
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
675
-			if ($permissions === null && $password === null && $publicUpload === null && $expireDate === null) {
676
-				throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given'));
677
-			}
678
-
679
-			$newPermissions = null;
680
-			if ($publicUpload === 'true') {
681
-				$newPermissions = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE;
682
-			} else if ($publicUpload === 'false') {
683
-				$newPermissions = \OCP\Constants::PERMISSION_READ;
684
-			}
685
-
686
-			if ($permissions !== null) {
687
-				$newPermissions = (int)$permissions;
688
-			}
689
-
690
-			if ($newPermissions !== null &&
691
-				!in_array($newPermissions, [
692
-					\OCP\Constants::PERMISSION_READ,
693
-					\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE, // legacy
694
-					\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE, // correct
695
-					\OCP\Constants::PERMISSION_CREATE, // hidden file list
696
-					\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_UPDATE, // allow to edit single files
697
-				])
698
-			) {
699
-				throw new OCSBadRequestException($this->l->t('Can\'t change permissions for public share links'));
700
-			}
701
-
702
-			if (
703
-				// legacy
704
-				$newPermissions === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE) ||
705
-				// correct
706
-				$newPermissions === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE)
707
-			) {
708
-				if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
709
-					throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
710
-				}
711
-
712
-				if (!($share->getNode() instanceof \OCP\Files\Folder)) {
713
-					throw new OCSBadRequestException($this->l->t('Public upload is only possible for publicly shared folders'));
714
-				}
715
-
716
-				// normalize to correct public upload permissions
717
-				$newPermissions = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE;
718
-			}
719
-
720
-			if ($newPermissions !== null) {
721
-				$share->setPermissions($newPermissions);
722
-				$permissions = $newPermissions;
723
-			}
724
-
725
-			if ($expireDate === '') {
726
-				$share->setExpirationDate(null);
727
-			} else if ($expireDate !== null) {
728
-				try {
729
-					$expireDate = $this->parseDate($expireDate);
730
-				} catch (\Exception $e) {
731
-					throw new OCSBadRequestException($e->getMessage());
732
-				}
733
-				$share->setExpirationDate($expireDate);
734
-			}
735
-
736
-			if ($password === '') {
737
-				$share->setPassword(null);
738
-			} else if ($password !== null) {
739
-				$share->setPassword($password);
740
-			}
741
-
742
-		} else {
743
-			// For other shares only permissions is valid.
744
-			if ($permissions === null) {
745
-				throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given'));
746
-			} else {
747
-				$permissions = (int)$permissions;
748
-				$share->setPermissions($permissions);
749
-			}
750
-		}
751
-
752
-		if ($permissions !== null && $share->getShareOwner() !== $this->currentUser) {
753
-			/* Check if this is an incomming share */
754
-			$incomingShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $share->getNode(), -1, 0);
755
-			$incomingShares = array_merge($incomingShares, $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $share->getNode(), -1, 0));
756
-
757
-			/** @var \OCP\Share\IShare[] $incomingShares */
758
-			if (!empty($incomingShares)) {
759
-				$maxPermissions = 0;
760
-				foreach ($incomingShares as $incomingShare) {
761
-					$maxPermissions |= $incomingShare->getPermissions();
762
-				}
763
-
764
-				if ($share->getPermissions() & ~$maxPermissions) {
765
-					throw new OCSNotFoundException($this->l->t('Cannot increase permissions'));
766
-				}
767
-			}
768
-		}
769
-
770
-
771
-		try {
772
-			$share = $this->shareManager->updateShare($share);
773
-		} catch (\Exception $e) {
774
-			throw new OCSBadRequestException($e->getMessage());
775
-		}
776
-
777
-		return new DataResponse($this->formatShare($share));
778
-	}
779
-
780
-	/**
781
-	 * @param \OCP\Share\IShare $share
782
-	 * @return bool
783
-	 */
784
-	protected function canAccessShare(\OCP\Share\IShare $share, $checkGroups = true) {
785
-		// A file with permissions 0 can't be accessed by us. So Don't show it
786
-		if ($share->getPermissions() === 0) {
787
-			return false;
788
-		}
789
-
790
-		// Owner of the file and the sharer of the file can always get share
791
-		if ($share->getShareOwner() === $this->currentUser ||
792
-			$share->getSharedBy() === $this->currentUser
793
-		) {
794
-			return true;
795
-		}
796
-
797
-		// If the share is shared with you (or a group you are a member of)
798
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
799
-			$share->getSharedWith() === $this->currentUser
800
-		) {
801
-			return true;
802
-		}
803
-
804
-		if ($checkGroups && $share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
805
-			$sharedWith = $this->groupManager->get($share->getSharedWith());
806
-			$user = $this->userManager->get($this->currentUser);
807
-			if ($user !== null && $sharedWith->inGroup($user)) {
808
-				return true;
809
-			}
810
-		}
811
-
812
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_CIRCLE) {
813
-			// TODO: have a sanity check like above?
814
-			return true;
815
-		}
816
-
817
-		return false;
818
-	}
819
-
820
-	/**
821
-	 * Make sure that the passed date is valid ISO 8601
822
-	 * So YYYY-MM-DD
823
-	 * If not throw an exception
824
-	 *
825
-	 * @param string $expireDate
826
-	 *
827
-	 * @throws \Exception
828
-	 * @return \DateTime
829
-	 */
830
-	private function parseDate($expireDate) {
831
-		try {
832
-			$date = new \DateTime($expireDate);
833
-		} catch (\Exception $e) {
834
-			throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
835
-		}
836
-
837
-		if ($date === false) {
838
-			throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
839
-		}
840
-
841
-		$date->setTime(0, 0, 0);
842
-
843
-		return $date;
844
-	}
845
-
846
-	/**
847
-	 * Since we have multiple providers but the OCS Share API v1 does
848
-	 * not support this we need to check all backends.
849
-	 *
850
-	 * @param string $id
851
-	 * @return \OCP\Share\IShare
852
-	 * @throws ShareNotFound
853
-	 */
854
-	private function getShareById($id) {
855
-		$share = null;
856
-
857
-		// First check if it is an internal share.
858
-		try {
859
-			$share = $this->shareManager->getShareById('ocinternal:' . $id);
860
-			return $share;
861
-		} catch (ShareNotFound $e) {
862
-			// Do nothing, just try the other share type
863
-		}
864
-
865
-
866
-		try {
867
-			if ($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_CIRCLE)) {
868
-				$share = $this->shareManager->getShareById('ocCircleShare:' . $id);
869
-				return $share;
870
-			}
871
-		} catch (ShareNotFound $e) {
872
-			// Do nothing, just try the other share type
873
-		}
874
-
875
-		try {
876
-			if ($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
877
-				$share = $this->shareManager->getShareById('ocMailShare:' . $id);
878
-				return $share;
879
-			}
880
-		} catch (ShareNotFound $e) {
881
-			// Do nothing, just try the other share type
882
-		}
883
-
884
-		if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
885
-			throw new ShareNotFound();
886
-		}
887
-		$share = $this->shareManager->getShareById('ocFederatedSharing:' . $id);
888
-
889
-		return $share;
890
-	}
891
-
892
-	/**
893
-	 * Lock a Node
894
-	 *
895
-	 * @param \OCP\Files\Node $node
896
-	 */
897
-	private function lock(\OCP\Files\Node $node) {
898
-		$node->lock(ILockingProvider::LOCK_SHARED);
899
-		$this->lockedNode = $node;
900
-	}
901
-
902
-	/**
903
-	 * Cleanup the remaining locks
904
-	 */
905
-	public function cleanup() {
906
-		if ($this->lockedNode !== null) {
907
-			$this->lockedNode->unlock(ILockingProvider::LOCK_SHARED);
908
-		}
909
-	}
674
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
675
+            if ($permissions === null && $password === null && $publicUpload === null && $expireDate === null) {
676
+                throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given'));
677
+            }
678
+
679
+            $newPermissions = null;
680
+            if ($publicUpload === 'true') {
681
+                $newPermissions = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE;
682
+            } else if ($publicUpload === 'false') {
683
+                $newPermissions = \OCP\Constants::PERMISSION_READ;
684
+            }
685
+
686
+            if ($permissions !== null) {
687
+                $newPermissions = (int)$permissions;
688
+            }
689
+
690
+            if ($newPermissions !== null &&
691
+                !in_array($newPermissions, [
692
+                    \OCP\Constants::PERMISSION_READ,
693
+                    \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE, // legacy
694
+                    \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE, // correct
695
+                    \OCP\Constants::PERMISSION_CREATE, // hidden file list
696
+                    \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_UPDATE, // allow to edit single files
697
+                ])
698
+            ) {
699
+                throw new OCSBadRequestException($this->l->t('Can\'t change permissions for public share links'));
700
+            }
701
+
702
+            if (
703
+                // legacy
704
+                $newPermissions === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE) ||
705
+                // correct
706
+                $newPermissions === (\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE)
707
+            ) {
708
+                if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
709
+                    throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
710
+                }
711
+
712
+                if (!($share->getNode() instanceof \OCP\Files\Folder)) {
713
+                    throw new OCSBadRequestException($this->l->t('Public upload is only possible for publicly shared folders'));
714
+                }
715
+
716
+                // normalize to correct public upload permissions
717
+                $newPermissions = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE;
718
+            }
719
+
720
+            if ($newPermissions !== null) {
721
+                $share->setPermissions($newPermissions);
722
+                $permissions = $newPermissions;
723
+            }
724
+
725
+            if ($expireDate === '') {
726
+                $share->setExpirationDate(null);
727
+            } else if ($expireDate !== null) {
728
+                try {
729
+                    $expireDate = $this->parseDate($expireDate);
730
+                } catch (\Exception $e) {
731
+                    throw new OCSBadRequestException($e->getMessage());
732
+                }
733
+                $share->setExpirationDate($expireDate);
734
+            }
735
+
736
+            if ($password === '') {
737
+                $share->setPassword(null);
738
+            } else if ($password !== null) {
739
+                $share->setPassword($password);
740
+            }
741
+
742
+        } else {
743
+            // For other shares only permissions is valid.
744
+            if ($permissions === null) {
745
+                throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given'));
746
+            } else {
747
+                $permissions = (int)$permissions;
748
+                $share->setPermissions($permissions);
749
+            }
750
+        }
751
+
752
+        if ($permissions !== null && $share->getShareOwner() !== $this->currentUser) {
753
+            /* Check if this is an incomming share */
754
+            $incomingShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $share->getNode(), -1, 0);
755
+            $incomingShares = array_merge($incomingShares, $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $share->getNode(), -1, 0));
756
+
757
+            /** @var \OCP\Share\IShare[] $incomingShares */
758
+            if (!empty($incomingShares)) {
759
+                $maxPermissions = 0;
760
+                foreach ($incomingShares as $incomingShare) {
761
+                    $maxPermissions |= $incomingShare->getPermissions();
762
+                }
763
+
764
+                if ($share->getPermissions() & ~$maxPermissions) {
765
+                    throw new OCSNotFoundException($this->l->t('Cannot increase permissions'));
766
+                }
767
+            }
768
+        }
769
+
770
+
771
+        try {
772
+            $share = $this->shareManager->updateShare($share);
773
+        } catch (\Exception $e) {
774
+            throw new OCSBadRequestException($e->getMessage());
775
+        }
776
+
777
+        return new DataResponse($this->formatShare($share));
778
+    }
779
+
780
+    /**
781
+     * @param \OCP\Share\IShare $share
782
+     * @return bool
783
+     */
784
+    protected function canAccessShare(\OCP\Share\IShare $share, $checkGroups = true) {
785
+        // A file with permissions 0 can't be accessed by us. So Don't show it
786
+        if ($share->getPermissions() === 0) {
787
+            return false;
788
+        }
789
+
790
+        // Owner of the file and the sharer of the file can always get share
791
+        if ($share->getShareOwner() === $this->currentUser ||
792
+            $share->getSharedBy() === $this->currentUser
793
+        ) {
794
+            return true;
795
+        }
796
+
797
+        // If the share is shared with you (or a group you are a member of)
798
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
799
+            $share->getSharedWith() === $this->currentUser
800
+        ) {
801
+            return true;
802
+        }
803
+
804
+        if ($checkGroups && $share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
805
+            $sharedWith = $this->groupManager->get($share->getSharedWith());
806
+            $user = $this->userManager->get($this->currentUser);
807
+            if ($user !== null && $sharedWith->inGroup($user)) {
808
+                return true;
809
+            }
810
+        }
811
+
812
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_CIRCLE) {
813
+            // TODO: have a sanity check like above?
814
+            return true;
815
+        }
816
+
817
+        return false;
818
+    }
819
+
820
+    /**
821
+     * Make sure that the passed date is valid ISO 8601
822
+     * So YYYY-MM-DD
823
+     * If not throw an exception
824
+     *
825
+     * @param string $expireDate
826
+     *
827
+     * @throws \Exception
828
+     * @return \DateTime
829
+     */
830
+    private function parseDate($expireDate) {
831
+        try {
832
+            $date = new \DateTime($expireDate);
833
+        } catch (\Exception $e) {
834
+            throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
835
+        }
836
+
837
+        if ($date === false) {
838
+            throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
839
+        }
840
+
841
+        $date->setTime(0, 0, 0);
842
+
843
+        return $date;
844
+    }
845
+
846
+    /**
847
+     * Since we have multiple providers but the OCS Share API v1 does
848
+     * not support this we need to check all backends.
849
+     *
850
+     * @param string $id
851
+     * @return \OCP\Share\IShare
852
+     * @throws ShareNotFound
853
+     */
854
+    private function getShareById($id) {
855
+        $share = null;
856
+
857
+        // First check if it is an internal share.
858
+        try {
859
+            $share = $this->shareManager->getShareById('ocinternal:' . $id);
860
+            return $share;
861
+        } catch (ShareNotFound $e) {
862
+            // Do nothing, just try the other share type
863
+        }
864
+
865
+
866
+        try {
867
+            if ($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_CIRCLE)) {
868
+                $share = $this->shareManager->getShareById('ocCircleShare:' . $id);
869
+                return $share;
870
+            }
871
+        } catch (ShareNotFound $e) {
872
+            // Do nothing, just try the other share type
873
+        }
874
+
875
+        try {
876
+            if ($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
877
+                $share = $this->shareManager->getShareById('ocMailShare:' . $id);
878
+                return $share;
879
+            }
880
+        } catch (ShareNotFound $e) {
881
+            // Do nothing, just try the other share type
882
+        }
883
+
884
+        if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
885
+            throw new ShareNotFound();
886
+        }
887
+        $share = $this->shareManager->getShareById('ocFederatedSharing:' . $id);
888
+
889
+        return $share;
890
+    }
891
+
892
+    /**
893
+     * Lock a Node
894
+     *
895
+     * @param \OCP\Files\Node $node
896
+     */
897
+    private function lock(\OCP\Files\Node $node) {
898
+        $node->lock(ILockingProvider::LOCK_SHARED);
899
+        $this->lockedNode = $node;
900
+    }
901
+
902
+    /**
903
+     * Cleanup the remaining locks
904
+     */
905
+    public function cleanup() {
906
+        if ($this->lockedNode !== null) {
907
+            $this->lockedNode->unlock(ILockingProvider::LOCK_SHARED);
908
+        }
909
+    }
910 910
 }
Please login to merge, or discard this patch.
apps/files_sharing/lib/MountProvider.php 2 patches
Indentation   +154 added lines, -154 removed lines patch added patch discarded remove patch
@@ -33,158 +33,158 @@
 block discarded – undo
33 33
 use OCP\Share\IManager;
34 34
 
35 35
 class MountProvider implements IMountProvider {
36
-	/**
37
-	 * @var \OCP\IConfig
38
-	 */
39
-	protected $config;
40
-
41
-	/**
42
-	 * @var IManager
43
-	 */
44
-	protected $shareManager;
45
-
46
-	/**
47
-	 * @var ILogger
48
-	 */
49
-	protected $logger;
50
-
51
-	/**
52
-	 * @param \OCP\IConfig $config
53
-	 * @param IManager $shareManager
54
-	 * @param ILogger $logger
55
-	 */
56
-	public function __construct(IConfig $config, IManager $shareManager, ILogger $logger) {
57
-		$this->config = $config;
58
-		$this->shareManager = $shareManager;
59
-		$this->logger = $logger;
60
-	}
61
-
62
-
63
-	/**
64
-	 * Get all mountpoints applicable for the user and check for shares where we need to update the etags
65
-	 *
66
-	 * @param \OCP\IUser $user
67
-	 * @param \OCP\Files\Storage\IStorageFactory $storageFactory
68
-	 * @return \OCP\Files\Mount\IMountPoint[]
69
-	 */
70
-	public function getMountsForUser(IUser $user, IStorageFactory $storageFactory) {
71
-
72
-		$shares = $this->shareManager->getSharedWith($user->getUID(), \OCP\Share::SHARE_TYPE_USER, null, -1);
73
-		$shares = array_merge($shares, $this->shareManager->getSharedWith($user->getUID(), \OCP\Share::SHARE_TYPE_GROUP, null, -1));
74
-		$shares = array_merge($shares, $this->shareManager->getSharedWith($user->getUID(), \OCP\Share::SHARE_TYPE_CIRCLE, null, -1));
75
-
76
-		// filter out excluded shares and group shares that includes self
77
-		$shares = array_filter($shares, function (\OCP\Share\IShare $share) use ($user) {
78
-			return $share->getPermissions() > 0 && $share->getShareOwner() !== $user->getUID();
79
-		});
80
-
81
-		$superShares = $this->buildSuperShares($shares, $user);
82
-
83
-		$mounts = [];
84
-		foreach ($superShares as $share) {
85
-			try {
86
-				$mounts[] = new SharedMount(
87
-					'\OCA\Files_Sharing\SharedStorage',
88
-					$mounts,
89
-					[
90
-						'user' => $user->getUID(),
91
-						// parent share
92
-						'superShare' => $share[0],
93
-						// children/component of the superShare
94
-						'groupedShares' => $share[1],
95
-					],
96
-					$storageFactory
97
-				);
98
-			} catch (\Exception $e) {
99
-				$this->logger->logException($e);
100
-				$this->logger->error('Error while trying to create shared mount');
101
-			}
102
-		}
103
-
104
-		// array_filter removes the null values from the array
105
-		return array_filter($mounts);
106
-	}
107
-
108
-	/**
109
-	 * Groups shares by path (nodeId) and target path
110
-	 *
111
-	 * @param \OCP\Share\IShare[] $shares
112
-	 * @return \OCP\Share\IShare[][] array of grouped shares, each element in the
113
-	 * array is a group which itself is an array of shares
114
-	 */
115
-	private function groupShares(array $shares) {
116
-		$tmp = [];
117
-
118
-		foreach ($shares as $share) {
119
-			if (!isset($tmp[$share->getNodeId()])) {
120
-				$tmp[$share->getNodeId()] = [];
121
-			}
122
-			$tmp[$share->getNodeId()][] = $share;
123
-		}
124
-
125
-		$result = [];
126
-		// sort by stime, the super share will be based on the least recent share
127
-		foreach ($tmp as &$tmp2) {
128
-			@usort($tmp2, function($a, $b) {
129
-				if ($a->getShareTime() <= $b->getShareTime()) {
130
-					return -1;
131
-				}
132
-				return 1;
133
-			});
134
-			$result[] = $tmp2;
135
-		}
136
-
137
-		return array_values($result);
138
-	}
139
-
140
-	/**
141
-	 * Build super shares (virtual share) by grouping them by node id and target,
142
-	 * then for each group compute the super share and return it along with the matching
143
-	 * grouped shares. The most permissive permissions are used based on the permissions
144
-	 * of all shares within the group.
145
-	 *
146
-	 * @param \OCP\Share\IShare[] $allShares
147
-	 * @param \OCP\IUser $user user
148
-	 * @return array Tuple of [superShare, groupedShares]
149
-	 */
150
-	private function buildSuperShares(array $allShares, \OCP\IUser $user) {
151
-		$result = [];
152
-
153
-		$groupedShares = $this->groupShares($allShares);
154
-
155
-		/** @var \OCP\Share\IShare[] $shares */
156
-		foreach ($groupedShares as $shares) {
157
-			if (count($shares) === 0) {
158
-				continue;
159
-			}
160
-
161
-			$superShare = $this->shareManager->newShare();
162
-
163
-			// compute super share based on first entry of the group
164
-			$superShare->setId($shares[0]->getId())
165
-				->setShareOwner($shares[0]->getShareOwner())
166
-				->setNodeId($shares[0]->getNodeId())
167
-				->setTarget($shares[0]->getTarget());
168
-
169
-			// use most permissive permissions
170
-			$permissions = 0;
171
-			foreach ($shares as $share) {
172
-				$permissions |= $share->getPermissions();
173
-				if ($share->getTarget() !== $superShare->getTarget()) {
174
-					// adjust target, for database consistency
175
-					$share->setTarget($superShare->getTarget());
176
-					$this->shareManager->moveShare($share, $user->getUID());
177
-				}
178
-				if (!is_null($share->getNodeCacheEntry())) {
179
-					$superShare->setNodeCacheEntry($share->getNodeCacheEntry());
180
-				}
181
-			}
182
-
183
-			$superShare->setPermissions($permissions);
184
-
185
-			$result[] = [$superShare, $shares];
186
-		}
187
-
188
-		return $result;
189
-	}
36
+    /**
37
+     * @var \OCP\IConfig
38
+     */
39
+    protected $config;
40
+
41
+    /**
42
+     * @var IManager
43
+     */
44
+    protected $shareManager;
45
+
46
+    /**
47
+     * @var ILogger
48
+     */
49
+    protected $logger;
50
+
51
+    /**
52
+     * @param \OCP\IConfig $config
53
+     * @param IManager $shareManager
54
+     * @param ILogger $logger
55
+     */
56
+    public function __construct(IConfig $config, IManager $shareManager, ILogger $logger) {
57
+        $this->config = $config;
58
+        $this->shareManager = $shareManager;
59
+        $this->logger = $logger;
60
+    }
61
+
62
+
63
+    /**
64
+     * Get all mountpoints applicable for the user and check for shares where we need to update the etags
65
+     *
66
+     * @param \OCP\IUser $user
67
+     * @param \OCP\Files\Storage\IStorageFactory $storageFactory
68
+     * @return \OCP\Files\Mount\IMountPoint[]
69
+     */
70
+    public function getMountsForUser(IUser $user, IStorageFactory $storageFactory) {
71
+
72
+        $shares = $this->shareManager->getSharedWith($user->getUID(), \OCP\Share::SHARE_TYPE_USER, null, -1);
73
+        $shares = array_merge($shares, $this->shareManager->getSharedWith($user->getUID(), \OCP\Share::SHARE_TYPE_GROUP, null, -1));
74
+        $shares = array_merge($shares, $this->shareManager->getSharedWith($user->getUID(), \OCP\Share::SHARE_TYPE_CIRCLE, null, -1));
75
+
76
+        // filter out excluded shares and group shares that includes self
77
+        $shares = array_filter($shares, function (\OCP\Share\IShare $share) use ($user) {
78
+            return $share->getPermissions() > 0 && $share->getShareOwner() !== $user->getUID();
79
+        });
80
+
81
+        $superShares = $this->buildSuperShares($shares, $user);
82
+
83
+        $mounts = [];
84
+        foreach ($superShares as $share) {
85
+            try {
86
+                $mounts[] = new SharedMount(
87
+                    '\OCA\Files_Sharing\SharedStorage',
88
+                    $mounts,
89
+                    [
90
+                        'user' => $user->getUID(),
91
+                        // parent share
92
+                        'superShare' => $share[0],
93
+                        // children/component of the superShare
94
+                        'groupedShares' => $share[1],
95
+                    ],
96
+                    $storageFactory
97
+                );
98
+            } catch (\Exception $e) {
99
+                $this->logger->logException($e);
100
+                $this->logger->error('Error while trying to create shared mount');
101
+            }
102
+        }
103
+
104
+        // array_filter removes the null values from the array
105
+        return array_filter($mounts);
106
+    }
107
+
108
+    /**
109
+     * Groups shares by path (nodeId) and target path
110
+     *
111
+     * @param \OCP\Share\IShare[] $shares
112
+     * @return \OCP\Share\IShare[][] array of grouped shares, each element in the
113
+     * array is a group which itself is an array of shares
114
+     */
115
+    private function groupShares(array $shares) {
116
+        $tmp = [];
117
+
118
+        foreach ($shares as $share) {
119
+            if (!isset($tmp[$share->getNodeId()])) {
120
+                $tmp[$share->getNodeId()] = [];
121
+            }
122
+            $tmp[$share->getNodeId()][] = $share;
123
+        }
124
+
125
+        $result = [];
126
+        // sort by stime, the super share will be based on the least recent share
127
+        foreach ($tmp as &$tmp2) {
128
+            @usort($tmp2, function($a, $b) {
129
+                if ($a->getShareTime() <= $b->getShareTime()) {
130
+                    return -1;
131
+                }
132
+                return 1;
133
+            });
134
+            $result[] = $tmp2;
135
+        }
136
+
137
+        return array_values($result);
138
+    }
139
+
140
+    /**
141
+     * Build super shares (virtual share) by grouping them by node id and target,
142
+     * then for each group compute the super share and return it along with the matching
143
+     * grouped shares. The most permissive permissions are used based on the permissions
144
+     * of all shares within the group.
145
+     *
146
+     * @param \OCP\Share\IShare[] $allShares
147
+     * @param \OCP\IUser $user user
148
+     * @return array Tuple of [superShare, groupedShares]
149
+     */
150
+    private function buildSuperShares(array $allShares, \OCP\IUser $user) {
151
+        $result = [];
152
+
153
+        $groupedShares = $this->groupShares($allShares);
154
+
155
+        /** @var \OCP\Share\IShare[] $shares */
156
+        foreach ($groupedShares as $shares) {
157
+            if (count($shares) === 0) {
158
+                continue;
159
+            }
160
+
161
+            $superShare = $this->shareManager->newShare();
162
+
163
+            // compute super share based on first entry of the group
164
+            $superShare->setId($shares[0]->getId())
165
+                ->setShareOwner($shares[0]->getShareOwner())
166
+                ->setNodeId($shares[0]->getNodeId())
167
+                ->setTarget($shares[0]->getTarget());
168
+
169
+            // use most permissive permissions
170
+            $permissions = 0;
171
+            foreach ($shares as $share) {
172
+                $permissions |= $share->getPermissions();
173
+                if ($share->getTarget() !== $superShare->getTarget()) {
174
+                    // adjust target, for database consistency
175
+                    $share->setTarget($superShare->getTarget());
176
+                    $this->shareManager->moveShare($share, $user->getUID());
177
+                }
178
+                if (!is_null($share->getNodeCacheEntry())) {
179
+                    $superShare->setNodeCacheEntry($share->getNodeCacheEntry());
180
+                }
181
+            }
182
+
183
+            $superShare->setPermissions($permissions);
184
+
185
+            $result[] = [$superShare, $shares];
186
+        }
187
+
188
+        return $result;
189
+    }
190 190
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -74,7 +74,7 @@
 block discarded – undo
74 74
 		$shares = array_merge($shares, $this->shareManager->getSharedWith($user->getUID(), \OCP\Share::SHARE_TYPE_CIRCLE, null, -1));
75 75
 
76 76
 		// filter out excluded shares and group shares that includes self
77
-		$shares = array_filter($shares, function (\OCP\Share\IShare $share) use ($user) {
77
+		$shares = array_filter($shares, function(\OCP\Share\IShare $share) use ($user) {
78 78
 			return $share->getPermissions() > 0 && $share->getShareOwner() !== $user->getUID();
79 79
 		});
80 80
 
Please login to merge, or discard this patch.
lib/private/Share/Constants.php 1 patch
Indentation   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -26,25 +26,25 @@
 block discarded – undo
26 26
 
27 27
 class Constants {
28 28
 
29
-	const SHARE_TYPE_USER = 0;
30
-	const SHARE_TYPE_GROUP = 1;
31
-	const SHARE_TYPE_LINK = 3;
32
-	const SHARE_TYPE_EMAIL = 4;
33
-	const SHARE_TYPE_CONTACT = 5; // ToDo Check if it is still in use otherwise remove it
34
-	const SHARE_TYPE_REMOTE = 6;
35
-	const SHARE_TYPE_CIRCLE = 7;
29
+    const SHARE_TYPE_USER = 0;
30
+    const SHARE_TYPE_GROUP = 1;
31
+    const SHARE_TYPE_LINK = 3;
32
+    const SHARE_TYPE_EMAIL = 4;
33
+    const SHARE_TYPE_CONTACT = 5; // ToDo Check if it is still in use otherwise remove it
34
+    const SHARE_TYPE_REMOTE = 6;
35
+    const SHARE_TYPE_CIRCLE = 7;
36 36
 
37
-	const FORMAT_NONE = -1;
38
-	const FORMAT_STATUSES = -2;
39
-	const FORMAT_SOURCES = -3;  // ToDo Check if it is still in use otherwise remove it
37
+    const FORMAT_NONE = -1;
38
+    const FORMAT_STATUSES = -2;
39
+    const FORMAT_SOURCES = -3;  // ToDo Check if it is still in use otherwise remove it
40 40
 
41
-	const RESPONSE_FORMAT = 'json'; // default resonse format for ocs calls
41
+    const RESPONSE_FORMAT = 'json'; // default resonse format for ocs calls
42 42
 
43
-	const TOKEN_LENGTH = 15; // old (oc7) length is 32, keep token length in db at least that for compatibility
43
+    const TOKEN_LENGTH = 15; // old (oc7) length is 32, keep token length in db at least that for compatibility
44 44
 
45
-	protected static $shareTypeUserAndGroups = -1;
46
-	protected static $shareTypeGroupUserUnique = 2;
47
-	protected static $backends = array();
48
-	protected static $backendTypes = array();
49
-	protected static $isResharingAllowed;
45
+    protected static $shareTypeUserAndGroups = -1;
46
+    protected static $shareTypeGroupUserUnique = 2;
47
+    protected static $backends = array();
48
+    protected static $backendTypes = array();
49
+    protected static $isResharingAllowed;
50 50
 }
Please login to merge, or discard this patch.
lib/private/Share20/ProviderFactory.php 2 patches
Indentation   +213 added lines, -213 removed lines patch added patch discarded remove patch
@@ -40,224 +40,224 @@
 block discarded – undo
40 40
  */
41 41
 class ProviderFactory implements IProviderFactory {
42 42
 
43
-	/** @var IServerContainer */
44
-	private $serverContainer;
45
-	/** @var DefaultShareProvider */
46
-	private $defaultProvider = null;
47
-	/** @var FederatedShareProvider */
48
-	private $federatedProvider = null;
49
-	/** @var  ShareByMailProvider */
50
-	private $shareByMailProvider;
51
-	/** @var  \OCA\Circles\ShareByCircleProvider;
52
-	 * ShareByCircleProvider */
53
-	private $shareByCircleProvider;
54
-
55
-	/**
56
-	 * IProviderFactory constructor.
57
-	 *
58
-	 * @param IServerContainer $serverContainer
59
-	 */
60
-	public function __construct(IServerContainer $serverContainer) {
61
-		$this->serverContainer = $serverContainer;
62
-	}
63
-
64
-	/**
65
-	 * Create the default share provider.
66
-	 *
67
-	 * @return DefaultShareProvider
68
-	 */
69
-	protected function defaultShareProvider() {
70
-		if ($this->defaultProvider === null) {
71
-			$this->defaultProvider = new DefaultShareProvider(
72
-				$this->serverContainer->getDatabaseConnection(),
73
-				$this->serverContainer->getUserManager(),
74
-				$this->serverContainer->getGroupManager(),
75
-				$this->serverContainer->getLazyRootFolder()
76
-			);
77
-		}
78
-
79
-		return $this->defaultProvider;
80
-	}
81
-
82
-	/**
83
-	 * Create the federated share provider
84
-	 *
85
-	 * @return FederatedShareProvider
86
-	 */
87
-	protected function federatedShareProvider() {
88
-		if ($this->federatedProvider === null) {
89
-			/*
43
+    /** @var IServerContainer */
44
+    private $serverContainer;
45
+    /** @var DefaultShareProvider */
46
+    private $defaultProvider = null;
47
+    /** @var FederatedShareProvider */
48
+    private $federatedProvider = null;
49
+    /** @var  ShareByMailProvider */
50
+    private $shareByMailProvider;
51
+    /** @var  \OCA\Circles\ShareByCircleProvider;
52
+     * ShareByCircleProvider */
53
+    private $shareByCircleProvider;
54
+
55
+    /**
56
+     * IProviderFactory constructor.
57
+     *
58
+     * @param IServerContainer $serverContainer
59
+     */
60
+    public function __construct(IServerContainer $serverContainer) {
61
+        $this->serverContainer = $serverContainer;
62
+    }
63
+
64
+    /**
65
+     * Create the default share provider.
66
+     *
67
+     * @return DefaultShareProvider
68
+     */
69
+    protected function defaultShareProvider() {
70
+        if ($this->defaultProvider === null) {
71
+            $this->defaultProvider = new DefaultShareProvider(
72
+                $this->serverContainer->getDatabaseConnection(),
73
+                $this->serverContainer->getUserManager(),
74
+                $this->serverContainer->getGroupManager(),
75
+                $this->serverContainer->getLazyRootFolder()
76
+            );
77
+        }
78
+
79
+        return $this->defaultProvider;
80
+    }
81
+
82
+    /**
83
+     * Create the federated share provider
84
+     *
85
+     * @return FederatedShareProvider
86
+     */
87
+    protected function federatedShareProvider() {
88
+        if ($this->federatedProvider === null) {
89
+            /*
90 90
 			 * Check if the app is enabled
91 91
 			 */
92
-			$appManager = $this->serverContainer->getAppManager();
93
-			if (!$appManager->isEnabledForUser('federatedfilesharing')) {
94
-				return null;
95
-			}
92
+            $appManager = $this->serverContainer->getAppManager();
93
+            if (!$appManager->isEnabledForUser('federatedfilesharing')) {
94
+                return null;
95
+            }
96 96
 
97
-			/*
97
+            /*
98 98
 			 * TODO: add factory to federated sharing app
99 99
 			 */
100
-			$l = $this->serverContainer->getL10N('federatedfilessharing');
101
-			$addressHandler = new AddressHandler(
102
-				$this->serverContainer->getURLGenerator(),
103
-				$l,
104
-				$this->serverContainer->getCloudIdManager()
105
-			);
106
-			$discoveryManager = new DiscoveryManager(
107
-				$this->serverContainer->getMemCacheFactory(),
108
-				$this->serverContainer->getHTTPClientService()
109
-			);
110
-			$notifications = new Notifications(
111
-				$addressHandler,
112
-				$this->serverContainer->getHTTPClientService(),
113
-				$discoveryManager,
114
-				$this->serverContainer->getJobList()
115
-			);
116
-			$tokenHandler = new TokenHandler(
117
-				$this->serverContainer->getSecureRandom()
118
-			);
119
-
120
-			$this->federatedProvider = new FederatedShareProvider(
121
-				$this->serverContainer->getDatabaseConnection(),
122
-				$addressHandler,
123
-				$notifications,
124
-				$tokenHandler,
125
-				$l,
126
-				$this->serverContainer->getLogger(),
127
-				$this->serverContainer->getLazyRootFolder(),
128
-				$this->serverContainer->getConfig(),
129
-				$this->serverContainer->getUserManager(),
130
-				$this->serverContainer->getCloudIdManager()
131
-			);
132
-		}
133
-
134
-		return $this->federatedProvider;
135
-	}
136
-
137
-	/**
138
-	 * Create the federated share provider
139
-	 *
140
-	 * @return ShareByMailProvider
141
-	 */
142
-	protected function getShareByMailProvider() {
143
-		if ($this->shareByMailProvider === null) {
144
-			/*
100
+            $l = $this->serverContainer->getL10N('federatedfilessharing');
101
+            $addressHandler = new AddressHandler(
102
+                $this->serverContainer->getURLGenerator(),
103
+                $l,
104
+                $this->serverContainer->getCloudIdManager()
105
+            );
106
+            $discoveryManager = new DiscoveryManager(
107
+                $this->serverContainer->getMemCacheFactory(),
108
+                $this->serverContainer->getHTTPClientService()
109
+            );
110
+            $notifications = new Notifications(
111
+                $addressHandler,
112
+                $this->serverContainer->getHTTPClientService(),
113
+                $discoveryManager,
114
+                $this->serverContainer->getJobList()
115
+            );
116
+            $tokenHandler = new TokenHandler(
117
+                $this->serverContainer->getSecureRandom()
118
+            );
119
+
120
+            $this->federatedProvider = new FederatedShareProvider(
121
+                $this->serverContainer->getDatabaseConnection(),
122
+                $addressHandler,
123
+                $notifications,
124
+                $tokenHandler,
125
+                $l,
126
+                $this->serverContainer->getLogger(),
127
+                $this->serverContainer->getLazyRootFolder(),
128
+                $this->serverContainer->getConfig(),
129
+                $this->serverContainer->getUserManager(),
130
+                $this->serverContainer->getCloudIdManager()
131
+            );
132
+        }
133
+
134
+        return $this->federatedProvider;
135
+    }
136
+
137
+    /**
138
+     * Create the federated share provider
139
+     *
140
+     * @return ShareByMailProvider
141
+     */
142
+    protected function getShareByMailProvider() {
143
+        if ($this->shareByMailProvider === null) {
144
+            /*
145 145
 			 * Check if the app is enabled
146 146
 			 */
147
-			$appManager = $this->serverContainer->getAppManager();
148
-			if (!$appManager->isEnabledForUser('sharebymail')) {
149
-				return null;
150
-			}
151
-
152
-			$l = $this->serverContainer->getL10N('sharebymail');
153
-
154
-			$this->shareByMailProvider = new ShareByMailProvider(
155
-				$this->serverContainer->getDatabaseConnection(),
156
-				$this->serverContainer->getSecureRandom(),
157
-				$this->serverContainer->getUserManager(),
158
-				$this->serverContainer->getLazyRootFolder(),
159
-				$l,
160
-				$this->serverContainer->getLogger(),
161
-				$this->serverContainer->getMailer(),
162
-				$this->serverContainer->getURLGenerator(),
163
-				$this->serverContainer->getActivityManager()
164
-			);
165
-		}
166
-
167
-		return $this->shareByMailProvider;
168
-	}
169
-
170
-
171
-	/**
172
-	 * Create the circle share provider
173
-	 *
174
-	 * @return FederatedShareProvider
175
-	 */
176
-	protected function getShareByCircleProvider() {
177
-
178
-		$appManager = $this->serverContainer->getAppManager();
179
-		if (!$appManager->isEnabledForUser('circles')) {
180
-			return null;
181
-		}
182
-
183
-
184
-		if ($this->shareByCircleProvider === null) {
185
-
186
-			$this->shareByCircleProvider = new \OCA\Circles\ShareByCircleProvider(
187
-				$this->serverContainer->getDatabaseConnection(),
188
-				$this->serverContainer->getSecureRandom(),
189
-				$this->serverContainer->getUserManager(),
190
-				$this->serverContainer->getLazyRootFolder(),
191
-				$this->serverContainer->getL10N('circles'),
192
-				$this->serverContainer->getLogger(),
193
-				$this->serverContainer->getURLGenerator()
194
-			);
195
-		}
196
-
197
-		return $this->shareByCircleProvider;
198
-	}
199
-
200
-
201
-	/**
202
-	 * @inheritdoc
203
-	 */
204
-	public function getProvider($id) {
205
-		$provider = null;
206
-		if ($id === 'ocinternal') {
207
-			$provider = $this->defaultShareProvider();
208
-		} else if ($id === 'ocFederatedSharing') {
209
-			$provider = $this->federatedShareProvider();
210
-		} else if ($id === 'ocMailShare') {
211
-			$provider = $this->getShareByMailProvider();
212
-		} else if ($id === 'ocCircleShare') {
213
-			$provider = $this->getShareByCircleProvider();
214
-		}
215
-
216
-		if ($provider === null) {
217
-			throw new ProviderException('No provider with id .' . $id . ' found.');
218
-		}
219
-
220
-		return $provider;
221
-	}
222
-
223
-	/**
224
-	 * @inheritdoc
225
-	 */
226
-	public function getProviderForType($shareType) {
227
-		$provider = null;
228
-
229
-		if ($shareType === \OCP\Share::SHARE_TYPE_USER ||
230
-			$shareType === \OCP\Share::SHARE_TYPE_GROUP ||
231
-			$shareType === \OCP\Share::SHARE_TYPE_LINK
232
-		) {
233
-			$provider = $this->defaultShareProvider();
234
-		} else if ($shareType === \OCP\Share::SHARE_TYPE_REMOTE) {
235
-			$provider = $this->federatedShareProvider();
236
-		} else if ($shareType === \OCP\Share::SHARE_TYPE_EMAIL) {
237
-			$provider = $this->getShareByMailProvider();
238
-		} else if ($shareType === \OCP\Share::SHARE_TYPE_CIRCLE) {
239
-			$provider = $this->getShareByCircleProvider();
240
-		}
241
-
242
-
243
-		if ($provider === null) {
244
-			throw new ProviderException('No share provider for share type ' . $shareType);
245
-		}
246
-
247
-		return $provider;
248
-	}
249
-
250
-	public function getAllProviders() {
251
-		$shares = [$this->defaultShareProvider(), $this->federatedShareProvider()];
252
-		$shareByMail = $this->getShareByMailProvider();
253
-		if ($shareByMail !== null) {
254
-			$shares[] = $shareByMail;
255
-		}
256
-		$shareByCircle = $this->getShareByCircleProvider();
257
-		if ($shareByCircle !== null) {
258
-			$shares[] = $shareByCircle;
259
-		}
260
-
261
-		return $shares;
262
-	}
147
+            $appManager = $this->serverContainer->getAppManager();
148
+            if (!$appManager->isEnabledForUser('sharebymail')) {
149
+                return null;
150
+            }
151
+
152
+            $l = $this->serverContainer->getL10N('sharebymail');
153
+
154
+            $this->shareByMailProvider = new ShareByMailProvider(
155
+                $this->serverContainer->getDatabaseConnection(),
156
+                $this->serverContainer->getSecureRandom(),
157
+                $this->serverContainer->getUserManager(),
158
+                $this->serverContainer->getLazyRootFolder(),
159
+                $l,
160
+                $this->serverContainer->getLogger(),
161
+                $this->serverContainer->getMailer(),
162
+                $this->serverContainer->getURLGenerator(),
163
+                $this->serverContainer->getActivityManager()
164
+            );
165
+        }
166
+
167
+        return $this->shareByMailProvider;
168
+    }
169
+
170
+
171
+    /**
172
+     * Create the circle share provider
173
+     *
174
+     * @return FederatedShareProvider
175
+     */
176
+    protected function getShareByCircleProvider() {
177
+
178
+        $appManager = $this->serverContainer->getAppManager();
179
+        if (!$appManager->isEnabledForUser('circles')) {
180
+            return null;
181
+        }
182
+
183
+
184
+        if ($this->shareByCircleProvider === null) {
185
+
186
+            $this->shareByCircleProvider = new \OCA\Circles\ShareByCircleProvider(
187
+                $this->serverContainer->getDatabaseConnection(),
188
+                $this->serverContainer->getSecureRandom(),
189
+                $this->serverContainer->getUserManager(),
190
+                $this->serverContainer->getLazyRootFolder(),
191
+                $this->serverContainer->getL10N('circles'),
192
+                $this->serverContainer->getLogger(),
193
+                $this->serverContainer->getURLGenerator()
194
+            );
195
+        }
196
+
197
+        return $this->shareByCircleProvider;
198
+    }
199
+
200
+
201
+    /**
202
+     * @inheritdoc
203
+     */
204
+    public function getProvider($id) {
205
+        $provider = null;
206
+        if ($id === 'ocinternal') {
207
+            $provider = $this->defaultShareProvider();
208
+        } else if ($id === 'ocFederatedSharing') {
209
+            $provider = $this->federatedShareProvider();
210
+        } else if ($id === 'ocMailShare') {
211
+            $provider = $this->getShareByMailProvider();
212
+        } else if ($id === 'ocCircleShare') {
213
+            $provider = $this->getShareByCircleProvider();
214
+        }
215
+
216
+        if ($provider === null) {
217
+            throw new ProviderException('No provider with id .' . $id . ' found.');
218
+        }
219
+
220
+        return $provider;
221
+    }
222
+
223
+    /**
224
+     * @inheritdoc
225
+     */
226
+    public function getProviderForType($shareType) {
227
+        $provider = null;
228
+
229
+        if ($shareType === \OCP\Share::SHARE_TYPE_USER ||
230
+            $shareType === \OCP\Share::SHARE_TYPE_GROUP ||
231
+            $shareType === \OCP\Share::SHARE_TYPE_LINK
232
+        ) {
233
+            $provider = $this->defaultShareProvider();
234
+        } else if ($shareType === \OCP\Share::SHARE_TYPE_REMOTE) {
235
+            $provider = $this->federatedShareProvider();
236
+        } else if ($shareType === \OCP\Share::SHARE_TYPE_EMAIL) {
237
+            $provider = $this->getShareByMailProvider();
238
+        } else if ($shareType === \OCP\Share::SHARE_TYPE_CIRCLE) {
239
+            $provider = $this->getShareByCircleProvider();
240
+        }
241
+
242
+
243
+        if ($provider === null) {
244
+            throw new ProviderException('No share provider for share type ' . $shareType);
245
+        }
246
+
247
+        return $provider;
248
+    }
249
+
250
+    public function getAllProviders() {
251
+        $shares = [$this->defaultShareProvider(), $this->federatedShareProvider()];
252
+        $shareByMail = $this->getShareByMailProvider();
253
+        if ($shareByMail !== null) {
254
+            $shares[] = $shareByMail;
255
+        }
256
+        $shareByCircle = $this->getShareByCircleProvider();
257
+        if ($shareByCircle !== null) {
258
+            $shares[] = $shareByCircle;
259
+        }
260
+
261
+        return $shares;
262
+    }
263 263
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -214,7 +214,7 @@  discard block
 block discarded – undo
214 214
 		}
215 215
 
216 216
 		if ($provider === null) {
217
-			throw new ProviderException('No provider with id .' . $id . ' found.');
217
+			throw new ProviderException('No provider with id .'.$id.' found.');
218 218
 		}
219 219
 
220 220
 		return $provider;
@@ -241,7 +241,7 @@  discard block
 block discarded – undo
241 241
 
242 242
 
243 243
 		if ($provider === null) {
244
-			throw new ProviderException('No share provider for share type ' . $shareType);
244
+			throw new ProviderException('No share provider for share type '.$shareType);
245 245
 		}
246 246
 
247 247
 		return $provider;
Please login to merge, or discard this patch.
lib/private/Share20/Manager.php 1 patch
Indentation   +1269 added lines, -1269 removed lines patch added patch discarded remove patch
@@ -57,1296 +57,1296 @@
 block discarded – undo
57 57
  */
58 58
 class Manager implements IManager {
59 59
 
60
-	/** @var IProviderFactory */
61
-	private $factory;
62
-	/** @var ILogger */
63
-	private $logger;
64
-	/** @var IConfig */
65
-	private $config;
66
-	/** @var ISecureRandom */
67
-	private $secureRandom;
68
-	/** @var IHasher */
69
-	private $hasher;
70
-	/** @var IMountManager */
71
-	private $mountManager;
72
-	/** @var IGroupManager */
73
-	private $groupManager;
74
-	/** @var IL10N */
75
-	private $l;
76
-	/** @var IUserManager */
77
-	private $userManager;
78
-	/** @var IRootFolder */
79
-	private $rootFolder;
80
-	/** @var CappedMemoryCache */
81
-	private $sharingDisabledForUsersCache;
82
-	/** @var EventDispatcher */
83
-	private $eventDispatcher;
84
-
85
-
86
-	/**
87
-	 * Manager constructor.
88
-	 *
89
-	 * @param ILogger $logger
90
-	 * @param IConfig $config
91
-	 * @param ISecureRandom $secureRandom
92
-	 * @param IHasher $hasher
93
-	 * @param IMountManager $mountManager
94
-	 * @param IGroupManager $groupManager
95
-	 * @param IL10N $l
96
-	 * @param IProviderFactory $factory
97
-	 * @param IUserManager $userManager
98
-	 * @param IRootFolder $rootFolder
99
-	 * @param EventDispatcher $eventDispatcher
100
-	 */
101
-	public function __construct(
102
-			ILogger $logger,
103
-			IConfig $config,
104
-			ISecureRandom $secureRandom,
105
-			IHasher $hasher,
106
-			IMountManager $mountManager,
107
-			IGroupManager $groupManager,
108
-			IL10N $l,
109
-			IProviderFactory $factory,
110
-			IUserManager $userManager,
111
-			IRootFolder $rootFolder,
112
-			EventDispatcher $eventDispatcher
113
-	) {
114
-		$this->logger = $logger;
115
-		$this->config = $config;
116
-		$this->secureRandom = $secureRandom;
117
-		$this->hasher = $hasher;
118
-		$this->mountManager = $mountManager;
119
-		$this->groupManager = $groupManager;
120
-		$this->l = $l;
121
-		$this->factory = $factory;
122
-		$this->userManager = $userManager;
123
-		$this->rootFolder = $rootFolder;
124
-		$this->eventDispatcher = $eventDispatcher;
125
-		$this->sharingDisabledForUsersCache = new CappedMemoryCache();
126
-	}
127
-
128
-	/**
129
-	 * Convert from a full share id to a tuple (providerId, shareId)
130
-	 *
131
-	 * @param string $id
132
-	 * @return string[]
133
-	 */
134
-	private function splitFullId($id) {
135
-		return explode(':', $id, 2);
136
-	}
137
-
138
-	/**
139
-	 * Verify if a password meets all requirements
140
-	 *
141
-	 * @param string $password
142
-	 * @throws \Exception
143
-	 */
144
-	protected function verifyPassword($password) {
145
-		if ($password === null) {
146
-			// No password is set, check if this is allowed.
147
-			if ($this->shareApiLinkEnforcePassword()) {
148
-				throw new \InvalidArgumentException('Passwords are enforced for link shares');
149
-			}
150
-
151
-			return;
152
-		}
153
-
154
-		// Let others verify the password
155
-		try {
156
-			$event = new GenericEvent($password);
157
-			$this->eventDispatcher->dispatch('OCP\PasswordPolicy::validate', $event);
158
-		} catch (HintException $e) {
159
-			throw new \Exception($e->getHint());
160
-		}
161
-	}
162
-
163
-	/**
164
-	 * Check for generic requirements before creating a share
165
-	 *
166
-	 * @param \OCP\Share\IShare $share
167
-	 * @throws \InvalidArgumentException
168
-	 * @throws GenericShareException
169
-	 */
170
-	protected function generalCreateChecks(\OCP\Share\IShare $share) {
171
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
172
-			// We expect a valid user as sharedWith for user shares
173
-			if (!$this->userManager->userExists($share->getSharedWith())) {
174
-				throw new \InvalidArgumentException('SharedWith is not a valid user');
175
-			}
176
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
177
-			// We expect a valid group as sharedWith for group shares
178
-			if (!$this->groupManager->groupExists($share->getSharedWith())) {
179
-				throw new \InvalidArgumentException('SharedWith is not a valid group');
180
-			}
181
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
182
-			if ($share->getSharedWith() !== null) {
183
-				throw new \InvalidArgumentException('SharedWith should be empty');
184
-			}
185
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_REMOTE) {
186
-			if ($share->getSharedWith() === null) {
187
-				throw new \InvalidArgumentException('SharedWith should not be empty');
188
-			}
189
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
190
-			if ($share->getSharedWith() === null) {
191
-				throw new \InvalidArgumentException('SharedWith should not be empty');
192
-			}
193
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_CIRCLE) {
194
-			$circle = \OCA\Circles\Api\Circles::detailsCircle($share->getSharedWith());
195
-			if ($circle === null) {
196
-				throw new \InvalidArgumentException('SharedWith is not a valid circle');
197
-			}
198
-		} else {
199
-			// We can't handle other types yet
200
-			throw new \InvalidArgumentException('unknown share type');
201
-		}
202
-
203
-		// Verify the initiator of the share is set
204
-		if ($share->getSharedBy() === null) {
205
-			throw new \InvalidArgumentException('SharedBy should be set');
206
-		}
207
-
208
-		// Cannot share with yourself
209
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
210
-			$share->getSharedWith() === $share->getSharedBy()) {
211
-			throw new \InvalidArgumentException('Can\'t share with yourself');
212
-		}
213
-
214
-		// The path should be set
215
-		if ($share->getNode() === null) {
216
-			throw new \InvalidArgumentException('Path should be set');
217
-		}
218
-
219
-		// And it should be a file or a folder
220
-		if (!($share->getNode() instanceof \OCP\Files\File) &&
221
-				!($share->getNode() instanceof \OCP\Files\Folder)) {
222
-			throw new \InvalidArgumentException('Path should be either a file or a folder');
223
-		}
224
-
225
-		// And you can't share your rootfolder
226
-		if ($this->userManager->userExists($share->getSharedBy())) {
227
-			$sharedPath = $this->rootFolder->getUserFolder($share->getSharedBy())->getPath();
228
-		} else {
229
-			$sharedPath = $this->rootFolder->getUserFolder($share->getShareOwner())->getPath();
230
-		}
231
-		if ($sharedPath === $share->getNode()->getPath()) {
232
-			throw new \InvalidArgumentException('You can\'t share your root folder');
233
-		}
234
-
235
-		// Check if we actually have share permissions
236
-		if (!$share->getNode()->isShareable()) {
237
-			$message_t = $this->l->t('You are not allowed to share %s', [$share->getNode()->getPath()]);
238
-			throw new GenericShareException($message_t, $message_t, 404);
239
-		}
240
-
241
-		// Permissions should be set
242
-		if ($share->getPermissions() === null) {
243
-			throw new \InvalidArgumentException('A share requires permissions');
244
-		}
245
-
246
-		/*
60
+    /** @var IProviderFactory */
61
+    private $factory;
62
+    /** @var ILogger */
63
+    private $logger;
64
+    /** @var IConfig */
65
+    private $config;
66
+    /** @var ISecureRandom */
67
+    private $secureRandom;
68
+    /** @var IHasher */
69
+    private $hasher;
70
+    /** @var IMountManager */
71
+    private $mountManager;
72
+    /** @var IGroupManager */
73
+    private $groupManager;
74
+    /** @var IL10N */
75
+    private $l;
76
+    /** @var IUserManager */
77
+    private $userManager;
78
+    /** @var IRootFolder */
79
+    private $rootFolder;
80
+    /** @var CappedMemoryCache */
81
+    private $sharingDisabledForUsersCache;
82
+    /** @var EventDispatcher */
83
+    private $eventDispatcher;
84
+
85
+
86
+    /**
87
+     * Manager constructor.
88
+     *
89
+     * @param ILogger $logger
90
+     * @param IConfig $config
91
+     * @param ISecureRandom $secureRandom
92
+     * @param IHasher $hasher
93
+     * @param IMountManager $mountManager
94
+     * @param IGroupManager $groupManager
95
+     * @param IL10N $l
96
+     * @param IProviderFactory $factory
97
+     * @param IUserManager $userManager
98
+     * @param IRootFolder $rootFolder
99
+     * @param EventDispatcher $eventDispatcher
100
+     */
101
+    public function __construct(
102
+            ILogger $logger,
103
+            IConfig $config,
104
+            ISecureRandom $secureRandom,
105
+            IHasher $hasher,
106
+            IMountManager $mountManager,
107
+            IGroupManager $groupManager,
108
+            IL10N $l,
109
+            IProviderFactory $factory,
110
+            IUserManager $userManager,
111
+            IRootFolder $rootFolder,
112
+            EventDispatcher $eventDispatcher
113
+    ) {
114
+        $this->logger = $logger;
115
+        $this->config = $config;
116
+        $this->secureRandom = $secureRandom;
117
+        $this->hasher = $hasher;
118
+        $this->mountManager = $mountManager;
119
+        $this->groupManager = $groupManager;
120
+        $this->l = $l;
121
+        $this->factory = $factory;
122
+        $this->userManager = $userManager;
123
+        $this->rootFolder = $rootFolder;
124
+        $this->eventDispatcher = $eventDispatcher;
125
+        $this->sharingDisabledForUsersCache = new CappedMemoryCache();
126
+    }
127
+
128
+    /**
129
+     * Convert from a full share id to a tuple (providerId, shareId)
130
+     *
131
+     * @param string $id
132
+     * @return string[]
133
+     */
134
+    private function splitFullId($id) {
135
+        return explode(':', $id, 2);
136
+    }
137
+
138
+    /**
139
+     * Verify if a password meets all requirements
140
+     *
141
+     * @param string $password
142
+     * @throws \Exception
143
+     */
144
+    protected function verifyPassword($password) {
145
+        if ($password === null) {
146
+            // No password is set, check if this is allowed.
147
+            if ($this->shareApiLinkEnforcePassword()) {
148
+                throw new \InvalidArgumentException('Passwords are enforced for link shares');
149
+            }
150
+
151
+            return;
152
+        }
153
+
154
+        // Let others verify the password
155
+        try {
156
+            $event = new GenericEvent($password);
157
+            $this->eventDispatcher->dispatch('OCP\PasswordPolicy::validate', $event);
158
+        } catch (HintException $e) {
159
+            throw new \Exception($e->getHint());
160
+        }
161
+    }
162
+
163
+    /**
164
+     * Check for generic requirements before creating a share
165
+     *
166
+     * @param \OCP\Share\IShare $share
167
+     * @throws \InvalidArgumentException
168
+     * @throws GenericShareException
169
+     */
170
+    protected function generalCreateChecks(\OCP\Share\IShare $share) {
171
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
172
+            // We expect a valid user as sharedWith for user shares
173
+            if (!$this->userManager->userExists($share->getSharedWith())) {
174
+                throw new \InvalidArgumentException('SharedWith is not a valid user');
175
+            }
176
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
177
+            // We expect a valid group as sharedWith for group shares
178
+            if (!$this->groupManager->groupExists($share->getSharedWith())) {
179
+                throw new \InvalidArgumentException('SharedWith is not a valid group');
180
+            }
181
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
182
+            if ($share->getSharedWith() !== null) {
183
+                throw new \InvalidArgumentException('SharedWith should be empty');
184
+            }
185
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_REMOTE) {
186
+            if ($share->getSharedWith() === null) {
187
+                throw new \InvalidArgumentException('SharedWith should not be empty');
188
+            }
189
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
190
+            if ($share->getSharedWith() === null) {
191
+                throw new \InvalidArgumentException('SharedWith should not be empty');
192
+            }
193
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_CIRCLE) {
194
+            $circle = \OCA\Circles\Api\Circles::detailsCircle($share->getSharedWith());
195
+            if ($circle === null) {
196
+                throw new \InvalidArgumentException('SharedWith is not a valid circle');
197
+            }
198
+        } else {
199
+            // We can't handle other types yet
200
+            throw new \InvalidArgumentException('unknown share type');
201
+        }
202
+
203
+        // Verify the initiator of the share is set
204
+        if ($share->getSharedBy() === null) {
205
+            throw new \InvalidArgumentException('SharedBy should be set');
206
+        }
207
+
208
+        // Cannot share with yourself
209
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
210
+            $share->getSharedWith() === $share->getSharedBy()) {
211
+            throw new \InvalidArgumentException('Can\'t share with yourself');
212
+        }
213
+
214
+        // The path should be set
215
+        if ($share->getNode() === null) {
216
+            throw new \InvalidArgumentException('Path should be set');
217
+        }
218
+
219
+        // And it should be a file or a folder
220
+        if (!($share->getNode() instanceof \OCP\Files\File) &&
221
+                !($share->getNode() instanceof \OCP\Files\Folder)) {
222
+            throw new \InvalidArgumentException('Path should be either a file or a folder');
223
+        }
224
+
225
+        // And you can't share your rootfolder
226
+        if ($this->userManager->userExists($share->getSharedBy())) {
227
+            $sharedPath = $this->rootFolder->getUserFolder($share->getSharedBy())->getPath();
228
+        } else {
229
+            $sharedPath = $this->rootFolder->getUserFolder($share->getShareOwner())->getPath();
230
+        }
231
+        if ($sharedPath === $share->getNode()->getPath()) {
232
+            throw new \InvalidArgumentException('You can\'t share your root folder');
233
+        }
234
+
235
+        // Check if we actually have share permissions
236
+        if (!$share->getNode()->isShareable()) {
237
+            $message_t = $this->l->t('You are not allowed to share %s', [$share->getNode()->getPath()]);
238
+            throw new GenericShareException($message_t, $message_t, 404);
239
+        }
240
+
241
+        // Permissions should be set
242
+        if ($share->getPermissions() === null) {
243
+            throw new \InvalidArgumentException('A share requires permissions');
244
+        }
245
+
246
+        /*
247 247
 		 * Quick fix for #23536
248 248
 		 * Non moveable mount points do not have update and delete permissions
249 249
 		 * while we 'most likely' do have that on the storage.
250 250
 		 */
251
-		$permissions = $share->getNode()->getPermissions();
252
-		$mount = $share->getNode()->getMountPoint();
253
-		if (!($mount instanceof MoveableMount)) {
254
-			$permissions |= \OCP\Constants::PERMISSION_DELETE | \OCP\Constants::PERMISSION_UPDATE;
255
-		}
256
-
257
-		// Check that we do not share with more permissions than we have
258
-		if ($share->getPermissions() & ~$permissions) {
259
-			$message_t = $this->l->t('Cannot increase permissions of %s', [$share->getNode()->getPath()]);
260
-			throw new GenericShareException($message_t, $message_t, 404);
261
-		}
262
-
263
-
264
-		// Check that read permissions are always set
265
-		// Link shares are allowed to have no read permissions to allow upload to hidden folders
266
-		if ($share->getShareType() !== \OCP\Share::SHARE_TYPE_LINK &&
267
-			($share->getPermissions() & \OCP\Constants::PERMISSION_READ) === 0) {
268
-			throw new \InvalidArgumentException('Shares need at least read permissions');
269
-		}
270
-
271
-		if ($share->getNode() instanceof \OCP\Files\File) {
272
-			if ($share->getPermissions() & \OCP\Constants::PERMISSION_DELETE) {
273
-				$message_t = $this->l->t('Files can\'t be shared with delete permissions');
274
-				throw new GenericShareException($message_t);
275
-			}
276
-			if ($share->getPermissions() & \OCP\Constants::PERMISSION_CREATE) {
277
-				$message_t = $this->l->t('Files can\'t be shared with create permissions');
278
-				throw new GenericShareException($message_t);
279
-			}
280
-		}
281
-	}
282
-
283
-	/**
284
-	 * Validate if the expiration date fits the system settings
285
-	 *
286
-	 * @param \OCP\Share\IShare $share The share to validate the expiration date of
287
-	 * @return \OCP\Share\IShare The modified share object
288
-	 * @throws GenericShareException
289
-	 * @throws \InvalidArgumentException
290
-	 * @throws \Exception
291
-	 */
292
-	protected function validateExpirationDate(\OCP\Share\IShare $share) {
293
-
294
-		$expirationDate = $share->getExpirationDate();
295
-
296
-		if ($expirationDate !== null) {
297
-			//Make sure the expiration date is a date
298
-			$expirationDate->setTime(0, 0, 0);
299
-
300
-			$date = new \DateTime();
301
-			$date->setTime(0, 0, 0);
302
-			if ($date >= $expirationDate) {
303
-				$message = $this->l->t('Expiration date is in the past');
304
-				throw new GenericShareException($message, $message, 404);
305
-			}
306
-		}
307
-
308
-		// If expiredate is empty set a default one if there is a default
309
-		$fullId = null;
310
-		try {
311
-			$fullId = $share->getFullId();
312
-		} catch (\UnexpectedValueException $e) {
313
-			// This is a new share
314
-		}
315
-
316
-		if ($fullId === null && $expirationDate === null && $this->shareApiLinkDefaultExpireDate()) {
317
-			$expirationDate = new \DateTime();
318
-			$expirationDate->setTime(0,0,0);
319
-			$expirationDate->add(new \DateInterval('P'.$this->shareApiLinkDefaultExpireDays().'D'));
320
-		}
321
-
322
-		// If we enforce the expiration date check that is does not exceed
323
-		if ($this->shareApiLinkDefaultExpireDateEnforced()) {
324
-			if ($expirationDate === null) {
325
-				throw new \InvalidArgumentException('Expiration date is enforced');
326
-			}
327
-
328
-			$date = new \DateTime();
329
-			$date->setTime(0, 0, 0);
330
-			$date->add(new \DateInterval('P' . $this->shareApiLinkDefaultExpireDays() . 'D'));
331
-			if ($date < $expirationDate) {
332
-				$message = $this->l->t('Cannot set expiration date more than %s days in the future', [$this->shareApiLinkDefaultExpireDays()]);
333
-				throw new GenericShareException($message, $message, 404);
334
-			}
335
-		}
336
-
337
-		$accepted = true;
338
-		$message = '';
339
-		\OCP\Util::emitHook('\OC\Share', 'verifyExpirationDate', [
340
-			'expirationDate' => &$expirationDate,
341
-			'accepted' => &$accepted,
342
-			'message' => &$message,
343
-			'passwordSet' => $share->getPassword() !== null,
344
-		]);
345
-
346
-		if (!$accepted) {
347
-			throw new \Exception($message);
348
-		}
349
-
350
-		$share->setExpirationDate($expirationDate);
351
-
352
-		return $share;
353
-	}
354
-
355
-	/**
356
-	 * Check for pre share requirements for user shares
357
-	 *
358
-	 * @param \OCP\Share\IShare $share
359
-	 * @throws \Exception
360
-	 */
361
-	protected function userCreateChecks(\OCP\Share\IShare $share) {
362
-		// Check if we can share with group members only
363
-		if ($this->shareWithGroupMembersOnly()) {
364
-			$sharedBy = $this->userManager->get($share->getSharedBy());
365
-			$sharedWith = $this->userManager->get($share->getSharedWith());
366
-			// Verify we can share with this user
367
-			$groups = array_intersect(
368
-					$this->groupManager->getUserGroupIds($sharedBy),
369
-					$this->groupManager->getUserGroupIds($sharedWith)
370
-			);
371
-			if (empty($groups)) {
372
-				throw new \Exception('Only sharing with group members is allowed');
373
-			}
374
-		}
375
-
376
-		/*
251
+        $permissions = $share->getNode()->getPermissions();
252
+        $mount = $share->getNode()->getMountPoint();
253
+        if (!($mount instanceof MoveableMount)) {
254
+            $permissions |= \OCP\Constants::PERMISSION_DELETE | \OCP\Constants::PERMISSION_UPDATE;
255
+        }
256
+
257
+        // Check that we do not share with more permissions than we have
258
+        if ($share->getPermissions() & ~$permissions) {
259
+            $message_t = $this->l->t('Cannot increase permissions of %s', [$share->getNode()->getPath()]);
260
+            throw new GenericShareException($message_t, $message_t, 404);
261
+        }
262
+
263
+
264
+        // Check that read permissions are always set
265
+        // Link shares are allowed to have no read permissions to allow upload to hidden folders
266
+        if ($share->getShareType() !== \OCP\Share::SHARE_TYPE_LINK &&
267
+            ($share->getPermissions() & \OCP\Constants::PERMISSION_READ) === 0) {
268
+            throw new \InvalidArgumentException('Shares need at least read permissions');
269
+        }
270
+
271
+        if ($share->getNode() instanceof \OCP\Files\File) {
272
+            if ($share->getPermissions() & \OCP\Constants::PERMISSION_DELETE) {
273
+                $message_t = $this->l->t('Files can\'t be shared with delete permissions');
274
+                throw new GenericShareException($message_t);
275
+            }
276
+            if ($share->getPermissions() & \OCP\Constants::PERMISSION_CREATE) {
277
+                $message_t = $this->l->t('Files can\'t be shared with create permissions');
278
+                throw new GenericShareException($message_t);
279
+            }
280
+        }
281
+    }
282
+
283
+    /**
284
+     * Validate if the expiration date fits the system settings
285
+     *
286
+     * @param \OCP\Share\IShare $share The share to validate the expiration date of
287
+     * @return \OCP\Share\IShare The modified share object
288
+     * @throws GenericShareException
289
+     * @throws \InvalidArgumentException
290
+     * @throws \Exception
291
+     */
292
+    protected function validateExpirationDate(\OCP\Share\IShare $share) {
293
+
294
+        $expirationDate = $share->getExpirationDate();
295
+
296
+        if ($expirationDate !== null) {
297
+            //Make sure the expiration date is a date
298
+            $expirationDate->setTime(0, 0, 0);
299
+
300
+            $date = new \DateTime();
301
+            $date->setTime(0, 0, 0);
302
+            if ($date >= $expirationDate) {
303
+                $message = $this->l->t('Expiration date is in the past');
304
+                throw new GenericShareException($message, $message, 404);
305
+            }
306
+        }
307
+
308
+        // If expiredate is empty set a default one if there is a default
309
+        $fullId = null;
310
+        try {
311
+            $fullId = $share->getFullId();
312
+        } catch (\UnexpectedValueException $e) {
313
+            // This is a new share
314
+        }
315
+
316
+        if ($fullId === null && $expirationDate === null && $this->shareApiLinkDefaultExpireDate()) {
317
+            $expirationDate = new \DateTime();
318
+            $expirationDate->setTime(0,0,0);
319
+            $expirationDate->add(new \DateInterval('P'.$this->shareApiLinkDefaultExpireDays().'D'));
320
+        }
321
+
322
+        // If we enforce the expiration date check that is does not exceed
323
+        if ($this->shareApiLinkDefaultExpireDateEnforced()) {
324
+            if ($expirationDate === null) {
325
+                throw new \InvalidArgumentException('Expiration date is enforced');
326
+            }
327
+
328
+            $date = new \DateTime();
329
+            $date->setTime(0, 0, 0);
330
+            $date->add(new \DateInterval('P' . $this->shareApiLinkDefaultExpireDays() . 'D'));
331
+            if ($date < $expirationDate) {
332
+                $message = $this->l->t('Cannot set expiration date more than %s days in the future', [$this->shareApiLinkDefaultExpireDays()]);
333
+                throw new GenericShareException($message, $message, 404);
334
+            }
335
+        }
336
+
337
+        $accepted = true;
338
+        $message = '';
339
+        \OCP\Util::emitHook('\OC\Share', 'verifyExpirationDate', [
340
+            'expirationDate' => &$expirationDate,
341
+            'accepted' => &$accepted,
342
+            'message' => &$message,
343
+            'passwordSet' => $share->getPassword() !== null,
344
+        ]);
345
+
346
+        if (!$accepted) {
347
+            throw new \Exception($message);
348
+        }
349
+
350
+        $share->setExpirationDate($expirationDate);
351
+
352
+        return $share;
353
+    }
354
+
355
+    /**
356
+     * Check for pre share requirements for user shares
357
+     *
358
+     * @param \OCP\Share\IShare $share
359
+     * @throws \Exception
360
+     */
361
+    protected function userCreateChecks(\OCP\Share\IShare $share) {
362
+        // Check if we can share with group members only
363
+        if ($this->shareWithGroupMembersOnly()) {
364
+            $sharedBy = $this->userManager->get($share->getSharedBy());
365
+            $sharedWith = $this->userManager->get($share->getSharedWith());
366
+            // Verify we can share with this user
367
+            $groups = array_intersect(
368
+                    $this->groupManager->getUserGroupIds($sharedBy),
369
+                    $this->groupManager->getUserGroupIds($sharedWith)
370
+            );
371
+            if (empty($groups)) {
372
+                throw new \Exception('Only sharing with group members is allowed');
373
+            }
374
+        }
375
+
376
+        /*
377 377
 		 * TODO: Could be costly, fix
378 378
 		 *
379 379
 		 * Also this is not what we want in the future.. then we want to squash identical shares.
380 380
 		 */
381
-		$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_USER);
382
-		$existingShares = $provider->getSharesByPath($share->getNode());
383
-		foreach($existingShares as $existingShare) {
384
-			// Ignore if it is the same share
385
-			try {
386
-				if ($existingShare->getFullId() === $share->getFullId()) {
387
-					continue;
388
-				}
389
-			} catch (\UnexpectedValueException $e) {
390
-				//Shares are not identical
391
-			}
392
-
393
-			// Identical share already existst
394
-			if ($existingShare->getSharedWith() === $share->getSharedWith()) {
395
-				throw new \Exception('Path already shared with this user');
396
-			}
397
-
398
-			// The share is already shared with this user via a group share
399
-			if ($existingShare->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
400
-				$group = $this->groupManager->get($existingShare->getSharedWith());
401
-				$user = $this->userManager->get($share->getSharedWith());
402
-
403
-				if ($group->inGroup($user) && $existingShare->getShareOwner() !== $share->getShareOwner()) {
404
-					throw new \Exception('Path already shared with this user');
405
-				}
406
-			}
407
-		}
408
-	}
409
-
410
-	/**
411
-	 * Check for pre share requirements for group shares
412
-	 *
413
-	 * @param \OCP\Share\IShare $share
414
-	 * @throws \Exception
415
-	 */
416
-	protected function groupCreateChecks(\OCP\Share\IShare $share) {
417
-		// Verify group shares are allowed
418
-		if (!$this->allowGroupSharing()) {
419
-			throw new \Exception('Group sharing is now allowed');
420
-		}
421
-
422
-		// Verify if the user can share with this group
423
-		if ($this->shareWithGroupMembersOnly()) {
424
-			$sharedBy = $this->userManager->get($share->getSharedBy());
425
-			$sharedWith = $this->groupManager->get($share->getSharedWith());
426
-			if (!$sharedWith->inGroup($sharedBy)) {
427
-				throw new \Exception('Only sharing within your own groups is allowed');
428
-			}
429
-		}
430
-
431
-		/*
381
+        $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_USER);
382
+        $existingShares = $provider->getSharesByPath($share->getNode());
383
+        foreach($existingShares as $existingShare) {
384
+            // Ignore if it is the same share
385
+            try {
386
+                if ($existingShare->getFullId() === $share->getFullId()) {
387
+                    continue;
388
+                }
389
+            } catch (\UnexpectedValueException $e) {
390
+                //Shares are not identical
391
+            }
392
+
393
+            // Identical share already existst
394
+            if ($existingShare->getSharedWith() === $share->getSharedWith()) {
395
+                throw new \Exception('Path already shared with this user');
396
+            }
397
+
398
+            // The share is already shared with this user via a group share
399
+            if ($existingShare->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
400
+                $group = $this->groupManager->get($existingShare->getSharedWith());
401
+                $user = $this->userManager->get($share->getSharedWith());
402
+
403
+                if ($group->inGroup($user) && $existingShare->getShareOwner() !== $share->getShareOwner()) {
404
+                    throw new \Exception('Path already shared with this user');
405
+                }
406
+            }
407
+        }
408
+    }
409
+
410
+    /**
411
+     * Check for pre share requirements for group shares
412
+     *
413
+     * @param \OCP\Share\IShare $share
414
+     * @throws \Exception
415
+     */
416
+    protected function groupCreateChecks(\OCP\Share\IShare $share) {
417
+        // Verify group shares are allowed
418
+        if (!$this->allowGroupSharing()) {
419
+            throw new \Exception('Group sharing is now allowed');
420
+        }
421
+
422
+        // Verify if the user can share with this group
423
+        if ($this->shareWithGroupMembersOnly()) {
424
+            $sharedBy = $this->userManager->get($share->getSharedBy());
425
+            $sharedWith = $this->groupManager->get($share->getSharedWith());
426
+            if (!$sharedWith->inGroup($sharedBy)) {
427
+                throw new \Exception('Only sharing within your own groups is allowed');
428
+            }
429
+        }
430
+
431
+        /*
432 432
 		 * TODO: Could be costly, fix
433 433
 		 *
434 434
 		 * Also this is not what we want in the future.. then we want to squash identical shares.
435 435
 		 */
436
-		$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
437
-		$existingShares = $provider->getSharesByPath($share->getNode());
438
-		foreach($existingShares as $existingShare) {
439
-			try {
440
-				if ($existingShare->getFullId() === $share->getFullId()) {
441
-					continue;
442
-				}
443
-			} catch (\UnexpectedValueException $e) {
444
-				//It is a new share so just continue
445
-			}
446
-
447
-			if ($existingShare->getSharedWith() === $share->getSharedWith()) {
448
-				throw new \Exception('Path already shared with this group');
449
-			}
450
-		}
451
-	}
452
-
453
-	/**
454
-	 * Check for pre share requirements for link shares
455
-	 *
456
-	 * @param \OCP\Share\IShare $share
457
-	 * @throws \Exception
458
-	 */
459
-	protected function linkCreateChecks(\OCP\Share\IShare $share) {
460
-		// Are link shares allowed?
461
-		if (!$this->shareApiAllowLinks()) {
462
-			throw new \Exception('Link sharing not allowed');
463
-		}
464
-
465
-		// Link shares by definition can't have share permissions
466
-		if ($share->getPermissions() & \OCP\Constants::PERMISSION_SHARE) {
467
-			throw new \InvalidArgumentException('Link shares can\'t have reshare permissions');
468
-		}
469
-
470
-		// Check if public upload is allowed
471
-		if (!$this->shareApiLinkAllowPublicUpload() &&
472
-			($share->getPermissions() & (\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE))) {
473
-			throw new \InvalidArgumentException('Public upload not allowed');
474
-		}
475
-	}
476
-
477
-	/**
478
-	 * To make sure we don't get invisible link shares we set the parent
479
-	 * of a link if it is a reshare. This is a quick word around
480
-	 * until we can properly display multiple link shares in the UI
481
-	 *
482
-	 * See: https://github.com/owncloud/core/issues/22295
483
-	 *
484
-	 * FIXME: Remove once multiple link shares can be properly displayed
485
-	 *
486
-	 * @param \OCP\Share\IShare $share
487
-	 */
488
-	protected function setLinkParent(\OCP\Share\IShare $share) {
489
-
490
-		// No sense in checking if the method is not there.
491
-		if (method_exists($share, 'setParent')) {
492
-			$storage = $share->getNode()->getStorage();
493
-			if ($storage->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
494
-				/** @var \OCA\Files_Sharing\SharedStorage $storage */
495
-				$share->setParent($storage->getShareId());
496
-			}
497
-		};
498
-	}
499
-
500
-	/**
501
-	 * @param File|Folder $path
502
-	 */
503
-	protected function pathCreateChecks($path) {
504
-		// Make sure that we do not share a path that contains a shared mountpoint
505
-		if ($path instanceof \OCP\Files\Folder) {
506
-			$mounts = $this->mountManager->findIn($path->getPath());
507
-			foreach($mounts as $mount) {
508
-				if ($mount->getStorage()->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
509
-					throw new \InvalidArgumentException('Path contains files shared with you');
510
-				}
511
-			}
512
-		}
513
-	}
514
-
515
-	/**
516
-	 * Check if the user that is sharing can actually share
517
-	 *
518
-	 * @param \OCP\Share\IShare $share
519
-	 * @throws \Exception
520
-	 */
521
-	protected function canShare(\OCP\Share\IShare $share) {
522
-		if (!$this->shareApiEnabled()) {
523
-			throw new \Exception('The share API is disabled');
524
-		}
525
-
526
-		if ($this->sharingDisabledForUser($share->getSharedBy())) {
527
-			throw new \Exception('You are not allowed to share');
528
-		}
529
-	}
530
-
531
-	/**
532
-	 * Share a path
533
-	 *
534
-	 * @param \OCP\Share\IShare $share
535
-	 * @return Share The share object
536
-	 * @throws \Exception
537
-	 *
538
-	 * TODO: handle link share permissions or check them
539
-	 */
540
-	public function createShare(\OCP\Share\IShare $share) {
541
-		$this->canShare($share);
542
-
543
-		$this->generalCreateChecks($share);
544
-
545
-		// Verify if there are any issues with the path
546
-		$this->pathCreateChecks($share->getNode());
547
-
548
-		/*
436
+        $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
437
+        $existingShares = $provider->getSharesByPath($share->getNode());
438
+        foreach($existingShares as $existingShare) {
439
+            try {
440
+                if ($existingShare->getFullId() === $share->getFullId()) {
441
+                    continue;
442
+                }
443
+            } catch (\UnexpectedValueException $e) {
444
+                //It is a new share so just continue
445
+            }
446
+
447
+            if ($existingShare->getSharedWith() === $share->getSharedWith()) {
448
+                throw new \Exception('Path already shared with this group');
449
+            }
450
+        }
451
+    }
452
+
453
+    /**
454
+     * Check for pre share requirements for link shares
455
+     *
456
+     * @param \OCP\Share\IShare $share
457
+     * @throws \Exception
458
+     */
459
+    protected function linkCreateChecks(\OCP\Share\IShare $share) {
460
+        // Are link shares allowed?
461
+        if (!$this->shareApiAllowLinks()) {
462
+            throw new \Exception('Link sharing not allowed');
463
+        }
464
+
465
+        // Link shares by definition can't have share permissions
466
+        if ($share->getPermissions() & \OCP\Constants::PERMISSION_SHARE) {
467
+            throw new \InvalidArgumentException('Link shares can\'t have reshare permissions');
468
+        }
469
+
470
+        // Check if public upload is allowed
471
+        if (!$this->shareApiLinkAllowPublicUpload() &&
472
+            ($share->getPermissions() & (\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE))) {
473
+            throw new \InvalidArgumentException('Public upload not allowed');
474
+        }
475
+    }
476
+
477
+    /**
478
+     * To make sure we don't get invisible link shares we set the parent
479
+     * of a link if it is a reshare. This is a quick word around
480
+     * until we can properly display multiple link shares in the UI
481
+     *
482
+     * See: https://github.com/owncloud/core/issues/22295
483
+     *
484
+     * FIXME: Remove once multiple link shares can be properly displayed
485
+     *
486
+     * @param \OCP\Share\IShare $share
487
+     */
488
+    protected function setLinkParent(\OCP\Share\IShare $share) {
489
+
490
+        // No sense in checking if the method is not there.
491
+        if (method_exists($share, 'setParent')) {
492
+            $storage = $share->getNode()->getStorage();
493
+            if ($storage->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
494
+                /** @var \OCA\Files_Sharing\SharedStorage $storage */
495
+                $share->setParent($storage->getShareId());
496
+            }
497
+        };
498
+    }
499
+
500
+    /**
501
+     * @param File|Folder $path
502
+     */
503
+    protected function pathCreateChecks($path) {
504
+        // Make sure that we do not share a path that contains a shared mountpoint
505
+        if ($path instanceof \OCP\Files\Folder) {
506
+            $mounts = $this->mountManager->findIn($path->getPath());
507
+            foreach($mounts as $mount) {
508
+                if ($mount->getStorage()->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
509
+                    throw new \InvalidArgumentException('Path contains files shared with you');
510
+                }
511
+            }
512
+        }
513
+    }
514
+
515
+    /**
516
+     * Check if the user that is sharing can actually share
517
+     *
518
+     * @param \OCP\Share\IShare $share
519
+     * @throws \Exception
520
+     */
521
+    protected function canShare(\OCP\Share\IShare $share) {
522
+        if (!$this->shareApiEnabled()) {
523
+            throw new \Exception('The share API is disabled');
524
+        }
525
+
526
+        if ($this->sharingDisabledForUser($share->getSharedBy())) {
527
+            throw new \Exception('You are not allowed to share');
528
+        }
529
+    }
530
+
531
+    /**
532
+     * Share a path
533
+     *
534
+     * @param \OCP\Share\IShare $share
535
+     * @return Share The share object
536
+     * @throws \Exception
537
+     *
538
+     * TODO: handle link share permissions or check them
539
+     */
540
+    public function createShare(\OCP\Share\IShare $share) {
541
+        $this->canShare($share);
542
+
543
+        $this->generalCreateChecks($share);
544
+
545
+        // Verify if there are any issues with the path
546
+        $this->pathCreateChecks($share->getNode());
547
+
548
+        /*
549 549
 		 * On creation of a share the owner is always the owner of the path
550 550
 		 * Except for mounted federated shares.
551 551
 		 */
552
-		$storage = $share->getNode()->getStorage();
553
-		if ($storage->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
554
-			$parent = $share->getNode()->getParent();
555
-			while($parent->getStorage()->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
556
-				$parent = $parent->getParent();
557
-			}
558
-			$share->setShareOwner($parent->getOwner()->getUID());
559
-		} else {
560
-			$share->setShareOwner($share->getNode()->getOwner()->getUID());
561
-		}
562
-
563
-		//Verify share type
564
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
565
-			$this->userCreateChecks($share);
566
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
567
-			$this->groupCreateChecks($share);
568
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
569
-			$this->linkCreateChecks($share);
570
-			$this->setLinkParent($share);
571
-
572
-			/*
552
+        $storage = $share->getNode()->getStorage();
553
+        if ($storage->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
554
+            $parent = $share->getNode()->getParent();
555
+            while($parent->getStorage()->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
556
+                $parent = $parent->getParent();
557
+            }
558
+            $share->setShareOwner($parent->getOwner()->getUID());
559
+        } else {
560
+            $share->setShareOwner($share->getNode()->getOwner()->getUID());
561
+        }
562
+
563
+        //Verify share type
564
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
565
+            $this->userCreateChecks($share);
566
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
567
+            $this->groupCreateChecks($share);
568
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
569
+            $this->linkCreateChecks($share);
570
+            $this->setLinkParent($share);
571
+
572
+            /*
573 573
 			 * For now ignore a set token.
574 574
 			 */
575
-			$share->setToken(
576
-				$this->secureRandom->generate(
577
-					\OC\Share\Constants::TOKEN_LENGTH,
578
-					\OCP\Security\ISecureRandom::CHAR_LOWER.
579
-					\OCP\Security\ISecureRandom::CHAR_UPPER.
580
-					\OCP\Security\ISecureRandom::CHAR_DIGITS
581
-				)
582
-			);
583
-
584
-			//Verify the expiration date
585
-			$this->validateExpirationDate($share);
586
-
587
-			//Verify the password
588
-			$this->verifyPassword($share->getPassword());
589
-
590
-			// If a password is set. Hash it!
591
-			if ($share->getPassword() !== null) {
592
-				$share->setPassword($this->hasher->hash($share->getPassword()));
593
-			}
594
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
595
-			$share->setToken(
596
-				$this->secureRandom->generate(
597
-					\OC\Share\Constants::TOKEN_LENGTH,
598
-					\OCP\Security\ISecureRandom::CHAR_LOWER.
599
-					\OCP\Security\ISecureRandom::CHAR_UPPER.
600
-					\OCP\Security\ISecureRandom::CHAR_DIGITS
601
-				)
602
-			);
603
-		}
604
-
605
-		// Cannot share with the owner
606
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
607
-			$share->getSharedWith() === $share->getShareOwner()) {
608
-			throw new \InvalidArgumentException('Can\'t share with the share owner');
609
-		}
610
-
611
-		// Generate the target
612
-		$target = $this->config->getSystemValue('share_folder', '/') .'/'. $share->getNode()->getName();
613
-		$target = \OC\Files\Filesystem::normalizePath($target);
614
-		$share->setTarget($target);
615
-
616
-		// Pre share hook
617
-		$run = true;
618
-		$error = '';
619
-		$preHookData = [
620
-			'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
621
-			'itemSource' => $share->getNode()->getId(),
622
-			'shareType' => $share->getShareType(),
623
-			'uidOwner' => $share->getSharedBy(),
624
-			'permissions' => $share->getPermissions(),
625
-			'fileSource' => $share->getNode()->getId(),
626
-			'expiration' => $share->getExpirationDate(),
627
-			'token' => $share->getToken(),
628
-			'itemTarget' => $share->getTarget(),
629
-			'shareWith' => $share->getSharedWith(),
630
-			'run' => &$run,
631
-			'error' => &$error,
632
-		];
633
-		\OC_Hook::emit('OCP\Share', 'pre_shared', $preHookData);
634
-
635
-		if ($run === false) {
636
-			throw new \Exception($error);
637
-		}
638
-
639
-		$oldShare = $share;
640
-		$provider = $this->factory->getProviderForType($share->getShareType());
641
-		$share = $provider->create($share);
642
-		//reuse the node we already have
643
-		$share->setNode($oldShare->getNode());
644
-
645
-		// Post share hook
646
-		$postHookData = [
647
-			'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
648
-			'itemSource' => $share->getNode()->getId(),
649
-			'shareType' => $share->getShareType(),
650
-			'uidOwner' => $share->getSharedBy(),
651
-			'permissions' => $share->getPermissions(),
652
-			'fileSource' => $share->getNode()->getId(),
653
-			'expiration' => $share->getExpirationDate(),
654
-			'token' => $share->getToken(),
655
-			'id' => $share->getId(),
656
-			'shareWith' => $share->getSharedWith(),
657
-			'itemTarget' => $share->getTarget(),
658
-			'fileTarget' => $share->getTarget(),
659
-		];
660
-
661
-		\OC_Hook::emit('OCP\Share', 'post_shared', $postHookData);
662
-
663
-		return $share;
664
-	}
665
-
666
-	/**
667
-	 * Update a share
668
-	 *
669
-	 * @param \OCP\Share\IShare $share
670
-	 * @return \OCP\Share\IShare The share object
671
-	 * @throws \InvalidArgumentException
672
-	 */
673
-	public function updateShare(\OCP\Share\IShare $share) {
674
-		$expirationDateUpdated = false;
675
-
676
-		$this->canShare($share);
677
-
678
-		try {
679
-			$originalShare = $this->getShareById($share->getFullId());
680
-		} catch (\UnexpectedValueException $e) {
681
-			throw new \InvalidArgumentException('Share does not have a full id');
682
-		}
683
-
684
-		// We can't change the share type!
685
-		if ($share->getShareType() !== $originalShare->getShareType()) {
686
-			throw new \InvalidArgumentException('Can\'t change share type');
687
-		}
688
-
689
-		// We can only change the recipient on user shares
690
-		if ($share->getSharedWith() !== $originalShare->getSharedWith() &&
691
-		    $share->getShareType() !== \OCP\Share::SHARE_TYPE_USER) {
692
-			throw new \InvalidArgumentException('Can only update recipient on user shares');
693
-		}
694
-
695
-		// Cannot share with the owner
696
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
697
-			$share->getSharedWith() === $share->getShareOwner()) {
698
-			throw new \InvalidArgumentException('Can\'t share with the share owner');
699
-		}
700
-
701
-		$this->generalCreateChecks($share);
702
-
703
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
704
-			$this->userCreateChecks($share);
705
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
706
-			$this->groupCreateChecks($share);
707
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
708
-			$this->linkCreateChecks($share);
709
-
710
-			// Password updated.
711
-			if ($share->getPassword() !== $originalShare->getPassword()) {
712
-				//Verify the password
713
-				$this->verifyPassword($share->getPassword());
714
-
715
-				// If a password is set. Hash it!
716
-				if ($share->getPassword() !== null) {
717
-					$share->setPassword($this->hasher->hash($share->getPassword()));
718
-				}
719
-			}
720
-
721
-			if ($share->getExpirationDate() != $originalShare->getExpirationDate()) {
722
-				//Verify the expiration date
723
-				$this->validateExpirationDate($share);
724
-				$expirationDateUpdated = true;
725
-			}
726
-		}
727
-
728
-		$this->pathCreateChecks($share->getNode());
729
-
730
-		// Now update the share!
731
-		$provider = $this->factory->getProviderForType($share->getShareType());
732
-		$share = $provider->update($share);
733
-
734
-		if ($expirationDateUpdated === true) {
735
-			\OC_Hook::emit('OCP\Share', 'post_set_expiration_date', [
736
-				'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
737
-				'itemSource' => $share->getNode()->getId(),
738
-				'date' => $share->getExpirationDate(),
739
-				'uidOwner' => $share->getSharedBy(),
740
-			]);
741
-		}
742
-
743
-		if ($share->getPassword() !== $originalShare->getPassword()) {
744
-			\OC_Hook::emit('OCP\Share', 'post_update_password', [
745
-				'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
746
-				'itemSource' => $share->getNode()->getId(),
747
-				'uidOwner' => $share->getSharedBy(),
748
-				'token' => $share->getToken(),
749
-				'disabled' => is_null($share->getPassword()),
750
-			]);
751
-		}
752
-
753
-		if ($share->getPermissions() !== $originalShare->getPermissions()) {
754
-			if ($this->userManager->userExists($share->getShareOwner())) {
755
-				$userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
756
-			} else {
757
-				$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
758
-			}
759
-			\OC_Hook::emit('OCP\Share', 'post_update_permissions', array(
760
-				'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
761
-				'itemSource' => $share->getNode()->getId(),
762
-				'shareType' => $share->getShareType(),
763
-				'shareWith' => $share->getSharedWith(),
764
-				'uidOwner' => $share->getSharedBy(),
765
-				'permissions' => $share->getPermissions(),
766
-				'path' => $userFolder->getRelativePath($share->getNode()->getPath()),
767
-			));
768
-		}
769
-
770
-		return $share;
771
-	}
772
-
773
-	/**
774
-	 * Delete all the children of this share
775
-	 * FIXME: remove once https://github.com/owncloud/core/pull/21660 is in
776
-	 *
777
-	 * @param \OCP\Share\IShare $share
778
-	 * @return \OCP\Share\IShare[] List of deleted shares
779
-	 */
780
-	protected function deleteChildren(\OCP\Share\IShare $share) {
781
-		$deletedShares = [];
782
-
783
-		$provider = $this->factory->getProviderForType($share->getShareType());
784
-
785
-		foreach ($provider->getChildren($share) as $child) {
786
-			$deletedChildren = $this->deleteChildren($child);
787
-			$deletedShares = array_merge($deletedShares, $deletedChildren);
788
-
789
-			$provider->delete($child);
790
-			$deletedShares[] = $child;
791
-		}
792
-
793
-		return $deletedShares;
794
-	}
795
-
796
-	/**
797
-	 * Delete a share
798
-	 *
799
-	 * @param \OCP\Share\IShare $share
800
-	 * @throws ShareNotFound
801
-	 * @throws \InvalidArgumentException
802
-	 */
803
-	public function deleteShare(\OCP\Share\IShare $share) {
804
-
805
-		try {
806
-			$share->getFullId();
807
-		} catch (\UnexpectedValueException $e) {
808
-			throw new \InvalidArgumentException('Share does not have a full id');
809
-		}
810
-
811
-		$formatHookParams = function(\OCP\Share\IShare $share) {
812
-			// Prepare hook
813
-			$shareType = $share->getShareType();
814
-			$sharedWith = '';
815
-			if ($shareType === \OCP\Share::SHARE_TYPE_USER) {
816
-				$sharedWith = $share->getSharedWith();
817
-			} else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) {
818
-				$sharedWith = $share->getSharedWith();
819
-			} else if ($shareType === \OCP\Share::SHARE_TYPE_REMOTE) {
820
-				$sharedWith = $share->getSharedWith();
821
-			}
822
-
823
-			$hookParams = [
824
-				'id'         => $share->getId(),
825
-				'itemType'   => $share->getNodeType(),
826
-				'itemSource' => $share->getNodeId(),
827
-				'shareType'  => $shareType,
828
-				'shareWith'  => $sharedWith,
829
-				'itemparent' => method_exists($share, 'getParent') ? $share->getParent() : '',
830
-				'uidOwner'   => $share->getSharedBy(),
831
-				'fileSource' => $share->getNodeId(),
832
-				'fileTarget' => $share->getTarget()
833
-			];
834
-			return $hookParams;
835
-		};
836
-
837
-		$hookParams = $formatHookParams($share);
838
-
839
-		// Emit pre-hook
840
-		\OC_Hook::emit('OCP\Share', 'pre_unshare', $hookParams);
841
-
842
-		// Get all children and delete them as well
843
-		$deletedShares = $this->deleteChildren($share);
844
-
845
-		// Do the actual delete
846
-		$provider = $this->factory->getProviderForType($share->getShareType());
847
-		$provider->delete($share);
848
-
849
-		// All the deleted shares caused by this delete
850
-		$deletedShares[] = $share;
851
-
852
-		//Format hook info
853
-		$formattedDeletedShares = array_map(function($share) use ($formatHookParams) {
854
-			return $formatHookParams($share);
855
-		}, $deletedShares);
856
-
857
-		$hookParams['deletedShares'] = $formattedDeletedShares;
858
-
859
-		// Emit post hook
860
-		\OC_Hook::emit('OCP\Share', 'post_unshare', $hookParams);
861
-	}
862
-
863
-
864
-	/**
865
-	 * Unshare a file as the recipient.
866
-	 * This can be different from a regular delete for example when one of
867
-	 * the users in a groups deletes that share. But the provider should
868
-	 * handle this.
869
-	 *
870
-	 * @param \OCP\Share\IShare $share
871
-	 * @param string $recipientId
872
-	 */
873
-	public function deleteFromSelf(\OCP\Share\IShare $share, $recipientId) {
874
-		list($providerId, ) = $this->splitFullId($share->getFullId());
875
-		$provider = $this->factory->getProvider($providerId);
876
-
877
-		$provider->deleteFromSelf($share, $recipientId);
878
-	}
879
-
880
-	/**
881
-	 * @inheritdoc
882
-	 */
883
-	public function moveShare(\OCP\Share\IShare $share, $recipientId) {
884
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
885
-			throw new \InvalidArgumentException('Can\'t change target of link share');
886
-		}
887
-
888
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER && $share->getSharedWith() !== $recipientId) {
889
-			throw new \InvalidArgumentException('Invalid recipient');
890
-		}
891
-
892
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
893
-			$sharedWith = $this->groupManager->get($share->getSharedWith());
894
-			$recipient = $this->userManager->get($recipientId);
895
-			if (!$sharedWith->inGroup($recipient)) {
896
-				throw new \InvalidArgumentException('Invalid recipient');
897
-			}
898
-		}
899
-
900
-		list($providerId, ) = $this->splitFullId($share->getFullId());
901
-		$provider = $this->factory->getProvider($providerId);
902
-
903
-		$provider->move($share, $recipientId);
904
-	}
905
-
906
-	public function getSharesInFolder($userId, Folder $node, $reshares = false) {
907
-		$providers = $this->factory->getAllProviders();
908
-
909
-		return array_reduce($providers, function($shares, IShareProvider $provider) use ($userId, $node, $reshares) {
910
-			$newShares = $provider->getSharesInFolder($userId, $node, $reshares);
911
-			foreach ($newShares as $fid => $data) {
912
-				if (!isset($shares[$fid])) {
913
-					$shares[$fid] = [];
914
-				}
915
-
916
-				$shares[$fid] = array_merge($shares[$fid], $data);
917
-			}
918
-			return $shares;
919
-		}, []);
920
-	}
921
-
922
-	/**
923
-	 * @inheritdoc
924
-	 */
925
-	public function getSharesBy($userId, $shareType, $path = null, $reshares = false, $limit = 50, $offset = 0) {
926
-		if ($path !== null &&
927
-				!($path instanceof \OCP\Files\File) &&
928
-				!($path instanceof \OCP\Files\Folder)) {
929
-			throw new \InvalidArgumentException('invalid path');
930
-		}
931
-
932
-		try {
933
-			$provider = $this->factory->getProviderForType($shareType);
934
-		} catch (ProviderException $e) {
935
-			return [];
936
-		}
937
-
938
-		$shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
939
-
940
-		/*
575
+            $share->setToken(
576
+                $this->secureRandom->generate(
577
+                    \OC\Share\Constants::TOKEN_LENGTH,
578
+                    \OCP\Security\ISecureRandom::CHAR_LOWER.
579
+                    \OCP\Security\ISecureRandom::CHAR_UPPER.
580
+                    \OCP\Security\ISecureRandom::CHAR_DIGITS
581
+                )
582
+            );
583
+
584
+            //Verify the expiration date
585
+            $this->validateExpirationDate($share);
586
+
587
+            //Verify the password
588
+            $this->verifyPassword($share->getPassword());
589
+
590
+            // If a password is set. Hash it!
591
+            if ($share->getPassword() !== null) {
592
+                $share->setPassword($this->hasher->hash($share->getPassword()));
593
+            }
594
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
595
+            $share->setToken(
596
+                $this->secureRandom->generate(
597
+                    \OC\Share\Constants::TOKEN_LENGTH,
598
+                    \OCP\Security\ISecureRandom::CHAR_LOWER.
599
+                    \OCP\Security\ISecureRandom::CHAR_UPPER.
600
+                    \OCP\Security\ISecureRandom::CHAR_DIGITS
601
+                )
602
+            );
603
+        }
604
+
605
+        // Cannot share with the owner
606
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
607
+            $share->getSharedWith() === $share->getShareOwner()) {
608
+            throw new \InvalidArgumentException('Can\'t share with the share owner');
609
+        }
610
+
611
+        // Generate the target
612
+        $target = $this->config->getSystemValue('share_folder', '/') .'/'. $share->getNode()->getName();
613
+        $target = \OC\Files\Filesystem::normalizePath($target);
614
+        $share->setTarget($target);
615
+
616
+        // Pre share hook
617
+        $run = true;
618
+        $error = '';
619
+        $preHookData = [
620
+            'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
621
+            'itemSource' => $share->getNode()->getId(),
622
+            'shareType' => $share->getShareType(),
623
+            'uidOwner' => $share->getSharedBy(),
624
+            'permissions' => $share->getPermissions(),
625
+            'fileSource' => $share->getNode()->getId(),
626
+            'expiration' => $share->getExpirationDate(),
627
+            'token' => $share->getToken(),
628
+            'itemTarget' => $share->getTarget(),
629
+            'shareWith' => $share->getSharedWith(),
630
+            'run' => &$run,
631
+            'error' => &$error,
632
+        ];
633
+        \OC_Hook::emit('OCP\Share', 'pre_shared', $preHookData);
634
+
635
+        if ($run === false) {
636
+            throw new \Exception($error);
637
+        }
638
+
639
+        $oldShare = $share;
640
+        $provider = $this->factory->getProviderForType($share->getShareType());
641
+        $share = $provider->create($share);
642
+        //reuse the node we already have
643
+        $share->setNode($oldShare->getNode());
644
+
645
+        // Post share hook
646
+        $postHookData = [
647
+            'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
648
+            'itemSource' => $share->getNode()->getId(),
649
+            'shareType' => $share->getShareType(),
650
+            'uidOwner' => $share->getSharedBy(),
651
+            'permissions' => $share->getPermissions(),
652
+            'fileSource' => $share->getNode()->getId(),
653
+            'expiration' => $share->getExpirationDate(),
654
+            'token' => $share->getToken(),
655
+            'id' => $share->getId(),
656
+            'shareWith' => $share->getSharedWith(),
657
+            'itemTarget' => $share->getTarget(),
658
+            'fileTarget' => $share->getTarget(),
659
+        ];
660
+
661
+        \OC_Hook::emit('OCP\Share', 'post_shared', $postHookData);
662
+
663
+        return $share;
664
+    }
665
+
666
+    /**
667
+     * Update a share
668
+     *
669
+     * @param \OCP\Share\IShare $share
670
+     * @return \OCP\Share\IShare The share object
671
+     * @throws \InvalidArgumentException
672
+     */
673
+    public function updateShare(\OCP\Share\IShare $share) {
674
+        $expirationDateUpdated = false;
675
+
676
+        $this->canShare($share);
677
+
678
+        try {
679
+            $originalShare = $this->getShareById($share->getFullId());
680
+        } catch (\UnexpectedValueException $e) {
681
+            throw new \InvalidArgumentException('Share does not have a full id');
682
+        }
683
+
684
+        // We can't change the share type!
685
+        if ($share->getShareType() !== $originalShare->getShareType()) {
686
+            throw new \InvalidArgumentException('Can\'t change share type');
687
+        }
688
+
689
+        // We can only change the recipient on user shares
690
+        if ($share->getSharedWith() !== $originalShare->getSharedWith() &&
691
+            $share->getShareType() !== \OCP\Share::SHARE_TYPE_USER) {
692
+            throw new \InvalidArgumentException('Can only update recipient on user shares');
693
+        }
694
+
695
+        // Cannot share with the owner
696
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
697
+            $share->getSharedWith() === $share->getShareOwner()) {
698
+            throw new \InvalidArgumentException('Can\'t share with the share owner');
699
+        }
700
+
701
+        $this->generalCreateChecks($share);
702
+
703
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
704
+            $this->userCreateChecks($share);
705
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
706
+            $this->groupCreateChecks($share);
707
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
708
+            $this->linkCreateChecks($share);
709
+
710
+            // Password updated.
711
+            if ($share->getPassword() !== $originalShare->getPassword()) {
712
+                //Verify the password
713
+                $this->verifyPassword($share->getPassword());
714
+
715
+                // If a password is set. Hash it!
716
+                if ($share->getPassword() !== null) {
717
+                    $share->setPassword($this->hasher->hash($share->getPassword()));
718
+                }
719
+            }
720
+
721
+            if ($share->getExpirationDate() != $originalShare->getExpirationDate()) {
722
+                //Verify the expiration date
723
+                $this->validateExpirationDate($share);
724
+                $expirationDateUpdated = true;
725
+            }
726
+        }
727
+
728
+        $this->pathCreateChecks($share->getNode());
729
+
730
+        // Now update the share!
731
+        $provider = $this->factory->getProviderForType($share->getShareType());
732
+        $share = $provider->update($share);
733
+
734
+        if ($expirationDateUpdated === true) {
735
+            \OC_Hook::emit('OCP\Share', 'post_set_expiration_date', [
736
+                'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
737
+                'itemSource' => $share->getNode()->getId(),
738
+                'date' => $share->getExpirationDate(),
739
+                'uidOwner' => $share->getSharedBy(),
740
+            ]);
741
+        }
742
+
743
+        if ($share->getPassword() !== $originalShare->getPassword()) {
744
+            \OC_Hook::emit('OCP\Share', 'post_update_password', [
745
+                'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
746
+                'itemSource' => $share->getNode()->getId(),
747
+                'uidOwner' => $share->getSharedBy(),
748
+                'token' => $share->getToken(),
749
+                'disabled' => is_null($share->getPassword()),
750
+            ]);
751
+        }
752
+
753
+        if ($share->getPermissions() !== $originalShare->getPermissions()) {
754
+            if ($this->userManager->userExists($share->getShareOwner())) {
755
+                $userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
756
+            } else {
757
+                $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
758
+            }
759
+            \OC_Hook::emit('OCP\Share', 'post_update_permissions', array(
760
+                'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
761
+                'itemSource' => $share->getNode()->getId(),
762
+                'shareType' => $share->getShareType(),
763
+                'shareWith' => $share->getSharedWith(),
764
+                'uidOwner' => $share->getSharedBy(),
765
+                'permissions' => $share->getPermissions(),
766
+                'path' => $userFolder->getRelativePath($share->getNode()->getPath()),
767
+            ));
768
+        }
769
+
770
+        return $share;
771
+    }
772
+
773
+    /**
774
+     * Delete all the children of this share
775
+     * FIXME: remove once https://github.com/owncloud/core/pull/21660 is in
776
+     *
777
+     * @param \OCP\Share\IShare $share
778
+     * @return \OCP\Share\IShare[] List of deleted shares
779
+     */
780
+    protected function deleteChildren(\OCP\Share\IShare $share) {
781
+        $deletedShares = [];
782
+
783
+        $provider = $this->factory->getProviderForType($share->getShareType());
784
+
785
+        foreach ($provider->getChildren($share) as $child) {
786
+            $deletedChildren = $this->deleteChildren($child);
787
+            $deletedShares = array_merge($deletedShares, $deletedChildren);
788
+
789
+            $provider->delete($child);
790
+            $deletedShares[] = $child;
791
+        }
792
+
793
+        return $deletedShares;
794
+    }
795
+
796
+    /**
797
+     * Delete a share
798
+     *
799
+     * @param \OCP\Share\IShare $share
800
+     * @throws ShareNotFound
801
+     * @throws \InvalidArgumentException
802
+     */
803
+    public function deleteShare(\OCP\Share\IShare $share) {
804
+
805
+        try {
806
+            $share->getFullId();
807
+        } catch (\UnexpectedValueException $e) {
808
+            throw new \InvalidArgumentException('Share does not have a full id');
809
+        }
810
+
811
+        $formatHookParams = function(\OCP\Share\IShare $share) {
812
+            // Prepare hook
813
+            $shareType = $share->getShareType();
814
+            $sharedWith = '';
815
+            if ($shareType === \OCP\Share::SHARE_TYPE_USER) {
816
+                $sharedWith = $share->getSharedWith();
817
+            } else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) {
818
+                $sharedWith = $share->getSharedWith();
819
+            } else if ($shareType === \OCP\Share::SHARE_TYPE_REMOTE) {
820
+                $sharedWith = $share->getSharedWith();
821
+            }
822
+
823
+            $hookParams = [
824
+                'id'         => $share->getId(),
825
+                'itemType'   => $share->getNodeType(),
826
+                'itemSource' => $share->getNodeId(),
827
+                'shareType'  => $shareType,
828
+                'shareWith'  => $sharedWith,
829
+                'itemparent' => method_exists($share, 'getParent') ? $share->getParent() : '',
830
+                'uidOwner'   => $share->getSharedBy(),
831
+                'fileSource' => $share->getNodeId(),
832
+                'fileTarget' => $share->getTarget()
833
+            ];
834
+            return $hookParams;
835
+        };
836
+
837
+        $hookParams = $formatHookParams($share);
838
+
839
+        // Emit pre-hook
840
+        \OC_Hook::emit('OCP\Share', 'pre_unshare', $hookParams);
841
+
842
+        // Get all children and delete them as well
843
+        $deletedShares = $this->deleteChildren($share);
844
+
845
+        // Do the actual delete
846
+        $provider = $this->factory->getProviderForType($share->getShareType());
847
+        $provider->delete($share);
848
+
849
+        // All the deleted shares caused by this delete
850
+        $deletedShares[] = $share;
851
+
852
+        //Format hook info
853
+        $formattedDeletedShares = array_map(function($share) use ($formatHookParams) {
854
+            return $formatHookParams($share);
855
+        }, $deletedShares);
856
+
857
+        $hookParams['deletedShares'] = $formattedDeletedShares;
858
+
859
+        // Emit post hook
860
+        \OC_Hook::emit('OCP\Share', 'post_unshare', $hookParams);
861
+    }
862
+
863
+
864
+    /**
865
+     * Unshare a file as the recipient.
866
+     * This can be different from a regular delete for example when one of
867
+     * the users in a groups deletes that share. But the provider should
868
+     * handle this.
869
+     *
870
+     * @param \OCP\Share\IShare $share
871
+     * @param string $recipientId
872
+     */
873
+    public function deleteFromSelf(\OCP\Share\IShare $share, $recipientId) {
874
+        list($providerId, ) = $this->splitFullId($share->getFullId());
875
+        $provider = $this->factory->getProvider($providerId);
876
+
877
+        $provider->deleteFromSelf($share, $recipientId);
878
+    }
879
+
880
+    /**
881
+     * @inheritdoc
882
+     */
883
+    public function moveShare(\OCP\Share\IShare $share, $recipientId) {
884
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
885
+            throw new \InvalidArgumentException('Can\'t change target of link share');
886
+        }
887
+
888
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER && $share->getSharedWith() !== $recipientId) {
889
+            throw new \InvalidArgumentException('Invalid recipient');
890
+        }
891
+
892
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
893
+            $sharedWith = $this->groupManager->get($share->getSharedWith());
894
+            $recipient = $this->userManager->get($recipientId);
895
+            if (!$sharedWith->inGroup($recipient)) {
896
+                throw new \InvalidArgumentException('Invalid recipient');
897
+            }
898
+        }
899
+
900
+        list($providerId, ) = $this->splitFullId($share->getFullId());
901
+        $provider = $this->factory->getProvider($providerId);
902
+
903
+        $provider->move($share, $recipientId);
904
+    }
905
+
906
+    public function getSharesInFolder($userId, Folder $node, $reshares = false) {
907
+        $providers = $this->factory->getAllProviders();
908
+
909
+        return array_reduce($providers, function($shares, IShareProvider $provider) use ($userId, $node, $reshares) {
910
+            $newShares = $provider->getSharesInFolder($userId, $node, $reshares);
911
+            foreach ($newShares as $fid => $data) {
912
+                if (!isset($shares[$fid])) {
913
+                    $shares[$fid] = [];
914
+                }
915
+
916
+                $shares[$fid] = array_merge($shares[$fid], $data);
917
+            }
918
+            return $shares;
919
+        }, []);
920
+    }
921
+
922
+    /**
923
+     * @inheritdoc
924
+     */
925
+    public function getSharesBy($userId, $shareType, $path = null, $reshares = false, $limit = 50, $offset = 0) {
926
+        if ($path !== null &&
927
+                !($path instanceof \OCP\Files\File) &&
928
+                !($path instanceof \OCP\Files\Folder)) {
929
+            throw new \InvalidArgumentException('invalid path');
930
+        }
931
+
932
+        try {
933
+            $provider = $this->factory->getProviderForType($shareType);
934
+        } catch (ProviderException $e) {
935
+            return [];
936
+        }
937
+
938
+        $shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
939
+
940
+        /*
941 941
 		 * Work around so we don't return expired shares but still follow
942 942
 		 * proper pagination.
943 943
 		 */
944
-		if ($shareType === \OCP\Share::SHARE_TYPE_LINK) {
945
-			$shares2 = [];
946
-			$today = new \DateTime();
947
-
948
-			while(true) {
949
-				$added = 0;
950
-				foreach ($shares as $share) {
951
-					// Check if the share is expired and if so delete it
952
-					if ($share->getExpirationDate() !== null &&
953
-						$share->getExpirationDate() <= $today
954
-					) {
955
-						try {
956
-							$this->deleteShare($share);
957
-						} catch (NotFoundException $e) {
958
-							//Ignore since this basically means the share is deleted
959
-						}
960
-						continue;
961
-					}
962
-					$added++;
963
-					$shares2[] = $share;
964
-
965
-					if (count($shares2) === $limit) {
966
-						break;
967
-					}
968
-				}
969
-
970
-				if (count($shares2) === $limit) {
971
-					break;
972
-				}
973
-
974
-				// If there was no limit on the select we are done
975
-				if ($limit === -1) {
976
-					break;
977
-				}
978
-
979
-				$offset += $added;
980
-
981
-				// Fetch again $limit shares
982
-				$shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
983
-
984
-				// No more shares means we are done
985
-				if (empty($shares)) {
986
-					break;
987
-				}
988
-			}
989
-
990
-			$shares = $shares2;
991
-		}
992
-
993
-		return $shares;
994
-	}
995
-
996
-	/**
997
-	 * @inheritdoc
998
-	 */
999
-	public function getSharedWith($userId, $shareType, $node = null, $limit = 50, $offset = 0) {
1000
-		try {
1001
-			$provider = $this->factory->getProviderForType($shareType);
1002
-		} catch (ProviderException $e) {
1003
-			return [];
1004
-		}
1005
-
1006
-		return $provider->getSharedWith($userId, $shareType, $node, $limit, $offset);
1007
-	}
1008
-
1009
-	/**
1010
-	 * @inheritdoc
1011
-	 */
1012
-	public function getShareById($id, $recipient = null) {
1013
-		if ($id === null) {
1014
-			throw new ShareNotFound();
1015
-		}
1016
-
1017
-		list($providerId, $id) = $this->splitFullId($id);
1018
-
1019
-		try {
1020
-			$provider = $this->factory->getProvider($providerId);
1021
-		} catch (ProviderException $e) {
1022
-			throw new ShareNotFound();
1023
-		}
1024
-
1025
-		$share = $provider->getShareById($id, $recipient);
1026
-
1027
-		// Validate link shares expiration date
1028
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK &&
1029
-			$share->getExpirationDate() !== null &&
1030
-			$share->getExpirationDate() <= new \DateTime()) {
1031
-			$this->deleteShare($share);
1032
-			throw new ShareNotFound();
1033
-		}
1034
-
1035
-		return $share;
1036
-	}
1037
-
1038
-	/**
1039
-	 * Get all the shares for a given path
1040
-	 *
1041
-	 * @param \OCP\Files\Node $path
1042
-	 * @param int $page
1043
-	 * @param int $perPage
1044
-	 *
1045
-	 * @return Share[]
1046
-	 */
1047
-	public function getSharesByPath(\OCP\Files\Node $path, $page=0, $perPage=50) {
1048
-		return [];
1049
-	}
1050
-
1051
-	/**
1052
-	 * Get the share by token possible with password
1053
-	 *
1054
-	 * @param string $token
1055
-	 * @return Share
1056
-	 *
1057
-	 * @throws ShareNotFound
1058
-	 */
1059
-	public function getShareByToken($token) {
1060
-		$share = null;
1061
-		try {
1062
-			if($this->shareApiAllowLinks()) {
1063
-				$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_LINK);
1064
-				$share = $provider->getShareByToken($token);
1065
-			}
1066
-		} catch (ProviderException $e) {
1067
-		} catch (ShareNotFound $e) {
1068
-		}
1069
-
1070
-
1071
-		// If it is not a link share try to fetch a federated share by token
1072
-		if ($share === null) {
1073
-			try {
1074
-				$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_REMOTE);
1075
-				$share = $provider->getShareByToken($token);
1076
-			} catch (ProviderException $e) {
1077
-			} catch (ShareNotFound $e) {
1078
-			}
1079
-		}
1080
-
1081
-		// If it is not a link share try to fetch a mail share by token
1082
-		if ($share === null && $this->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
1083
-			try {
1084
-				$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_EMAIL);
1085
-				$share = $provider->getShareByToken($token);
1086
-			} catch (ProviderException $e) {
1087
-			} catch (ShareNotFound $e) {
1088
-			}
1089
-		}
1090
-
1091
-		if ($share === null) {
1092
-			throw new ShareNotFound();
1093
-		}
1094
-
1095
-		if ($share->getExpirationDate() !== null &&
1096
-			$share->getExpirationDate() <= new \DateTime()) {
1097
-			$this->deleteShare($share);
1098
-			throw new ShareNotFound();
1099
-		}
1100
-
1101
-		/*
944
+        if ($shareType === \OCP\Share::SHARE_TYPE_LINK) {
945
+            $shares2 = [];
946
+            $today = new \DateTime();
947
+
948
+            while(true) {
949
+                $added = 0;
950
+                foreach ($shares as $share) {
951
+                    // Check if the share is expired and if so delete it
952
+                    if ($share->getExpirationDate() !== null &&
953
+                        $share->getExpirationDate() <= $today
954
+                    ) {
955
+                        try {
956
+                            $this->deleteShare($share);
957
+                        } catch (NotFoundException $e) {
958
+                            //Ignore since this basically means the share is deleted
959
+                        }
960
+                        continue;
961
+                    }
962
+                    $added++;
963
+                    $shares2[] = $share;
964
+
965
+                    if (count($shares2) === $limit) {
966
+                        break;
967
+                    }
968
+                }
969
+
970
+                if (count($shares2) === $limit) {
971
+                    break;
972
+                }
973
+
974
+                // If there was no limit on the select we are done
975
+                if ($limit === -1) {
976
+                    break;
977
+                }
978
+
979
+                $offset += $added;
980
+
981
+                // Fetch again $limit shares
982
+                $shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
983
+
984
+                // No more shares means we are done
985
+                if (empty($shares)) {
986
+                    break;
987
+                }
988
+            }
989
+
990
+            $shares = $shares2;
991
+        }
992
+
993
+        return $shares;
994
+    }
995
+
996
+    /**
997
+     * @inheritdoc
998
+     */
999
+    public function getSharedWith($userId, $shareType, $node = null, $limit = 50, $offset = 0) {
1000
+        try {
1001
+            $provider = $this->factory->getProviderForType($shareType);
1002
+        } catch (ProviderException $e) {
1003
+            return [];
1004
+        }
1005
+
1006
+        return $provider->getSharedWith($userId, $shareType, $node, $limit, $offset);
1007
+    }
1008
+
1009
+    /**
1010
+     * @inheritdoc
1011
+     */
1012
+    public function getShareById($id, $recipient = null) {
1013
+        if ($id === null) {
1014
+            throw new ShareNotFound();
1015
+        }
1016
+
1017
+        list($providerId, $id) = $this->splitFullId($id);
1018
+
1019
+        try {
1020
+            $provider = $this->factory->getProvider($providerId);
1021
+        } catch (ProviderException $e) {
1022
+            throw new ShareNotFound();
1023
+        }
1024
+
1025
+        $share = $provider->getShareById($id, $recipient);
1026
+
1027
+        // Validate link shares expiration date
1028
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK &&
1029
+            $share->getExpirationDate() !== null &&
1030
+            $share->getExpirationDate() <= new \DateTime()) {
1031
+            $this->deleteShare($share);
1032
+            throw new ShareNotFound();
1033
+        }
1034
+
1035
+        return $share;
1036
+    }
1037
+
1038
+    /**
1039
+     * Get all the shares for a given path
1040
+     *
1041
+     * @param \OCP\Files\Node $path
1042
+     * @param int $page
1043
+     * @param int $perPage
1044
+     *
1045
+     * @return Share[]
1046
+     */
1047
+    public function getSharesByPath(\OCP\Files\Node $path, $page=0, $perPage=50) {
1048
+        return [];
1049
+    }
1050
+
1051
+    /**
1052
+     * Get the share by token possible with password
1053
+     *
1054
+     * @param string $token
1055
+     * @return Share
1056
+     *
1057
+     * @throws ShareNotFound
1058
+     */
1059
+    public function getShareByToken($token) {
1060
+        $share = null;
1061
+        try {
1062
+            if($this->shareApiAllowLinks()) {
1063
+                $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_LINK);
1064
+                $share = $provider->getShareByToken($token);
1065
+            }
1066
+        } catch (ProviderException $e) {
1067
+        } catch (ShareNotFound $e) {
1068
+        }
1069
+
1070
+
1071
+        // If it is not a link share try to fetch a federated share by token
1072
+        if ($share === null) {
1073
+            try {
1074
+                $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_REMOTE);
1075
+                $share = $provider->getShareByToken($token);
1076
+            } catch (ProviderException $e) {
1077
+            } catch (ShareNotFound $e) {
1078
+            }
1079
+        }
1080
+
1081
+        // If it is not a link share try to fetch a mail share by token
1082
+        if ($share === null && $this->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
1083
+            try {
1084
+                $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_EMAIL);
1085
+                $share = $provider->getShareByToken($token);
1086
+            } catch (ProviderException $e) {
1087
+            } catch (ShareNotFound $e) {
1088
+            }
1089
+        }
1090
+
1091
+        if ($share === null) {
1092
+            throw new ShareNotFound();
1093
+        }
1094
+
1095
+        if ($share->getExpirationDate() !== null &&
1096
+            $share->getExpirationDate() <= new \DateTime()) {
1097
+            $this->deleteShare($share);
1098
+            throw new ShareNotFound();
1099
+        }
1100
+
1101
+        /*
1102 1102
 		 * Reduce the permissions for link shares if public upload is not enabled
1103 1103
 		 */
1104
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK &&
1105
-			!$this->shareApiLinkAllowPublicUpload()) {
1106
-			$share->setPermissions($share->getPermissions() & ~(\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE));
1107
-		}
1108
-
1109
-		return $share;
1110
-	}
1111
-
1112
-	/**
1113
-	 * Verify the password of a public share
1114
-	 *
1115
-	 * @param \OCP\Share\IShare $share
1116
-	 * @param string $password
1117
-	 * @return bool
1118
-	 */
1119
-	public function checkPassword(\OCP\Share\IShare $share, $password) {
1120
-		if ($share->getShareType() !== \OCP\Share::SHARE_TYPE_LINK) {
1121
-			//TODO maybe exception?
1122
-			return false;
1123
-		}
1124
-
1125
-		if ($password === null || $share->getPassword() === null) {
1126
-			return false;
1127
-		}
1128
-
1129
-		$newHash = '';
1130
-		if (!$this->hasher->verify($password, $share->getPassword(), $newHash)) {
1131
-			return false;
1132
-		}
1133
-
1134
-		if (!empty($newHash)) {
1135
-			$share->setPassword($newHash);
1136
-			$provider = $this->factory->getProviderForType($share->getShareType());
1137
-			$provider->update($share);
1138
-		}
1139
-
1140
-		return true;
1141
-	}
1142
-
1143
-	/**
1144
-	 * @inheritdoc
1145
-	 */
1146
-	public function userDeleted($uid) {
1147
-		$types = [\OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_GROUP, \OCP\Share::SHARE_TYPE_LINK, \OCP\Share::SHARE_TYPE_REMOTE, \OCP\Share::SHARE_TYPE_EMAIL];
1148
-
1149
-		foreach ($types as $type) {
1150
-			try {
1151
-				$provider = $this->factory->getProviderForType($type);
1152
-			} catch (ProviderException $e) {
1153
-				continue;
1154
-			}
1155
-			$provider->userDeleted($uid, $type);
1156
-		}
1157
-	}
1158
-
1159
-	/**
1160
-	 * @inheritdoc
1161
-	 */
1162
-	public function groupDeleted($gid) {
1163
-		$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
1164
-		$provider->groupDeleted($gid);
1165
-	}
1166
-
1167
-	/**
1168
-	 * @inheritdoc
1169
-	 */
1170
-	public function userDeletedFromGroup($uid, $gid) {
1171
-		$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
1172
-		$provider->userDeletedFromGroup($uid, $gid);
1173
-	}
1174
-
1175
-	/**
1176
-	 * Get access list to a path. This means
1177
-	 * all the users and groups that can access a given path.
1178
-	 *
1179
-	 * Consider:
1180
-	 * -root
1181
-	 * |-folder1
1182
-	 *  |-folder2
1183
-	 *   |-fileA
1184
-	 *
1185
-	 * fileA is shared with user1
1186
-	 * folder2 is shared with group2
1187
-	 * folder1 is shared with user2
1188
-	 *
1189
-	 * Then the access list will to '/folder1/folder2/fileA' is:
1190
-	 * [
1191
-	 * 	'users' => ['user1', 'user2'],
1192
-	 *  'groups' => ['group2']
1193
-	 * ]
1194
-	 *
1195
-	 * This is required for encryption
1196
-	 *
1197
-	 * @param \OCP\Files\Node $path
1198
-	 */
1199
-	public function getAccessList(\OCP\Files\Node $path) {
1200
-	}
1201
-
1202
-	/**
1203
-	 * Create a new share
1204
-	 * @return \OCP\Share\IShare;
1205
-	 */
1206
-	public function newShare() {
1207
-		return new \OC\Share20\Share($this->rootFolder, $this->userManager);
1208
-	}
1209
-
1210
-	/**
1211
-	 * Is the share API enabled
1212
-	 *
1213
-	 * @return bool
1214
-	 */
1215
-	public function shareApiEnabled() {
1216
-		return $this->config->getAppValue('core', 'shareapi_enabled', 'yes') === 'yes';
1217
-	}
1218
-
1219
-	/**
1220
-	 * Is public link sharing enabled
1221
-	 *
1222
-	 * @return bool
1223
-	 */
1224
-	public function shareApiAllowLinks() {
1225
-		return $this->config->getAppValue('core', 'shareapi_allow_links', 'yes') === 'yes';
1226
-	}
1227
-
1228
-	/**
1229
-	 * Is password on public link requires
1230
-	 *
1231
-	 * @return bool
1232
-	 */
1233
-	public function shareApiLinkEnforcePassword() {
1234
-		return $this->config->getAppValue('core', 'shareapi_enforce_links_password', 'no') === 'yes';
1235
-	}
1236
-
1237
-	/**
1238
-	 * Is default expire date enabled
1239
-	 *
1240
-	 * @return bool
1241
-	 */
1242
-	public function shareApiLinkDefaultExpireDate() {
1243
-		return $this->config->getAppValue('core', 'shareapi_default_expire_date', 'no') === 'yes';
1244
-	}
1245
-
1246
-	/**
1247
-	 * Is default expire date enforced
1248
-	 *`
1249
-	 * @return bool
1250
-	 */
1251
-	public function shareApiLinkDefaultExpireDateEnforced() {
1252
-		return $this->shareApiLinkDefaultExpireDate() &&
1253
-			$this->config->getAppValue('core', 'shareapi_enforce_expire_date', 'no') === 'yes';
1254
-	}
1255
-
1256
-	/**
1257
-	 * Number of default expire days
1258
-	 *shareApiLinkAllowPublicUpload
1259
-	 * @return int
1260
-	 */
1261
-	public function shareApiLinkDefaultExpireDays() {
1262
-		return (int)$this->config->getAppValue('core', 'shareapi_expire_after_n_days', '7');
1263
-	}
1264
-
1265
-	/**
1266
-	 * Allow public upload on link shares
1267
-	 *
1268
-	 * @return bool
1269
-	 */
1270
-	public function shareApiLinkAllowPublicUpload() {
1271
-		return $this->config->getAppValue('core', 'shareapi_allow_public_upload', 'yes') === 'yes';
1272
-	}
1273
-
1274
-	/**
1275
-	 * check if user can only share with group members
1276
-	 * @return bool
1277
-	 */
1278
-	public function shareWithGroupMembersOnly() {
1279
-		return $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
1280
-	}
1281
-
1282
-	/**
1283
-	 * Check if users can share with groups
1284
-	 * @return bool
1285
-	 */
1286
-	public function allowGroupSharing() {
1287
-		return $this->config->getAppValue('core', 'shareapi_allow_group_sharing', 'yes') === 'yes';
1288
-	}
1289
-
1290
-	/**
1291
-	 * Copied from \OC_Util::isSharingDisabledForUser
1292
-	 *
1293
-	 * TODO: Deprecate fuction from OC_Util
1294
-	 *
1295
-	 * @param string $userId
1296
-	 * @return bool
1297
-	 */
1298
-	public function sharingDisabledForUser($userId) {
1299
-		if ($userId === null) {
1300
-			return false;
1301
-		}
1302
-
1303
-		if (isset($this->sharingDisabledForUsersCache[$userId])) {
1304
-			return $this->sharingDisabledForUsersCache[$userId];
1305
-		}
1306
-
1307
-		if ($this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes') {
1308
-			$groupsList = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
1309
-			$excludedGroups = json_decode($groupsList);
1310
-			if (is_null($excludedGroups)) {
1311
-				$excludedGroups = explode(',', $groupsList);
1312
-				$newValue = json_encode($excludedGroups);
1313
-				$this->config->setAppValue('core', 'shareapi_exclude_groups_list', $newValue);
1314
-			}
1315
-			$user = $this->userManager->get($userId);
1316
-			$usersGroups = $this->groupManager->getUserGroupIds($user);
1317
-			if (!empty($usersGroups)) {
1318
-				$remainingGroups = array_diff($usersGroups, $excludedGroups);
1319
-				// if the user is only in groups which are disabled for sharing then
1320
-				// sharing is also disabled for the user
1321
-				if (empty($remainingGroups)) {
1322
-					$this->sharingDisabledForUsersCache[$userId] = true;
1323
-					return true;
1324
-				}
1325
-			}
1326
-		}
1327
-
1328
-		$this->sharingDisabledForUsersCache[$userId] = false;
1329
-		return false;
1330
-	}
1331
-
1332
-	/**
1333
-	 * @inheritdoc
1334
-	 */
1335
-	public function outgoingServer2ServerSharesAllowed() {
1336
-		return $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') === 'yes';
1337
-	}
1338
-
1339
-	/**
1340
-	 * @inheritdoc
1341
-	 */
1342
-	public function shareProviderExists($shareType) {
1343
-		try {
1344
-			$this->factory->getProviderForType($shareType);
1345
-		} catch (ProviderException $e) {
1346
-			return false;
1347
-		}
1348
-
1349
-		return true;
1350
-	}
1104
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK &&
1105
+            !$this->shareApiLinkAllowPublicUpload()) {
1106
+            $share->setPermissions($share->getPermissions() & ~(\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE));
1107
+        }
1108
+
1109
+        return $share;
1110
+    }
1111
+
1112
+    /**
1113
+     * Verify the password of a public share
1114
+     *
1115
+     * @param \OCP\Share\IShare $share
1116
+     * @param string $password
1117
+     * @return bool
1118
+     */
1119
+    public function checkPassword(\OCP\Share\IShare $share, $password) {
1120
+        if ($share->getShareType() !== \OCP\Share::SHARE_TYPE_LINK) {
1121
+            //TODO maybe exception?
1122
+            return false;
1123
+        }
1124
+
1125
+        if ($password === null || $share->getPassword() === null) {
1126
+            return false;
1127
+        }
1128
+
1129
+        $newHash = '';
1130
+        if (!$this->hasher->verify($password, $share->getPassword(), $newHash)) {
1131
+            return false;
1132
+        }
1133
+
1134
+        if (!empty($newHash)) {
1135
+            $share->setPassword($newHash);
1136
+            $provider = $this->factory->getProviderForType($share->getShareType());
1137
+            $provider->update($share);
1138
+        }
1139
+
1140
+        return true;
1141
+    }
1142
+
1143
+    /**
1144
+     * @inheritdoc
1145
+     */
1146
+    public function userDeleted($uid) {
1147
+        $types = [\OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_GROUP, \OCP\Share::SHARE_TYPE_LINK, \OCP\Share::SHARE_TYPE_REMOTE, \OCP\Share::SHARE_TYPE_EMAIL];
1148
+
1149
+        foreach ($types as $type) {
1150
+            try {
1151
+                $provider = $this->factory->getProviderForType($type);
1152
+            } catch (ProviderException $e) {
1153
+                continue;
1154
+            }
1155
+            $provider->userDeleted($uid, $type);
1156
+        }
1157
+    }
1158
+
1159
+    /**
1160
+     * @inheritdoc
1161
+     */
1162
+    public function groupDeleted($gid) {
1163
+        $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
1164
+        $provider->groupDeleted($gid);
1165
+    }
1166
+
1167
+    /**
1168
+     * @inheritdoc
1169
+     */
1170
+    public function userDeletedFromGroup($uid, $gid) {
1171
+        $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
1172
+        $provider->userDeletedFromGroup($uid, $gid);
1173
+    }
1174
+
1175
+    /**
1176
+     * Get access list to a path. This means
1177
+     * all the users and groups that can access a given path.
1178
+     *
1179
+     * Consider:
1180
+     * -root
1181
+     * |-folder1
1182
+     *  |-folder2
1183
+     *   |-fileA
1184
+     *
1185
+     * fileA is shared with user1
1186
+     * folder2 is shared with group2
1187
+     * folder1 is shared with user2
1188
+     *
1189
+     * Then the access list will to '/folder1/folder2/fileA' is:
1190
+     * [
1191
+     * 	'users' => ['user1', 'user2'],
1192
+     *  'groups' => ['group2']
1193
+     * ]
1194
+     *
1195
+     * This is required for encryption
1196
+     *
1197
+     * @param \OCP\Files\Node $path
1198
+     */
1199
+    public function getAccessList(\OCP\Files\Node $path) {
1200
+    }
1201
+
1202
+    /**
1203
+     * Create a new share
1204
+     * @return \OCP\Share\IShare;
1205
+     */
1206
+    public function newShare() {
1207
+        return new \OC\Share20\Share($this->rootFolder, $this->userManager);
1208
+    }
1209
+
1210
+    /**
1211
+     * Is the share API enabled
1212
+     *
1213
+     * @return bool
1214
+     */
1215
+    public function shareApiEnabled() {
1216
+        return $this->config->getAppValue('core', 'shareapi_enabled', 'yes') === 'yes';
1217
+    }
1218
+
1219
+    /**
1220
+     * Is public link sharing enabled
1221
+     *
1222
+     * @return bool
1223
+     */
1224
+    public function shareApiAllowLinks() {
1225
+        return $this->config->getAppValue('core', 'shareapi_allow_links', 'yes') === 'yes';
1226
+    }
1227
+
1228
+    /**
1229
+     * Is password on public link requires
1230
+     *
1231
+     * @return bool
1232
+     */
1233
+    public function shareApiLinkEnforcePassword() {
1234
+        return $this->config->getAppValue('core', 'shareapi_enforce_links_password', 'no') === 'yes';
1235
+    }
1236
+
1237
+    /**
1238
+     * Is default expire date enabled
1239
+     *
1240
+     * @return bool
1241
+     */
1242
+    public function shareApiLinkDefaultExpireDate() {
1243
+        return $this->config->getAppValue('core', 'shareapi_default_expire_date', 'no') === 'yes';
1244
+    }
1245
+
1246
+    /**
1247
+     * Is default expire date enforced
1248
+     *`
1249
+     * @return bool
1250
+     */
1251
+    public function shareApiLinkDefaultExpireDateEnforced() {
1252
+        return $this->shareApiLinkDefaultExpireDate() &&
1253
+            $this->config->getAppValue('core', 'shareapi_enforce_expire_date', 'no') === 'yes';
1254
+    }
1255
+
1256
+    /**
1257
+     * Number of default expire days
1258
+     *shareApiLinkAllowPublicUpload
1259
+     * @return int
1260
+     */
1261
+    public function shareApiLinkDefaultExpireDays() {
1262
+        return (int)$this->config->getAppValue('core', 'shareapi_expire_after_n_days', '7');
1263
+    }
1264
+
1265
+    /**
1266
+     * Allow public upload on link shares
1267
+     *
1268
+     * @return bool
1269
+     */
1270
+    public function shareApiLinkAllowPublicUpload() {
1271
+        return $this->config->getAppValue('core', 'shareapi_allow_public_upload', 'yes') === 'yes';
1272
+    }
1273
+
1274
+    /**
1275
+     * check if user can only share with group members
1276
+     * @return bool
1277
+     */
1278
+    public function shareWithGroupMembersOnly() {
1279
+        return $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
1280
+    }
1281
+
1282
+    /**
1283
+     * Check if users can share with groups
1284
+     * @return bool
1285
+     */
1286
+    public function allowGroupSharing() {
1287
+        return $this->config->getAppValue('core', 'shareapi_allow_group_sharing', 'yes') === 'yes';
1288
+    }
1289
+
1290
+    /**
1291
+     * Copied from \OC_Util::isSharingDisabledForUser
1292
+     *
1293
+     * TODO: Deprecate fuction from OC_Util
1294
+     *
1295
+     * @param string $userId
1296
+     * @return bool
1297
+     */
1298
+    public function sharingDisabledForUser($userId) {
1299
+        if ($userId === null) {
1300
+            return false;
1301
+        }
1302
+
1303
+        if (isset($this->sharingDisabledForUsersCache[$userId])) {
1304
+            return $this->sharingDisabledForUsersCache[$userId];
1305
+        }
1306
+
1307
+        if ($this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes') {
1308
+            $groupsList = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
1309
+            $excludedGroups = json_decode($groupsList);
1310
+            if (is_null($excludedGroups)) {
1311
+                $excludedGroups = explode(',', $groupsList);
1312
+                $newValue = json_encode($excludedGroups);
1313
+                $this->config->setAppValue('core', 'shareapi_exclude_groups_list', $newValue);
1314
+            }
1315
+            $user = $this->userManager->get($userId);
1316
+            $usersGroups = $this->groupManager->getUserGroupIds($user);
1317
+            if (!empty($usersGroups)) {
1318
+                $remainingGroups = array_diff($usersGroups, $excludedGroups);
1319
+                // if the user is only in groups which are disabled for sharing then
1320
+                // sharing is also disabled for the user
1321
+                if (empty($remainingGroups)) {
1322
+                    $this->sharingDisabledForUsersCache[$userId] = true;
1323
+                    return true;
1324
+                }
1325
+            }
1326
+        }
1327
+
1328
+        $this->sharingDisabledForUsersCache[$userId] = false;
1329
+        return false;
1330
+    }
1331
+
1332
+    /**
1333
+     * @inheritdoc
1334
+     */
1335
+    public function outgoingServer2ServerSharesAllowed() {
1336
+        return $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') === 'yes';
1337
+    }
1338
+
1339
+    /**
1340
+     * @inheritdoc
1341
+     */
1342
+    public function shareProviderExists($shareType) {
1343
+        try {
1344
+            $this->factory->getProviderForType($shareType);
1345
+        } catch (ProviderException $e) {
1346
+            return false;
1347
+        }
1348
+
1349
+        return true;
1350
+    }
1351 1351
 
1352 1352
 }
Please login to merge, or discard this patch.
apps/files_sharing/lib/Controller/ShareesAPIController.php 1 patch
Indentation   +668 added lines, -668 removed lines patch added patch discarded remove patch
@@ -43,672 +43,672 @@
 block discarded – undo
43 43
 
44 44
 class ShareesAPIController extends OCSController {
45 45
 
46
-	/** @var IGroupManager */
47
-	protected $groupManager;
48
-
49
-	/** @var IUserManager */
50
-	protected $userManager;
51
-
52
-	/** @var IManager */
53
-	protected $contactsManager;
54
-
55
-	/** @var IConfig */
56
-	protected $config;
57
-
58
-	/** @var IUserSession */
59
-	protected $userSession;
60
-
61
-	/** @var IURLGenerator */
62
-	protected $urlGenerator;
63
-
64
-	/** @var ILogger */
65
-	protected $logger;
66
-
67
-	/** @var \OCP\Share\IManager */
68
-	protected $shareManager;
69
-
70
-	/** @var IClientService */
71
-	protected $clientService;
72
-
73
-	/** @var ICloudIdManager  */
74
-	protected $cloudIdManager;
75
-
76
-	/** @var bool */
77
-	protected $shareWithGroupOnly = false;
78
-
79
-	/** @var bool */
80
-	protected $shareeEnumeration = true;
81
-
82
-	/** @var int */
83
-	protected $offset = 0;
84
-
85
-	/** @var int */
86
-	protected $limit = 10;
87
-
88
-	/** @var array */
89
-	protected $result = [
90
-		'exact' => [
91
-			'users' => [],
92
-			'groups' => [],
93
-			'remotes' => [],
94
-			'emails' => [],
95
-			'circles' => [],
96
-		],
97
-		'users' => [],
98
-		'groups' => [],
99
-		'remotes' => [],
100
-		'emails' => [],
101
-		'lookup' => [],
102
-		'circles' => [],
103
-	];
104
-
105
-	protected $reachedEndFor = [];
106
-
107
-	/**
108
-	 * @param string $appName
109
-	 * @param IRequest $request
110
-	 * @param IGroupManager $groupManager
111
-	 * @param IUserManager $userManager
112
-	 * @param IManager $contactsManager
113
-	 * @param IConfig $config
114
-	 * @param IUserSession $userSession
115
-	 * @param IURLGenerator $urlGenerator
116
-	 * @param ILogger $logger
117
-	 * @param \OCP\Share\IManager $shareManager
118
-	 * @param IClientService $clientService
119
-	 * @param ICloudIdManager $cloudIdManager
120
-	 */
121
-	public function __construct($appName,
122
-								IRequest $request,
123
-								IGroupManager $groupManager,
124
-								IUserManager $userManager,
125
-								IManager $contactsManager,
126
-								IConfig $config,
127
-								IUserSession $userSession,
128
-								IURLGenerator $urlGenerator,
129
-								ILogger $logger,
130
-								\OCP\Share\IManager $shareManager,
131
-								IClientService $clientService,
132
-								ICloudIdManager $cloudIdManager
133
-	) {
134
-		parent::__construct($appName, $request);
135
-
136
-		$this->groupManager = $groupManager;
137
-		$this->userManager = $userManager;
138
-		$this->contactsManager = $contactsManager;
139
-		$this->config = $config;
140
-		$this->userSession = $userSession;
141
-		$this->urlGenerator = $urlGenerator;
142
-		$this->logger = $logger;
143
-		$this->shareManager = $shareManager;
144
-		$this->clientService = $clientService;
145
-		$this->cloudIdManager = $cloudIdManager;
146
-	}
147
-
148
-	/**
149
-	 * @param string $search
150
-	 */
151
-	protected function getUsers($search) {
152
-		$this->result['users'] = $this->result['exact']['users'] = $users = [];
153
-
154
-		$userGroups = [];
155
-		if ($this->shareWithGroupOnly) {
156
-			// Search in all the groups this user is part of
157
-			$userGroups = $this->groupManager->getUserGroupIds($this->userSession->getUser());
158
-			foreach ($userGroups as $userGroup) {
159
-				$usersTmp = $this->groupManager->displayNamesInGroup($userGroup, $search, $this->limit, $this->offset);
160
-				foreach ($usersTmp as $uid => $userDisplayName) {
161
-					$users[$uid] = $userDisplayName;
162
-				}
163
-			}
164
-		} else {
165
-			// Search in all users
166
-			$usersTmp = $this->userManager->searchDisplayName($search, $this->limit, $this->offset);
167
-
168
-			foreach ($usersTmp as $user) {
169
-				$users[$user->getUID()] = $user->getDisplayName();
170
-			}
171
-		}
172
-
173
-		if (!$this->shareeEnumeration || sizeof($users) < $this->limit) {
174
-			$this->reachedEndFor[] = 'users';
175
-		}
176
-
177
-		$foundUserById = false;
178
-		$lowerSearch = strtolower($search);
179
-		foreach ($users as $uid => $userDisplayName) {
180
-			if (strtolower($uid) === $lowerSearch || strtolower($userDisplayName) === $lowerSearch) {
181
-				if (strtolower($uid) === $lowerSearch) {
182
-					$foundUserById = true;
183
-				}
184
-				$this->result['exact']['users'][] = [
185
-					'label' => $userDisplayName,
186
-					'value' => [
187
-						'shareType' => Share::SHARE_TYPE_USER,
188
-						'shareWith' => $uid,
189
-					],
190
-				];
191
-			} else {
192
-				$this->result['users'][] = [
193
-					'label' => $userDisplayName,
194
-					'value' => [
195
-						'shareType' => Share::SHARE_TYPE_USER,
196
-						'shareWith' => $uid,
197
-					],
198
-				];
199
-			}
200
-		}
201
-
202
-		if ($this->offset === 0 && !$foundUserById) {
203
-			// On page one we try if the search result has a direct hit on the
204
-			// user id and if so, we add that to the exact match list
205
-			$user = $this->userManager->get($search);
206
-			if ($user instanceof IUser) {
207
-				$addUser = true;
208
-
209
-				if ($this->shareWithGroupOnly) {
210
-					// Only add, if we have a common group
211
-					$commonGroups = array_intersect($userGroups, $this->groupManager->getUserGroupIds($user));
212
-					$addUser = !empty($commonGroups);
213
-				}
214
-
215
-				if ($addUser) {
216
-					array_push($this->result['exact']['users'], [
217
-						'label' => $user->getDisplayName(),
218
-						'value' => [
219
-							'shareType' => Share::SHARE_TYPE_USER,
220
-							'shareWith' => $user->getUID(),
221
-						],
222
-					]);
223
-				}
224
-			}
225
-		}
226
-
227
-		if (!$this->shareeEnumeration) {
228
-			$this->result['users'] = [];
229
-		}
230
-	}
231
-
232
-	/**
233
-	 * @param string $search
234
-	 */
235
-	protected function getGroups($search) {
236
-		$this->result['groups'] = $this->result['exact']['groups'] = [];
237
-
238
-		$groups = $this->groupManager->search($search, $this->limit, $this->offset);
239
-		$groupIds = array_map(function (IGroup $group) { return $group->getGID(); }, $groups);
240
-
241
-		if (!$this->shareeEnumeration || sizeof($groups) < $this->limit) {
242
-			$this->reachedEndFor[] = 'groups';
243
-		}
244
-
245
-		$userGroups =  [];
246
-		if (!empty($groups) && $this->shareWithGroupOnly) {
247
-			// Intersect all the groups that match with the groups this user is a member of
248
-			$userGroups = $this->groupManager->getUserGroups($this->userSession->getUser());
249
-			$userGroups = array_map(function (IGroup $group) { return $group->getGID(); }, $userGroups);
250
-			$groupIds = array_intersect($groupIds, $userGroups);
251
-		}
252
-
253
-		$lowerSearch = strtolower($search);
254
-		foreach ($groups as $group) {
255
-			// FIXME: use a more efficient approach
256
-			$gid = $group->getGID();
257
-			if (!in_array($gid, $groupIds)) {
258
-				continue;
259
-			}
260
-			if (strtolower($gid) === $lowerSearch || strtolower($group->getDisplayName()) === $lowerSearch) {
261
-				$this->result['exact']['groups'][] = [
262
-					'label' => $group->getDisplayName(),
263
-					'value' => [
264
-						'shareType' => Share::SHARE_TYPE_GROUP,
265
-						'shareWith' => $gid,
266
-					],
267
-				];
268
-			} else {
269
-				$this->result['groups'][] = [
270
-					'label' => $group->getDisplayName(),
271
-					'value' => [
272
-						'shareType' => Share::SHARE_TYPE_GROUP,
273
-						'shareWith' => $gid,
274
-					],
275
-				];
276
-			}
277
-		}
278
-
279
-		if ($this->offset === 0 && empty($this->result['exact']['groups'])) {
280
-			// On page one we try if the search result has a direct hit on the
281
-			// user id and if so, we add that to the exact match list
282
-			$group = $this->groupManager->get($search);
283
-			if ($group instanceof IGroup && (!$this->shareWithGroupOnly || in_array($group->getGID(), $userGroups))) {
284
-				array_push($this->result['exact']['groups'], [
285
-					'label' => $group->getDisplayName(),
286
-					'value' => [
287
-						'shareType' => Share::SHARE_TYPE_GROUP,
288
-						'shareWith' => $group->getGID(),
289
-					],
290
-				]);
291
-			}
292
-		}
293
-
294
-		if (!$this->shareeEnumeration) {
295
-			$this->result['groups'] = [];
296
-		}
297
-	}
298
-
299
-
300
-	/**
301
-	 * @param string $search
302
-	 */
303
-	protected function getCircles($search) {
304
-		$this->result['circles'] = $this->result['exact']['circles'] = [];
305
-
306
-		$result = \OCA\Circles\Api\Sharees::search($search, $this->limit, $this->offset);
307
-		if (array_key_exists('circles', $result['exact'])) {
308
-			$this->result['exact']['circles'] = $result['exact']['circles'];
309
-		}
310
-		if (array_key_exists('circles', $result)) {
311
-			$this->result['circles'] = $result['circles'];
312
-		}
313
-	}
314
-
315
-
316
-	/**
317
-	 * @param string $search
318
-	 * @return array
319
-	 */
320
-	protected function getRemote($search) {
321
-		$result = ['results' => [], 'exact' => []];
322
-
323
-		// Search in contacts
324
-		//@todo Pagination missing
325
-		$addressBookContacts = $this->contactsManager->search($search, ['CLOUD', 'FN']);
326
-		$result['exactIdMatch'] = false;
327
-		foreach ($addressBookContacts as $contact) {
328
-			if (isset($contact['isLocalSystemBook'])) {
329
-				continue;
330
-			}
331
-			if (isset($contact['CLOUD'])) {
332
-				$cloudIds = $contact['CLOUD'];
333
-				if (!is_array($cloudIds)) {
334
-					$cloudIds = [$cloudIds];
335
-				}
336
-				$lowerSearch = strtolower($search);
337
-				foreach ($cloudIds as $cloudId) {
338
-					list(, $serverUrl) = $this->splitUserRemote($cloudId);
339
-					if (strtolower($contact['FN']) === $lowerSearch || strtolower($cloudId) === $lowerSearch) {
340
-						if (strtolower($cloudId) === $lowerSearch) {
341
-							$result['exactIdMatch'] = true;
342
-						}
343
-						$result['exact'][] = [
344
-							'label' => $contact['FN'] . " ($cloudId)",
345
-							'value' => [
346
-								'shareType' => Share::SHARE_TYPE_REMOTE,
347
-								'shareWith' => $cloudId,
348
-								'server' => $serverUrl,
349
-							],
350
-						];
351
-					} else {
352
-						$result['results'][] = [
353
-							'label' => $contact['FN'] . " ($cloudId)",
354
-							'value' => [
355
-								'shareType' => Share::SHARE_TYPE_REMOTE,
356
-								'shareWith' => $cloudId,
357
-								'server' => $serverUrl,
358
-							],
359
-						];
360
-					}
361
-				}
362
-			}
363
-		}
364
-
365
-		if (!$this->shareeEnumeration) {
366
-			$result['results'] = [];
367
-		}
368
-
369
-		if (!$result['exactIdMatch'] && $this->cloudIdManager->isValidCloudId($search) && $this->offset === 0) {
370
-			$result['exact'][] = [
371
-				'label' => $search,
372
-				'value' => [
373
-					'shareType' => Share::SHARE_TYPE_REMOTE,
374
-					'shareWith' => $search,
375
-				],
376
-			];
377
-		}
378
-
379
-		$this->reachedEndFor[] = 'remotes';
380
-
381
-		return $result;
382
-	}
383
-
384
-	/**
385
-	 * split user and remote from federated cloud id
386
-	 *
387
-	 * @param string $address federated share address
388
-	 * @return array [user, remoteURL]
389
-	 * @throws \Exception
390
-	 */
391
-	public function splitUserRemote($address) {
392
-		try {
393
-			$cloudId = $this->cloudIdManager->resolveCloudId($address);
394
-			return [$cloudId->getUser(), $cloudId->getRemote()];
395
-		} catch (\InvalidArgumentException $e) {
396
-			throw new \Exception('Invalid Federated Cloud ID', 0, $e);
397
-		}
398
-	}
399
-
400
-	/**
401
-	 * Strips away a potential file names and trailing slashes:
402
-	 * - http://localhost
403
-	 * - http://localhost/
404
-	 * - http://localhost/index.php
405
-	 * - http://localhost/index.php/s/{shareToken}
406
-	 *
407
-	 * all return: http://localhost
408
-	 *
409
-	 * @param string $remote
410
-	 * @return string
411
-	 */
412
-	protected function fixRemoteURL($remote) {
413
-		$remote = str_replace('\\', '/', $remote);
414
-		if ($fileNamePosition = strpos($remote, '/index.php')) {
415
-			$remote = substr($remote, 0, $fileNamePosition);
416
-		}
417
-		$remote = rtrim($remote, '/');
418
-
419
-		return $remote;
420
-	}
421
-
422
-	/**
423
-	 * @NoAdminRequired
424
-	 *
425
-	 * @param string $search
426
-	 * @param string $itemType
427
-	 * @param int $page
428
-	 * @param int $perPage
429
-	 * @param int|int[] $shareType
430
-	 * @param bool $lookup
431
-	 * @return DataResponse
432
-	 * @throws OCSBadRequestException
433
-	 */
434
-	public function search($search = '', $itemType = null, $page = 1, $perPage = 200, $shareType = null, $lookup = true) {
435
-
436
-		// only search for string larger than a given threshold
437
-		$threshold = (int)$this->config->getSystemValue('sharing.minSearchStringLength', 0);
438
-		if (strlen($search) < $threshold) {
439
-			return new DataResponse($this->result);
440
-		}
441
-
442
-		// never return more than the max. number of results configured in the config.php
443
-		$maxResults = (int)$this->config->getSystemValue('sharing.maxAutocompleteResults', 0);
444
-		if ($maxResults > 0) {
445
-			$perPage = min($perPage, $maxResults);
446
-		}
447
-		if ($perPage <= 0) {
448
-			throw new OCSBadRequestException('Invalid perPage argument');
449
-		}
450
-		if ($page <= 0) {
451
-			throw new OCSBadRequestException('Invalid page');
452
-		}
453
-
454
-		$shareTypes = [
455
-			Share::SHARE_TYPE_USER,
456
-		];
457
-
458
-		if ($itemType === 'file' || $itemType === 'folder') {
459
-			if ($this->shareManager->allowGroupSharing()) {
460
-				$shareTypes[] = Share::SHARE_TYPE_GROUP;
461
-			}
462
-
463
-			if ($this->isRemoteSharingAllowed($itemType)) {
464
-				$shareTypes[] = Share::SHARE_TYPE_REMOTE;
465
-			}
466
-
467
-			if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
468
-				$shareTypes[] = Share::SHARE_TYPE_EMAIL;
469
-			}
470
-		} else {
471
-			$shareTypes[] = Share::SHARE_TYPE_GROUP;
472
-			$shareTypes[] = Share::SHARE_TYPE_EMAIL;
473
-		}
474
-
475
-		if (\OCP\App::isEnabled('circles')) {
476
-			$shareTypes[] = Share::SHARE_TYPE_CIRCLE;
477
-		}
478
-
479
-		if (isset($_GET['shareType']) && is_array($_GET['shareType'])) {
480
-			$shareTypes = array_intersect($shareTypes, $_GET['shareType']);
481
-			sort($shareTypes);
482
-		} else if (is_numeric($shareType)) {
483
-			$shareTypes = array_intersect($shareTypes, [(int) $shareType]);
484
-			sort($shareTypes);
485
-		}
486
-
487
-		$this->shareWithGroupOnly = $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
488
-		$this->shareeEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes';
489
-		$this->limit = (int) $perPage;
490
-		$this->offset = $perPage * ($page - 1);
491
-
492
-		return $this->searchSharees($search, $itemType, $shareTypes, $page, $perPage, $lookup);
493
-	}
494
-
495
-	/**
496
-	 * Method to get out the static call for better testing
497
-	 *
498
-	 * @param string $itemType
499
-	 * @return bool
500
-	 */
501
-	protected function isRemoteSharingAllowed($itemType) {
502
-		try {
503
-			$backend = Share::getBackend($itemType);
504
-			return $backend->isShareTypeAllowed(Share::SHARE_TYPE_REMOTE);
505
-		} catch (\Exception $e) {
506
-			return false;
507
-		}
508
-	}
509
-
510
-	/**
511
-	 * Testable search function that does not need globals
512
-	 *
513
-	 * @param string $search
514
-	 * @param string $itemType
515
-	 * @param array $shareTypes
516
-	 * @param int $page
517
-	 * @param int $perPage
518
-	 * @param bool $lookup
519
-	 * @return DataResponse
520
-	 * @throws OCSBadRequestException
521
-	 */
522
-	protected function searchSharees($search, $itemType, array $shareTypes, $page, $perPage, $lookup) {
523
-		// Verify arguments
524
-		if ($itemType === null) {
525
-			throw new OCSBadRequestException('Missing itemType');
526
-		}
527
-
528
-		// Get users
529
-		if (in_array(Share::SHARE_TYPE_USER, $shareTypes)) {
530
-			$this->getUsers($search);
531
-		}
532
-
533
-		// Get groups
534
-		if (in_array(Share::SHARE_TYPE_GROUP, $shareTypes)) {
535
-			$this->getGroups($search);
536
-		}
537
-
538
-		// Get circles
539
-		if (in_array(Share::SHARE_TYPE_CIRCLE, $shareTypes)) {
540
-			$this->getCircles($search);
541
-		}
542
-
543
-
544
-		// Get remote
545
-		$remoteResults = ['results' => [], 'exact' => [], 'exactIdMatch' => false];
546
-		if (in_array(Share::SHARE_TYPE_REMOTE, $shareTypes)) {
547
-			$remoteResults = $this->getRemote($search);
548
-		}
549
-
550
-		// Get emails
551
-		$mailResults = ['results' => [], 'exact' => [], 'exactIdMatch' => false];
552
-		if (in_array(Share::SHARE_TYPE_EMAIL, $shareTypes)) {
553
-			$mailResults = $this->getEmail($search);
554
-		}
555
-
556
-		// Get from lookup server
557
-		if ($lookup) {
558
-			$this->getLookup($search);
559
-		}
560
-
561
-		// if we have a exact match, either for the federated cloud id or for the
562
-		// email address we only return the exact match. It is highly unlikely
563
-		// that the exact same email address and federated cloud id exists
564
-		if ($mailResults['exactIdMatch'] && !$remoteResults['exactIdMatch']) {
565
-			$this->result['emails'] = $mailResults['results'];
566
-			$this->result['exact']['emails'] = $mailResults['exact'];
567
-		} else if (!$mailResults['exactIdMatch'] && $remoteResults['exactIdMatch']) {
568
-			$this->result['remotes'] = $remoteResults['results'];
569
-			$this->result['exact']['remotes'] = $remoteResults['exact'];
570
-		} else {
571
-			$this->result['remotes'] = $remoteResults['results'];
572
-			$this->result['exact']['remotes'] = $remoteResults['exact'];
573
-			$this->result['emails'] = $mailResults['results'];
574
-			$this->result['exact']['emails'] = $mailResults['exact'];
575
-		}
576
-
577
-		$response = new DataResponse($this->result);
578
-
579
-		if (sizeof($this->reachedEndFor) < 3) {
580
-			$response->addHeader('Link', $this->getPaginationLink($page, [
581
-				'search' => $search,
582
-				'itemType' => $itemType,
583
-				'shareType' => $shareTypes,
584
-				'perPage' => $perPage,
585
-			]));
586
-		}
587
-
588
-		return $response;
589
-	}
590
-
591
-	/**
592
-	 * @param string $search
593
-	 * @return array
594
-	 */
595
-	protected function getEmail($search) {
596
-		$result = ['results' => [], 'exact' => []];
597
-
598
-		// Search in contacts
599
-		//@todo Pagination missing
600
-		$addressBookContacts = $this->contactsManager->search($search, ['EMAIL', 'FN']);
601
-		$result['exactIdMatch'] = false;
602
-		foreach ($addressBookContacts as $contact) {
603
-			if (isset($contact['isLocalSystemBook'])) {
604
-				continue;
605
-			}
606
-			if (isset($contact['EMAIL'])) {
607
-				$emailAddresses = $contact['EMAIL'];
608
-				if (!is_array($emailAddresses)) {
609
-					$emailAddresses = [$emailAddresses];
610
-				}
611
-				foreach ($emailAddresses as $emailAddress) {
612
-					if (strtolower($contact['FN']) === strtolower($search) || strtolower($emailAddress) === strtolower($search)) {
613
-						if (strtolower($emailAddress) === strtolower($search)) {
614
-							$result['exactIdMatch'] = true;
615
-						}
616
-						$result['exact'][] = [
617
-							'label' => $contact['FN'] . " ($emailAddress)",
618
-							'value' => [
619
-								'shareType' => Share::SHARE_TYPE_EMAIL,
620
-								'shareWith' => $emailAddress,
621
-							],
622
-						];
623
-					} else {
624
-						$result['results'][] = [
625
-							'label' => $contact['FN'] . " ($emailAddress)",
626
-							'value' => [
627
-								'shareType' => Share::SHARE_TYPE_EMAIL,
628
-								'shareWith' => $emailAddress,
629
-							],
630
-						];
631
-					}
632
-				}
633
-			}
634
-		}
635
-
636
-		if (!$this->shareeEnumeration) {
637
-			$result['results'] = [];
638
-		}
639
-
640
-		if (!$result['exactIdMatch'] && filter_var($search, FILTER_VALIDATE_EMAIL)) {
641
-			$result['exact'][] = [
642
-				'label' => $search,
643
-				'value' => [
644
-					'shareType' => Share::SHARE_TYPE_EMAIL,
645
-					'shareWith' => $search,
646
-				],
647
-			];
648
-		}
649
-
650
-		$this->reachedEndFor[] = 'emails';
651
-
652
-		return $result;
653
-	}
654
-
655
-	protected function getLookup($search) {
656
-		$isEnabled = $this->config->getAppValue('files_sharing', 'lookupServerEnabled', 'no');
657
-		$result = [];
658
-
659
-		if($isEnabled === 'yes') {
660
-			try {
661
-				$client = $this->clientService->newClient();
662
-				$response = $client->get(
663
-					'https://lookup.nextcloud.com/users?search=' . urlencode($search),
664
-					[
665
-						'timeout' => 10,
666
-						'connect_timeout' => 3,
667
-					]
668
-				);
669
-
670
-				$body = json_decode($response->getBody(), true);
671
-
672
-				$result = [];
673
-				foreach ($body as $lookup) {
674
-					$result[] = [
675
-						'label' => $lookup['federationId'],
676
-						'value' => [
677
-							'shareType' => Share::SHARE_TYPE_REMOTE,
678
-							'shareWith' => $lookup['federationId'],
679
-						],
680
-						'extra' => $lookup,
681
-					];
682
-				}
683
-			} catch (\Exception $e) {}
684
-		}
685
-
686
-		$this->result['lookup'] = $result;
687
-	}
688
-
689
-	/**
690
-	 * Generates a bunch of pagination links for the current page
691
-	 *
692
-	 * @param int $page Current page
693
-	 * @param array $params Parameters for the URL
694
-	 * @return string
695
-	 */
696
-	protected function getPaginationLink($page, array $params) {
697
-		if ($this->isV2()) {
698
-			$url = $this->urlGenerator->getAbsoluteURL('/ocs/v2.php/apps/files_sharing/api/v1/sharees') . '?';
699
-		} else {
700
-			$url = $this->urlGenerator->getAbsoluteURL('/ocs/v1.php/apps/files_sharing/api/v1/sharees') . '?';
701
-		}
702
-		$params['page'] = $page + 1;
703
-		$link = '<' . $url . http_build_query($params) . '>; rel="next"';
704
-
705
-		return $link;
706
-	}
707
-
708
-	/**
709
-	 * @return bool
710
-	 */
711
-	protected function isV2() {
712
-		return $this->request->getScriptName() === '/ocs/v2.php';
713
-	}
46
+    /** @var IGroupManager */
47
+    protected $groupManager;
48
+
49
+    /** @var IUserManager */
50
+    protected $userManager;
51
+
52
+    /** @var IManager */
53
+    protected $contactsManager;
54
+
55
+    /** @var IConfig */
56
+    protected $config;
57
+
58
+    /** @var IUserSession */
59
+    protected $userSession;
60
+
61
+    /** @var IURLGenerator */
62
+    protected $urlGenerator;
63
+
64
+    /** @var ILogger */
65
+    protected $logger;
66
+
67
+    /** @var \OCP\Share\IManager */
68
+    protected $shareManager;
69
+
70
+    /** @var IClientService */
71
+    protected $clientService;
72
+
73
+    /** @var ICloudIdManager  */
74
+    protected $cloudIdManager;
75
+
76
+    /** @var bool */
77
+    protected $shareWithGroupOnly = false;
78
+
79
+    /** @var bool */
80
+    protected $shareeEnumeration = true;
81
+
82
+    /** @var int */
83
+    protected $offset = 0;
84
+
85
+    /** @var int */
86
+    protected $limit = 10;
87
+
88
+    /** @var array */
89
+    protected $result = [
90
+        'exact' => [
91
+            'users' => [],
92
+            'groups' => [],
93
+            'remotes' => [],
94
+            'emails' => [],
95
+            'circles' => [],
96
+        ],
97
+        'users' => [],
98
+        'groups' => [],
99
+        'remotes' => [],
100
+        'emails' => [],
101
+        'lookup' => [],
102
+        'circles' => [],
103
+    ];
104
+
105
+    protected $reachedEndFor = [];
106
+
107
+    /**
108
+     * @param string $appName
109
+     * @param IRequest $request
110
+     * @param IGroupManager $groupManager
111
+     * @param IUserManager $userManager
112
+     * @param IManager $contactsManager
113
+     * @param IConfig $config
114
+     * @param IUserSession $userSession
115
+     * @param IURLGenerator $urlGenerator
116
+     * @param ILogger $logger
117
+     * @param \OCP\Share\IManager $shareManager
118
+     * @param IClientService $clientService
119
+     * @param ICloudIdManager $cloudIdManager
120
+     */
121
+    public function __construct($appName,
122
+                                IRequest $request,
123
+                                IGroupManager $groupManager,
124
+                                IUserManager $userManager,
125
+                                IManager $contactsManager,
126
+                                IConfig $config,
127
+                                IUserSession $userSession,
128
+                                IURLGenerator $urlGenerator,
129
+                                ILogger $logger,
130
+                                \OCP\Share\IManager $shareManager,
131
+                                IClientService $clientService,
132
+                                ICloudIdManager $cloudIdManager
133
+    ) {
134
+        parent::__construct($appName, $request);
135
+
136
+        $this->groupManager = $groupManager;
137
+        $this->userManager = $userManager;
138
+        $this->contactsManager = $contactsManager;
139
+        $this->config = $config;
140
+        $this->userSession = $userSession;
141
+        $this->urlGenerator = $urlGenerator;
142
+        $this->logger = $logger;
143
+        $this->shareManager = $shareManager;
144
+        $this->clientService = $clientService;
145
+        $this->cloudIdManager = $cloudIdManager;
146
+    }
147
+
148
+    /**
149
+     * @param string $search
150
+     */
151
+    protected function getUsers($search) {
152
+        $this->result['users'] = $this->result['exact']['users'] = $users = [];
153
+
154
+        $userGroups = [];
155
+        if ($this->shareWithGroupOnly) {
156
+            // Search in all the groups this user is part of
157
+            $userGroups = $this->groupManager->getUserGroupIds($this->userSession->getUser());
158
+            foreach ($userGroups as $userGroup) {
159
+                $usersTmp = $this->groupManager->displayNamesInGroup($userGroup, $search, $this->limit, $this->offset);
160
+                foreach ($usersTmp as $uid => $userDisplayName) {
161
+                    $users[$uid] = $userDisplayName;
162
+                }
163
+            }
164
+        } else {
165
+            // Search in all users
166
+            $usersTmp = $this->userManager->searchDisplayName($search, $this->limit, $this->offset);
167
+
168
+            foreach ($usersTmp as $user) {
169
+                $users[$user->getUID()] = $user->getDisplayName();
170
+            }
171
+        }
172
+
173
+        if (!$this->shareeEnumeration || sizeof($users) < $this->limit) {
174
+            $this->reachedEndFor[] = 'users';
175
+        }
176
+
177
+        $foundUserById = false;
178
+        $lowerSearch = strtolower($search);
179
+        foreach ($users as $uid => $userDisplayName) {
180
+            if (strtolower($uid) === $lowerSearch || strtolower($userDisplayName) === $lowerSearch) {
181
+                if (strtolower($uid) === $lowerSearch) {
182
+                    $foundUserById = true;
183
+                }
184
+                $this->result['exact']['users'][] = [
185
+                    'label' => $userDisplayName,
186
+                    'value' => [
187
+                        'shareType' => Share::SHARE_TYPE_USER,
188
+                        'shareWith' => $uid,
189
+                    ],
190
+                ];
191
+            } else {
192
+                $this->result['users'][] = [
193
+                    'label' => $userDisplayName,
194
+                    'value' => [
195
+                        'shareType' => Share::SHARE_TYPE_USER,
196
+                        'shareWith' => $uid,
197
+                    ],
198
+                ];
199
+            }
200
+        }
201
+
202
+        if ($this->offset === 0 && !$foundUserById) {
203
+            // On page one we try if the search result has a direct hit on the
204
+            // user id and if so, we add that to the exact match list
205
+            $user = $this->userManager->get($search);
206
+            if ($user instanceof IUser) {
207
+                $addUser = true;
208
+
209
+                if ($this->shareWithGroupOnly) {
210
+                    // Only add, if we have a common group
211
+                    $commonGroups = array_intersect($userGroups, $this->groupManager->getUserGroupIds($user));
212
+                    $addUser = !empty($commonGroups);
213
+                }
214
+
215
+                if ($addUser) {
216
+                    array_push($this->result['exact']['users'], [
217
+                        'label' => $user->getDisplayName(),
218
+                        'value' => [
219
+                            'shareType' => Share::SHARE_TYPE_USER,
220
+                            'shareWith' => $user->getUID(),
221
+                        ],
222
+                    ]);
223
+                }
224
+            }
225
+        }
226
+
227
+        if (!$this->shareeEnumeration) {
228
+            $this->result['users'] = [];
229
+        }
230
+    }
231
+
232
+    /**
233
+     * @param string $search
234
+     */
235
+    protected function getGroups($search) {
236
+        $this->result['groups'] = $this->result['exact']['groups'] = [];
237
+
238
+        $groups = $this->groupManager->search($search, $this->limit, $this->offset);
239
+        $groupIds = array_map(function (IGroup $group) { return $group->getGID(); }, $groups);
240
+
241
+        if (!$this->shareeEnumeration || sizeof($groups) < $this->limit) {
242
+            $this->reachedEndFor[] = 'groups';
243
+        }
244
+
245
+        $userGroups =  [];
246
+        if (!empty($groups) && $this->shareWithGroupOnly) {
247
+            // Intersect all the groups that match with the groups this user is a member of
248
+            $userGroups = $this->groupManager->getUserGroups($this->userSession->getUser());
249
+            $userGroups = array_map(function (IGroup $group) { return $group->getGID(); }, $userGroups);
250
+            $groupIds = array_intersect($groupIds, $userGroups);
251
+        }
252
+
253
+        $lowerSearch = strtolower($search);
254
+        foreach ($groups as $group) {
255
+            // FIXME: use a more efficient approach
256
+            $gid = $group->getGID();
257
+            if (!in_array($gid, $groupIds)) {
258
+                continue;
259
+            }
260
+            if (strtolower($gid) === $lowerSearch || strtolower($group->getDisplayName()) === $lowerSearch) {
261
+                $this->result['exact']['groups'][] = [
262
+                    'label' => $group->getDisplayName(),
263
+                    'value' => [
264
+                        'shareType' => Share::SHARE_TYPE_GROUP,
265
+                        'shareWith' => $gid,
266
+                    ],
267
+                ];
268
+            } else {
269
+                $this->result['groups'][] = [
270
+                    'label' => $group->getDisplayName(),
271
+                    'value' => [
272
+                        'shareType' => Share::SHARE_TYPE_GROUP,
273
+                        'shareWith' => $gid,
274
+                    ],
275
+                ];
276
+            }
277
+        }
278
+
279
+        if ($this->offset === 0 && empty($this->result['exact']['groups'])) {
280
+            // On page one we try if the search result has a direct hit on the
281
+            // user id and if so, we add that to the exact match list
282
+            $group = $this->groupManager->get($search);
283
+            if ($group instanceof IGroup && (!$this->shareWithGroupOnly || in_array($group->getGID(), $userGroups))) {
284
+                array_push($this->result['exact']['groups'], [
285
+                    'label' => $group->getDisplayName(),
286
+                    'value' => [
287
+                        'shareType' => Share::SHARE_TYPE_GROUP,
288
+                        'shareWith' => $group->getGID(),
289
+                    ],
290
+                ]);
291
+            }
292
+        }
293
+
294
+        if (!$this->shareeEnumeration) {
295
+            $this->result['groups'] = [];
296
+        }
297
+    }
298
+
299
+
300
+    /**
301
+     * @param string $search
302
+     */
303
+    protected function getCircles($search) {
304
+        $this->result['circles'] = $this->result['exact']['circles'] = [];
305
+
306
+        $result = \OCA\Circles\Api\Sharees::search($search, $this->limit, $this->offset);
307
+        if (array_key_exists('circles', $result['exact'])) {
308
+            $this->result['exact']['circles'] = $result['exact']['circles'];
309
+        }
310
+        if (array_key_exists('circles', $result)) {
311
+            $this->result['circles'] = $result['circles'];
312
+        }
313
+    }
314
+
315
+
316
+    /**
317
+     * @param string $search
318
+     * @return array
319
+     */
320
+    protected function getRemote($search) {
321
+        $result = ['results' => [], 'exact' => []];
322
+
323
+        // Search in contacts
324
+        //@todo Pagination missing
325
+        $addressBookContacts = $this->contactsManager->search($search, ['CLOUD', 'FN']);
326
+        $result['exactIdMatch'] = false;
327
+        foreach ($addressBookContacts as $contact) {
328
+            if (isset($contact['isLocalSystemBook'])) {
329
+                continue;
330
+            }
331
+            if (isset($contact['CLOUD'])) {
332
+                $cloudIds = $contact['CLOUD'];
333
+                if (!is_array($cloudIds)) {
334
+                    $cloudIds = [$cloudIds];
335
+                }
336
+                $lowerSearch = strtolower($search);
337
+                foreach ($cloudIds as $cloudId) {
338
+                    list(, $serverUrl) = $this->splitUserRemote($cloudId);
339
+                    if (strtolower($contact['FN']) === $lowerSearch || strtolower($cloudId) === $lowerSearch) {
340
+                        if (strtolower($cloudId) === $lowerSearch) {
341
+                            $result['exactIdMatch'] = true;
342
+                        }
343
+                        $result['exact'][] = [
344
+                            'label' => $contact['FN'] . " ($cloudId)",
345
+                            'value' => [
346
+                                'shareType' => Share::SHARE_TYPE_REMOTE,
347
+                                'shareWith' => $cloudId,
348
+                                'server' => $serverUrl,
349
+                            ],
350
+                        ];
351
+                    } else {
352
+                        $result['results'][] = [
353
+                            'label' => $contact['FN'] . " ($cloudId)",
354
+                            'value' => [
355
+                                'shareType' => Share::SHARE_TYPE_REMOTE,
356
+                                'shareWith' => $cloudId,
357
+                                'server' => $serverUrl,
358
+                            ],
359
+                        ];
360
+                    }
361
+                }
362
+            }
363
+        }
364
+
365
+        if (!$this->shareeEnumeration) {
366
+            $result['results'] = [];
367
+        }
368
+
369
+        if (!$result['exactIdMatch'] && $this->cloudIdManager->isValidCloudId($search) && $this->offset === 0) {
370
+            $result['exact'][] = [
371
+                'label' => $search,
372
+                'value' => [
373
+                    'shareType' => Share::SHARE_TYPE_REMOTE,
374
+                    'shareWith' => $search,
375
+                ],
376
+            ];
377
+        }
378
+
379
+        $this->reachedEndFor[] = 'remotes';
380
+
381
+        return $result;
382
+    }
383
+
384
+    /**
385
+     * split user and remote from federated cloud id
386
+     *
387
+     * @param string $address federated share address
388
+     * @return array [user, remoteURL]
389
+     * @throws \Exception
390
+     */
391
+    public function splitUserRemote($address) {
392
+        try {
393
+            $cloudId = $this->cloudIdManager->resolveCloudId($address);
394
+            return [$cloudId->getUser(), $cloudId->getRemote()];
395
+        } catch (\InvalidArgumentException $e) {
396
+            throw new \Exception('Invalid Federated Cloud ID', 0, $e);
397
+        }
398
+    }
399
+
400
+    /**
401
+     * Strips away a potential file names and trailing slashes:
402
+     * - http://localhost
403
+     * - http://localhost/
404
+     * - http://localhost/index.php
405
+     * - http://localhost/index.php/s/{shareToken}
406
+     *
407
+     * all return: http://localhost
408
+     *
409
+     * @param string $remote
410
+     * @return string
411
+     */
412
+    protected function fixRemoteURL($remote) {
413
+        $remote = str_replace('\\', '/', $remote);
414
+        if ($fileNamePosition = strpos($remote, '/index.php')) {
415
+            $remote = substr($remote, 0, $fileNamePosition);
416
+        }
417
+        $remote = rtrim($remote, '/');
418
+
419
+        return $remote;
420
+    }
421
+
422
+    /**
423
+     * @NoAdminRequired
424
+     *
425
+     * @param string $search
426
+     * @param string $itemType
427
+     * @param int $page
428
+     * @param int $perPage
429
+     * @param int|int[] $shareType
430
+     * @param bool $lookup
431
+     * @return DataResponse
432
+     * @throws OCSBadRequestException
433
+     */
434
+    public function search($search = '', $itemType = null, $page = 1, $perPage = 200, $shareType = null, $lookup = true) {
435
+
436
+        // only search for string larger than a given threshold
437
+        $threshold = (int)$this->config->getSystemValue('sharing.minSearchStringLength', 0);
438
+        if (strlen($search) < $threshold) {
439
+            return new DataResponse($this->result);
440
+        }
441
+
442
+        // never return more than the max. number of results configured in the config.php
443
+        $maxResults = (int)$this->config->getSystemValue('sharing.maxAutocompleteResults', 0);
444
+        if ($maxResults > 0) {
445
+            $perPage = min($perPage, $maxResults);
446
+        }
447
+        if ($perPage <= 0) {
448
+            throw new OCSBadRequestException('Invalid perPage argument');
449
+        }
450
+        if ($page <= 0) {
451
+            throw new OCSBadRequestException('Invalid page');
452
+        }
453
+
454
+        $shareTypes = [
455
+            Share::SHARE_TYPE_USER,
456
+        ];
457
+
458
+        if ($itemType === 'file' || $itemType === 'folder') {
459
+            if ($this->shareManager->allowGroupSharing()) {
460
+                $shareTypes[] = Share::SHARE_TYPE_GROUP;
461
+            }
462
+
463
+            if ($this->isRemoteSharingAllowed($itemType)) {
464
+                $shareTypes[] = Share::SHARE_TYPE_REMOTE;
465
+            }
466
+
467
+            if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
468
+                $shareTypes[] = Share::SHARE_TYPE_EMAIL;
469
+            }
470
+        } else {
471
+            $shareTypes[] = Share::SHARE_TYPE_GROUP;
472
+            $shareTypes[] = Share::SHARE_TYPE_EMAIL;
473
+        }
474
+
475
+        if (\OCP\App::isEnabled('circles')) {
476
+            $shareTypes[] = Share::SHARE_TYPE_CIRCLE;
477
+        }
478
+
479
+        if (isset($_GET['shareType']) && is_array($_GET['shareType'])) {
480
+            $shareTypes = array_intersect($shareTypes, $_GET['shareType']);
481
+            sort($shareTypes);
482
+        } else if (is_numeric($shareType)) {
483
+            $shareTypes = array_intersect($shareTypes, [(int) $shareType]);
484
+            sort($shareTypes);
485
+        }
486
+
487
+        $this->shareWithGroupOnly = $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
488
+        $this->shareeEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes';
489
+        $this->limit = (int) $perPage;
490
+        $this->offset = $perPage * ($page - 1);
491
+
492
+        return $this->searchSharees($search, $itemType, $shareTypes, $page, $perPage, $lookup);
493
+    }
494
+
495
+    /**
496
+     * Method to get out the static call for better testing
497
+     *
498
+     * @param string $itemType
499
+     * @return bool
500
+     */
501
+    protected function isRemoteSharingAllowed($itemType) {
502
+        try {
503
+            $backend = Share::getBackend($itemType);
504
+            return $backend->isShareTypeAllowed(Share::SHARE_TYPE_REMOTE);
505
+        } catch (\Exception $e) {
506
+            return false;
507
+        }
508
+    }
509
+
510
+    /**
511
+     * Testable search function that does not need globals
512
+     *
513
+     * @param string $search
514
+     * @param string $itemType
515
+     * @param array $shareTypes
516
+     * @param int $page
517
+     * @param int $perPage
518
+     * @param bool $lookup
519
+     * @return DataResponse
520
+     * @throws OCSBadRequestException
521
+     */
522
+    protected function searchSharees($search, $itemType, array $shareTypes, $page, $perPage, $lookup) {
523
+        // Verify arguments
524
+        if ($itemType === null) {
525
+            throw new OCSBadRequestException('Missing itemType');
526
+        }
527
+
528
+        // Get users
529
+        if (in_array(Share::SHARE_TYPE_USER, $shareTypes)) {
530
+            $this->getUsers($search);
531
+        }
532
+
533
+        // Get groups
534
+        if (in_array(Share::SHARE_TYPE_GROUP, $shareTypes)) {
535
+            $this->getGroups($search);
536
+        }
537
+
538
+        // Get circles
539
+        if (in_array(Share::SHARE_TYPE_CIRCLE, $shareTypes)) {
540
+            $this->getCircles($search);
541
+        }
542
+
543
+
544
+        // Get remote
545
+        $remoteResults = ['results' => [], 'exact' => [], 'exactIdMatch' => false];
546
+        if (in_array(Share::SHARE_TYPE_REMOTE, $shareTypes)) {
547
+            $remoteResults = $this->getRemote($search);
548
+        }
549
+
550
+        // Get emails
551
+        $mailResults = ['results' => [], 'exact' => [], 'exactIdMatch' => false];
552
+        if (in_array(Share::SHARE_TYPE_EMAIL, $shareTypes)) {
553
+            $mailResults = $this->getEmail($search);
554
+        }
555
+
556
+        // Get from lookup server
557
+        if ($lookup) {
558
+            $this->getLookup($search);
559
+        }
560
+
561
+        // if we have a exact match, either for the federated cloud id or for the
562
+        // email address we only return the exact match. It is highly unlikely
563
+        // that the exact same email address and federated cloud id exists
564
+        if ($mailResults['exactIdMatch'] && !$remoteResults['exactIdMatch']) {
565
+            $this->result['emails'] = $mailResults['results'];
566
+            $this->result['exact']['emails'] = $mailResults['exact'];
567
+        } else if (!$mailResults['exactIdMatch'] && $remoteResults['exactIdMatch']) {
568
+            $this->result['remotes'] = $remoteResults['results'];
569
+            $this->result['exact']['remotes'] = $remoteResults['exact'];
570
+        } else {
571
+            $this->result['remotes'] = $remoteResults['results'];
572
+            $this->result['exact']['remotes'] = $remoteResults['exact'];
573
+            $this->result['emails'] = $mailResults['results'];
574
+            $this->result['exact']['emails'] = $mailResults['exact'];
575
+        }
576
+
577
+        $response = new DataResponse($this->result);
578
+
579
+        if (sizeof($this->reachedEndFor) < 3) {
580
+            $response->addHeader('Link', $this->getPaginationLink($page, [
581
+                'search' => $search,
582
+                'itemType' => $itemType,
583
+                'shareType' => $shareTypes,
584
+                'perPage' => $perPage,
585
+            ]));
586
+        }
587
+
588
+        return $response;
589
+    }
590
+
591
+    /**
592
+     * @param string $search
593
+     * @return array
594
+     */
595
+    protected function getEmail($search) {
596
+        $result = ['results' => [], 'exact' => []];
597
+
598
+        // Search in contacts
599
+        //@todo Pagination missing
600
+        $addressBookContacts = $this->contactsManager->search($search, ['EMAIL', 'FN']);
601
+        $result['exactIdMatch'] = false;
602
+        foreach ($addressBookContacts as $contact) {
603
+            if (isset($contact['isLocalSystemBook'])) {
604
+                continue;
605
+            }
606
+            if (isset($contact['EMAIL'])) {
607
+                $emailAddresses = $contact['EMAIL'];
608
+                if (!is_array($emailAddresses)) {
609
+                    $emailAddresses = [$emailAddresses];
610
+                }
611
+                foreach ($emailAddresses as $emailAddress) {
612
+                    if (strtolower($contact['FN']) === strtolower($search) || strtolower($emailAddress) === strtolower($search)) {
613
+                        if (strtolower($emailAddress) === strtolower($search)) {
614
+                            $result['exactIdMatch'] = true;
615
+                        }
616
+                        $result['exact'][] = [
617
+                            'label' => $contact['FN'] . " ($emailAddress)",
618
+                            'value' => [
619
+                                'shareType' => Share::SHARE_TYPE_EMAIL,
620
+                                'shareWith' => $emailAddress,
621
+                            ],
622
+                        ];
623
+                    } else {
624
+                        $result['results'][] = [
625
+                            'label' => $contact['FN'] . " ($emailAddress)",
626
+                            'value' => [
627
+                                'shareType' => Share::SHARE_TYPE_EMAIL,
628
+                                'shareWith' => $emailAddress,
629
+                            ],
630
+                        ];
631
+                    }
632
+                }
633
+            }
634
+        }
635
+
636
+        if (!$this->shareeEnumeration) {
637
+            $result['results'] = [];
638
+        }
639
+
640
+        if (!$result['exactIdMatch'] && filter_var($search, FILTER_VALIDATE_EMAIL)) {
641
+            $result['exact'][] = [
642
+                'label' => $search,
643
+                'value' => [
644
+                    'shareType' => Share::SHARE_TYPE_EMAIL,
645
+                    'shareWith' => $search,
646
+                ],
647
+            ];
648
+        }
649
+
650
+        $this->reachedEndFor[] = 'emails';
651
+
652
+        return $result;
653
+    }
654
+
655
+    protected function getLookup($search) {
656
+        $isEnabled = $this->config->getAppValue('files_sharing', 'lookupServerEnabled', 'no');
657
+        $result = [];
658
+
659
+        if($isEnabled === 'yes') {
660
+            try {
661
+                $client = $this->clientService->newClient();
662
+                $response = $client->get(
663
+                    'https://lookup.nextcloud.com/users?search=' . urlencode($search),
664
+                    [
665
+                        'timeout' => 10,
666
+                        'connect_timeout' => 3,
667
+                    ]
668
+                );
669
+
670
+                $body = json_decode($response->getBody(), true);
671
+
672
+                $result = [];
673
+                foreach ($body as $lookup) {
674
+                    $result[] = [
675
+                        'label' => $lookup['federationId'],
676
+                        'value' => [
677
+                            'shareType' => Share::SHARE_TYPE_REMOTE,
678
+                            'shareWith' => $lookup['federationId'],
679
+                        ],
680
+                        'extra' => $lookup,
681
+                    ];
682
+                }
683
+            } catch (\Exception $e) {}
684
+        }
685
+
686
+        $this->result['lookup'] = $result;
687
+    }
688
+
689
+    /**
690
+     * Generates a bunch of pagination links for the current page
691
+     *
692
+     * @param int $page Current page
693
+     * @param array $params Parameters for the URL
694
+     * @return string
695
+     */
696
+    protected function getPaginationLink($page, array $params) {
697
+        if ($this->isV2()) {
698
+            $url = $this->urlGenerator->getAbsoluteURL('/ocs/v2.php/apps/files_sharing/api/v1/sharees') . '?';
699
+        } else {
700
+            $url = $this->urlGenerator->getAbsoluteURL('/ocs/v1.php/apps/files_sharing/api/v1/sharees') . '?';
701
+        }
702
+        $params['page'] = $page + 1;
703
+        $link = '<' . $url . http_build_query($params) . '>; rel="next"';
704
+
705
+        return $link;
706
+    }
707
+
708
+    /**
709
+     * @return bool
710
+     */
711
+    protected function isV2() {
712
+        return $this->request->getScriptName() === '/ocs/v2.php';
713
+    }
714 714
 }
Please login to merge, or discard this patch.