Completed
Push — master ( 7da815...9b9d72 )
by Morris
21:22
created
apps/files_sharing/lib/Controller/ShareAPIController.php 2 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -335,7 +335,7 @@
 block discarded – undo
335 335
 	 * @param string $shareWith
336 336
 	 * @param string $publicUpload
337 337
 	 * @param string $password
338
-	 * @param bool $sendPasswordByTalk
338
+	 * @param string $sendPasswordByTalk
339 339
 	 * @param string $expireDate
340 340
 	 *
341 341
 	 * @return DataResponse
Please login to merge, or discard this patch.
Indentation   +943 added lines, -943 removed lines patch added patch discarded remove patch
@@ -64,956 +64,956 @@
 block discarded – undo
64 64
  */
65 65
 class ShareAPIController extends OCSController {
66 66
 
67
-	/** @var IManager */
68
-	private $shareManager;
69
-	/** @var IGroupManager */
70
-	private $groupManager;
71
-	/** @var IUserManager */
72
-	private $userManager;
73
-	/** @var IRootFolder */
74
-	private $rootFolder;
75
-	/** @var IURLGenerator */
76
-	private $urlGenerator;
77
-	/** @var string */
78
-	private $currentUser;
79
-	/** @var IL10N */
80
-	private $l;
81
-	/** @var \OCP\Files\Node */
82
-	private $lockedNode;
83
-	/** @var IConfig */
84
-	private $config;
85
-	/** @var IAppManager */
86
-	private $appManager;
87
-
88
-	/**
89
-	 * Share20OCS constructor.
90
-	 *
91
-	 * @param string $appName
92
-	 * @param IRequest $request
93
-	 * @param IManager $shareManager
94
-	 * @param IGroupManager $groupManager
95
-	 * @param IUserManager $userManager
96
-	 * @param IRootFolder $rootFolder
97
-	 * @param IURLGenerator $urlGenerator
98
-	 * @param string $userId
99
-	 * @param IL10N $l10n
100
-	 * @param IConfig $config
101
-	 * @param IAppManager $appManager
102
-	 */
103
-	public function __construct(
104
-		string $appName,
105
-		IRequest $request,
106
-		IManager $shareManager,
107
-		IGroupManager $groupManager,
108
-		IUserManager $userManager,
109
-		IRootFolder $rootFolder,
110
-		IURLGenerator $urlGenerator,
111
-		string $userId,
112
-		IL10N $l10n,
113
-		IConfig $config,
114
-		IAppManager $appManager
115
-	) {
116
-		parent::__construct($appName, $request);
117
-
118
-		$this->shareManager = $shareManager;
119
-		$this->userManager = $userManager;
120
-		$this->groupManager = $groupManager;
121
-		$this->request = $request;
122
-		$this->rootFolder = $rootFolder;
123
-		$this->urlGenerator = $urlGenerator;
124
-		$this->currentUser = $userId;
125
-		$this->l = $l10n;
126
-		$this->config = $config;
127
-		$this->appManager = $appManager;
128
-	}
129
-
130
-	/**
131
-	 * Convert an IShare to an array for OCS output
132
-	 *
133
-	 * @param \OCP\Share\IShare $share
134
-	 * @param Node|null $recipientNode
135
-	 * @return array
136
-	 * @throws NotFoundException In case the node can't be resolved.
137
-	 */
138
-	protected function formatShare(\OCP\Share\IShare $share, Node $recipientNode = null): array {
139
-		$sharedBy = $this->userManager->get($share->getSharedBy());
140
-		$shareOwner = $this->userManager->get($share->getShareOwner());
141
-
142
-		$result = [
143
-			'id' => $share->getId(),
144
-			'share_type' => $share->getShareType(),
145
-			'uid_owner' => $share->getSharedBy(),
146
-			'displayname_owner' => $sharedBy !== null ? $sharedBy->getDisplayName() : $share->getSharedBy(),
147
-			'permissions' => $share->getPermissions(),
148
-			'stime' => $share->getShareTime()->getTimestamp(),
149
-			'parent' => null,
150
-			'expiration' => null,
151
-			'token' => null,
152
-			'uid_file_owner' => $share->getShareOwner(),
153
-			'note' => $share->getNote(),
154
-			'displayname_file_owner' => $shareOwner !== null ? $shareOwner->getDisplayName() : $share->getShareOwner(),
155
-		];
156
-
157
-		$userFolder = $this->rootFolder->getUserFolder($this->currentUser);
158
-		if ($recipientNode) {
159
-			$node = $recipientNode;
160
-		} else {
161
-			$nodes = $userFolder->getById($share->getNodeId());
162
-			if (empty($nodes)) {
163
-				// fallback to guessing the path
164
-				$node = $userFolder->get($share->getTarget());
165
-				if ($node === null || $share->getTarget() === '') {
166
-					throw new NotFoundException();
167
-				}
168
-			} else {
169
-				$node = $nodes[0];
170
-			}
171
-		}
172
-
173
-		$result['path'] = $userFolder->getRelativePath($node->getPath());
174
-		if ($node instanceOf \OCP\Files\Folder) {
175
-			$result['item_type'] = 'folder';
176
-		} else {
177
-			$result['item_type'] = 'file';
178
-		}
179
-		$result['mimetype'] = $node->getMimetype();
180
-		$result['storage_id'] = $node->getStorage()->getId();
181
-		$result['storage'] = $node->getStorage()->getCache()->getNumericStorageId();
182
-		$result['item_source'] = $node->getId();
183
-		$result['file_source'] = $node->getId();
184
-		$result['file_parent'] = $node->getParent()->getId();
185
-		$result['file_target'] = $share->getTarget();
186
-
187
-		$expiration = $share->getExpirationDate();
188
-		if ($expiration !== null) {
189
-			$result['expiration'] = $expiration->format('Y-m-d 00:00:00');
190
-		}
191
-
192
-		if ($share->getShareType() === Share::SHARE_TYPE_USER) {
193
-			$sharedWith = $this->userManager->get($share->getSharedWith());
194
-			$result['share_with'] = $share->getSharedWith();
195
-			$result['share_with_displayname'] = $sharedWith !== null ? $sharedWith->getDisplayName() : $share->getSharedWith();
196
-		} else if ($share->getShareType() === Share::SHARE_TYPE_GROUP) {
197
-			$group = $this->groupManager->get($share->getSharedWith());
198
-			$result['share_with'] = $share->getSharedWith();
199
-			$result['share_with_displayname'] = $group !== null ? $group->getDisplayName() : $share->getSharedWith();
200
-		} else if ($share->getShareType() === Share::SHARE_TYPE_LINK) {
201
-
202
-			$result['share_with'] = $share->getPassword();
203
-			$result['share_with_displayname'] = $share->getPassword();
204
-
205
-			$result['token'] = $share->getToken();
206
-			$result['url'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $share->getToken()]);
207
-
208
-		} else if ($share->getShareType() === Share::SHARE_TYPE_REMOTE || $share->getShareType() === Share::SHARE_TYPE_REMOTE_GROUP) {
209
-			$result['share_with'] = $share->getSharedWith();
210
-			$result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'CLOUD');
211
-			$result['token'] = $share->getToken();
212
-		} else if ($share->getShareType() === Share::SHARE_TYPE_EMAIL) {
213
-			$result['share_with'] = $share->getSharedWith();
214
-			$result['password'] = $share->getPassword();
215
-			$result['send_password_by_talk'] = $share->getSendPasswordByTalk();
216
-			$result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'EMAIL');
217
-			$result['token'] = $share->getToken();
218
-		} else if ($share->getShareType() === Share::SHARE_TYPE_CIRCLE) {
219
-			// getSharedWith() returns either "name (type, owner)" or
220
-			// "name (type, owner) [id]", depending on the Circles app version.
221
-			$hasCircleId = (substr($share->getSharedWith(), -1) === ']');
222
-
223
-			$result['share_with_displayname'] = $share->getSharedWithDisplayName();
224
-			if (empty($result['share_with_displayname'])) {
225
-				$displayNameLength = ($hasCircleId? strrpos($share->getSharedWith(), ' '): strlen($share->getSharedWith()));
226
-				$result['share_with_displayname'] = substr($share->getSharedWith(), 0, $displayNameLength);
227
-			}
228
-
229
-			$result['share_with_avatar'] = $share->getSharedWithAvatar();
230
-
231
-			$shareWithStart = ($hasCircleId? strrpos($share->getSharedWith(), '[') + 1: 0);
232
-			$shareWithLength = ($hasCircleId? -1: strpos($share->getSharedWith(), ' '));
233
-			$result['share_with'] = substr($share->getSharedWith(), $shareWithStart, $shareWithLength);
234
-		}
235
-
236
-
237
-		$result['mail_send'] = $share->getMailSend() ? 1 : 0;
238
-
239
-		return $result;
240
-	}
241
-
242
-	/**
243
-	 * Check if one of the users address books knows the exact property, if
244
-	 * yes we return the full name.
245
-	 *
246
-	 * @param string $query
247
-	 * @param string $property
248
-	 * @return string
249
-	 */
250
-	private function getDisplayNameFromAddressBook(string $query, string $property): string {
251
-		// FIXME: If we inject the contacts manager it gets initialized bofore any address books are registered
252
-		$result = \OC::$server->getContactsManager()->search($query, [$property]);
253
-		foreach ($result as $r) {
254
-			foreach($r[$property] as $value) {
255
-				if ($value === $query) {
256
-					return $r['FN'];
257
-				}
258
-			}
259
-		}
260
-
261
-		return $query;
262
-	}
263
-
264
-	/**
265
-	 * Get a specific share by id
266
-	 *
267
-	 * @NoAdminRequired
268
-	 *
269
-	 * @param string $id
270
-	 * @return DataResponse
271
-	 * @throws OCSNotFoundException
272
-	 */
273
-	public function getShare(string $id): DataResponse {
274
-		try {
275
-			$share = $this->getShareById($id);
276
-		} catch (ShareNotFound $e) {
277
-			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
278
-		}
279
-
280
-		if ($this->canAccessShare($share)) {
281
-			try {
282
-				$share = $this->formatShare($share);
283
-				return new DataResponse([$share]);
284
-			} catch (NotFoundException $e) {
285
-				//Fall trough
286
-			}
287
-		}
288
-
289
-		throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
290
-	}
291
-
292
-	/**
293
-	 * Delete a share
294
-	 *
295
-	 * @NoAdminRequired
296
-	 *
297
-	 * @param string $id
298
-	 * @return DataResponse
299
-	 * @throws OCSNotFoundException
300
-	 */
301
-	public function deleteShare(string $id): DataResponse {
302
-		try {
303
-			$share = $this->getShareById($id);
304
-		} catch (ShareNotFound $e) {
305
-			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
306
-		}
307
-
308
-		try {
309
-			$this->lock($share->getNode());
310
-		} catch (LockedException $e) {
311
-			throw new OCSNotFoundException($this->l->t('could not delete share'));
312
-		}
313
-
314
-		if (!$this->canAccessShare($share)) {
315
-			throw new OCSNotFoundException($this->l->t('Could not delete share'));
316
-		}
317
-
318
-		if ($share->getShareType() === Share::SHARE_TYPE_GROUP &&
319
-			$share->getShareOwner() !== $this->currentUser &&
320
-			$share->getSharedBy() !== $this->currentUser) {
321
-			$this->shareManager->deleteFromSelf($share, $this->currentUser);
322
-		} else {
323
-			$this->shareManager->deleteShare($share);
324
-		}
325
-
326
-		return new DataResponse();
327
-	}
328
-
329
-	/**
330
-	 * @NoAdminRequired
331
-	 *
332
-	 * @param string $path
333
-	 * @param int $permissions
334
-	 * @param int $shareType
335
-	 * @param string $shareWith
336
-	 * @param string $publicUpload
337
-	 * @param string $password
338
-	 * @param bool $sendPasswordByTalk
339
-	 * @param string $expireDate
340
-	 *
341
-	 * @return DataResponse
342
-	 * @throws OCSNotFoundException
343
-	 * @throws OCSForbiddenException
344
-	 * @throws OCSBadRequestException
345
-	 * @throws OCSException
346
-	 *
347
-	 * @suppress PhanUndeclaredClassMethod
348
-	 */
349
-	public function createShare(
350
-		string $path = null,
351
-		int $permissions = null,
352
-		int $shareType = -1,
353
-		string $shareWith = null,
354
-		string $publicUpload = 'false',
355
-		string $password = '',
356
-		string $sendPasswordByTalk = null,
357
-		string $expireDate = ''
358
-	): DataResponse {
359
-		$share = $this->shareManager->newShare();
360
-
361
-		if ($permissions === null) {
362
-			$permissions = $this->config->getAppValue('core', 'shareapi_default_permissions', Constants::PERMISSION_ALL);
363
-		}
364
-
365
-		// Verify path
366
-		if ($path === null) {
367
-			throw new OCSNotFoundException($this->l->t('Please specify a file or folder path'));
368
-		}
369
-
370
-		$userFolder = $this->rootFolder->getUserFolder($this->currentUser);
371
-		try {
372
-			$path = $userFolder->get($path);
373
-		} catch (NotFoundException $e) {
374
-			throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
375
-		}
376
-
377
-		$share->setNode($path);
378
-
379
-		try {
380
-			$this->lock($share->getNode());
381
-		} catch (LockedException $e) {
382
-			throw new OCSNotFoundException($this->l->t('Could not create share'));
383
-		}
384
-
385
-		if ($permissions < 0 || $permissions > Constants::PERMISSION_ALL) {
386
-			throw new OCSNotFoundException($this->l->t('invalid permissions'));
387
-		}
388
-
389
-		// Shares always require read permissions
390
-		$permissions |= Constants::PERMISSION_READ;
391
-
392
-		if ($path instanceof \OCP\Files\File) {
393
-			// Single file shares should never have delete or create permissions
394
-			$permissions &= ~Constants::PERMISSION_DELETE;
395
-			$permissions &= ~Constants::PERMISSION_CREATE;
396
-		}
397
-
398
-		/*
67
+    /** @var IManager */
68
+    private $shareManager;
69
+    /** @var IGroupManager */
70
+    private $groupManager;
71
+    /** @var IUserManager */
72
+    private $userManager;
73
+    /** @var IRootFolder */
74
+    private $rootFolder;
75
+    /** @var IURLGenerator */
76
+    private $urlGenerator;
77
+    /** @var string */
78
+    private $currentUser;
79
+    /** @var IL10N */
80
+    private $l;
81
+    /** @var \OCP\Files\Node */
82
+    private $lockedNode;
83
+    /** @var IConfig */
84
+    private $config;
85
+    /** @var IAppManager */
86
+    private $appManager;
87
+
88
+    /**
89
+     * Share20OCS constructor.
90
+     *
91
+     * @param string $appName
92
+     * @param IRequest $request
93
+     * @param IManager $shareManager
94
+     * @param IGroupManager $groupManager
95
+     * @param IUserManager $userManager
96
+     * @param IRootFolder $rootFolder
97
+     * @param IURLGenerator $urlGenerator
98
+     * @param string $userId
99
+     * @param IL10N $l10n
100
+     * @param IConfig $config
101
+     * @param IAppManager $appManager
102
+     */
103
+    public function __construct(
104
+        string $appName,
105
+        IRequest $request,
106
+        IManager $shareManager,
107
+        IGroupManager $groupManager,
108
+        IUserManager $userManager,
109
+        IRootFolder $rootFolder,
110
+        IURLGenerator $urlGenerator,
111
+        string $userId,
112
+        IL10N $l10n,
113
+        IConfig $config,
114
+        IAppManager $appManager
115
+    ) {
116
+        parent::__construct($appName, $request);
117
+
118
+        $this->shareManager = $shareManager;
119
+        $this->userManager = $userManager;
120
+        $this->groupManager = $groupManager;
121
+        $this->request = $request;
122
+        $this->rootFolder = $rootFolder;
123
+        $this->urlGenerator = $urlGenerator;
124
+        $this->currentUser = $userId;
125
+        $this->l = $l10n;
126
+        $this->config = $config;
127
+        $this->appManager = $appManager;
128
+    }
129
+
130
+    /**
131
+     * Convert an IShare to an array for OCS output
132
+     *
133
+     * @param \OCP\Share\IShare $share
134
+     * @param Node|null $recipientNode
135
+     * @return array
136
+     * @throws NotFoundException In case the node can't be resolved.
137
+     */
138
+    protected function formatShare(\OCP\Share\IShare $share, Node $recipientNode = null): array {
139
+        $sharedBy = $this->userManager->get($share->getSharedBy());
140
+        $shareOwner = $this->userManager->get($share->getShareOwner());
141
+
142
+        $result = [
143
+            'id' => $share->getId(),
144
+            'share_type' => $share->getShareType(),
145
+            'uid_owner' => $share->getSharedBy(),
146
+            'displayname_owner' => $sharedBy !== null ? $sharedBy->getDisplayName() : $share->getSharedBy(),
147
+            'permissions' => $share->getPermissions(),
148
+            'stime' => $share->getShareTime()->getTimestamp(),
149
+            'parent' => null,
150
+            'expiration' => null,
151
+            'token' => null,
152
+            'uid_file_owner' => $share->getShareOwner(),
153
+            'note' => $share->getNote(),
154
+            'displayname_file_owner' => $shareOwner !== null ? $shareOwner->getDisplayName() : $share->getShareOwner(),
155
+        ];
156
+
157
+        $userFolder = $this->rootFolder->getUserFolder($this->currentUser);
158
+        if ($recipientNode) {
159
+            $node = $recipientNode;
160
+        } else {
161
+            $nodes = $userFolder->getById($share->getNodeId());
162
+            if (empty($nodes)) {
163
+                // fallback to guessing the path
164
+                $node = $userFolder->get($share->getTarget());
165
+                if ($node === null || $share->getTarget() === '') {
166
+                    throw new NotFoundException();
167
+                }
168
+            } else {
169
+                $node = $nodes[0];
170
+            }
171
+        }
172
+
173
+        $result['path'] = $userFolder->getRelativePath($node->getPath());
174
+        if ($node instanceOf \OCP\Files\Folder) {
175
+            $result['item_type'] = 'folder';
176
+        } else {
177
+            $result['item_type'] = 'file';
178
+        }
179
+        $result['mimetype'] = $node->getMimetype();
180
+        $result['storage_id'] = $node->getStorage()->getId();
181
+        $result['storage'] = $node->getStorage()->getCache()->getNumericStorageId();
182
+        $result['item_source'] = $node->getId();
183
+        $result['file_source'] = $node->getId();
184
+        $result['file_parent'] = $node->getParent()->getId();
185
+        $result['file_target'] = $share->getTarget();
186
+
187
+        $expiration = $share->getExpirationDate();
188
+        if ($expiration !== null) {
189
+            $result['expiration'] = $expiration->format('Y-m-d 00:00:00');
190
+        }
191
+
192
+        if ($share->getShareType() === Share::SHARE_TYPE_USER) {
193
+            $sharedWith = $this->userManager->get($share->getSharedWith());
194
+            $result['share_with'] = $share->getSharedWith();
195
+            $result['share_with_displayname'] = $sharedWith !== null ? $sharedWith->getDisplayName() : $share->getSharedWith();
196
+        } else if ($share->getShareType() === Share::SHARE_TYPE_GROUP) {
197
+            $group = $this->groupManager->get($share->getSharedWith());
198
+            $result['share_with'] = $share->getSharedWith();
199
+            $result['share_with_displayname'] = $group !== null ? $group->getDisplayName() : $share->getSharedWith();
200
+        } else if ($share->getShareType() === Share::SHARE_TYPE_LINK) {
201
+
202
+            $result['share_with'] = $share->getPassword();
203
+            $result['share_with_displayname'] = $share->getPassword();
204
+
205
+            $result['token'] = $share->getToken();
206
+            $result['url'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $share->getToken()]);
207
+
208
+        } else if ($share->getShareType() === Share::SHARE_TYPE_REMOTE || $share->getShareType() === Share::SHARE_TYPE_REMOTE_GROUP) {
209
+            $result['share_with'] = $share->getSharedWith();
210
+            $result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'CLOUD');
211
+            $result['token'] = $share->getToken();
212
+        } else if ($share->getShareType() === Share::SHARE_TYPE_EMAIL) {
213
+            $result['share_with'] = $share->getSharedWith();
214
+            $result['password'] = $share->getPassword();
215
+            $result['send_password_by_talk'] = $share->getSendPasswordByTalk();
216
+            $result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'EMAIL');
217
+            $result['token'] = $share->getToken();
218
+        } else if ($share->getShareType() === Share::SHARE_TYPE_CIRCLE) {
219
+            // getSharedWith() returns either "name (type, owner)" or
220
+            // "name (type, owner) [id]", depending on the Circles app version.
221
+            $hasCircleId = (substr($share->getSharedWith(), -1) === ']');
222
+
223
+            $result['share_with_displayname'] = $share->getSharedWithDisplayName();
224
+            if (empty($result['share_with_displayname'])) {
225
+                $displayNameLength = ($hasCircleId? strrpos($share->getSharedWith(), ' '): strlen($share->getSharedWith()));
226
+                $result['share_with_displayname'] = substr($share->getSharedWith(), 0, $displayNameLength);
227
+            }
228
+
229
+            $result['share_with_avatar'] = $share->getSharedWithAvatar();
230
+
231
+            $shareWithStart = ($hasCircleId? strrpos($share->getSharedWith(), '[') + 1: 0);
232
+            $shareWithLength = ($hasCircleId? -1: strpos($share->getSharedWith(), ' '));
233
+            $result['share_with'] = substr($share->getSharedWith(), $shareWithStart, $shareWithLength);
234
+        }
235
+
236
+
237
+        $result['mail_send'] = $share->getMailSend() ? 1 : 0;
238
+
239
+        return $result;
240
+    }
241
+
242
+    /**
243
+     * Check if one of the users address books knows the exact property, if
244
+     * yes we return the full name.
245
+     *
246
+     * @param string $query
247
+     * @param string $property
248
+     * @return string
249
+     */
250
+    private function getDisplayNameFromAddressBook(string $query, string $property): string {
251
+        // FIXME: If we inject the contacts manager it gets initialized bofore any address books are registered
252
+        $result = \OC::$server->getContactsManager()->search($query, [$property]);
253
+        foreach ($result as $r) {
254
+            foreach($r[$property] as $value) {
255
+                if ($value === $query) {
256
+                    return $r['FN'];
257
+                }
258
+            }
259
+        }
260
+
261
+        return $query;
262
+    }
263
+
264
+    /**
265
+     * Get a specific share by id
266
+     *
267
+     * @NoAdminRequired
268
+     *
269
+     * @param string $id
270
+     * @return DataResponse
271
+     * @throws OCSNotFoundException
272
+     */
273
+    public function getShare(string $id): DataResponse {
274
+        try {
275
+            $share = $this->getShareById($id);
276
+        } catch (ShareNotFound $e) {
277
+            throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
278
+        }
279
+
280
+        if ($this->canAccessShare($share)) {
281
+            try {
282
+                $share = $this->formatShare($share);
283
+                return new DataResponse([$share]);
284
+            } catch (NotFoundException $e) {
285
+                //Fall trough
286
+            }
287
+        }
288
+
289
+        throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
290
+    }
291
+
292
+    /**
293
+     * Delete a share
294
+     *
295
+     * @NoAdminRequired
296
+     *
297
+     * @param string $id
298
+     * @return DataResponse
299
+     * @throws OCSNotFoundException
300
+     */
301
+    public function deleteShare(string $id): DataResponse {
302
+        try {
303
+            $share = $this->getShareById($id);
304
+        } catch (ShareNotFound $e) {
305
+            throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
306
+        }
307
+
308
+        try {
309
+            $this->lock($share->getNode());
310
+        } catch (LockedException $e) {
311
+            throw new OCSNotFoundException($this->l->t('could not delete share'));
312
+        }
313
+
314
+        if (!$this->canAccessShare($share)) {
315
+            throw new OCSNotFoundException($this->l->t('Could not delete share'));
316
+        }
317
+
318
+        if ($share->getShareType() === Share::SHARE_TYPE_GROUP &&
319
+            $share->getShareOwner() !== $this->currentUser &&
320
+            $share->getSharedBy() !== $this->currentUser) {
321
+            $this->shareManager->deleteFromSelf($share, $this->currentUser);
322
+        } else {
323
+            $this->shareManager->deleteShare($share);
324
+        }
325
+
326
+        return new DataResponse();
327
+    }
328
+
329
+    /**
330
+     * @NoAdminRequired
331
+     *
332
+     * @param string $path
333
+     * @param int $permissions
334
+     * @param int $shareType
335
+     * @param string $shareWith
336
+     * @param string $publicUpload
337
+     * @param string $password
338
+     * @param bool $sendPasswordByTalk
339
+     * @param string $expireDate
340
+     *
341
+     * @return DataResponse
342
+     * @throws OCSNotFoundException
343
+     * @throws OCSForbiddenException
344
+     * @throws OCSBadRequestException
345
+     * @throws OCSException
346
+     *
347
+     * @suppress PhanUndeclaredClassMethod
348
+     */
349
+    public function createShare(
350
+        string $path = null,
351
+        int $permissions = null,
352
+        int $shareType = -1,
353
+        string $shareWith = null,
354
+        string $publicUpload = 'false',
355
+        string $password = '',
356
+        string $sendPasswordByTalk = null,
357
+        string $expireDate = ''
358
+    ): DataResponse {
359
+        $share = $this->shareManager->newShare();
360
+
361
+        if ($permissions === null) {
362
+            $permissions = $this->config->getAppValue('core', 'shareapi_default_permissions', Constants::PERMISSION_ALL);
363
+        }
364
+
365
+        // Verify path
366
+        if ($path === null) {
367
+            throw new OCSNotFoundException($this->l->t('Please specify a file or folder path'));
368
+        }
369
+
370
+        $userFolder = $this->rootFolder->getUserFolder($this->currentUser);
371
+        try {
372
+            $path = $userFolder->get($path);
373
+        } catch (NotFoundException $e) {
374
+            throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
375
+        }
376
+
377
+        $share->setNode($path);
378
+
379
+        try {
380
+            $this->lock($share->getNode());
381
+        } catch (LockedException $e) {
382
+            throw new OCSNotFoundException($this->l->t('Could not create share'));
383
+        }
384
+
385
+        if ($permissions < 0 || $permissions > Constants::PERMISSION_ALL) {
386
+            throw new OCSNotFoundException($this->l->t('invalid permissions'));
387
+        }
388
+
389
+        // Shares always require read permissions
390
+        $permissions |= Constants::PERMISSION_READ;
391
+
392
+        if ($path instanceof \OCP\Files\File) {
393
+            // Single file shares should never have delete or create permissions
394
+            $permissions &= ~Constants::PERMISSION_DELETE;
395
+            $permissions &= ~Constants::PERMISSION_CREATE;
396
+        }
397
+
398
+        /*
399 399
 		 * Hack for https://github.com/owncloud/core/issues/22587
400 400
 		 * We check the permissions via webdav. But the permissions of the mount point
401 401
 		 * do not equal the share permissions. Here we fix that for federated mounts.
402 402
 		 */
403
-		if ($path->getStorage()->instanceOfStorage(Storage::class)) {
404
-			$permissions &= ~($permissions & ~$path->getPermissions());
405
-		}
406
-
407
-		if ($shareType === Share::SHARE_TYPE_USER) {
408
-			// Valid user is required to share
409
-			if ($shareWith === null || !$this->userManager->userExists($shareWith)) {
410
-				throw new OCSNotFoundException($this->l->t('Please specify a valid user'));
411
-			}
412
-			$share->setSharedWith($shareWith);
413
-			$share->setPermissions($permissions);
414
-		} else if ($shareType === Share::SHARE_TYPE_GROUP) {
415
-			if (!$this->shareManager->allowGroupSharing()) {
416
-				throw new OCSNotFoundException($this->l->t('Group sharing is disabled by the administrator'));
417
-			}
418
-
419
-			// Valid group is required to share
420
-			if ($shareWith === null || !$this->groupManager->groupExists($shareWith)) {
421
-				throw new OCSNotFoundException($this->l->t('Please specify a valid group'));
422
-			}
423
-			$share->setSharedWith($shareWith);
424
-			$share->setPermissions($permissions);
425
-		} else if ($shareType === Share::SHARE_TYPE_LINK) {
426
-			//Can we even share links?
427
-			if (!$this->shareManager->shareApiAllowLinks()) {
428
-				throw new OCSNotFoundException($this->l->t('Public link sharing is disabled by the administrator'));
429
-			}
430
-
431
-			/*
403
+        if ($path->getStorage()->instanceOfStorage(Storage::class)) {
404
+            $permissions &= ~($permissions & ~$path->getPermissions());
405
+        }
406
+
407
+        if ($shareType === Share::SHARE_TYPE_USER) {
408
+            // Valid user is required to share
409
+            if ($shareWith === null || !$this->userManager->userExists($shareWith)) {
410
+                throw new OCSNotFoundException($this->l->t('Please specify a valid user'));
411
+            }
412
+            $share->setSharedWith($shareWith);
413
+            $share->setPermissions($permissions);
414
+        } else if ($shareType === Share::SHARE_TYPE_GROUP) {
415
+            if (!$this->shareManager->allowGroupSharing()) {
416
+                throw new OCSNotFoundException($this->l->t('Group sharing is disabled by the administrator'));
417
+            }
418
+
419
+            // Valid group is required to share
420
+            if ($shareWith === null || !$this->groupManager->groupExists($shareWith)) {
421
+                throw new OCSNotFoundException($this->l->t('Please specify a valid group'));
422
+            }
423
+            $share->setSharedWith($shareWith);
424
+            $share->setPermissions($permissions);
425
+        } else if ($shareType === Share::SHARE_TYPE_LINK) {
426
+            //Can we even share links?
427
+            if (!$this->shareManager->shareApiAllowLinks()) {
428
+                throw new OCSNotFoundException($this->l->t('Public link sharing is disabled by the administrator'));
429
+            }
430
+
431
+            /*
432 432
 			 * For now we only allow 1 link share.
433 433
 			 * Return the existing link share if this is a duplicate
434 434
 			 */
435
-			$existingShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_LINK, $path, false, 1, 0);
436
-			if (!empty($existingShares)) {
437
-				return new DataResponse($this->formatShare($existingShares[0]));
438
-			}
439
-
440
-			if ($publicUpload === 'true') {
441
-				// Check if public upload is allowed
442
-				if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
443
-					throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
444
-				}
445
-
446
-				// Public upload can only be set for folders
447
-				if ($path instanceof \OCP\Files\File) {
448
-					throw new OCSNotFoundException($this->l->t('Public upload is only possible for publicly shared folders'));
449
-				}
450
-
451
-				$share->setPermissions(
452
-					Constants::PERMISSION_READ |
453
-					Constants::PERMISSION_CREATE |
454
-					Constants::PERMISSION_UPDATE |
455
-					Constants::PERMISSION_DELETE
456
-				);
457
-			} else {
458
-				$share->setPermissions(Constants::PERMISSION_READ);
459
-			}
460
-
461
-			// Set password
462
-			if ($password !== '') {
463
-				$share->setPassword($password);
464
-			}
465
-
466
-			//Expire date
467
-			if ($expireDate !== '') {
468
-				try {
469
-					$expireDate = $this->parseDate($expireDate);
470
-					$share->setExpirationDate($expireDate);
471
-				} catch (\Exception $e) {
472
-					throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD'));
473
-				}
474
-			}
475
-
476
-		} else if ($shareType === Share::SHARE_TYPE_REMOTE) {
477
-			if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
478
-				throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not allow shares from type %s', [$path->getPath(), $shareType]));
479
-			}
480
-
481
-			$share->setSharedWith($shareWith);
482
-			$share->setPermissions($permissions);
483
-		}  else if ($shareType === Share::SHARE_TYPE_REMOTE_GROUP) {
484
-			if (!$this->shareManager->outgoingServer2ServerGroupSharesAllowed()) {
485
-				throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not allow shares from type %s', [$path->getPath(), $shareType]));
486
-			}
487
-
488
-			$share->setSharedWith($shareWith);
489
-			$share->setPermissions($permissions);
490
-		} else if ($shareType === Share::SHARE_TYPE_EMAIL) {
491
-			if ($share->getNodeType() === 'file') {
492
-				$share->setPermissions(Constants::PERMISSION_READ);
493
-			} else {
494
-				$share->setPermissions($permissions);
495
-			}
496
-			$share->setSharedWith($shareWith);
497
-
498
-			if ($sendPasswordByTalk === 'true') {
499
-				if (!$this->appManager->isEnabledForUser('spreed')) {
500
-					throw new OCSForbiddenException($this->l->t('Sharing %s sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled', [$path->getPath()]));
501
-				}
502
-
503
-				$share->setSendPasswordByTalk(true);
504
-			}
505
-		} else if ($shareType === Share::SHARE_TYPE_CIRCLE) {
506
-			if (!\OC::$server->getAppManager()->isEnabledForUser('circles') || !class_exists('\OCA\Circles\ShareByCircleProvider')) {
507
-				throw new OCSNotFoundException($this->l->t('You cannot share to a Circle if the app is not enabled'));
508
-			}
509
-
510
-			$circle = \OCA\Circles\Api\v1\Circles::detailsCircle($shareWith);
511
-
512
-			// Valid circle is required to share
513
-			if ($circle === null) {
514
-				throw new OCSNotFoundException($this->l->t('Please specify a valid circle'));
515
-			}
516
-			$share->setSharedWith($shareWith);
517
-			$share->setPermissions($permissions);
518
-		} else {
519
-			throw new OCSBadRequestException($this->l->t('Unknown share type'));
520
-		}
521
-
522
-		$share->setShareType($shareType);
523
-		$share->setSharedBy($this->currentUser);
524
-
525
-		try {
526
-			$share = $this->shareManager->createShare($share);
527
-		} catch (GenericShareException $e) {
528
-			$code = $e->getCode() === 0 ? 403 : $e->getCode();
529
-			throw new OCSException($e->getHint(), $code);
530
-		} catch (\Exception $e) {
531
-			throw new OCSForbiddenException($e->getMessage(), $e);
532
-		}
533
-
534
-		$output = $this->formatShare($share);
535
-
536
-		return new DataResponse($output);
537
-	}
538
-
539
-	/**
540
-	 * @param \OCP\Files\File|\OCP\Files\Folder $node
541
-	 * @param boolean $includeTags
542
-	 * @return DataResponse
543
-	 */
544
-	private function getSharedWithMe($node = null, bool $includeTags): DataResponse {
545
-
546
-		$userShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_USER, $node, -1, 0);
547
-		$groupShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_GROUP, $node, -1, 0);
548
-		$circleShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_CIRCLE, $node, -1, 0);
549
-
550
-		$shares = array_merge($userShares, $groupShares, $circleShares);
551
-
552
-		$shares = array_filter($shares, function (IShare $share) {
553
-			return $share->getShareOwner() !== $this->currentUser;
554
-		});
555
-
556
-		$formatted = [];
557
-		foreach ($shares as $share) {
558
-			if ($this->canAccessShare($share)) {
559
-				try {
560
-					$formatted[] = $this->formatShare($share);
561
-				} catch (NotFoundException $e) {
562
-					// Ignore this share
563
-				}
564
-			}
565
-		}
566
-
567
-		if ($includeTags) {
568
-			$formatted = Helper::populateTags($formatted, 'file_source', \OC::$server->getTagManager());
569
-		}
570
-
571
-		return new DataResponse($formatted);
572
-	}
573
-
574
-	/**
575
-	 * @param \OCP\Files\Folder $folder
576
-	 * @return DataResponse
577
-	 * @throws OCSBadRequestException
578
-	 */
579
-	private function getSharesInDir(Node $folder): DataResponse {
580
-		if (!($folder instanceof \OCP\Files\Folder)) {
581
-			throw new OCSBadRequestException($this->l->t('Not a directory'));
582
-		}
583
-
584
-		$nodes = $folder->getDirectoryListing();
585
-		/** @var \OCP\Share\IShare[] $shares */
586
-		$shares = [];
587
-		foreach ($nodes as $node) {
588
-			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_USER, $node, false, -1, 0));
589
-			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_GROUP, $node, false, -1, 0));
590
-			$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_LINK, $node, false, -1, 0));
591
-			if($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
592
-				$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_EMAIL, $node, false, -1, 0));
593
-			}
594
-			if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
595
-				$shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_REMOTE, $node, false, -1, 0));
596
-			}
597
-		}
598
-
599
-		$formatted = [];
600
-		foreach ($shares as $share) {
601
-			try {
602
-				$formatted[] = $this->formatShare($share);
603
-			} catch (NotFoundException $e) {
604
-				//Ignore this share
605
-			}
606
-		}
607
-
608
-		return new DataResponse($formatted);
609
-	}
610
-
611
-	/**
612
-	 * The getShares function.
613
-	 *
614
-	 * @NoAdminRequired
615
-	 *
616
-	 * @param string $shared_with_me
617
-	 * @param string $reshares
618
-	 * @param string $subfiles
619
-	 * @param string $path
620
-	 *
621
-	 * - Get shares by the current user
622
-	 * - Get shares by the current user and reshares (?reshares=true)
623
-	 * - Get shares with the current user (?shared_with_me=true)
624
-	 * - Get shares for a specific path (?path=...)
625
-	 * - Get all shares in a folder (?subfiles=true&path=..)
626
-	 *
627
-	 * @return DataResponse
628
-	 * @throws OCSNotFoundException
629
-	 */
630
-	public function getShares(
631
-		string $shared_with_me = 'false',
632
-		string $reshares = 'false',
633
-		string $subfiles = 'false',
634
-		string $path = null,
635
-		string $include_tags = 'false'
636
-	): DataResponse {
637
-
638
-		if ($path !== null) {
639
-			$userFolder = $this->rootFolder->getUserFolder($this->currentUser);
640
-			try {
641
-				$path = $userFolder->get($path);
642
-				$this->lock($path);
643
-			} catch (\OCP\Files\NotFoundException $e) {
644
-				throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
645
-			} catch (LockedException $e) {
646
-				throw new OCSNotFoundException($this->l->t('Could not lock path'));
647
-			}
648
-		}
649
-
650
-		$include_tags = $include_tags === 'true';
651
-
652
-		if ($shared_with_me === 'true') {
653
-			$result = $this->getSharedWithMe($path, $include_tags);
654
-			return $result;
655
-		}
656
-
657
-		if ($subfiles === 'true') {
658
-			$result = $this->getSharesInDir($path);
659
-			return $result;
660
-		}
661
-
662
-		if ($reshares === 'true') {
663
-			$reshares = true;
664
-		} else {
665
-			$reshares = false;
666
-		}
667
-
668
-		// Get all shares
669
-		$userShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_USER, $path, $reshares, -1, 0);
670
-		$groupShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_GROUP, $path, $reshares, -1, 0);
671
-		$linkShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_LINK, $path, $reshares, -1, 0);
672
-		if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
673
-			$mailShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_EMAIL, $path, $reshares, -1, 0);
674
-		} else {
675
-			$mailShares = [];
676
-		}
677
-		if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_CIRCLE)) {
678
-			$circleShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_CIRCLE, $path, $reshares, -1, 0);
679
-		} else {
680
-			$circleShares = [];
681
-		}
682
-
683
-		$shares = array_merge($userShares, $groupShares, $linkShares, $mailShares, $circleShares);
684
-
685
-		if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
686
-			$federatedShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_REMOTE, $path, $reshares, -1, 0);
687
-			$shares = array_merge($shares, $federatedShares);
688
-		}
689
-
690
-		if ($this->shareManager->outgoingServer2ServerGroupSharesAllowed()) {
691
-			$federatedShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_REMOTE_GROUP, $path, $reshares, -1, 0);
692
-			$shares = array_merge($shares, $federatedShares);
693
-		}
694
-
695
-		$formatted = [];
696
-		foreach ($shares as $share) {
697
-			try {
698
-				$formatted[] = $this->formatShare($share, $path);
699
-			} catch (NotFoundException $e) {
700
-				//Ignore share
701
-			}
702
-		}
703
-
704
-		if ($include_tags) {
705
-			$formatted = Helper::populateTags($formatted, 'file_source', \OC::$server->getTagManager());
706
-		}
707
-
708
-		return new DataResponse($formatted);
709
-	}
710
-
711
-	/**
712
-	 * @NoAdminRequired
713
-	 *
714
-	 * @param string $id
715
-	 * @param int $permissions
716
-	 * @param string $password
717
-	 * @param string $sendPasswordByTalk
718
-	 * @param string $publicUpload
719
-	 * @param string $expireDate
720
-	 * @param string $note
721
-	 * @return DataResponse
722
-	 * @throws LockedException
723
-	 * @throws NotFoundException
724
-	 * @throws OCSBadRequestException
725
-	 * @throws OCSForbiddenException
726
-	 * @throws OCSNotFoundException
727
-	 */
728
-	public function updateShare(
729
-		string $id,
730
-		int $permissions = null,
731
-		string $password = null,
732
-		string $sendPasswordByTalk = null,
733
-		string $publicUpload = null,
734
-		string $expireDate = null,
735
-		string $note = null
736
-	): DataResponse {
737
-		try {
738
-			$share = $this->getShareById($id);
739
-		} catch (ShareNotFound $e) {
740
-			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
741
-		}
742
-
743
-		$this->lock($share->getNode());
744
-
745
-		if (!$this->canAccessShare($share, false)) {
746
-			throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
747
-		}
748
-
749
-		if ($permissions === null && $password === null && $sendPasswordByTalk === null && $publicUpload === null && $expireDate === null && $note === null) {
750
-			throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given'));
751
-		}
752
-
753
-		if($note !== null) {
754
-			$share->setNote($note);
755
-		}
756
-
757
-		/*
435
+            $existingShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_LINK, $path, false, 1, 0);
436
+            if (!empty($existingShares)) {
437
+                return new DataResponse($this->formatShare($existingShares[0]));
438
+            }
439
+
440
+            if ($publicUpload === 'true') {
441
+                // Check if public upload is allowed
442
+                if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
443
+                    throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
444
+                }
445
+
446
+                // Public upload can only be set for folders
447
+                if ($path instanceof \OCP\Files\File) {
448
+                    throw new OCSNotFoundException($this->l->t('Public upload is only possible for publicly shared folders'));
449
+                }
450
+
451
+                $share->setPermissions(
452
+                    Constants::PERMISSION_READ |
453
+                    Constants::PERMISSION_CREATE |
454
+                    Constants::PERMISSION_UPDATE |
455
+                    Constants::PERMISSION_DELETE
456
+                );
457
+            } else {
458
+                $share->setPermissions(Constants::PERMISSION_READ);
459
+            }
460
+
461
+            // Set password
462
+            if ($password !== '') {
463
+                $share->setPassword($password);
464
+            }
465
+
466
+            //Expire date
467
+            if ($expireDate !== '') {
468
+                try {
469
+                    $expireDate = $this->parseDate($expireDate);
470
+                    $share->setExpirationDate($expireDate);
471
+                } catch (\Exception $e) {
472
+                    throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD'));
473
+                }
474
+            }
475
+
476
+        } else if ($shareType === Share::SHARE_TYPE_REMOTE) {
477
+            if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
478
+                throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not allow shares from type %s', [$path->getPath(), $shareType]));
479
+            }
480
+
481
+            $share->setSharedWith($shareWith);
482
+            $share->setPermissions($permissions);
483
+        }  else if ($shareType === Share::SHARE_TYPE_REMOTE_GROUP) {
484
+            if (!$this->shareManager->outgoingServer2ServerGroupSharesAllowed()) {
485
+                throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not allow shares from type %s', [$path->getPath(), $shareType]));
486
+            }
487
+
488
+            $share->setSharedWith($shareWith);
489
+            $share->setPermissions($permissions);
490
+        } else if ($shareType === Share::SHARE_TYPE_EMAIL) {
491
+            if ($share->getNodeType() === 'file') {
492
+                $share->setPermissions(Constants::PERMISSION_READ);
493
+            } else {
494
+                $share->setPermissions($permissions);
495
+            }
496
+            $share->setSharedWith($shareWith);
497
+
498
+            if ($sendPasswordByTalk === 'true') {
499
+                if (!$this->appManager->isEnabledForUser('spreed')) {
500
+                    throw new OCSForbiddenException($this->l->t('Sharing %s sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled', [$path->getPath()]));
501
+                }
502
+
503
+                $share->setSendPasswordByTalk(true);
504
+            }
505
+        } else if ($shareType === Share::SHARE_TYPE_CIRCLE) {
506
+            if (!\OC::$server->getAppManager()->isEnabledForUser('circles') || !class_exists('\OCA\Circles\ShareByCircleProvider')) {
507
+                throw new OCSNotFoundException($this->l->t('You cannot share to a Circle if the app is not enabled'));
508
+            }
509
+
510
+            $circle = \OCA\Circles\Api\v1\Circles::detailsCircle($shareWith);
511
+
512
+            // Valid circle is required to share
513
+            if ($circle === null) {
514
+                throw new OCSNotFoundException($this->l->t('Please specify a valid circle'));
515
+            }
516
+            $share->setSharedWith($shareWith);
517
+            $share->setPermissions($permissions);
518
+        } else {
519
+            throw new OCSBadRequestException($this->l->t('Unknown share type'));
520
+        }
521
+
522
+        $share->setShareType($shareType);
523
+        $share->setSharedBy($this->currentUser);
524
+
525
+        try {
526
+            $share = $this->shareManager->createShare($share);
527
+        } catch (GenericShareException $e) {
528
+            $code = $e->getCode() === 0 ? 403 : $e->getCode();
529
+            throw new OCSException($e->getHint(), $code);
530
+        } catch (\Exception $e) {
531
+            throw new OCSForbiddenException($e->getMessage(), $e);
532
+        }
533
+
534
+        $output = $this->formatShare($share);
535
+
536
+        return new DataResponse($output);
537
+    }
538
+
539
+    /**
540
+     * @param \OCP\Files\File|\OCP\Files\Folder $node
541
+     * @param boolean $includeTags
542
+     * @return DataResponse
543
+     */
544
+    private function getSharedWithMe($node = null, bool $includeTags): DataResponse {
545
+
546
+        $userShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_USER, $node, -1, 0);
547
+        $groupShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_GROUP, $node, -1, 0);
548
+        $circleShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_CIRCLE, $node, -1, 0);
549
+
550
+        $shares = array_merge($userShares, $groupShares, $circleShares);
551
+
552
+        $shares = array_filter($shares, function (IShare $share) {
553
+            return $share->getShareOwner() !== $this->currentUser;
554
+        });
555
+
556
+        $formatted = [];
557
+        foreach ($shares as $share) {
558
+            if ($this->canAccessShare($share)) {
559
+                try {
560
+                    $formatted[] = $this->formatShare($share);
561
+                } catch (NotFoundException $e) {
562
+                    // Ignore this share
563
+                }
564
+            }
565
+        }
566
+
567
+        if ($includeTags) {
568
+            $formatted = Helper::populateTags($formatted, 'file_source', \OC::$server->getTagManager());
569
+        }
570
+
571
+        return new DataResponse($formatted);
572
+    }
573
+
574
+    /**
575
+     * @param \OCP\Files\Folder $folder
576
+     * @return DataResponse
577
+     * @throws OCSBadRequestException
578
+     */
579
+    private function getSharesInDir(Node $folder): DataResponse {
580
+        if (!($folder instanceof \OCP\Files\Folder)) {
581
+            throw new OCSBadRequestException($this->l->t('Not a directory'));
582
+        }
583
+
584
+        $nodes = $folder->getDirectoryListing();
585
+        /** @var \OCP\Share\IShare[] $shares */
586
+        $shares = [];
587
+        foreach ($nodes as $node) {
588
+            $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_USER, $node, false, -1, 0));
589
+            $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_GROUP, $node, false, -1, 0));
590
+            $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_LINK, $node, false, -1, 0));
591
+            if($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
592
+                $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_EMAIL, $node, false, -1, 0));
593
+            }
594
+            if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
595
+                $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_REMOTE, $node, false, -1, 0));
596
+            }
597
+        }
598
+
599
+        $formatted = [];
600
+        foreach ($shares as $share) {
601
+            try {
602
+                $formatted[] = $this->formatShare($share);
603
+            } catch (NotFoundException $e) {
604
+                //Ignore this share
605
+            }
606
+        }
607
+
608
+        return new DataResponse($formatted);
609
+    }
610
+
611
+    /**
612
+     * The getShares function.
613
+     *
614
+     * @NoAdminRequired
615
+     *
616
+     * @param string $shared_with_me
617
+     * @param string $reshares
618
+     * @param string $subfiles
619
+     * @param string $path
620
+     *
621
+     * - Get shares by the current user
622
+     * - Get shares by the current user and reshares (?reshares=true)
623
+     * - Get shares with the current user (?shared_with_me=true)
624
+     * - Get shares for a specific path (?path=...)
625
+     * - Get all shares in a folder (?subfiles=true&path=..)
626
+     *
627
+     * @return DataResponse
628
+     * @throws OCSNotFoundException
629
+     */
630
+    public function getShares(
631
+        string $shared_with_me = 'false',
632
+        string $reshares = 'false',
633
+        string $subfiles = 'false',
634
+        string $path = null,
635
+        string $include_tags = 'false'
636
+    ): DataResponse {
637
+
638
+        if ($path !== null) {
639
+            $userFolder = $this->rootFolder->getUserFolder($this->currentUser);
640
+            try {
641
+                $path = $userFolder->get($path);
642
+                $this->lock($path);
643
+            } catch (\OCP\Files\NotFoundException $e) {
644
+                throw new OCSNotFoundException($this->l->t('Wrong path, file/folder doesn\'t exist'));
645
+            } catch (LockedException $e) {
646
+                throw new OCSNotFoundException($this->l->t('Could not lock path'));
647
+            }
648
+        }
649
+
650
+        $include_tags = $include_tags === 'true';
651
+
652
+        if ($shared_with_me === 'true') {
653
+            $result = $this->getSharedWithMe($path, $include_tags);
654
+            return $result;
655
+        }
656
+
657
+        if ($subfiles === 'true') {
658
+            $result = $this->getSharesInDir($path);
659
+            return $result;
660
+        }
661
+
662
+        if ($reshares === 'true') {
663
+            $reshares = true;
664
+        } else {
665
+            $reshares = false;
666
+        }
667
+
668
+        // Get all shares
669
+        $userShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_USER, $path, $reshares, -1, 0);
670
+        $groupShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_GROUP, $path, $reshares, -1, 0);
671
+        $linkShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_LINK, $path, $reshares, -1, 0);
672
+        if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
673
+            $mailShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_EMAIL, $path, $reshares, -1, 0);
674
+        } else {
675
+            $mailShares = [];
676
+        }
677
+        if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_CIRCLE)) {
678
+            $circleShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_CIRCLE, $path, $reshares, -1, 0);
679
+        } else {
680
+            $circleShares = [];
681
+        }
682
+
683
+        $shares = array_merge($userShares, $groupShares, $linkShares, $mailShares, $circleShares);
684
+
685
+        if ($this->shareManager->outgoingServer2ServerSharesAllowed()) {
686
+            $federatedShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_REMOTE, $path, $reshares, -1, 0);
687
+            $shares = array_merge($shares, $federatedShares);
688
+        }
689
+
690
+        if ($this->shareManager->outgoingServer2ServerGroupSharesAllowed()) {
691
+            $federatedShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_REMOTE_GROUP, $path, $reshares, -1, 0);
692
+            $shares = array_merge($shares, $federatedShares);
693
+        }
694
+
695
+        $formatted = [];
696
+        foreach ($shares as $share) {
697
+            try {
698
+                $formatted[] = $this->formatShare($share, $path);
699
+            } catch (NotFoundException $e) {
700
+                //Ignore share
701
+            }
702
+        }
703
+
704
+        if ($include_tags) {
705
+            $formatted = Helper::populateTags($formatted, 'file_source', \OC::$server->getTagManager());
706
+        }
707
+
708
+        return new DataResponse($formatted);
709
+    }
710
+
711
+    /**
712
+     * @NoAdminRequired
713
+     *
714
+     * @param string $id
715
+     * @param int $permissions
716
+     * @param string $password
717
+     * @param string $sendPasswordByTalk
718
+     * @param string $publicUpload
719
+     * @param string $expireDate
720
+     * @param string $note
721
+     * @return DataResponse
722
+     * @throws LockedException
723
+     * @throws NotFoundException
724
+     * @throws OCSBadRequestException
725
+     * @throws OCSForbiddenException
726
+     * @throws OCSNotFoundException
727
+     */
728
+    public function updateShare(
729
+        string $id,
730
+        int $permissions = null,
731
+        string $password = null,
732
+        string $sendPasswordByTalk = null,
733
+        string $publicUpload = null,
734
+        string $expireDate = null,
735
+        string $note = null
736
+    ): DataResponse {
737
+        try {
738
+            $share = $this->getShareById($id);
739
+        } catch (ShareNotFound $e) {
740
+            throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
741
+        }
742
+
743
+        $this->lock($share->getNode());
744
+
745
+        if (!$this->canAccessShare($share, false)) {
746
+            throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
747
+        }
748
+
749
+        if ($permissions === null && $password === null && $sendPasswordByTalk === null && $publicUpload === null && $expireDate === null && $note === null) {
750
+            throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given'));
751
+        }
752
+
753
+        if($note !== null) {
754
+            $share->setNote($note);
755
+        }
756
+
757
+        /*
758 758
 		 * expirationdate, password and publicUpload only make sense for link shares
759 759
 		 */
760
-		if ($share->getShareType() === Share::SHARE_TYPE_LINK) {
761
-
762
-			$newPermissions = null;
763
-			if ($publicUpload === 'true') {
764
-				$newPermissions = Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE;
765
-			} else if ($publicUpload === 'false') {
766
-				$newPermissions = Constants::PERMISSION_READ;
767
-			}
768
-
769
-			if ($permissions !== null) {
770
-				$newPermissions = (int)$permissions;
771
-				$newPermissions = $newPermissions & ~Constants::PERMISSION_SHARE;
772
-			}
773
-
774
-			if ($newPermissions !== null &&
775
-				!in_array($newPermissions, [
776
-					Constants::PERMISSION_READ,
777
-					Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE, // legacy
778
-					Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE, // correct
779
-					Constants::PERMISSION_CREATE, // hidden file list
780
-					Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE, // allow to edit single files
781
-				], true)
782
-			) {
783
-				throw new OCSBadRequestException($this->l->t('Can\'t change permissions for public share links'));
784
-			}
785
-
786
-			if (
787
-				// legacy
788
-				$newPermissions === (Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE) ||
789
-				// correct
790
-				$newPermissions === (Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE)
791
-			) {
792
-				if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
793
-					throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
794
-				}
795
-
796
-				if (!($share->getNode() instanceof \OCP\Files\Folder)) {
797
-					throw new OCSBadRequestException($this->l->t('Public upload is only possible for publicly shared folders'));
798
-				}
799
-
800
-				// normalize to correct public upload permissions
801
-				$newPermissions = Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE;
802
-			}
803
-
804
-			if ($newPermissions !== null) {
805
-				$share->setPermissions($newPermissions);
806
-				$permissions = $newPermissions;
807
-			}
808
-
809
-			if ($expireDate === '') {
810
-				$share->setExpirationDate(null);
811
-			} else if ($expireDate !== null) {
812
-				try {
813
-					$expireDate = $this->parseDate($expireDate);
814
-				} catch (\Exception $e) {
815
-					throw new OCSBadRequestException($e->getMessage(), $e);
816
-				}
817
-				$share->setExpirationDate($expireDate);
818
-			}
819
-
820
-			if ($password === '') {
821
-				$share->setPassword(null);
822
-			} else if ($password !== null) {
823
-				$share->setPassword($password);
824
-			}
825
-
826
-		} else {
827
-			if ($permissions !== null) {
828
-				$permissions = (int)$permissions;
829
-				$share->setPermissions($permissions);
830
-			}
831
-
832
-			if ($share->getShareType() === Share::SHARE_TYPE_EMAIL) {
833
-				if ($password === '') {
834
-					$share->setPassword(null);
835
-				} else if ($password !== null) {
836
-					$share->setPassword($password);
837
-				}
838
-
839
-				if ($sendPasswordByTalk === 'true') {
840
-					if (!$this->appManager->isEnabledForUser('spreed')) {
841
-						throw new OCSForbiddenException($this->l->t('Sharing sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled'));
842
-					}
843
-
844
-					$share->setSendPasswordByTalk(true);
845
-				} else {
846
-					$share->setSendPasswordByTalk(false);
847
-				}
848
-			}
849
-
850
-			if ($expireDate === '') {
851
-				$share->setExpirationDate(null);
852
-			} else if ($expireDate !== null) {
853
-				try {
854
-					$expireDate = $this->parseDate($expireDate);
855
-				} catch (\Exception $e) {
856
-					throw new OCSBadRequestException($e->getMessage(), $e);
857
-				}
858
-				$share->setExpirationDate($expireDate);
859
-			}
860
-
861
-		}
862
-
863
-		if ($permissions !== null && $share->getShareOwner() !== $this->currentUser) {
864
-			/* Check if this is an incomming share */
865
-			$incomingShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_USER, $share->getNode(), -1, 0);
866
-			$incomingShares = array_merge($incomingShares, $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_GROUP, $share->getNode(), -1, 0));
867
-
868
-			/** @var \OCP\Share\IShare[] $incomingShares */
869
-			if (!empty($incomingShares)) {
870
-				$maxPermissions = 0;
871
-				foreach ($incomingShares as $incomingShare) {
872
-					$maxPermissions |= $incomingShare->getPermissions();
873
-				}
874
-
875
-				if ($share->getPermissions() & ~$maxPermissions) {
876
-					throw new OCSNotFoundException($this->l->t('Cannot increase permissions'));
877
-				}
878
-			}
879
-		}
880
-
881
-
882
-		try {
883
-			$share = $this->shareManager->updateShare($share);
884
-		} catch (\Exception $e) {
885
-			throw new OCSBadRequestException($e->getMessage(), $e);
886
-		}
887
-
888
-		return new DataResponse($this->formatShare($share));
889
-	}
890
-
891
-	protected function canAccessShare(\OCP\Share\IShare $share, bool $checkGroups = true): bool {
892
-		// A file with permissions 0 can't be accessed by us. So Don't show it
893
-		if ($share->getPermissions() === 0) {
894
-			return false;
895
-		}
896
-
897
-		// Owner of the file and the sharer of the file can always get share
898
-		if ($share->getShareOwner() === $this->currentUser ||
899
-			$share->getSharedBy() === $this->currentUser
900
-		) {
901
-			return true;
902
-		}
903
-
904
-		// If the share is shared with you (or a group you are a member of)
905
-		if ($share->getShareType() === Share::SHARE_TYPE_USER &&
906
-			$share->getSharedWith() === $this->currentUser
907
-		) {
908
-			return true;
909
-		}
910
-
911
-		if ($checkGroups && $share->getShareType() === Share::SHARE_TYPE_GROUP) {
912
-			$sharedWith = $this->groupManager->get($share->getSharedWith());
913
-			$user = $this->userManager->get($this->currentUser);
914
-			if ($user !== null && $sharedWith !== null && $sharedWith->inGroup($user)) {
915
-				return true;
916
-			}
917
-		}
918
-
919
-		if ($share->getShareType() === Share::SHARE_TYPE_CIRCLE) {
920
-			// TODO: have a sanity check like above?
921
-			return true;
922
-		}
923
-
924
-		return false;
925
-	}
926
-
927
-	/**
928
-	 * Make sure that the passed date is valid ISO 8601
929
-	 * So YYYY-MM-DD
930
-	 * If not throw an exception
931
-	 *
932
-	 * @param string $expireDate
933
-	 *
934
-	 * @throws \Exception
935
-	 * @return \DateTime
936
-	 */
937
-	private function parseDate(string $expireDate): \DateTime {
938
-		try {
939
-			$date = new \DateTime($expireDate);
940
-		} catch (\Exception $e) {
941
-			throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
942
-		}
943
-
944
-		if ($date === false) {
945
-			throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
946
-		}
947
-
948
-		$date->setTime(0, 0, 0);
949
-
950
-		return $date;
951
-	}
952
-
953
-	/**
954
-	 * Since we have multiple providers but the OCS Share API v1 does
955
-	 * not support this we need to check all backends.
956
-	 *
957
-	 * @param string $id
958
-	 * @return \OCP\Share\IShare
959
-	 * @throws ShareNotFound
960
-	 */
961
-	private function getShareById(string $id): IShare {
962
-		$share = null;
963
-
964
-		// First check if it is an internal share.
965
-		try {
966
-			$share = $this->shareManager->getShareById('ocinternal:' . $id, $this->currentUser);
967
-			return $share;
968
-		} catch (ShareNotFound $e) {
969
-			// Do nothing, just try the other share type
970
-		}
971
-
972
-
973
-		try {
974
-			if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_CIRCLE)) {
975
-				$share = $this->shareManager->getShareById('ocCircleShare:' . $id, $this->currentUser);
976
-				return $share;
977
-			}
978
-		} catch (ShareNotFound $e) {
979
-			// Do nothing, just try the other share type
980
-		}
981
-
982
-		try {
983
-			if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
984
-				$share = $this->shareManager->getShareById('ocMailShare:' . $id, $this->currentUser);
985
-				return $share;
986
-			}
987
-		} catch (ShareNotFound $e) {
988
-			// Do nothing, just try the other share type
989
-		}
990
-
991
-		if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
992
-			throw new ShareNotFound();
993
-		}
994
-		$share = $this->shareManager->getShareById('ocFederatedSharing:' . $id, $this->currentUser);
995
-
996
-		return $share;
997
-	}
998
-
999
-	/**
1000
-	 * Lock a Node
1001
-	 *
1002
-	 * @param \OCP\Files\Node $node
1003
-	 * @throws LockedException
1004
-	 */
1005
-	private function lock(\OCP\Files\Node $node) {
1006
-		$node->lock(ILockingProvider::LOCK_SHARED);
1007
-		$this->lockedNode = $node;
1008
-	}
1009
-
1010
-	/**
1011
-	 * Cleanup the remaining locks
1012
-	 * @throws @LockedException
1013
-	 */
1014
-	public function cleanup() {
1015
-		if ($this->lockedNode !== null) {
1016
-			$this->lockedNode->unlock(ILockingProvider::LOCK_SHARED);
1017
-		}
1018
-	}
760
+        if ($share->getShareType() === Share::SHARE_TYPE_LINK) {
761
+
762
+            $newPermissions = null;
763
+            if ($publicUpload === 'true') {
764
+                $newPermissions = Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE;
765
+            } else if ($publicUpload === 'false') {
766
+                $newPermissions = Constants::PERMISSION_READ;
767
+            }
768
+
769
+            if ($permissions !== null) {
770
+                $newPermissions = (int)$permissions;
771
+                $newPermissions = $newPermissions & ~Constants::PERMISSION_SHARE;
772
+            }
773
+
774
+            if ($newPermissions !== null &&
775
+                !in_array($newPermissions, [
776
+                    Constants::PERMISSION_READ,
777
+                    Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE, // legacy
778
+                    Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE, // correct
779
+                    Constants::PERMISSION_CREATE, // hidden file list
780
+                    Constants::PERMISSION_READ | Constants::PERMISSION_UPDATE, // allow to edit single files
781
+                ], true)
782
+            ) {
783
+                throw new OCSBadRequestException($this->l->t('Can\'t change permissions for public share links'));
784
+            }
785
+
786
+            if (
787
+                // legacy
788
+                $newPermissions === (Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE) ||
789
+                // correct
790
+                $newPermissions === (Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE)
791
+            ) {
792
+                if (!$this->shareManager->shareApiLinkAllowPublicUpload()) {
793
+                    throw new OCSForbiddenException($this->l->t('Public upload disabled by the administrator'));
794
+                }
795
+
796
+                if (!($share->getNode() instanceof \OCP\Files\Folder)) {
797
+                    throw new OCSBadRequestException($this->l->t('Public upload is only possible for publicly shared folders'));
798
+                }
799
+
800
+                // normalize to correct public upload permissions
801
+                $newPermissions = Constants::PERMISSION_READ | Constants::PERMISSION_CREATE | Constants::PERMISSION_UPDATE | Constants::PERMISSION_DELETE;
802
+            }
803
+
804
+            if ($newPermissions !== null) {
805
+                $share->setPermissions($newPermissions);
806
+                $permissions = $newPermissions;
807
+            }
808
+
809
+            if ($expireDate === '') {
810
+                $share->setExpirationDate(null);
811
+            } else if ($expireDate !== null) {
812
+                try {
813
+                    $expireDate = $this->parseDate($expireDate);
814
+                } catch (\Exception $e) {
815
+                    throw new OCSBadRequestException($e->getMessage(), $e);
816
+                }
817
+                $share->setExpirationDate($expireDate);
818
+            }
819
+
820
+            if ($password === '') {
821
+                $share->setPassword(null);
822
+            } else if ($password !== null) {
823
+                $share->setPassword($password);
824
+            }
825
+
826
+        } else {
827
+            if ($permissions !== null) {
828
+                $permissions = (int)$permissions;
829
+                $share->setPermissions($permissions);
830
+            }
831
+
832
+            if ($share->getShareType() === Share::SHARE_TYPE_EMAIL) {
833
+                if ($password === '') {
834
+                    $share->setPassword(null);
835
+                } else if ($password !== null) {
836
+                    $share->setPassword($password);
837
+                }
838
+
839
+                if ($sendPasswordByTalk === 'true') {
840
+                    if (!$this->appManager->isEnabledForUser('spreed')) {
841
+                        throw new OCSForbiddenException($this->l->t('Sharing sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled'));
842
+                    }
843
+
844
+                    $share->setSendPasswordByTalk(true);
845
+                } else {
846
+                    $share->setSendPasswordByTalk(false);
847
+                }
848
+            }
849
+
850
+            if ($expireDate === '') {
851
+                $share->setExpirationDate(null);
852
+            } else if ($expireDate !== null) {
853
+                try {
854
+                    $expireDate = $this->parseDate($expireDate);
855
+                } catch (\Exception $e) {
856
+                    throw new OCSBadRequestException($e->getMessage(), $e);
857
+                }
858
+                $share->setExpirationDate($expireDate);
859
+            }
860
+
861
+        }
862
+
863
+        if ($permissions !== null && $share->getShareOwner() !== $this->currentUser) {
864
+            /* Check if this is an incomming share */
865
+            $incomingShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_USER, $share->getNode(), -1, 0);
866
+            $incomingShares = array_merge($incomingShares, $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_GROUP, $share->getNode(), -1, 0));
867
+
868
+            /** @var \OCP\Share\IShare[] $incomingShares */
869
+            if (!empty($incomingShares)) {
870
+                $maxPermissions = 0;
871
+                foreach ($incomingShares as $incomingShare) {
872
+                    $maxPermissions |= $incomingShare->getPermissions();
873
+                }
874
+
875
+                if ($share->getPermissions() & ~$maxPermissions) {
876
+                    throw new OCSNotFoundException($this->l->t('Cannot increase permissions'));
877
+                }
878
+            }
879
+        }
880
+
881
+
882
+        try {
883
+            $share = $this->shareManager->updateShare($share);
884
+        } catch (\Exception $e) {
885
+            throw new OCSBadRequestException($e->getMessage(), $e);
886
+        }
887
+
888
+        return new DataResponse($this->formatShare($share));
889
+    }
890
+
891
+    protected function canAccessShare(\OCP\Share\IShare $share, bool $checkGroups = true): bool {
892
+        // A file with permissions 0 can't be accessed by us. So Don't show it
893
+        if ($share->getPermissions() === 0) {
894
+            return false;
895
+        }
896
+
897
+        // Owner of the file and the sharer of the file can always get share
898
+        if ($share->getShareOwner() === $this->currentUser ||
899
+            $share->getSharedBy() === $this->currentUser
900
+        ) {
901
+            return true;
902
+        }
903
+
904
+        // If the share is shared with you (or a group you are a member of)
905
+        if ($share->getShareType() === Share::SHARE_TYPE_USER &&
906
+            $share->getSharedWith() === $this->currentUser
907
+        ) {
908
+            return true;
909
+        }
910
+
911
+        if ($checkGroups && $share->getShareType() === Share::SHARE_TYPE_GROUP) {
912
+            $sharedWith = $this->groupManager->get($share->getSharedWith());
913
+            $user = $this->userManager->get($this->currentUser);
914
+            if ($user !== null && $sharedWith !== null && $sharedWith->inGroup($user)) {
915
+                return true;
916
+            }
917
+        }
918
+
919
+        if ($share->getShareType() === Share::SHARE_TYPE_CIRCLE) {
920
+            // TODO: have a sanity check like above?
921
+            return true;
922
+        }
923
+
924
+        return false;
925
+    }
926
+
927
+    /**
928
+     * Make sure that the passed date is valid ISO 8601
929
+     * So YYYY-MM-DD
930
+     * If not throw an exception
931
+     *
932
+     * @param string $expireDate
933
+     *
934
+     * @throws \Exception
935
+     * @return \DateTime
936
+     */
937
+    private function parseDate(string $expireDate): \DateTime {
938
+        try {
939
+            $date = new \DateTime($expireDate);
940
+        } catch (\Exception $e) {
941
+            throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
942
+        }
943
+
944
+        if ($date === false) {
945
+            throw new \Exception('Invalid date. Format must be YYYY-MM-DD');
946
+        }
947
+
948
+        $date->setTime(0, 0, 0);
949
+
950
+        return $date;
951
+    }
952
+
953
+    /**
954
+     * Since we have multiple providers but the OCS Share API v1 does
955
+     * not support this we need to check all backends.
956
+     *
957
+     * @param string $id
958
+     * @return \OCP\Share\IShare
959
+     * @throws ShareNotFound
960
+     */
961
+    private function getShareById(string $id): IShare {
962
+        $share = null;
963
+
964
+        // First check if it is an internal share.
965
+        try {
966
+            $share = $this->shareManager->getShareById('ocinternal:' . $id, $this->currentUser);
967
+            return $share;
968
+        } catch (ShareNotFound $e) {
969
+            // Do nothing, just try the other share type
970
+        }
971
+
972
+
973
+        try {
974
+            if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_CIRCLE)) {
975
+                $share = $this->shareManager->getShareById('ocCircleShare:' . $id, $this->currentUser);
976
+                return $share;
977
+            }
978
+        } catch (ShareNotFound $e) {
979
+            // Do nothing, just try the other share type
980
+        }
981
+
982
+        try {
983
+            if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) {
984
+                $share = $this->shareManager->getShareById('ocMailShare:' . $id, $this->currentUser);
985
+                return $share;
986
+            }
987
+        } catch (ShareNotFound $e) {
988
+            // Do nothing, just try the other share type
989
+        }
990
+
991
+        if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
992
+            throw new ShareNotFound();
993
+        }
994
+        $share = $this->shareManager->getShareById('ocFederatedSharing:' . $id, $this->currentUser);
995
+
996
+        return $share;
997
+    }
998
+
999
+    /**
1000
+     * Lock a Node
1001
+     *
1002
+     * @param \OCP\Files\Node $node
1003
+     * @throws LockedException
1004
+     */
1005
+    private function lock(\OCP\Files\Node $node) {
1006
+        $node->lock(ILockingProvider::LOCK_SHARED);
1007
+        $this->lockedNode = $node;
1008
+    }
1009
+
1010
+    /**
1011
+     * Cleanup the remaining locks
1012
+     * @throws @LockedException
1013
+     */
1014
+    public function cleanup() {
1015
+        if ($this->lockedNode !== null) {
1016
+            $this->lockedNode->unlock(ILockingProvider::LOCK_SHARED);
1017
+        }
1018
+    }
1019 1019
 }
Please login to merge, or discard this patch.
apps/sharebymail/lib/ShareByMailProvider.php 3 patches
Doc Comments   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -307,10 +307,10 @@  discard block
 block discarded – undo
307 307
 	 * publish activity if a file/folder was shared by mail
308 308
 	 *
309 309
 	 * @param $subject
310
-	 * @param $parameters
311
-	 * @param $affectedUser
310
+	 * @param string[] $parameters
311
+	 * @param string $affectedUser
312 312
 	 * @param $fileId
313
-	 * @param $filePath
313
+	 * @param string $filePath
314 314
 	 */
315 315
 	protected function publishActivity($subject, $parameters, $affectedUser, $fileId, $filePath) {
316 316
 		$event = $this->activityManager->generateEvent();
@@ -1067,7 +1067,7 @@  discard block
 block discarded – undo
1067 1067
 	/**
1068 1068
 	 * get database row of a give share
1069 1069
 	 *
1070
-	 * @param $id
1070
+	 * @param integer $id
1071 1071
 	 * @return array
1072 1072
 	 * @throws ShareNotFound
1073 1073
 	 */
Please login to merge, or discard this patch.
Indentation   +1090 added lines, -1090 removed lines patch added patch discarded remove patch
@@ -54,1108 +54,1108 @@
 block discarded – undo
54 54
  */
55 55
 class ShareByMailProvider implements IShareProvider {
56 56
 
57
-	/** @var  IDBConnection */
58
-	private $dbConnection;
59
-
60
-	/** @var ILogger */
61
-	private $logger;
62
-
63
-	/** @var ISecureRandom */
64
-	private $secureRandom;
65
-
66
-	/** @var IUserManager */
67
-	private $userManager;
68
-
69
-	/** @var IRootFolder */
70
-	private $rootFolder;
71
-
72
-	/** @var IL10N */
73
-	private $l;
74
-
75
-	/** @var IMailer */
76
-	private $mailer;
77
-
78
-	/** @var IURLGenerator */
79
-	private $urlGenerator;
80
-
81
-	/** @var IManager  */
82
-	private $activityManager;
83
-
84
-	/** @var SettingsManager */
85
-	private $settingsManager;
86
-
87
-	/** @var Defaults */
88
-	private $defaults;
89
-
90
-	/** @var IHasher */
91
-	private $hasher;
92
-
93
-	/** @var  CapabilitiesManager */
94
-	private $capabilitiesManager;
95
-
96
-	/**
97
-	 * Return the identifier of this provider.
98
-	 *
99
-	 * @return string Containing only [a-zA-Z0-9]
100
-	 */
101
-	public function identifier() {
102
-		return 'ocMailShare';
103
-	}
104
-
105
-	/**
106
-	 * DefaultShareProvider constructor.
107
-	 *
108
-	 * @param IDBConnection $connection
109
-	 * @param ISecureRandom $secureRandom
110
-	 * @param IUserManager $userManager
111
-	 * @param IRootFolder $rootFolder
112
-	 * @param IL10N $l
113
-	 * @param ILogger $logger
114
-	 * @param IMailer $mailer
115
-	 * @param IURLGenerator $urlGenerator
116
-	 * @param IManager $activityManager
117
-	 * @param SettingsManager $settingsManager
118
-	 * @param Defaults $defaults
119
-	 * @param IHasher $hasher
120
-	 * @param CapabilitiesManager $capabilitiesManager
121
-	 */
122
-	public function __construct(
123
-		IDBConnection $connection,
124
-		ISecureRandom $secureRandom,
125
-		IUserManager $userManager,
126
-		IRootFolder $rootFolder,
127
-		IL10N $l,
128
-		ILogger $logger,
129
-		IMailer $mailer,
130
-		IURLGenerator $urlGenerator,
131
-		IManager $activityManager,
132
-		SettingsManager $settingsManager,
133
-		Defaults $defaults,
134
-		IHasher $hasher,
135
-		CapabilitiesManager $capabilitiesManager
136
-	) {
137
-		$this->dbConnection = $connection;
138
-		$this->secureRandom = $secureRandom;
139
-		$this->userManager = $userManager;
140
-		$this->rootFolder = $rootFolder;
141
-		$this->l = $l;
142
-		$this->logger = $logger;
143
-		$this->mailer = $mailer;
144
-		$this->urlGenerator = $urlGenerator;
145
-		$this->activityManager = $activityManager;
146
-		$this->settingsManager = $settingsManager;
147
-		$this->defaults = $defaults;
148
-		$this->hasher = $hasher;
149
-		$this->capabilitiesManager = $capabilitiesManager;
150
-	}
151
-
152
-	/**
153
-	 * Share a path
154
-	 *
155
-	 * @param IShare $share
156
-	 * @return IShare The share object
157
-	 * @throws ShareNotFound
158
-	 * @throws \Exception
159
-	 */
160
-	public function create(IShare $share) {
161
-
162
-		$shareWith = $share->getSharedWith();
163
-		/*
57
+    /** @var  IDBConnection */
58
+    private $dbConnection;
59
+
60
+    /** @var ILogger */
61
+    private $logger;
62
+
63
+    /** @var ISecureRandom */
64
+    private $secureRandom;
65
+
66
+    /** @var IUserManager */
67
+    private $userManager;
68
+
69
+    /** @var IRootFolder */
70
+    private $rootFolder;
71
+
72
+    /** @var IL10N */
73
+    private $l;
74
+
75
+    /** @var IMailer */
76
+    private $mailer;
77
+
78
+    /** @var IURLGenerator */
79
+    private $urlGenerator;
80
+
81
+    /** @var IManager  */
82
+    private $activityManager;
83
+
84
+    /** @var SettingsManager */
85
+    private $settingsManager;
86
+
87
+    /** @var Defaults */
88
+    private $defaults;
89
+
90
+    /** @var IHasher */
91
+    private $hasher;
92
+
93
+    /** @var  CapabilitiesManager */
94
+    private $capabilitiesManager;
95
+
96
+    /**
97
+     * Return the identifier of this provider.
98
+     *
99
+     * @return string Containing only [a-zA-Z0-9]
100
+     */
101
+    public function identifier() {
102
+        return 'ocMailShare';
103
+    }
104
+
105
+    /**
106
+     * DefaultShareProvider constructor.
107
+     *
108
+     * @param IDBConnection $connection
109
+     * @param ISecureRandom $secureRandom
110
+     * @param IUserManager $userManager
111
+     * @param IRootFolder $rootFolder
112
+     * @param IL10N $l
113
+     * @param ILogger $logger
114
+     * @param IMailer $mailer
115
+     * @param IURLGenerator $urlGenerator
116
+     * @param IManager $activityManager
117
+     * @param SettingsManager $settingsManager
118
+     * @param Defaults $defaults
119
+     * @param IHasher $hasher
120
+     * @param CapabilitiesManager $capabilitiesManager
121
+     */
122
+    public function __construct(
123
+        IDBConnection $connection,
124
+        ISecureRandom $secureRandom,
125
+        IUserManager $userManager,
126
+        IRootFolder $rootFolder,
127
+        IL10N $l,
128
+        ILogger $logger,
129
+        IMailer $mailer,
130
+        IURLGenerator $urlGenerator,
131
+        IManager $activityManager,
132
+        SettingsManager $settingsManager,
133
+        Defaults $defaults,
134
+        IHasher $hasher,
135
+        CapabilitiesManager $capabilitiesManager
136
+    ) {
137
+        $this->dbConnection = $connection;
138
+        $this->secureRandom = $secureRandom;
139
+        $this->userManager = $userManager;
140
+        $this->rootFolder = $rootFolder;
141
+        $this->l = $l;
142
+        $this->logger = $logger;
143
+        $this->mailer = $mailer;
144
+        $this->urlGenerator = $urlGenerator;
145
+        $this->activityManager = $activityManager;
146
+        $this->settingsManager = $settingsManager;
147
+        $this->defaults = $defaults;
148
+        $this->hasher = $hasher;
149
+        $this->capabilitiesManager = $capabilitiesManager;
150
+    }
151
+
152
+    /**
153
+     * Share a path
154
+     *
155
+     * @param IShare $share
156
+     * @return IShare The share object
157
+     * @throws ShareNotFound
158
+     * @throws \Exception
159
+     */
160
+    public function create(IShare $share) {
161
+
162
+        $shareWith = $share->getSharedWith();
163
+        /*
164 164
 		 * Check if file is not already shared with the remote user
165 165
 		 */
166
-		$alreadyShared = $this->getSharedWith($shareWith, \OCP\Share::SHARE_TYPE_EMAIL, $share->getNode(), 1, 0);
167
-		if (!empty($alreadyShared)) {
168
-			$message = 'Sharing %s failed, this item is already shared with %s';
169
-			$message_t = $this->l->t('Sharing %s failed, this item is already shared with %s', array($share->getNode()->getName(), $shareWith));
170
-			$this->logger->debug(sprintf($message, $share->getNode()->getName(), $shareWith), ['app' => 'Federated File Sharing']);
171
-			throw new \Exception($message_t);
172
-		}
173
-
174
-		// if the admin enforces a password for all mail shares we create a
175
-		// random password and send it to the recipient
176
-		$password = '';
177
-		$passwordEnforced = $this->settingsManager->enforcePasswordProtection();
178
-		if ($passwordEnforced) {
179
-			$password = $this->autoGeneratePassword($share);
180
-		}
181
-
182
-		$shareId = $this->createMailShare($share);
183
-		$send = $this->sendPassword($share, $password);
184
-		if ($passwordEnforced && $send === false) {
185
-			$this->sendPasswordToOwner($share, $password);
186
-		}
187
-
188
-		$this->createShareActivity($share);
189
-		$data = $this->getRawShare($shareId);
190
-
191
-		return $this->createShareObject($data);
192
-
193
-	}
194
-
195
-	/**
196
-	 * auto generate password in case of password enforcement on mail shares
197
-	 *
198
-	 * @param IShare $share
199
-	 * @return string
200
-	 * @throws \Exception
201
-	 */
202
-	protected function autoGeneratePassword($share) {
203
-		$initiatorUser = $this->userManager->get($share->getSharedBy());
204
-		$initiatorEMailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
205
-		$allowPasswordByMail = $this->settingsManager->sendPasswordByMail();
206
-
207
-		if ($initiatorEMailAddress === null && !$allowPasswordByMail) {
208
-			throw new \Exception(
209
-				$this->l->t("We can't send you the auto-generated password. Please set a valid email address in your personal settings and try again.")
210
-			);
211
-		}
212
-
213
-		$passwordPolicy = $this->getPasswordPolicy();
214
-		$passwordCharset = ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS;
215
-		$passwordLength = 8;
216
-		if (!empty($passwordPolicy)) {
217
-			$passwordLength = (int)$passwordPolicy['minLength'] > 0 ? (int)$passwordPolicy['minLength'] : $passwordLength;
218
-			$passwordCharset .= $passwordPolicy['enforceSpecialCharacters'] ? ISecureRandom::CHAR_SYMBOLS : '';
219
-		}
220
-
221
-		$password = $this->secureRandom->generate($passwordLength, $passwordCharset);
222
-
223
-		$share->setPassword($this->hasher->hash($password));
224
-
225
-		return $password;
226
-	}
227
-
228
-	/**
229
-	 * get password policy
230
-	 *
231
-	 * @return array
232
-	 */
233
-	protected function getPasswordPolicy() {
234
-		$capabilities = $this->capabilitiesManager->getCapabilities();
235
-		if (isset($capabilities['password_policy'])) {
236
-			return $capabilities['password_policy'];
237
-		}
238
-
239
-		return [];
240
-	}
241
-
242
-	/**
243
-	 * create activity if a file/folder was shared by mail
244
-	 *
245
-	 * @param IShare $share
246
-	 */
247
-	protected function createShareActivity(IShare $share) {
248
-
249
-		$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
250
-
251
-		$this->publishActivity(
252
-			Activity::SUBJECT_SHARED_EMAIL_SELF,
253
-			[$userFolder->getRelativePath($share->getNode()->getPath()), $share->getSharedWith()],
254
-			$share->getSharedBy(),
255
-			$share->getNode()->getId(),
256
-			$userFolder->getRelativePath($share->getNode()->getPath())
257
-		);
258
-
259
-		if ($share->getShareOwner() !== $share->getSharedBy()) {
260
-			$ownerFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
261
-			$fileId = $share->getNode()->getId();
262
-			$nodes = $ownerFolder->getById($fileId);
263
-			$ownerPath = $nodes[0]->getPath();
264
-			$this->publishActivity(
265
-				Activity::SUBJECT_SHARED_EMAIL_BY,
266
-				[$ownerFolder->getRelativePath($ownerPath), $share->getSharedWith(), $share->getSharedBy()],
267
-				$share->getShareOwner(),
268
-				$fileId,
269
-				$ownerFolder->getRelativePath($ownerPath)
270
-			);
271
-		}
272
-
273
-	}
274
-
275
-	/**
276
-	 * create activity if a file/folder was shared by mail
277
-	 *
278
-	 * @param IShare $share
279
-	 * @param string $sharedWith
280
-	 * @param bool $sendToSelf
281
-	 */
282
-	protected function createPasswordSendActivity(IShare $share, $sharedWith, $sendToSelf) {
283
-
284
-		$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
285
-
286
-		if ($sendToSelf) {
287
-			$this->publishActivity(
288
-				Activity::SUBJECT_SHARED_EMAIL_PASSWORD_SEND_SELF,
289
-				[$userFolder->getRelativePath($share->getNode()->getPath())],
290
-				$share->getSharedBy(),
291
-				$share->getNode()->getId(),
292
-				$userFolder->getRelativePath($share->getNode()->getPath())
293
-			);
294
-		} else {
295
-			$this->publishActivity(
296
-				Activity::SUBJECT_SHARED_EMAIL_PASSWORD_SEND,
297
-				[$userFolder->getRelativePath($share->getNode()->getPath()), $sharedWith],
298
-				$share->getSharedBy(),
299
-				$share->getNode()->getId(),
300
-				$userFolder->getRelativePath($share->getNode()->getPath())
301
-			);
302
-		}
303
-	}
304
-
305
-
306
-	/**
307
-	 * publish activity if a file/folder was shared by mail
308
-	 *
309
-	 * @param $subject
310
-	 * @param $parameters
311
-	 * @param $affectedUser
312
-	 * @param $fileId
313
-	 * @param $filePath
314
-	 */
315
-	protected function publishActivity($subject, $parameters, $affectedUser, $fileId, $filePath) {
316
-		$event = $this->activityManager->generateEvent();
317
-		$event->setApp('sharebymail')
318
-			->setType('shared')
319
-			->setSubject($subject, $parameters)
320
-			->setAffectedUser($affectedUser)
321
-			->setObject('files', $fileId, $filePath);
322
-		$this->activityManager->publish($event);
323
-
324
-	}
325
-
326
-	/**
327
-	 * @param IShare $share
328
-	 * @return int
329
-	 * @throws \Exception
330
-	 */
331
-	protected function createMailShare(IShare $share) {
332
-		$share->setToken($this->generateToken());
333
-		$shareId = $this->addShareToDB(
334
-			$share->getNodeId(),
335
-			$share->getNodeType(),
336
-			$share->getSharedWith(),
337
-			$share->getSharedBy(),
338
-			$share->getShareOwner(),
339
-			$share->getPermissions(),
340
-			$share->getToken(),
341
-			$share->getPassword(),
342
-			$share->getSendPasswordByTalk()
343
-		);
344
-
345
-		try {
346
-			$link = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare',
347
-				['token' => $share->getToken()]);
348
-			$this->sendMailNotification(
349
-				$share->getNode()->getName(),
350
-				$link,
351
-				$share->getSharedBy(),
352
-				$share->getSharedWith(),
353
-				$share->getExpirationDate()
354
-			);
355
-		} catch (HintException $hintException) {
356
-			$this->logger->logException($hintException, [
357
-				'message' => 'Failed to send share by mail.',
358
-				'level' => ILogger::ERROR,
359
-				'app' => 'sharebymail',
360
-			]);
361
-			$this->removeShareFromTable($shareId);
362
-			throw $hintException;
363
-		} catch (\Exception $e) {
364
-			$this->logger->logException($e, [
365
-				'message' => 'Failed to send share by mail.',
366
-				'level' => ILogger::ERROR,
367
-				'app' => 'sharebymail',
368
-			]);
369
-			$this->removeShareFromTable($shareId);
370
-			throw new HintException('Failed to send share by mail',
371
-				$this->l->t('Failed to send share by email'));
372
-		}
373
-
374
-		return $shareId;
375
-
376
-	}
377
-
378
-	/**
379
-	 * @param string $filename
380
-	 * @param string $link
381
-	 * @param string $initiator
382
-	 * @param string $shareWith
383
-	 * @param \DateTime|null $expiration
384
-	 * @throws \Exception If mail couldn't be sent
385
-	 */
386
-	protected function sendMailNotification($filename,
387
-											$link,
388
-											$initiator,
389
-											$shareWith,
390
-											\DateTime $expiration = null) {
391
-		$initiatorUser = $this->userManager->get($initiator);
392
-		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
393
-		$message = $this->mailer->createMessage();
394
-
395
-		$emailTemplate = $this->mailer->createEMailTemplate('sharebymail.RecipientNotification', [
396
-			'filename' => $filename,
397
-			'link' => $link,
398
-			'initiator' => $initiatorDisplayName,
399
-			'expiration' => $expiration,
400
-			'shareWith' => $shareWith,
401
-		]);
402
-
403
-		$emailTemplate->setSubject($this->l->t('%s shared »%s« with you', array($initiatorDisplayName, $filename)));
404
-		$emailTemplate->addHeader();
405
-		$emailTemplate->addHeading($this->l->t('%s shared »%s« with you', [$initiatorDisplayName, $filename]), false);
406
-		$text = $this->l->t('%s shared »%s« with you.', [$initiatorDisplayName, $filename]);
407
-
408
-		$emailTemplate->addBodyText(
409
-			htmlspecialchars($text . ' ' . $this->l->t('Click the button below to open it.')),
410
-			$text
411
-		);
412
-		$emailTemplate->addBodyButton(
413
-			$this->l->t('Open »%s«', [$filename]),
414
-			$link
415
-		);
416
-
417
-		$message->setTo([$shareWith]);
418
-
419
-		// The "From" contains the sharers name
420
-		$instanceName = $this->defaults->getName();
421
-		$senderName = $this->l->t(
422
-			'%s via %s',
423
-			[
424
-				$initiatorDisplayName,
425
-				$instanceName
426
-			]
427
-		);
428
-		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
429
-
430
-		// The "Reply-To" is set to the sharer if an mail address is configured
431
-		// also the default footer contains a "Do not reply" which needs to be adjusted.
432
-		$initiatorEmail = $initiatorUser->getEMailAddress();
433
-		if($initiatorEmail !== null) {
434
-			$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
435
-			$emailTemplate->addFooter($instanceName . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : ''));
436
-		} else {
437
-			$emailTemplate->addFooter();
438
-		}
439
-
440
-		$message->useTemplate($emailTemplate);
441
-		$this->mailer->send($message);
442
-	}
443
-
444
-	/**
445
-	 * send password to recipient of a mail share
446
-	 *
447
-	 * @param IShare $share
448
-	 * @param string $password
449
-	 * @return bool
450
-	 */
451
-	protected function sendPassword(IShare $share, $password) {
452
-
453
-		$filename = $share->getNode()->getName();
454
-		$initiator = $share->getSharedBy();
455
-		$shareWith = $share->getSharedWith();
456
-
457
-		if ($password === '' || $this->settingsManager->sendPasswordByMail() === false || $share->getSendPasswordByTalk()) {
458
-			return false;
459
-		}
460
-
461
-		$initiatorUser = $this->userManager->get($initiator);
462
-		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
463
-		$initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
464
-
465
-		$plainBodyPart = $this->l->t("%s shared »%s« with you.\nYou should have already received a separate mail with a link to access it.\n", [$initiatorDisplayName, $filename]);
466
-		$htmlBodyPart = $this->l->t('%s shared »%s« with you. You should have already received a separate mail with a link to access it.', [$initiatorDisplayName, $filename]);
467
-
468
-		$message = $this->mailer->createMessage();
469
-
470
-		$emailTemplate = $this->mailer->createEMailTemplate('sharebymail.RecipientPasswordNotification', [
471
-			'filename' => $filename,
472
-			'password' => $password,
473
-			'initiator' => $initiatorDisplayName,
474
-			'initiatorEmail' => $initiatorEmailAddress,
475
-			'shareWith' => $shareWith,
476
-		]);
477
-
478
-		$emailTemplate->setSubject($this->l->t('Password to access »%s« shared to you by %s', [$filename, $initiatorDisplayName]));
479
-		$emailTemplate->addHeader();
480
-		$emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
481
-		$emailTemplate->addBodyText(htmlspecialchars($htmlBodyPart), $plainBodyPart);
482
-		$emailTemplate->addBodyText($this->l->t('It is protected with the following password: %s', [$password]));
483
-
484
-		// The "From" contains the sharers name
485
-		$instanceName = $this->defaults->getName();
486
-		$senderName = $this->l->t(
487
-			'%s via %s',
488
-			[
489
-				$initiatorDisplayName,
490
-				$instanceName
491
-			]
492
-		);
493
-		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
494
-		if ($initiatorEmailAddress !== null) {
495
-			$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
496
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
497
-		} else {
498
-			$emailTemplate->addFooter();
499
-		}
500
-
501
-		$message->setTo([$shareWith]);
502
-		$message->useTemplate($emailTemplate);
503
-		$this->mailer->send($message);
504
-
505
-		$this->createPasswordSendActivity($share, $shareWith, false);
506
-
507
-		return true;
508
-	}
509
-
510
-	protected function sendNote(IShare $share) {
511
-
512
-		$recipient = $share->getSharedWith();
513
-
514
-
515
-		$filename = $share->getNode()->getName();
516
-		$initiator = $share->getSharedBy();
517
-		$note = $share->getNote();
518
-
519
-		$initiatorUser = $this->userManager->get($initiator);
520
-		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
521
-		$initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
522
-
523
-		$plainHeading = $this->l->t('%1$s shared »%2$s« with you and wants to add:', [$initiatorDisplayName, $filename]);
524
-		$htmlHeading = $this->l->t('%1$s shared »%2$s« with you and wants to add', [$initiatorDisplayName, $filename]);
525
-
526
-		$message = $this->mailer->createMessage();
527
-
528
-		$emailTemplate = $this->mailer->createEMailTemplate('shareByMail.sendNote');
529
-
530
-		$emailTemplate->setSubject($this->l->t('»%s« added a note to a file shared with you', [$initiatorDisplayName]));
531
-		$emailTemplate->addHeader();
532
-		$emailTemplate->addHeading(htmlspecialchars($htmlHeading), $plainHeading);
533
-		$emailTemplate->addBodyText(htmlspecialchars($note), $note);
534
-
535
-		$link = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare',
536
-			['token' => $share->getToken()]);
537
-		$emailTemplate->addBodyButton(
538
-			$this->l->t('Open »%s«', [$filename]),
539
-			$link
540
-		);
541
-
542
-		// The "From" contains the sharers name
543
-		$instanceName = $this->defaults->getName();
544
-		$senderName = $this->l->t(
545
-			'%1$s via %2$s',
546
-			[
547
-				$initiatorDisplayName,
548
-				$instanceName
549
-			]
550
-		);
551
-		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
552
-		if ($initiatorEmailAddress !== null) {
553
-			$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
554
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
555
-		} else {
556
-			$emailTemplate->addFooter();
557
-		}
558
-
559
-		$message->setTo([$recipient]);
560
-		$message->useTemplate($emailTemplate);
561
-		$this->mailer->send($message);
562
-
563
-	}
564
-
565
-	/**
566
-	 * send auto generated password to the owner. This happens if the admin enforces
567
-	 * a password for mail shares and forbid to send the password by mail to the recipient
568
-	 *
569
-	 * @param IShare $share
570
-	 * @param string $password
571
-	 * @return bool
572
-	 * @throws \Exception
573
-	 */
574
-	protected function sendPasswordToOwner(IShare $share, $password) {
575
-
576
-		$filename = $share->getNode()->getName();
577
-		$initiator = $this->userManager->get($share->getSharedBy());
578
-		$initiatorEMailAddress = ($initiator instanceof IUser) ? $initiator->getEMailAddress() : null;
579
-		$initiatorDisplayName = ($initiator instanceof IUser) ? $initiator->getDisplayName() : $share->getSharedBy();
580
-		$shareWith = $share->getSharedWith();
581
-
582
-		if ($initiatorEMailAddress === null) {
583
-			throw new \Exception(
584
-				$this->l->t("We can't send you the auto-generated password. Please set a valid email address in your personal settings and try again.")
585
-			);
586
-		}
587
-
588
-		$bodyPart = $this->l->t("You just shared »%s« with %s. The share was already send to the recipient. Due to the security policies defined by the administrator of %s each share needs to be protected by password and it is not allowed to send the password directly to the recipient. Therefore you need to forward the password manually to the recipient.", [$filename, $shareWith, $this->defaults->getName()]);
589
-
590
-		$message = $this->mailer->createMessage();
591
-		$emailTemplate = $this->mailer->createEMailTemplate('sharebymail.OwnerPasswordNotification', [
592
-			'filename' => $filename,
593
-			'password' => $password,
594
-			'initiator' => $initiatorDisplayName,
595
-			'initiatorEmail' => $initiatorEMailAddress,
596
-			'shareWith' => $shareWith,
597
-		]);
598
-
599
-		$emailTemplate->setSubject($this->l->t('Password to access »%s« shared with %s', [$filename, $shareWith]));
600
-		$emailTemplate->addHeader();
601
-		$emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
602
-		$emailTemplate->addBodyText($bodyPart);
603
-		$emailTemplate->addBodyText($this->l->t('This is the password: %s', [$password]));
604
-		$emailTemplate->addBodyText($this->l->t('You can choose a different password at any time in the share dialog.'));
605
-		$emailTemplate->addFooter();
606
-
607
-		if ($initiatorEMailAddress) {
608
-			$message->setFrom([$initiatorEMailAddress => $initiatorDisplayName]);
609
-		}
610
-		$message->setTo([$initiatorEMailAddress => $initiatorDisplayName]);
611
-		$message->useTemplate($emailTemplate);
612
-		$this->mailer->send($message);
613
-
614
-		$this->createPasswordSendActivity($share, $shareWith, true);
615
-
616
-		return true;
617
-	}
618
-
619
-	/**
620
-	 * generate share token
621
-	 *
622
-	 * @return string
623
-	 */
624
-	protected function generateToken($size = 15) {
625
-		$token = $this->secureRandom->generate($size, ISecureRandom::CHAR_HUMAN_READABLE);
626
-		return $token;
627
-	}
628
-
629
-	/**
630
-	 * Get all children of this share
631
-	 *
632
-	 * @param IShare $parent
633
-	 * @return IShare[]
634
-	 */
635
-	public function getChildren(IShare $parent) {
636
-		$children = [];
637
-
638
-		$qb = $this->dbConnection->getQueryBuilder();
639
-		$qb->select('*')
640
-			->from('share')
641
-			->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
642
-			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
643
-			->orderBy('id');
644
-
645
-		$cursor = $qb->execute();
646
-		while($data = $cursor->fetch()) {
647
-			$children[] = $this->createShareObject($data);
648
-		}
649
-		$cursor->closeCursor();
650
-
651
-		return $children;
652
-	}
653
-
654
-	/**
655
-	 * add share to the database and return the ID
656
-	 *
657
-	 * @param int $itemSource
658
-	 * @param string $itemType
659
-	 * @param string $shareWith
660
-	 * @param string $sharedBy
661
-	 * @param string $uidOwner
662
-	 * @param int $permissions
663
-	 * @param string $token
664
-	 * @param string $password
665
-	 * @param bool $sendPasswordByTalk
666
-	 * @return int
667
-	 */
668
-	protected function addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token, $password, $sendPasswordByTalk) {
669
-		$qb = $this->dbConnection->getQueryBuilder();
670
-		$qb->insert('share')
671
-			->setValue('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))
672
-			->setValue('item_type', $qb->createNamedParameter($itemType))
673
-			->setValue('item_source', $qb->createNamedParameter($itemSource))
674
-			->setValue('file_source', $qb->createNamedParameter($itemSource))
675
-			->setValue('share_with', $qb->createNamedParameter($shareWith))
676
-			->setValue('uid_owner', $qb->createNamedParameter($uidOwner))
677
-			->setValue('uid_initiator', $qb->createNamedParameter($sharedBy))
678
-			->setValue('permissions', $qb->createNamedParameter($permissions))
679
-			->setValue('token', $qb->createNamedParameter($token))
680
-			->setValue('password', $qb->createNamedParameter($password))
681
-			->setValue('password_by_talk', $qb->createNamedParameter($sendPasswordByTalk, IQueryBuilder::PARAM_BOOL))
682
-			->setValue('stime', $qb->createNamedParameter(time()));
683
-
684
-		/*
166
+        $alreadyShared = $this->getSharedWith($shareWith, \OCP\Share::SHARE_TYPE_EMAIL, $share->getNode(), 1, 0);
167
+        if (!empty($alreadyShared)) {
168
+            $message = 'Sharing %s failed, this item is already shared with %s';
169
+            $message_t = $this->l->t('Sharing %s failed, this item is already shared with %s', array($share->getNode()->getName(), $shareWith));
170
+            $this->logger->debug(sprintf($message, $share->getNode()->getName(), $shareWith), ['app' => 'Federated File Sharing']);
171
+            throw new \Exception($message_t);
172
+        }
173
+
174
+        // if the admin enforces a password for all mail shares we create a
175
+        // random password and send it to the recipient
176
+        $password = '';
177
+        $passwordEnforced = $this->settingsManager->enforcePasswordProtection();
178
+        if ($passwordEnforced) {
179
+            $password = $this->autoGeneratePassword($share);
180
+        }
181
+
182
+        $shareId = $this->createMailShare($share);
183
+        $send = $this->sendPassword($share, $password);
184
+        if ($passwordEnforced && $send === false) {
185
+            $this->sendPasswordToOwner($share, $password);
186
+        }
187
+
188
+        $this->createShareActivity($share);
189
+        $data = $this->getRawShare($shareId);
190
+
191
+        return $this->createShareObject($data);
192
+
193
+    }
194
+
195
+    /**
196
+     * auto generate password in case of password enforcement on mail shares
197
+     *
198
+     * @param IShare $share
199
+     * @return string
200
+     * @throws \Exception
201
+     */
202
+    protected function autoGeneratePassword($share) {
203
+        $initiatorUser = $this->userManager->get($share->getSharedBy());
204
+        $initiatorEMailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
205
+        $allowPasswordByMail = $this->settingsManager->sendPasswordByMail();
206
+
207
+        if ($initiatorEMailAddress === null && !$allowPasswordByMail) {
208
+            throw new \Exception(
209
+                $this->l->t("We can't send you the auto-generated password. Please set a valid email address in your personal settings and try again.")
210
+            );
211
+        }
212
+
213
+        $passwordPolicy = $this->getPasswordPolicy();
214
+        $passwordCharset = ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS;
215
+        $passwordLength = 8;
216
+        if (!empty($passwordPolicy)) {
217
+            $passwordLength = (int)$passwordPolicy['minLength'] > 0 ? (int)$passwordPolicy['minLength'] : $passwordLength;
218
+            $passwordCharset .= $passwordPolicy['enforceSpecialCharacters'] ? ISecureRandom::CHAR_SYMBOLS : '';
219
+        }
220
+
221
+        $password = $this->secureRandom->generate($passwordLength, $passwordCharset);
222
+
223
+        $share->setPassword($this->hasher->hash($password));
224
+
225
+        return $password;
226
+    }
227
+
228
+    /**
229
+     * get password policy
230
+     *
231
+     * @return array
232
+     */
233
+    protected function getPasswordPolicy() {
234
+        $capabilities = $this->capabilitiesManager->getCapabilities();
235
+        if (isset($capabilities['password_policy'])) {
236
+            return $capabilities['password_policy'];
237
+        }
238
+
239
+        return [];
240
+    }
241
+
242
+    /**
243
+     * create activity if a file/folder was shared by mail
244
+     *
245
+     * @param IShare $share
246
+     */
247
+    protected function createShareActivity(IShare $share) {
248
+
249
+        $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
250
+
251
+        $this->publishActivity(
252
+            Activity::SUBJECT_SHARED_EMAIL_SELF,
253
+            [$userFolder->getRelativePath($share->getNode()->getPath()), $share->getSharedWith()],
254
+            $share->getSharedBy(),
255
+            $share->getNode()->getId(),
256
+            $userFolder->getRelativePath($share->getNode()->getPath())
257
+        );
258
+
259
+        if ($share->getShareOwner() !== $share->getSharedBy()) {
260
+            $ownerFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
261
+            $fileId = $share->getNode()->getId();
262
+            $nodes = $ownerFolder->getById($fileId);
263
+            $ownerPath = $nodes[0]->getPath();
264
+            $this->publishActivity(
265
+                Activity::SUBJECT_SHARED_EMAIL_BY,
266
+                [$ownerFolder->getRelativePath($ownerPath), $share->getSharedWith(), $share->getSharedBy()],
267
+                $share->getShareOwner(),
268
+                $fileId,
269
+                $ownerFolder->getRelativePath($ownerPath)
270
+            );
271
+        }
272
+
273
+    }
274
+
275
+    /**
276
+     * create activity if a file/folder was shared by mail
277
+     *
278
+     * @param IShare $share
279
+     * @param string $sharedWith
280
+     * @param bool $sendToSelf
281
+     */
282
+    protected function createPasswordSendActivity(IShare $share, $sharedWith, $sendToSelf) {
283
+
284
+        $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
285
+
286
+        if ($sendToSelf) {
287
+            $this->publishActivity(
288
+                Activity::SUBJECT_SHARED_EMAIL_PASSWORD_SEND_SELF,
289
+                [$userFolder->getRelativePath($share->getNode()->getPath())],
290
+                $share->getSharedBy(),
291
+                $share->getNode()->getId(),
292
+                $userFolder->getRelativePath($share->getNode()->getPath())
293
+            );
294
+        } else {
295
+            $this->publishActivity(
296
+                Activity::SUBJECT_SHARED_EMAIL_PASSWORD_SEND,
297
+                [$userFolder->getRelativePath($share->getNode()->getPath()), $sharedWith],
298
+                $share->getSharedBy(),
299
+                $share->getNode()->getId(),
300
+                $userFolder->getRelativePath($share->getNode()->getPath())
301
+            );
302
+        }
303
+    }
304
+
305
+
306
+    /**
307
+     * publish activity if a file/folder was shared by mail
308
+     *
309
+     * @param $subject
310
+     * @param $parameters
311
+     * @param $affectedUser
312
+     * @param $fileId
313
+     * @param $filePath
314
+     */
315
+    protected function publishActivity($subject, $parameters, $affectedUser, $fileId, $filePath) {
316
+        $event = $this->activityManager->generateEvent();
317
+        $event->setApp('sharebymail')
318
+            ->setType('shared')
319
+            ->setSubject($subject, $parameters)
320
+            ->setAffectedUser($affectedUser)
321
+            ->setObject('files', $fileId, $filePath);
322
+        $this->activityManager->publish($event);
323
+
324
+    }
325
+
326
+    /**
327
+     * @param IShare $share
328
+     * @return int
329
+     * @throws \Exception
330
+     */
331
+    protected function createMailShare(IShare $share) {
332
+        $share->setToken($this->generateToken());
333
+        $shareId = $this->addShareToDB(
334
+            $share->getNodeId(),
335
+            $share->getNodeType(),
336
+            $share->getSharedWith(),
337
+            $share->getSharedBy(),
338
+            $share->getShareOwner(),
339
+            $share->getPermissions(),
340
+            $share->getToken(),
341
+            $share->getPassword(),
342
+            $share->getSendPasswordByTalk()
343
+        );
344
+
345
+        try {
346
+            $link = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare',
347
+                ['token' => $share->getToken()]);
348
+            $this->sendMailNotification(
349
+                $share->getNode()->getName(),
350
+                $link,
351
+                $share->getSharedBy(),
352
+                $share->getSharedWith(),
353
+                $share->getExpirationDate()
354
+            );
355
+        } catch (HintException $hintException) {
356
+            $this->logger->logException($hintException, [
357
+                'message' => 'Failed to send share by mail.',
358
+                'level' => ILogger::ERROR,
359
+                'app' => 'sharebymail',
360
+            ]);
361
+            $this->removeShareFromTable($shareId);
362
+            throw $hintException;
363
+        } catch (\Exception $e) {
364
+            $this->logger->logException($e, [
365
+                'message' => 'Failed to send share by mail.',
366
+                'level' => ILogger::ERROR,
367
+                'app' => 'sharebymail',
368
+            ]);
369
+            $this->removeShareFromTable($shareId);
370
+            throw new HintException('Failed to send share by mail',
371
+                $this->l->t('Failed to send share by email'));
372
+        }
373
+
374
+        return $shareId;
375
+
376
+    }
377
+
378
+    /**
379
+     * @param string $filename
380
+     * @param string $link
381
+     * @param string $initiator
382
+     * @param string $shareWith
383
+     * @param \DateTime|null $expiration
384
+     * @throws \Exception If mail couldn't be sent
385
+     */
386
+    protected function sendMailNotification($filename,
387
+                                            $link,
388
+                                            $initiator,
389
+                                            $shareWith,
390
+                                            \DateTime $expiration = null) {
391
+        $initiatorUser = $this->userManager->get($initiator);
392
+        $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
393
+        $message = $this->mailer->createMessage();
394
+
395
+        $emailTemplate = $this->mailer->createEMailTemplate('sharebymail.RecipientNotification', [
396
+            'filename' => $filename,
397
+            'link' => $link,
398
+            'initiator' => $initiatorDisplayName,
399
+            'expiration' => $expiration,
400
+            'shareWith' => $shareWith,
401
+        ]);
402
+
403
+        $emailTemplate->setSubject($this->l->t('%s shared »%s« with you', array($initiatorDisplayName, $filename)));
404
+        $emailTemplate->addHeader();
405
+        $emailTemplate->addHeading($this->l->t('%s shared »%s« with you', [$initiatorDisplayName, $filename]), false);
406
+        $text = $this->l->t('%s shared »%s« with you.', [$initiatorDisplayName, $filename]);
407
+
408
+        $emailTemplate->addBodyText(
409
+            htmlspecialchars($text . ' ' . $this->l->t('Click the button below to open it.')),
410
+            $text
411
+        );
412
+        $emailTemplate->addBodyButton(
413
+            $this->l->t('Open »%s«', [$filename]),
414
+            $link
415
+        );
416
+
417
+        $message->setTo([$shareWith]);
418
+
419
+        // The "From" contains the sharers name
420
+        $instanceName = $this->defaults->getName();
421
+        $senderName = $this->l->t(
422
+            '%s via %s',
423
+            [
424
+                $initiatorDisplayName,
425
+                $instanceName
426
+            ]
427
+        );
428
+        $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
429
+
430
+        // The "Reply-To" is set to the sharer if an mail address is configured
431
+        // also the default footer contains a "Do not reply" which needs to be adjusted.
432
+        $initiatorEmail = $initiatorUser->getEMailAddress();
433
+        if($initiatorEmail !== null) {
434
+            $message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
435
+            $emailTemplate->addFooter($instanceName . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : ''));
436
+        } else {
437
+            $emailTemplate->addFooter();
438
+        }
439
+
440
+        $message->useTemplate($emailTemplate);
441
+        $this->mailer->send($message);
442
+    }
443
+
444
+    /**
445
+     * send password to recipient of a mail share
446
+     *
447
+     * @param IShare $share
448
+     * @param string $password
449
+     * @return bool
450
+     */
451
+    protected function sendPassword(IShare $share, $password) {
452
+
453
+        $filename = $share->getNode()->getName();
454
+        $initiator = $share->getSharedBy();
455
+        $shareWith = $share->getSharedWith();
456
+
457
+        if ($password === '' || $this->settingsManager->sendPasswordByMail() === false || $share->getSendPasswordByTalk()) {
458
+            return false;
459
+        }
460
+
461
+        $initiatorUser = $this->userManager->get($initiator);
462
+        $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
463
+        $initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
464
+
465
+        $plainBodyPart = $this->l->t("%s shared »%s« with you.\nYou should have already received a separate mail with a link to access it.\n", [$initiatorDisplayName, $filename]);
466
+        $htmlBodyPart = $this->l->t('%s shared »%s« with you. You should have already received a separate mail with a link to access it.', [$initiatorDisplayName, $filename]);
467
+
468
+        $message = $this->mailer->createMessage();
469
+
470
+        $emailTemplate = $this->mailer->createEMailTemplate('sharebymail.RecipientPasswordNotification', [
471
+            'filename' => $filename,
472
+            'password' => $password,
473
+            'initiator' => $initiatorDisplayName,
474
+            'initiatorEmail' => $initiatorEmailAddress,
475
+            'shareWith' => $shareWith,
476
+        ]);
477
+
478
+        $emailTemplate->setSubject($this->l->t('Password to access »%s« shared to you by %s', [$filename, $initiatorDisplayName]));
479
+        $emailTemplate->addHeader();
480
+        $emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
481
+        $emailTemplate->addBodyText(htmlspecialchars($htmlBodyPart), $plainBodyPart);
482
+        $emailTemplate->addBodyText($this->l->t('It is protected with the following password: %s', [$password]));
483
+
484
+        // The "From" contains the sharers name
485
+        $instanceName = $this->defaults->getName();
486
+        $senderName = $this->l->t(
487
+            '%s via %s',
488
+            [
489
+                $initiatorDisplayName,
490
+                $instanceName
491
+            ]
492
+        );
493
+        $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
494
+        if ($initiatorEmailAddress !== null) {
495
+            $message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
496
+            $emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
497
+        } else {
498
+            $emailTemplate->addFooter();
499
+        }
500
+
501
+        $message->setTo([$shareWith]);
502
+        $message->useTemplate($emailTemplate);
503
+        $this->mailer->send($message);
504
+
505
+        $this->createPasswordSendActivity($share, $shareWith, false);
506
+
507
+        return true;
508
+    }
509
+
510
+    protected function sendNote(IShare $share) {
511
+
512
+        $recipient = $share->getSharedWith();
513
+
514
+
515
+        $filename = $share->getNode()->getName();
516
+        $initiator = $share->getSharedBy();
517
+        $note = $share->getNote();
518
+
519
+        $initiatorUser = $this->userManager->get($initiator);
520
+        $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
521
+        $initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
522
+
523
+        $plainHeading = $this->l->t('%1$s shared »%2$s« with you and wants to add:', [$initiatorDisplayName, $filename]);
524
+        $htmlHeading = $this->l->t('%1$s shared »%2$s« with you and wants to add', [$initiatorDisplayName, $filename]);
525
+
526
+        $message = $this->mailer->createMessage();
527
+
528
+        $emailTemplate = $this->mailer->createEMailTemplate('shareByMail.sendNote');
529
+
530
+        $emailTemplate->setSubject($this->l->t('»%s« added a note to a file shared with you', [$initiatorDisplayName]));
531
+        $emailTemplate->addHeader();
532
+        $emailTemplate->addHeading(htmlspecialchars($htmlHeading), $plainHeading);
533
+        $emailTemplate->addBodyText(htmlspecialchars($note), $note);
534
+
535
+        $link = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare',
536
+            ['token' => $share->getToken()]);
537
+        $emailTemplate->addBodyButton(
538
+            $this->l->t('Open »%s«', [$filename]),
539
+            $link
540
+        );
541
+
542
+        // The "From" contains the sharers name
543
+        $instanceName = $this->defaults->getName();
544
+        $senderName = $this->l->t(
545
+            '%1$s via %2$s',
546
+            [
547
+                $initiatorDisplayName,
548
+                $instanceName
549
+            ]
550
+        );
551
+        $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
552
+        if ($initiatorEmailAddress !== null) {
553
+            $message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
554
+            $emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
555
+        } else {
556
+            $emailTemplate->addFooter();
557
+        }
558
+
559
+        $message->setTo([$recipient]);
560
+        $message->useTemplate($emailTemplate);
561
+        $this->mailer->send($message);
562
+
563
+    }
564
+
565
+    /**
566
+     * send auto generated password to the owner. This happens if the admin enforces
567
+     * a password for mail shares and forbid to send the password by mail to the recipient
568
+     *
569
+     * @param IShare $share
570
+     * @param string $password
571
+     * @return bool
572
+     * @throws \Exception
573
+     */
574
+    protected function sendPasswordToOwner(IShare $share, $password) {
575
+
576
+        $filename = $share->getNode()->getName();
577
+        $initiator = $this->userManager->get($share->getSharedBy());
578
+        $initiatorEMailAddress = ($initiator instanceof IUser) ? $initiator->getEMailAddress() : null;
579
+        $initiatorDisplayName = ($initiator instanceof IUser) ? $initiator->getDisplayName() : $share->getSharedBy();
580
+        $shareWith = $share->getSharedWith();
581
+
582
+        if ($initiatorEMailAddress === null) {
583
+            throw new \Exception(
584
+                $this->l->t("We can't send you the auto-generated password. Please set a valid email address in your personal settings and try again.")
585
+            );
586
+        }
587
+
588
+        $bodyPart = $this->l->t("You just shared »%s« with %s. The share was already send to the recipient. Due to the security policies defined by the administrator of %s each share needs to be protected by password and it is not allowed to send the password directly to the recipient. Therefore you need to forward the password manually to the recipient.", [$filename, $shareWith, $this->defaults->getName()]);
589
+
590
+        $message = $this->mailer->createMessage();
591
+        $emailTemplate = $this->mailer->createEMailTemplate('sharebymail.OwnerPasswordNotification', [
592
+            'filename' => $filename,
593
+            'password' => $password,
594
+            'initiator' => $initiatorDisplayName,
595
+            'initiatorEmail' => $initiatorEMailAddress,
596
+            'shareWith' => $shareWith,
597
+        ]);
598
+
599
+        $emailTemplate->setSubject($this->l->t('Password to access »%s« shared with %s', [$filename, $shareWith]));
600
+        $emailTemplate->addHeader();
601
+        $emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
602
+        $emailTemplate->addBodyText($bodyPart);
603
+        $emailTemplate->addBodyText($this->l->t('This is the password: %s', [$password]));
604
+        $emailTemplate->addBodyText($this->l->t('You can choose a different password at any time in the share dialog.'));
605
+        $emailTemplate->addFooter();
606
+
607
+        if ($initiatorEMailAddress) {
608
+            $message->setFrom([$initiatorEMailAddress => $initiatorDisplayName]);
609
+        }
610
+        $message->setTo([$initiatorEMailAddress => $initiatorDisplayName]);
611
+        $message->useTemplate($emailTemplate);
612
+        $this->mailer->send($message);
613
+
614
+        $this->createPasswordSendActivity($share, $shareWith, true);
615
+
616
+        return true;
617
+    }
618
+
619
+    /**
620
+     * generate share token
621
+     *
622
+     * @return string
623
+     */
624
+    protected function generateToken($size = 15) {
625
+        $token = $this->secureRandom->generate($size, ISecureRandom::CHAR_HUMAN_READABLE);
626
+        return $token;
627
+    }
628
+
629
+    /**
630
+     * Get all children of this share
631
+     *
632
+     * @param IShare $parent
633
+     * @return IShare[]
634
+     */
635
+    public function getChildren(IShare $parent) {
636
+        $children = [];
637
+
638
+        $qb = $this->dbConnection->getQueryBuilder();
639
+        $qb->select('*')
640
+            ->from('share')
641
+            ->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
642
+            ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
643
+            ->orderBy('id');
644
+
645
+        $cursor = $qb->execute();
646
+        while($data = $cursor->fetch()) {
647
+            $children[] = $this->createShareObject($data);
648
+        }
649
+        $cursor->closeCursor();
650
+
651
+        return $children;
652
+    }
653
+
654
+    /**
655
+     * add share to the database and return the ID
656
+     *
657
+     * @param int $itemSource
658
+     * @param string $itemType
659
+     * @param string $shareWith
660
+     * @param string $sharedBy
661
+     * @param string $uidOwner
662
+     * @param int $permissions
663
+     * @param string $token
664
+     * @param string $password
665
+     * @param bool $sendPasswordByTalk
666
+     * @return int
667
+     */
668
+    protected function addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token, $password, $sendPasswordByTalk) {
669
+        $qb = $this->dbConnection->getQueryBuilder();
670
+        $qb->insert('share')
671
+            ->setValue('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))
672
+            ->setValue('item_type', $qb->createNamedParameter($itemType))
673
+            ->setValue('item_source', $qb->createNamedParameter($itemSource))
674
+            ->setValue('file_source', $qb->createNamedParameter($itemSource))
675
+            ->setValue('share_with', $qb->createNamedParameter($shareWith))
676
+            ->setValue('uid_owner', $qb->createNamedParameter($uidOwner))
677
+            ->setValue('uid_initiator', $qb->createNamedParameter($sharedBy))
678
+            ->setValue('permissions', $qb->createNamedParameter($permissions))
679
+            ->setValue('token', $qb->createNamedParameter($token))
680
+            ->setValue('password', $qb->createNamedParameter($password))
681
+            ->setValue('password_by_talk', $qb->createNamedParameter($sendPasswordByTalk, IQueryBuilder::PARAM_BOOL))
682
+            ->setValue('stime', $qb->createNamedParameter(time()));
683
+
684
+        /*
685 685
 		 * Added to fix https://github.com/owncloud/core/issues/22215
686 686
 		 * Can be removed once we get rid of ajax/share.php
687 687
 		 */
688
-		$qb->setValue('file_target', $qb->createNamedParameter(''));
688
+        $qb->setValue('file_target', $qb->createNamedParameter(''));
689 689
 
690
-		$qb->execute();
691
-		$id = $qb->getLastInsertId();
690
+        $qb->execute();
691
+        $id = $qb->getLastInsertId();
692 692
 
693
-		return (int)$id;
694
-	}
693
+        return (int)$id;
694
+    }
695 695
 
696
-	/**
697
-	 * Update a share
698
-	 *
699
-	 * @param IShare $share
700
-	 * @param string|null $plainTextPassword
701
-	 * @return IShare The share object
702
-	 */
703
-	public function update(IShare $share, $plainTextPassword = null) {
696
+    /**
697
+     * Update a share
698
+     *
699
+     * @param IShare $share
700
+     * @param string|null $plainTextPassword
701
+     * @return IShare The share object
702
+     */
703
+    public function update(IShare $share, $plainTextPassword = null) {
704 704
 
705
-		$originalShare = $this->getShareById($share->getId());
705
+        $originalShare = $this->getShareById($share->getId());
706 706
 
707
-		// a real password was given
708
-		$validPassword = $plainTextPassword !== null && $plainTextPassword !== '';
707
+        // a real password was given
708
+        $validPassword = $plainTextPassword !== null && $plainTextPassword !== '';
709 709
 
710
-		if($validPassword && ($originalShare->getPassword() !== $share->getPassword() ||
711
-								($originalShare->getSendPasswordByTalk() && !$share->getSendPasswordByTalk()))) {
712
-			$this->sendPassword($share, $plainTextPassword);
713
-		}
714
-		/*
710
+        if($validPassword && ($originalShare->getPassword() !== $share->getPassword() ||
711
+                                ($originalShare->getSendPasswordByTalk() && !$share->getSendPasswordByTalk()))) {
712
+            $this->sendPassword($share, $plainTextPassword);
713
+        }
714
+        /*
715 715
 		 * We allow updating the permissions and password of mail shares
716 716
 		 */
717
-		$qb = $this->dbConnection->getQueryBuilder();
718
-		$qb->update('share')
719
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
720
-			->set('permissions', $qb->createNamedParameter($share->getPermissions()))
721
-			->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
722
-			->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
723
-			->set('password', $qb->createNamedParameter($share->getPassword()))
724
-			->set('password_by_talk', $qb->createNamedParameter($share->getSendPasswordByTalk(), IQueryBuilder::PARAM_BOOL))
725
-			->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
726
-			->set('note', $qb->createNamedParameter($share->getNote()))
727
-			->execute();
728
-
729
-		if ($originalShare->getNote() !== $share->getNote() && $share->getNote() !== '') {
730
-			$this->sendNote($share);
731
-		}
732
-
733
-		return $share;
734
-	}
735
-
736
-	/**
737
-	 * @inheritdoc
738
-	 */
739
-	public function move(IShare $share, $recipient) {
740
-		/**
741
-		 * nothing to do here, mail shares are only outgoing shares
742
-		 */
743
-		return $share;
744
-	}
745
-
746
-	/**
747
-	 * Delete a share (owner unShares the file)
748
-	 *
749
-	 * @param IShare $share
750
-	 */
751
-	public function delete(IShare $share) {
752
-		$this->removeShareFromTable($share->getId());
753
-	}
754
-
755
-	/**
756
-	 * @inheritdoc
757
-	 */
758
-	public function deleteFromSelf(IShare $share, $recipient) {
759
-		// nothing to do here, mail shares are only outgoing shares
760
-	}
761
-
762
-	public function restore(IShare $share, string $recipient): IShare {
763
-		throw new GenericShareException('not implemented');
764
-	}
765
-
766
-	/**
767
-	 * @inheritdoc
768
-	 */
769
-	public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
770
-		$qb = $this->dbConnection->getQueryBuilder();
771
-		$qb->select('*')
772
-			->from('share');
773
-
774
-		$qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
775
-
776
-		/**
777
-		 * Reshares for this user are shares where they are the owner.
778
-		 */
779
-		if ($reshares === false) {
780
-			//Special case for old shares created via the web UI
781
-			$or1 = $qb->expr()->andX(
782
-				$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
783
-				$qb->expr()->isNull('uid_initiator')
784
-			);
785
-
786
-			$qb->andWhere(
787
-				$qb->expr()->orX(
788
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)),
789
-					$or1
790
-				)
791
-			);
792
-		} else {
793
-			$qb->andWhere(
794
-				$qb->expr()->orX(
795
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
796
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
797
-				)
798
-			);
799
-		}
800
-
801
-		if ($node !== null) {
802
-			$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
803
-		}
804
-
805
-		if ($limit !== -1) {
806
-			$qb->setMaxResults($limit);
807
-		}
808
-
809
-		$qb->setFirstResult($offset);
810
-		$qb->orderBy('id');
811
-
812
-		$cursor = $qb->execute();
813
-		$shares = [];
814
-		while($data = $cursor->fetch()) {
815
-			$shares[] = $this->createShareObject($data);
816
-		}
817
-		$cursor->closeCursor();
818
-
819
-		return $shares;
820
-	}
821
-
822
-	/**
823
-	 * @inheritdoc
824
-	 */
825
-	public function getShareById($id, $recipientId = null) {
826
-		$qb = $this->dbConnection->getQueryBuilder();
827
-
828
-		$qb->select('*')
829
-			->from('share')
830
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
831
-			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
832
-
833
-		$cursor = $qb->execute();
834
-		$data = $cursor->fetch();
835
-		$cursor->closeCursor();
836
-
837
-		if ($data === false) {
838
-			throw new ShareNotFound();
839
-		}
840
-
841
-		try {
842
-			$share = $this->createShareObject($data);
843
-		} catch (InvalidShare $e) {
844
-			throw new ShareNotFound();
845
-		}
846
-
847
-		return $share;
848
-	}
849
-
850
-	/**
851
-	 * Get shares for a given path
852
-	 *
853
-	 * @param \OCP\Files\Node $path
854
-	 * @return IShare[]
855
-	 */
856
-	public function getSharesByPath(Node $path) {
857
-		$qb = $this->dbConnection->getQueryBuilder();
858
-
859
-		$cursor = $qb->select('*')
860
-			->from('share')
861
-			->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
862
-			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
863
-			->execute();
864
-
865
-		$shares = [];
866
-		while($data = $cursor->fetch()) {
867
-			$shares[] = $this->createShareObject($data);
868
-		}
869
-		$cursor->closeCursor();
870
-
871
-		return $shares;
872
-	}
873
-
874
-	/**
875
-	 * @inheritdoc
876
-	 */
877
-	public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
878
-		/** @var IShare[] $shares */
879
-		$shares = [];
880
-
881
-		//Get shares directly with this user
882
-		$qb = $this->dbConnection->getQueryBuilder();
883
-		$qb->select('*')
884
-			->from('share');
885
-
886
-		// Order by id
887
-		$qb->orderBy('id');
888
-
889
-		// Set limit and offset
890
-		if ($limit !== -1) {
891
-			$qb->setMaxResults($limit);
892
-		}
893
-		$qb->setFirstResult($offset);
894
-
895
-		$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
896
-		$qb->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)));
897
-
898
-		// Filter by node if provided
899
-		if ($node !== null) {
900
-			$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
901
-		}
902
-
903
-		$cursor = $qb->execute();
904
-
905
-		while($data = $cursor->fetch()) {
906
-			$shares[] = $this->createShareObject($data);
907
-		}
908
-		$cursor->closeCursor();
909
-
910
-
911
-		return $shares;
912
-	}
913
-
914
-	/**
915
-	 * Get a share by token
916
-	 *
917
-	 * @param string $token
918
-	 * @return IShare
919
-	 * @throws ShareNotFound
920
-	 */
921
-	public function getShareByToken($token) {
922
-		$qb = $this->dbConnection->getQueryBuilder();
923
-
924
-		$cursor = $qb->select('*')
925
-			->from('share')
926
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
927
-			->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
928
-			->execute();
929
-
930
-		$data = $cursor->fetch();
931
-
932
-		if ($data === false) {
933
-			throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
934
-		}
935
-
936
-		try {
937
-			$share = $this->createShareObject($data);
938
-		} catch (InvalidShare $e) {
939
-			throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
940
-		}
941
-
942
-		return $share;
943
-	}
944
-
945
-	/**
946
-	 * remove share from table
947
-	 *
948
-	 * @param string $shareId
949
-	 */
950
-	protected function removeShareFromTable($shareId) {
951
-		$qb = $this->dbConnection->getQueryBuilder();
952
-		$qb->delete('share')
953
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($shareId)));
954
-		$qb->execute();
955
-	}
956
-
957
-	/**
958
-	 * Create a share object from an database row
959
-	 *
960
-	 * @param array $data
961
-	 * @return IShare
962
-	 * @throws InvalidShare
963
-	 * @throws ShareNotFound
964
-	 */
965
-	protected function createShareObject($data) {
966
-
967
-		$share = new Share($this->rootFolder, $this->userManager);
968
-		$share->setId((int)$data['id'])
969
-			->setShareType((int)$data['share_type'])
970
-			->setPermissions((int)$data['permissions'])
971
-			->setTarget($data['file_target'])
972
-			->setMailSend((bool)$data['mail_send'])
973
-			->setNote($data['note'])
974
-			->setToken($data['token']);
975
-
976
-		$shareTime = new \DateTime();
977
-		$shareTime->setTimestamp((int)$data['stime']);
978
-		$share->setShareTime($shareTime);
979
-		$share->setSharedWith($data['share_with']);
980
-		$share->setPassword($data['password']);
981
-		$share->setSendPasswordByTalk($data['password_by_talk']);
982
-
983
-		if ($data['uid_initiator'] !== null) {
984
-			$share->setShareOwner($data['uid_owner']);
985
-			$share->setSharedBy($data['uid_initiator']);
986
-		} else {
987
-			//OLD SHARE
988
-			$share->setSharedBy($data['uid_owner']);
989
-			$path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
990
-
991
-			$owner = $path->getOwner();
992
-			$share->setShareOwner($owner->getUID());
993
-		}
994
-
995
-		if ($data['expiration'] !== null) {
996
-			$expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']);
997
-			if ($expiration !== false) {
998
-				$share->setExpirationDate($expiration);
999
-			}
1000
-		}
1001
-
1002
-		$share->setNodeId((int)$data['file_source']);
1003
-		$share->setNodeType($data['item_type']);
1004
-
1005
-		$share->setProviderId($this->identifier());
1006
-
1007
-		return $share;
1008
-	}
1009
-
1010
-	/**
1011
-	 * Get the node with file $id for $user
1012
-	 *
1013
-	 * @param string $userId
1014
-	 * @param int $id
1015
-	 * @return \OCP\Files\File|\OCP\Files\Folder
1016
-	 * @throws InvalidShare
1017
-	 */
1018
-	private function getNode($userId, $id) {
1019
-		try {
1020
-			$userFolder = $this->rootFolder->getUserFolder($userId);
1021
-		} catch (NoUserException $e) {
1022
-			throw new InvalidShare();
1023
-		}
1024
-
1025
-		$nodes = $userFolder->getById($id);
1026
-
1027
-		if (empty($nodes)) {
1028
-			throw new InvalidShare();
1029
-		}
1030
-
1031
-		return $nodes[0];
1032
-	}
1033
-
1034
-	/**
1035
-	 * A user is deleted from the system
1036
-	 * So clean up the relevant shares.
1037
-	 *
1038
-	 * @param string $uid
1039
-	 * @param int $shareType
1040
-	 */
1041
-	public function userDeleted($uid, $shareType) {
1042
-		$qb = $this->dbConnection->getQueryBuilder();
1043
-
1044
-		$qb->delete('share')
1045
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
1046
-			->andWhere($qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)))
1047
-			->execute();
1048
-	}
1049
-
1050
-	/**
1051
-	 * This provider does not support group shares
1052
-	 *
1053
-	 * @param string $gid
1054
-	 */
1055
-	public function groupDeleted($gid) {
1056
-	}
1057
-
1058
-	/**
1059
-	 * This provider does not support group shares
1060
-	 *
1061
-	 * @param string $uid
1062
-	 * @param string $gid
1063
-	 */
1064
-	public function userDeletedFromGroup($uid, $gid) {
1065
-	}
1066
-
1067
-	/**
1068
-	 * get database row of a give share
1069
-	 *
1070
-	 * @param $id
1071
-	 * @return array
1072
-	 * @throws ShareNotFound
1073
-	 */
1074
-	protected function getRawShare($id) {
1075
-
1076
-		// Now fetch the inserted share and create a complete share object
1077
-		$qb = $this->dbConnection->getQueryBuilder();
1078
-		$qb->select('*')
1079
-			->from('share')
1080
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
1081
-
1082
-		$cursor = $qb->execute();
1083
-		$data = $cursor->fetch();
1084
-		$cursor->closeCursor();
1085
-
1086
-		if ($data === false) {
1087
-			throw new ShareNotFound;
1088
-		}
1089
-
1090
-		return $data;
1091
-	}
1092
-
1093
-	public function getSharesInFolder($userId, Folder $node, $reshares) {
1094
-		$qb = $this->dbConnection->getQueryBuilder();
1095
-		$qb->select('*')
1096
-			->from('share', 's')
1097
-			->andWhere($qb->expr()->orX(
1098
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1099
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1100
-			))
1101
-			->andWhere(
1102
-				$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))
1103
-			);
1104
-
1105
-		/**
1106
-		 * Reshares for this user are shares where they are the owner.
1107
-		 */
1108
-		if ($reshares === false) {
1109
-			$qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
1110
-		} else {
1111
-			$qb->andWhere(
1112
-				$qb->expr()->orX(
1113
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
1114
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
1115
-				)
1116
-			);
1117
-		}
1118
-
1119
-		$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1120
-		$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
1121
-
1122
-		$qb->orderBy('id');
1123
-
1124
-		$cursor = $qb->execute();
1125
-		$shares = [];
1126
-		while ($data = $cursor->fetch()) {
1127
-			$shares[$data['fileid']][] = $this->createShareObject($data);
1128
-		}
1129
-		$cursor->closeCursor();
1130
-
1131
-		return $shares;
1132
-	}
1133
-
1134
-	/**
1135
-	 * @inheritdoc
1136
-	 */
1137
-	public function getAccessList($nodes, $currentAccess) {
1138
-		$ids = [];
1139
-		foreach ($nodes as $node) {
1140
-			$ids[] = $node->getId();
1141
-		}
1142
-
1143
-		$qb = $this->dbConnection->getQueryBuilder();
1144
-		$qb->select('share_with')
1145
-			->from('share')
1146
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
1147
-			->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1148
-			->andWhere($qb->expr()->orX(
1149
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1150
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1151
-			))
1152
-			->setMaxResults(1);
1153
-		$cursor = $qb->execute();
1154
-
1155
-		$mail = $cursor->fetch() !== false;
1156
-		$cursor->closeCursor();
1157
-
1158
-		return ['public' => $mail];
1159
-	}
717
+        $qb = $this->dbConnection->getQueryBuilder();
718
+        $qb->update('share')
719
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
720
+            ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
721
+            ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
722
+            ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
723
+            ->set('password', $qb->createNamedParameter($share->getPassword()))
724
+            ->set('password_by_talk', $qb->createNamedParameter($share->getSendPasswordByTalk(), IQueryBuilder::PARAM_BOOL))
725
+            ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
726
+            ->set('note', $qb->createNamedParameter($share->getNote()))
727
+            ->execute();
728
+
729
+        if ($originalShare->getNote() !== $share->getNote() && $share->getNote() !== '') {
730
+            $this->sendNote($share);
731
+        }
732
+
733
+        return $share;
734
+    }
735
+
736
+    /**
737
+     * @inheritdoc
738
+     */
739
+    public function move(IShare $share, $recipient) {
740
+        /**
741
+         * nothing to do here, mail shares are only outgoing shares
742
+         */
743
+        return $share;
744
+    }
745
+
746
+    /**
747
+     * Delete a share (owner unShares the file)
748
+     *
749
+     * @param IShare $share
750
+     */
751
+    public function delete(IShare $share) {
752
+        $this->removeShareFromTable($share->getId());
753
+    }
754
+
755
+    /**
756
+     * @inheritdoc
757
+     */
758
+    public function deleteFromSelf(IShare $share, $recipient) {
759
+        // nothing to do here, mail shares are only outgoing shares
760
+    }
761
+
762
+    public function restore(IShare $share, string $recipient): IShare {
763
+        throw new GenericShareException('not implemented');
764
+    }
765
+
766
+    /**
767
+     * @inheritdoc
768
+     */
769
+    public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
770
+        $qb = $this->dbConnection->getQueryBuilder();
771
+        $qb->select('*')
772
+            ->from('share');
773
+
774
+        $qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
775
+
776
+        /**
777
+         * Reshares for this user are shares where they are the owner.
778
+         */
779
+        if ($reshares === false) {
780
+            //Special case for old shares created via the web UI
781
+            $or1 = $qb->expr()->andX(
782
+                $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
783
+                $qb->expr()->isNull('uid_initiator')
784
+            );
785
+
786
+            $qb->andWhere(
787
+                $qb->expr()->orX(
788
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)),
789
+                    $or1
790
+                )
791
+            );
792
+        } else {
793
+            $qb->andWhere(
794
+                $qb->expr()->orX(
795
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
796
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
797
+                )
798
+            );
799
+        }
800
+
801
+        if ($node !== null) {
802
+            $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
803
+        }
804
+
805
+        if ($limit !== -1) {
806
+            $qb->setMaxResults($limit);
807
+        }
808
+
809
+        $qb->setFirstResult($offset);
810
+        $qb->orderBy('id');
811
+
812
+        $cursor = $qb->execute();
813
+        $shares = [];
814
+        while($data = $cursor->fetch()) {
815
+            $shares[] = $this->createShareObject($data);
816
+        }
817
+        $cursor->closeCursor();
818
+
819
+        return $shares;
820
+    }
821
+
822
+    /**
823
+     * @inheritdoc
824
+     */
825
+    public function getShareById($id, $recipientId = null) {
826
+        $qb = $this->dbConnection->getQueryBuilder();
827
+
828
+        $qb->select('*')
829
+            ->from('share')
830
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
831
+            ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
832
+
833
+        $cursor = $qb->execute();
834
+        $data = $cursor->fetch();
835
+        $cursor->closeCursor();
836
+
837
+        if ($data === false) {
838
+            throw new ShareNotFound();
839
+        }
840
+
841
+        try {
842
+            $share = $this->createShareObject($data);
843
+        } catch (InvalidShare $e) {
844
+            throw new ShareNotFound();
845
+        }
846
+
847
+        return $share;
848
+    }
849
+
850
+    /**
851
+     * Get shares for a given path
852
+     *
853
+     * @param \OCP\Files\Node $path
854
+     * @return IShare[]
855
+     */
856
+    public function getSharesByPath(Node $path) {
857
+        $qb = $this->dbConnection->getQueryBuilder();
858
+
859
+        $cursor = $qb->select('*')
860
+            ->from('share')
861
+            ->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
862
+            ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
863
+            ->execute();
864
+
865
+        $shares = [];
866
+        while($data = $cursor->fetch()) {
867
+            $shares[] = $this->createShareObject($data);
868
+        }
869
+        $cursor->closeCursor();
870
+
871
+        return $shares;
872
+    }
873
+
874
+    /**
875
+     * @inheritdoc
876
+     */
877
+    public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
878
+        /** @var IShare[] $shares */
879
+        $shares = [];
880
+
881
+        //Get shares directly with this user
882
+        $qb = $this->dbConnection->getQueryBuilder();
883
+        $qb->select('*')
884
+            ->from('share');
885
+
886
+        // Order by id
887
+        $qb->orderBy('id');
888
+
889
+        // Set limit and offset
890
+        if ($limit !== -1) {
891
+            $qb->setMaxResults($limit);
892
+        }
893
+        $qb->setFirstResult($offset);
894
+
895
+        $qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
896
+        $qb->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)));
897
+
898
+        // Filter by node if provided
899
+        if ($node !== null) {
900
+            $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
901
+        }
902
+
903
+        $cursor = $qb->execute();
904
+
905
+        while($data = $cursor->fetch()) {
906
+            $shares[] = $this->createShareObject($data);
907
+        }
908
+        $cursor->closeCursor();
909
+
910
+
911
+        return $shares;
912
+    }
913
+
914
+    /**
915
+     * Get a share by token
916
+     *
917
+     * @param string $token
918
+     * @return IShare
919
+     * @throws ShareNotFound
920
+     */
921
+    public function getShareByToken($token) {
922
+        $qb = $this->dbConnection->getQueryBuilder();
923
+
924
+        $cursor = $qb->select('*')
925
+            ->from('share')
926
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
927
+            ->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
928
+            ->execute();
929
+
930
+        $data = $cursor->fetch();
931
+
932
+        if ($data === false) {
933
+            throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
934
+        }
935
+
936
+        try {
937
+            $share = $this->createShareObject($data);
938
+        } catch (InvalidShare $e) {
939
+            throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
940
+        }
941
+
942
+        return $share;
943
+    }
944
+
945
+    /**
946
+     * remove share from table
947
+     *
948
+     * @param string $shareId
949
+     */
950
+    protected function removeShareFromTable($shareId) {
951
+        $qb = $this->dbConnection->getQueryBuilder();
952
+        $qb->delete('share')
953
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($shareId)));
954
+        $qb->execute();
955
+    }
956
+
957
+    /**
958
+     * Create a share object from an database row
959
+     *
960
+     * @param array $data
961
+     * @return IShare
962
+     * @throws InvalidShare
963
+     * @throws ShareNotFound
964
+     */
965
+    protected function createShareObject($data) {
966
+
967
+        $share = new Share($this->rootFolder, $this->userManager);
968
+        $share->setId((int)$data['id'])
969
+            ->setShareType((int)$data['share_type'])
970
+            ->setPermissions((int)$data['permissions'])
971
+            ->setTarget($data['file_target'])
972
+            ->setMailSend((bool)$data['mail_send'])
973
+            ->setNote($data['note'])
974
+            ->setToken($data['token']);
975
+
976
+        $shareTime = new \DateTime();
977
+        $shareTime->setTimestamp((int)$data['stime']);
978
+        $share->setShareTime($shareTime);
979
+        $share->setSharedWith($data['share_with']);
980
+        $share->setPassword($data['password']);
981
+        $share->setSendPasswordByTalk($data['password_by_talk']);
982
+
983
+        if ($data['uid_initiator'] !== null) {
984
+            $share->setShareOwner($data['uid_owner']);
985
+            $share->setSharedBy($data['uid_initiator']);
986
+        } else {
987
+            //OLD SHARE
988
+            $share->setSharedBy($data['uid_owner']);
989
+            $path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
990
+
991
+            $owner = $path->getOwner();
992
+            $share->setShareOwner($owner->getUID());
993
+        }
994
+
995
+        if ($data['expiration'] !== null) {
996
+            $expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']);
997
+            if ($expiration !== false) {
998
+                $share->setExpirationDate($expiration);
999
+            }
1000
+        }
1001
+
1002
+        $share->setNodeId((int)$data['file_source']);
1003
+        $share->setNodeType($data['item_type']);
1004
+
1005
+        $share->setProviderId($this->identifier());
1006
+
1007
+        return $share;
1008
+    }
1009
+
1010
+    /**
1011
+     * Get the node with file $id for $user
1012
+     *
1013
+     * @param string $userId
1014
+     * @param int $id
1015
+     * @return \OCP\Files\File|\OCP\Files\Folder
1016
+     * @throws InvalidShare
1017
+     */
1018
+    private function getNode($userId, $id) {
1019
+        try {
1020
+            $userFolder = $this->rootFolder->getUserFolder($userId);
1021
+        } catch (NoUserException $e) {
1022
+            throw new InvalidShare();
1023
+        }
1024
+
1025
+        $nodes = $userFolder->getById($id);
1026
+
1027
+        if (empty($nodes)) {
1028
+            throw new InvalidShare();
1029
+        }
1030
+
1031
+        return $nodes[0];
1032
+    }
1033
+
1034
+    /**
1035
+     * A user is deleted from the system
1036
+     * So clean up the relevant shares.
1037
+     *
1038
+     * @param string $uid
1039
+     * @param int $shareType
1040
+     */
1041
+    public function userDeleted($uid, $shareType) {
1042
+        $qb = $this->dbConnection->getQueryBuilder();
1043
+
1044
+        $qb->delete('share')
1045
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
1046
+            ->andWhere($qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)))
1047
+            ->execute();
1048
+    }
1049
+
1050
+    /**
1051
+     * This provider does not support group shares
1052
+     *
1053
+     * @param string $gid
1054
+     */
1055
+    public function groupDeleted($gid) {
1056
+    }
1057
+
1058
+    /**
1059
+     * This provider does not support group shares
1060
+     *
1061
+     * @param string $uid
1062
+     * @param string $gid
1063
+     */
1064
+    public function userDeletedFromGroup($uid, $gid) {
1065
+    }
1066
+
1067
+    /**
1068
+     * get database row of a give share
1069
+     *
1070
+     * @param $id
1071
+     * @return array
1072
+     * @throws ShareNotFound
1073
+     */
1074
+    protected function getRawShare($id) {
1075
+
1076
+        // Now fetch the inserted share and create a complete share object
1077
+        $qb = $this->dbConnection->getQueryBuilder();
1078
+        $qb->select('*')
1079
+            ->from('share')
1080
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
1081
+
1082
+        $cursor = $qb->execute();
1083
+        $data = $cursor->fetch();
1084
+        $cursor->closeCursor();
1085
+
1086
+        if ($data === false) {
1087
+            throw new ShareNotFound;
1088
+        }
1089
+
1090
+        return $data;
1091
+    }
1092
+
1093
+    public function getSharesInFolder($userId, Folder $node, $reshares) {
1094
+        $qb = $this->dbConnection->getQueryBuilder();
1095
+        $qb->select('*')
1096
+            ->from('share', 's')
1097
+            ->andWhere($qb->expr()->orX(
1098
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1099
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1100
+            ))
1101
+            ->andWhere(
1102
+                $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))
1103
+            );
1104
+
1105
+        /**
1106
+         * Reshares for this user are shares where they are the owner.
1107
+         */
1108
+        if ($reshares === false) {
1109
+            $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
1110
+        } else {
1111
+            $qb->andWhere(
1112
+                $qb->expr()->orX(
1113
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
1114
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
1115
+                )
1116
+            );
1117
+        }
1118
+
1119
+        $qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1120
+        $qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
1121
+
1122
+        $qb->orderBy('id');
1123
+
1124
+        $cursor = $qb->execute();
1125
+        $shares = [];
1126
+        while ($data = $cursor->fetch()) {
1127
+            $shares[$data['fileid']][] = $this->createShareObject($data);
1128
+        }
1129
+        $cursor->closeCursor();
1130
+
1131
+        return $shares;
1132
+    }
1133
+
1134
+    /**
1135
+     * @inheritdoc
1136
+     */
1137
+    public function getAccessList($nodes, $currentAccess) {
1138
+        $ids = [];
1139
+        foreach ($nodes as $node) {
1140
+            $ids[] = $node->getId();
1141
+        }
1142
+
1143
+        $qb = $this->dbConnection->getQueryBuilder();
1144
+        $qb->select('share_with')
1145
+            ->from('share')
1146
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
1147
+            ->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1148
+            ->andWhere($qb->expr()->orX(
1149
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1150
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1151
+            ))
1152
+            ->setMaxResults(1);
1153
+        $cursor = $qb->execute();
1154
+
1155
+        $mail = $cursor->fetch() !== false;
1156
+        $cursor->closeCursor();
1157
+
1158
+        return ['public' => $mail];
1159
+    }
1160 1160
 
1161 1161
 }
Please login to merge, or discard this patch.
Spacing   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -211,10 +211,10 @@  discard block
 block discarded – undo
211 211
 		}
212 212
 
213 213
 		$passwordPolicy = $this->getPasswordPolicy();
214
-		$passwordCharset = ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS;
214
+		$passwordCharset = ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_UPPER.ISecureRandom::CHAR_DIGITS;
215 215
 		$passwordLength = 8;
216 216
 		if (!empty($passwordPolicy)) {
217
-			$passwordLength = (int)$passwordPolicy['minLength'] > 0 ? (int)$passwordPolicy['minLength'] : $passwordLength;
217
+			$passwordLength = (int) $passwordPolicy['minLength'] > 0 ? (int) $passwordPolicy['minLength'] : $passwordLength;
218 218
 			$passwordCharset .= $passwordPolicy['enforceSpecialCharacters'] ? ISecureRandom::CHAR_SYMBOLS : '';
219 219
 		}
220 220
 
@@ -406,7 +406,7 @@  discard block
 block discarded – undo
406 406
 		$text = $this->l->t('%s shared »%s« with you.', [$initiatorDisplayName, $filename]);
407 407
 
408 408
 		$emailTemplate->addBodyText(
409
-			htmlspecialchars($text . ' ' . $this->l->t('Click the button below to open it.')),
409
+			htmlspecialchars($text.' '.$this->l->t('Click the button below to open it.')),
410 410
 			$text
411 411
 		);
412 412
 		$emailTemplate->addBodyButton(
@@ -430,9 +430,9 @@  discard block
 block discarded – undo
430 430
 		// The "Reply-To" is set to the sharer if an mail address is configured
431 431
 		// also the default footer contains a "Do not reply" which needs to be adjusted.
432 432
 		$initiatorEmail = $initiatorUser->getEMailAddress();
433
-		if($initiatorEmail !== null) {
433
+		if ($initiatorEmail !== null) {
434 434
 			$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
435
-			$emailTemplate->addFooter($instanceName . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : ''));
435
+			$emailTemplate->addFooter($instanceName.($this->defaults->getSlogan() !== '' ? ' - '.$this->defaults->getSlogan() : ''));
436 436
 		} else {
437 437
 			$emailTemplate->addFooter();
438 438
 		}
@@ -493,7 +493,7 @@  discard block
 block discarded – undo
493 493
 		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
494 494
 		if ($initiatorEmailAddress !== null) {
495 495
 			$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
496
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
496
+			$emailTemplate->addFooter($instanceName.' - '.$this->defaults->getSlogan());
497 497
 		} else {
498 498
 			$emailTemplate->addFooter();
499 499
 		}
@@ -551,7 +551,7 @@  discard block
 block discarded – undo
551 551
 		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
552 552
 		if ($initiatorEmailAddress !== null) {
553 553
 			$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
554
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
554
+			$emailTemplate->addFooter($instanceName.' - '.$this->defaults->getSlogan());
555 555
 		} else {
556 556
 			$emailTemplate->addFooter();
557 557
 		}
@@ -643,7 +643,7 @@  discard block
 block discarded – undo
643 643
 			->orderBy('id');
644 644
 
645 645
 		$cursor = $qb->execute();
646
-		while($data = $cursor->fetch()) {
646
+		while ($data = $cursor->fetch()) {
647 647
 			$children[] = $this->createShareObject($data);
648 648
 		}
649 649
 		$cursor->closeCursor();
@@ -690,7 +690,7 @@  discard block
 block discarded – undo
690 690
 		$qb->execute();
691 691
 		$id = $qb->getLastInsertId();
692 692
 
693
-		return (int)$id;
693
+		return (int) $id;
694 694
 	}
695 695
 
696 696
 	/**
@@ -707,7 +707,7 @@  discard block
 block discarded – undo
707 707
 		// a real password was given
708 708
 		$validPassword = $plainTextPassword !== null && $plainTextPassword !== '';
709 709
 
710
-		if($validPassword && ($originalShare->getPassword() !== $share->getPassword() ||
710
+		if ($validPassword && ($originalShare->getPassword() !== $share->getPassword() ||
711 711
 								($originalShare->getSendPasswordByTalk() && !$share->getSendPasswordByTalk()))) {
712 712
 			$this->sendPassword($share, $plainTextPassword);
713 713
 		}
@@ -811,7 +811,7 @@  discard block
 block discarded – undo
811 811
 
812 812
 		$cursor = $qb->execute();
813 813
 		$shares = [];
814
-		while($data = $cursor->fetch()) {
814
+		while ($data = $cursor->fetch()) {
815 815
 			$shares[] = $this->createShareObject($data);
816 816
 		}
817 817
 		$cursor->closeCursor();
@@ -863,7 +863,7 @@  discard block
 block discarded – undo
863 863
 			->execute();
864 864
 
865 865
 		$shares = [];
866
-		while($data = $cursor->fetch()) {
866
+		while ($data = $cursor->fetch()) {
867 867
 			$shares[] = $this->createShareObject($data);
868 868
 		}
869 869
 		$cursor->closeCursor();
@@ -902,7 +902,7 @@  discard block
 block discarded – undo
902 902
 
903 903
 		$cursor = $qb->execute();
904 904
 
905
-		while($data = $cursor->fetch()) {
905
+		while ($data = $cursor->fetch()) {
906 906
 			$shares[] = $this->createShareObject($data);
907 907
 		}
908 908
 		$cursor->closeCursor();
@@ -965,16 +965,16 @@  discard block
 block discarded – undo
965 965
 	protected function createShareObject($data) {
966 966
 
967 967
 		$share = new Share($this->rootFolder, $this->userManager);
968
-		$share->setId((int)$data['id'])
969
-			->setShareType((int)$data['share_type'])
970
-			->setPermissions((int)$data['permissions'])
968
+		$share->setId((int) $data['id'])
969
+			->setShareType((int) $data['share_type'])
970
+			->setPermissions((int) $data['permissions'])
971 971
 			->setTarget($data['file_target'])
972
-			->setMailSend((bool)$data['mail_send'])
972
+			->setMailSend((bool) $data['mail_send'])
973 973
 			->setNote($data['note'])
974 974
 			->setToken($data['token']);
975 975
 
976 976
 		$shareTime = new \DateTime();
977
-		$shareTime->setTimestamp((int)$data['stime']);
977
+		$shareTime->setTimestamp((int) $data['stime']);
978 978
 		$share->setShareTime($shareTime);
979 979
 		$share->setSharedWith($data['share_with']);
980 980
 		$share->setPassword($data['password']);
@@ -986,7 +986,7 @@  discard block
 block discarded – undo
986 986
 		} else {
987 987
 			//OLD SHARE
988 988
 			$share->setSharedBy($data['uid_owner']);
989
-			$path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
989
+			$path = $this->getNode($share->getSharedBy(), (int) $data['file_source']);
990 990
 
991 991
 			$owner = $path->getOwner();
992 992
 			$share->setShareOwner($owner->getUID());
@@ -999,7 +999,7 @@  discard block
 block discarded – undo
999 999
 			}
1000 1000
 		}
1001 1001
 
1002
-		$share->setNodeId((int)$data['file_source']);
1002
+		$share->setNodeId((int) $data['file_source']);
1003 1003
 		$share->setNodeType($data['item_type']);
1004 1004
 
1005 1005
 		$share->setProviderId($this->identifier());
@@ -1116,7 +1116,7 @@  discard block
 block discarded – undo
1116 1116
 			);
1117 1117
 		}
1118 1118
 
1119
-		$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1119
+		$qb->innerJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1120 1120
 		$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
1121 1121
 
1122 1122
 		$qb->orderBy('id');
Please login to merge, or discard this patch.
lib/public/Share/IShare.php 1 patch
Indentation   +379 added lines, -379 removed lines patch added patch discarded remove patch
@@ -39,383 +39,383 @@
 block discarded – undo
39 39
  */
40 40
 interface IShare {
41 41
 
42
-	/**
43
-	 * Set the internal id of the share
44
-	 * It is only allowed to set the internal id of a share once.
45
-	 * Attempts to override the internal id will result in an IllegalIDChangeException
46
-	 *
47
-	 * @param string $id
48
-	 * @return \OCP\Share\IShare
49
-	 * @throws IllegalIDChangeException
50
-	 * @throws \InvalidArgumentException
51
-	 * @since 9.1.0
52
-	 */
53
-	public function setId($id);
54
-
55
-	/**
56
-	 * Get the internal id of the share.
57
-	 *
58
-	 * @return string
59
-	 * @since 9.0.0
60
-	 */
61
-	public function getId();
62
-
63
-	/**
64
-	 * Get the full share id. This is the <providerid>:<internalid>.
65
-	 * The full id is unique in the system.
66
-	 *
67
-	 * @return string
68
-	 * @since 9.0.0
69
-	 * @throws \UnexpectedValueException If the fullId could not be constructed
70
-	 */
71
-	public function getFullId();
72
-
73
-	/**
74
-	 * Set the provider id of the share
75
-	 * It is only allowed to set the provider id of a share once.
76
-	 * Attempts to override the provider id will result in an IllegalIDChangeException
77
-	 *
78
-	 * @param string $id
79
-	 * @return \OCP\Share\IShare
80
-	 * @throws IllegalIDChangeException
81
-	 * @throws \InvalidArgumentException
82
-	 * @since 9.1.0
83
-	 */
84
-	public function setProviderId($id);
85
-
86
-	/**
87
-	 * Set the node of the file/folder that is shared
88
-	 *
89
-	 * @param Node $node
90
-	 * @return \OCP\Share\IShare The modified object
91
-	 * @since 9.0.0
92
-	 */
93
-	public function setNode(Node $node);
94
-
95
-	/**
96
-	 * Get the node of the file/folder that is shared
97
-	 *
98
-	 * @return File|Folder
99
-	 * @since 9.0.0
100
-	 * @throws NotFoundException
101
-	 */
102
-	public function getNode();
103
-
104
-	/**
105
-	 * Set file id for lazy evaluation of the node
106
-	 * @param int $fileId
107
-	 * @return \OCP\Share\IShare The modified object
108
-	 * @since 9.0.0
109
-	 */
110
-	public function setNodeId($fileId);
111
-
112
-	/**
113
-	 * Get the fileid of the node of this share
114
-	 * @return int
115
-	 * @since 9.0.0
116
-	 * @throws NotFoundException
117
-	 */
118
-	public function getNodeId();
119
-
120
-	/**
121
-	 * Set the type of node (file/folder)
122
-	 *
123
-	 * @param string $type
124
-	 * @return \OCP\Share\IShare The modified object
125
-	 * @since 9.0.0
126
-	 */
127
-	public function setNodeType($type);
128
-
129
-	/**
130
-	 * Get the type of node (file/folder)
131
-	 *
132
-	 * @return string
133
-	 * @since 9.0.0
134
-	 * @throws NotFoundException
135
-	 */
136
-	public function getNodeType();
137
-
138
-	/**
139
-	 * Set the shareType
140
-	 *
141
-	 * @param int $shareType
142
-	 * @return \OCP\Share\IShare The modified object
143
-	 * @since 9.0.0
144
-	 */
145
-	public function setShareType($shareType);
146
-
147
-	/**
148
-	 * Get the shareType
149
-	 *
150
-	 * @return int
151
-	 * @since 9.0.0
152
-	 */
153
-	public function getShareType();
154
-
155
-	/**
156
-	 * Set the receiver of this share.
157
-	 *
158
-	 * @param string $sharedWith
159
-	 * @return \OCP\Share\IShare The modified object
160
-	 * @since 9.0.0
161
-	 */
162
-	public function setSharedWith($sharedWith);
163
-
164
-	/**
165
-	 * Get the receiver of this share.
166
-	 *
167
-	 * @return string
168
-	 * @since 9.0.0
169
-	 */
170
-	public function getSharedWith();
171
-
172
-	/**
173
-	 * Set the display name of the receiver of this share.
174
-	 *
175
-	 * @param string $displayName
176
-	 * @return \OCP\Share\IShare The modified object
177
-	 * @since 14.0.0
178
-	 */
179
-	public function setSharedWithDisplayName($displayName);
180
-
181
-	/**
182
-	 * Get the display name of the receiver of this share.
183
-	 *
184
-	 * @return string
185
-	 * @since 14.0.0
186
-	 */
187
-	public function getSharedWithDisplayName();
188
-
189
-	/**
190
-	 * Set the avatar of the receiver of this share.
191
-	 *
192
-	 * @param string $src
193
-	 * @return \OCP\Share\IShare The modified object
194
-	 * @since 14.0.0
195
-	 */
196
-	public function setSharedWithAvatar($src);
197
-
198
-	/**
199
-	 * Get the avatar of the receiver of this share.
200
-	 *
201
-	 * @return string
202
-	 * @since 14.0.0
203
-	 */
204
-	public function getSharedWithAvatar();
205
-
206
-	/**
207
-	 * Set the permissions.
208
-	 * See \OCP\Constants::PERMISSION_*
209
-	 *
210
-	 * @param int $permissions
211
-	 * @return \OCP\Share\IShare The modified object
212
-	 * @since 9.0.0
213
-	 */
214
-	public function setPermissions($permissions);
215
-
216
-	/**
217
-	 * Get the share permissions
218
-	 * See \OCP\Constants::PERMISSION_*
219
-	 *
220
-	 * @return int
221
-	 * @since 9.0.0
222
-	 */
223
-	public function getPermissions();
224
-
225
-	/**
226
-	 * Attach a note to a share
227
-	 *
228
-	 * @param string $note
229
-	 * @return \OCP\Share\IShare The modified object
230
-	 * @since 14.0.0
231
-	 */
232
-	public function setNote($note);
233
-
234
-	/**
235
-	 * Get note attached to a share
236
-	 *
237
-	 * @return string
238
-	 * @since 14.0.0
239
-	 */
240
-	public function getNote();
241
-
242
-
243
-	/**
244
-	 * Set the expiration date
245
-	 *
246
-	 * @param null|\DateTime $expireDate
247
-	 * @return \OCP\Share\IShare The modified object
248
-	 * @since 9.0.0
249
-	 */
250
-	public function setExpirationDate($expireDate);
251
-
252
-	/**
253
-	 * Get the expiration date
254
-	 *
255
-	 * @return \DateTime
256
-	 * @since 9.0.0
257
-	 */
258
-	public function getExpirationDate();
259
-
260
-	/**
261
-	 * Set the sharer of the path.
262
-	 *
263
-	 * @param string $sharedBy
264
-	 * @return \OCP\Share\IShare The modified object
265
-	 * @since 9.0.0
266
-	 */
267
-	public function setSharedBy($sharedBy);
268
-
269
-	/**
270
-	 * Get share sharer
271
-	 *
272
-	 * @return string
273
-	 * @since 9.0.0
274
-	 */
275
-	public function getSharedBy();
276
-
277
-	/**
278
-	 * Set the original share owner (who owns the path that is shared)
279
-	 *
280
-	 * @param string $shareOwner
281
-	 * @return \OCP\Share\IShare The modified object
282
-	 * @since 9.0.0
283
-	 */
284
-	public function setShareOwner($shareOwner);
285
-
286
-	/**
287
-	 * Get the original share owner (who owns the path that is shared)
288
-	 *
289
-	 * @return string
290
-	 * @since 9.0.0
291
-	 */
292
-	public function getShareOwner();
293
-
294
-	/**
295
-	 * Set the password for this share.
296
-	 * When the share is passed to the share manager to be created
297
-	 * or updated the password will be hashed.
298
-	 *
299
-	 * @param string $password
300
-	 * @return \OCP\Share\IShare The modified object
301
-	 * @since 9.0.0
302
-	 */
303
-	public function setPassword($password);
304
-
305
-	/**
306
-	 * Get the password of this share.
307
-	 * If this share is obtained via a shareprovider the password is
308
-	 * hashed.
309
-	 *
310
-	 * @return string
311
-	 * @since 9.0.0
312
-	 */
313
-	public function getPassword();
314
-
315
-
316
-	/**
317
-	 * Set if the recipient can start a conversation with the owner to get the
318
-	 * password using Nextcloud Talk.
319
-	 *
320
-	 * @param bool $sendPasswordByTalk
321
-	 * @return \OCP\Share\IShare The modified object
322
-	 * @since 14.0.0
323
-	 */
324
-	public function setSendPasswordByTalk(bool $sendPasswordByTalk);
325
-
326
-	/**
327
-	 * Get if the recipient can start a conversation with the owner to get the
328
-	 * password using Nextcloud Talk.
329
-	 * The returned value does not take into account other factors, like Talk
330
-	 * being enabled for the owner of the share or not; it just cover whether
331
-	 * the option is enabled for the share itself or not.
332
-	 *
333
-	 * @return bool
334
-	 * @since 14.0.0
335
-	 */
336
-	public function getSendPasswordByTalk(): bool;
337
-
338
-	/**
339
-	 * Set the public link token.
340
-	 *
341
-	 * @param string $token
342
-	 * @return \OCP\Share\IShare The modified object
343
-	 * @since 9.0.0
344
-	 */
345
-	public function setToken($token);
346
-
347
-	/**
348
-	 * Get the public link token.
349
-	 *
350
-	 * @return string
351
-	 * @since 9.0.0
352
-	 */
353
-	public function getToken();
354
-
355
-	/**
356
-	 * Set the target path of this share relative to the recipients user folder.
357
-	 *
358
-	 * @param string $target
359
-	 * @return \OCP\Share\IShare The modified object
360
-	 * @since 9.0.0
361
-	 */
362
-	public function setTarget($target);
363
-
364
-	/**
365
-	 * Get the target path of this share relative to the recipients user folder.
366
-	 *
367
-	 * @return string
368
-	 * @since 9.0.0
369
-	 */
370
-	public function getTarget();
371
-
372
-	/**
373
-	 * Set the time this share was created
374
-	 *
375
-	 * @param \DateTime $shareTime
376
-	 * @return \OCP\Share\IShare The modified object
377
-	 * @since 9.0.0
378
-	 */
379
-	public function setShareTime(\DateTime $shareTime);
380
-
381
-	/**
382
-	 * Get the timestamp this share was created
383
-	 *
384
-	 * @return \DateTime
385
-	 * @since 9.0.0
386
-	 */
387
-	public function getShareTime();
388
-
389
-	/**
390
-	 * Set if the recipient is informed by mail about the share.
391
-	 *
392
-	 * @param bool $mailSend
393
-	 * @return \OCP\Share\IShare The modified object
394
-	 * @since 9.0.0
395
-	 */
396
-	public function setMailSend($mailSend);
397
-
398
-	/**
399
-	 * Get if the recipient informed by mail about the share.
400
-	 *
401
-	 * @return bool
402
-	 * @since 9.0.0
403
-	 */
404
-	public function getMailSend();
405
-
406
-	/**
407
-	 * Set the cache entry for the shared node
408
-	 *
409
-	 * @param ICacheEntry $entry
410
-	 * @since 11.0.0
411
-	 */
412
-	public function setNodeCacheEntry(ICacheEntry $entry);
413
-
414
-	/**
415
-	 * Get the cache entry for the shared node
416
-	 *
417
-	 * @return null|ICacheEntry
418
-	 * @since 11.0.0
419
-	 */
420
-	public function getNodeCacheEntry();
42
+    /**
43
+     * Set the internal id of the share
44
+     * It is only allowed to set the internal id of a share once.
45
+     * Attempts to override the internal id will result in an IllegalIDChangeException
46
+     *
47
+     * @param string $id
48
+     * @return \OCP\Share\IShare
49
+     * @throws IllegalIDChangeException
50
+     * @throws \InvalidArgumentException
51
+     * @since 9.1.0
52
+     */
53
+    public function setId($id);
54
+
55
+    /**
56
+     * Get the internal id of the share.
57
+     *
58
+     * @return string
59
+     * @since 9.0.0
60
+     */
61
+    public function getId();
62
+
63
+    /**
64
+     * Get the full share id. This is the <providerid>:<internalid>.
65
+     * The full id is unique in the system.
66
+     *
67
+     * @return string
68
+     * @since 9.0.0
69
+     * @throws \UnexpectedValueException If the fullId could not be constructed
70
+     */
71
+    public function getFullId();
72
+
73
+    /**
74
+     * Set the provider id of the share
75
+     * It is only allowed to set the provider id of a share once.
76
+     * Attempts to override the provider id will result in an IllegalIDChangeException
77
+     *
78
+     * @param string $id
79
+     * @return \OCP\Share\IShare
80
+     * @throws IllegalIDChangeException
81
+     * @throws \InvalidArgumentException
82
+     * @since 9.1.0
83
+     */
84
+    public function setProviderId($id);
85
+
86
+    /**
87
+     * Set the node of the file/folder that is shared
88
+     *
89
+     * @param Node $node
90
+     * @return \OCP\Share\IShare The modified object
91
+     * @since 9.0.0
92
+     */
93
+    public function setNode(Node $node);
94
+
95
+    /**
96
+     * Get the node of the file/folder that is shared
97
+     *
98
+     * @return File|Folder
99
+     * @since 9.0.0
100
+     * @throws NotFoundException
101
+     */
102
+    public function getNode();
103
+
104
+    /**
105
+     * Set file id for lazy evaluation of the node
106
+     * @param int $fileId
107
+     * @return \OCP\Share\IShare The modified object
108
+     * @since 9.0.0
109
+     */
110
+    public function setNodeId($fileId);
111
+
112
+    /**
113
+     * Get the fileid of the node of this share
114
+     * @return int
115
+     * @since 9.0.0
116
+     * @throws NotFoundException
117
+     */
118
+    public function getNodeId();
119
+
120
+    /**
121
+     * Set the type of node (file/folder)
122
+     *
123
+     * @param string $type
124
+     * @return \OCP\Share\IShare The modified object
125
+     * @since 9.0.0
126
+     */
127
+    public function setNodeType($type);
128
+
129
+    /**
130
+     * Get the type of node (file/folder)
131
+     *
132
+     * @return string
133
+     * @since 9.0.0
134
+     * @throws NotFoundException
135
+     */
136
+    public function getNodeType();
137
+
138
+    /**
139
+     * Set the shareType
140
+     *
141
+     * @param int $shareType
142
+     * @return \OCP\Share\IShare The modified object
143
+     * @since 9.0.0
144
+     */
145
+    public function setShareType($shareType);
146
+
147
+    /**
148
+     * Get the shareType
149
+     *
150
+     * @return int
151
+     * @since 9.0.0
152
+     */
153
+    public function getShareType();
154
+
155
+    /**
156
+     * Set the receiver of this share.
157
+     *
158
+     * @param string $sharedWith
159
+     * @return \OCP\Share\IShare The modified object
160
+     * @since 9.0.0
161
+     */
162
+    public function setSharedWith($sharedWith);
163
+
164
+    /**
165
+     * Get the receiver of this share.
166
+     *
167
+     * @return string
168
+     * @since 9.0.0
169
+     */
170
+    public function getSharedWith();
171
+
172
+    /**
173
+     * Set the display name of the receiver of this share.
174
+     *
175
+     * @param string $displayName
176
+     * @return \OCP\Share\IShare The modified object
177
+     * @since 14.0.0
178
+     */
179
+    public function setSharedWithDisplayName($displayName);
180
+
181
+    /**
182
+     * Get the display name of the receiver of this share.
183
+     *
184
+     * @return string
185
+     * @since 14.0.0
186
+     */
187
+    public function getSharedWithDisplayName();
188
+
189
+    /**
190
+     * Set the avatar of the receiver of this share.
191
+     *
192
+     * @param string $src
193
+     * @return \OCP\Share\IShare The modified object
194
+     * @since 14.0.0
195
+     */
196
+    public function setSharedWithAvatar($src);
197
+
198
+    /**
199
+     * Get the avatar of the receiver of this share.
200
+     *
201
+     * @return string
202
+     * @since 14.0.0
203
+     */
204
+    public function getSharedWithAvatar();
205
+
206
+    /**
207
+     * Set the permissions.
208
+     * See \OCP\Constants::PERMISSION_*
209
+     *
210
+     * @param int $permissions
211
+     * @return \OCP\Share\IShare The modified object
212
+     * @since 9.0.0
213
+     */
214
+    public function setPermissions($permissions);
215
+
216
+    /**
217
+     * Get the share permissions
218
+     * See \OCP\Constants::PERMISSION_*
219
+     *
220
+     * @return int
221
+     * @since 9.0.0
222
+     */
223
+    public function getPermissions();
224
+
225
+    /**
226
+     * Attach a note to a share
227
+     *
228
+     * @param string $note
229
+     * @return \OCP\Share\IShare The modified object
230
+     * @since 14.0.0
231
+     */
232
+    public function setNote($note);
233
+
234
+    /**
235
+     * Get note attached to a share
236
+     *
237
+     * @return string
238
+     * @since 14.0.0
239
+     */
240
+    public function getNote();
241
+
242
+
243
+    /**
244
+     * Set the expiration date
245
+     *
246
+     * @param null|\DateTime $expireDate
247
+     * @return \OCP\Share\IShare The modified object
248
+     * @since 9.0.0
249
+     */
250
+    public function setExpirationDate($expireDate);
251
+
252
+    /**
253
+     * Get the expiration date
254
+     *
255
+     * @return \DateTime
256
+     * @since 9.0.0
257
+     */
258
+    public function getExpirationDate();
259
+
260
+    /**
261
+     * Set the sharer of the path.
262
+     *
263
+     * @param string $sharedBy
264
+     * @return \OCP\Share\IShare The modified object
265
+     * @since 9.0.0
266
+     */
267
+    public function setSharedBy($sharedBy);
268
+
269
+    /**
270
+     * Get share sharer
271
+     *
272
+     * @return string
273
+     * @since 9.0.0
274
+     */
275
+    public function getSharedBy();
276
+
277
+    /**
278
+     * Set the original share owner (who owns the path that is shared)
279
+     *
280
+     * @param string $shareOwner
281
+     * @return \OCP\Share\IShare The modified object
282
+     * @since 9.0.0
283
+     */
284
+    public function setShareOwner($shareOwner);
285
+
286
+    /**
287
+     * Get the original share owner (who owns the path that is shared)
288
+     *
289
+     * @return string
290
+     * @since 9.0.0
291
+     */
292
+    public function getShareOwner();
293
+
294
+    /**
295
+     * Set the password for this share.
296
+     * When the share is passed to the share manager to be created
297
+     * or updated the password will be hashed.
298
+     *
299
+     * @param string $password
300
+     * @return \OCP\Share\IShare The modified object
301
+     * @since 9.0.0
302
+     */
303
+    public function setPassword($password);
304
+
305
+    /**
306
+     * Get the password of this share.
307
+     * If this share is obtained via a shareprovider the password is
308
+     * hashed.
309
+     *
310
+     * @return string
311
+     * @since 9.0.0
312
+     */
313
+    public function getPassword();
314
+
315
+
316
+    /**
317
+     * Set if the recipient can start a conversation with the owner to get the
318
+     * password using Nextcloud Talk.
319
+     *
320
+     * @param bool $sendPasswordByTalk
321
+     * @return \OCP\Share\IShare The modified object
322
+     * @since 14.0.0
323
+     */
324
+    public function setSendPasswordByTalk(bool $sendPasswordByTalk);
325
+
326
+    /**
327
+     * Get if the recipient can start a conversation with the owner to get the
328
+     * password using Nextcloud Talk.
329
+     * The returned value does not take into account other factors, like Talk
330
+     * being enabled for the owner of the share or not; it just cover whether
331
+     * the option is enabled for the share itself or not.
332
+     *
333
+     * @return bool
334
+     * @since 14.0.0
335
+     */
336
+    public function getSendPasswordByTalk(): bool;
337
+
338
+    /**
339
+     * Set the public link token.
340
+     *
341
+     * @param string $token
342
+     * @return \OCP\Share\IShare The modified object
343
+     * @since 9.0.0
344
+     */
345
+    public function setToken($token);
346
+
347
+    /**
348
+     * Get the public link token.
349
+     *
350
+     * @return string
351
+     * @since 9.0.0
352
+     */
353
+    public function getToken();
354
+
355
+    /**
356
+     * Set the target path of this share relative to the recipients user folder.
357
+     *
358
+     * @param string $target
359
+     * @return \OCP\Share\IShare The modified object
360
+     * @since 9.0.0
361
+     */
362
+    public function setTarget($target);
363
+
364
+    /**
365
+     * Get the target path of this share relative to the recipients user folder.
366
+     *
367
+     * @return string
368
+     * @since 9.0.0
369
+     */
370
+    public function getTarget();
371
+
372
+    /**
373
+     * Set the time this share was created
374
+     *
375
+     * @param \DateTime $shareTime
376
+     * @return \OCP\Share\IShare The modified object
377
+     * @since 9.0.0
378
+     */
379
+    public function setShareTime(\DateTime $shareTime);
380
+
381
+    /**
382
+     * Get the timestamp this share was created
383
+     *
384
+     * @return \DateTime
385
+     * @since 9.0.0
386
+     */
387
+    public function getShareTime();
388
+
389
+    /**
390
+     * Set if the recipient is informed by mail about the share.
391
+     *
392
+     * @param bool $mailSend
393
+     * @return \OCP\Share\IShare The modified object
394
+     * @since 9.0.0
395
+     */
396
+    public function setMailSend($mailSend);
397
+
398
+    /**
399
+     * Get if the recipient informed by mail about the share.
400
+     *
401
+     * @return bool
402
+     * @since 9.0.0
403
+     */
404
+    public function getMailSend();
405
+
406
+    /**
407
+     * Set the cache entry for the shared node
408
+     *
409
+     * @param ICacheEntry $entry
410
+     * @since 11.0.0
411
+     */
412
+    public function setNodeCacheEntry(ICacheEntry $entry);
413
+
414
+    /**
415
+     * Get the cache entry for the shared node
416
+     *
417
+     * @return null|ICacheEntry
418
+     * @since 11.0.0
419
+     */
420
+    public function getNodeCacheEntry();
421 421
 }
Please login to merge, or discard this patch.
lib/private/Share20/Manager.php 1 patch
Indentation   +1517 added lines, -1517 removed lines patch added patch discarded remove patch
@@ -72,1545 +72,1545 @@
 block discarded – undo
72 72
  */
73 73
 class Manager implements IManager {
74 74
 
75
-	/** @var IProviderFactory */
76
-	private $factory;
77
-	/** @var ILogger */
78
-	private $logger;
79
-	/** @var IConfig */
80
-	private $config;
81
-	/** @var ISecureRandom */
82
-	private $secureRandom;
83
-	/** @var IHasher */
84
-	private $hasher;
85
-	/** @var IMountManager */
86
-	private $mountManager;
87
-	/** @var IGroupManager */
88
-	private $groupManager;
89
-	/** @var IL10N */
90
-	private $l;
91
-	/** @var IFactory */
92
-	private $l10nFactory;
93
-	/** @var IUserManager */
94
-	private $userManager;
95
-	/** @var IRootFolder */
96
-	private $rootFolder;
97
-	/** @var CappedMemoryCache */
98
-	private $sharingDisabledForUsersCache;
99
-	/** @var EventDispatcher */
100
-	private $eventDispatcher;
101
-	/** @var LegacyHooks */
102
-	private $legacyHooks;
103
-	/** @var IMailer */
104
-	private $mailer;
105
-	/** @var IURLGenerator */
106
-	private $urlGenerator;
107
-	/** @var \OC_Defaults */
108
-	private $defaults;
109
-
110
-
111
-	/**
112
-	 * Manager constructor.
113
-	 *
114
-	 * @param ILogger $logger
115
-	 * @param IConfig $config
116
-	 * @param ISecureRandom $secureRandom
117
-	 * @param IHasher $hasher
118
-	 * @param IMountManager $mountManager
119
-	 * @param IGroupManager $groupManager
120
-	 * @param IL10N $l
121
-	 * @param IFactory $l10nFactory
122
-	 * @param IProviderFactory $factory
123
-	 * @param IUserManager $userManager
124
-	 * @param IRootFolder $rootFolder
125
-	 * @param EventDispatcher $eventDispatcher
126
-	 * @param IMailer $mailer
127
-	 * @param IURLGenerator $urlGenerator
128
-	 * @param \OC_Defaults $defaults
129
-	 */
130
-	public function __construct(
131
-			ILogger $logger,
132
-			IConfig $config,
133
-			ISecureRandom $secureRandom,
134
-			IHasher $hasher,
135
-			IMountManager $mountManager,
136
-			IGroupManager $groupManager,
137
-			IL10N $l,
138
-			IFactory $l10nFactory,
139
-			IProviderFactory $factory,
140
-			IUserManager $userManager,
141
-			IRootFolder $rootFolder,
142
-			EventDispatcher $eventDispatcher,
143
-			IMailer $mailer,
144
-			IURLGenerator $urlGenerator,
145
-			\OC_Defaults $defaults
146
-	) {
147
-		$this->logger = $logger;
148
-		$this->config = $config;
149
-		$this->secureRandom = $secureRandom;
150
-		$this->hasher = $hasher;
151
-		$this->mountManager = $mountManager;
152
-		$this->groupManager = $groupManager;
153
-		$this->l = $l;
154
-		$this->l10nFactory = $l10nFactory;
155
-		$this->factory = $factory;
156
-		$this->userManager = $userManager;
157
-		$this->rootFolder = $rootFolder;
158
-		$this->eventDispatcher = $eventDispatcher;
159
-		$this->sharingDisabledForUsersCache = new CappedMemoryCache();
160
-		$this->legacyHooks = new LegacyHooks($this->eventDispatcher);
161
-		$this->mailer = $mailer;
162
-		$this->urlGenerator = $urlGenerator;
163
-		$this->defaults = $defaults;
164
-	}
165
-
166
-	/**
167
-	 * Convert from a full share id to a tuple (providerId, shareId)
168
-	 *
169
-	 * @param string $id
170
-	 * @return string[]
171
-	 */
172
-	private function splitFullId($id) {
173
-		return explode(':', $id, 2);
174
-	}
175
-
176
-	/**
177
-	 * Verify if a password meets all requirements
178
-	 *
179
-	 * @param string $password
180
-	 * @throws \Exception
181
-	 */
182
-	protected function verifyPassword($password) {
183
-		if ($password === null) {
184
-			// No password is set, check if this is allowed.
185
-			if ($this->shareApiLinkEnforcePassword()) {
186
-				throw new \InvalidArgumentException('Passwords are enforced for link shares');
187
-			}
188
-
189
-			return;
190
-		}
191
-
192
-		// Let others verify the password
193
-		try {
194
-			$event = new GenericEvent($password);
195
-			$this->eventDispatcher->dispatch('OCP\PasswordPolicy::validate', $event);
196
-		} catch (HintException $e) {
197
-			throw new \Exception($e->getHint());
198
-		}
199
-	}
200
-
201
-	/**
202
-	 * Check for generic requirements before creating a share
203
-	 *
204
-	 * @param \OCP\Share\IShare $share
205
-	 * @throws \InvalidArgumentException
206
-	 * @throws GenericShareException
207
-	 *
208
-	 * @suppress PhanUndeclaredClassMethod
209
-	 */
210
-	protected function generalCreateChecks(\OCP\Share\IShare $share) {
211
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
212
-			// We expect a valid user as sharedWith for user shares
213
-			if (!$this->userManager->userExists($share->getSharedWith())) {
214
-				throw new \InvalidArgumentException('SharedWith is not a valid user');
215
-			}
216
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
217
-			// We expect a valid group as sharedWith for group shares
218
-			if (!$this->groupManager->groupExists($share->getSharedWith())) {
219
-				throw new \InvalidArgumentException('SharedWith is not a valid group');
220
-			}
221
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
222
-			if ($share->getSharedWith() !== null) {
223
-				throw new \InvalidArgumentException('SharedWith should be empty');
224
-			}
225
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_REMOTE) {
226
-			if ($share->getSharedWith() === null) {
227
-				throw new \InvalidArgumentException('SharedWith should not be empty');
228
-			}
229
-		}  else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_REMOTE_GROUP) {
230
-			if ($share->getSharedWith() === null) {
231
-				throw new \InvalidArgumentException('SharedWith should not be empty');
232
-			}
233
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
234
-			if ($share->getSharedWith() === null) {
235
-				throw new \InvalidArgumentException('SharedWith should not be empty');
236
-			}
237
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_CIRCLE) {
238
-			$circle = \OCA\Circles\Api\v1\Circles::detailsCircle($share->getSharedWith());
239
-			if ($circle === null) {
240
-				throw new \InvalidArgumentException('SharedWith is not a valid circle');
241
-			}
242
-		} else {
243
-			// We can't handle other types yet
244
-			throw new \InvalidArgumentException('unknown share type');
245
-		}
246
-
247
-		// Verify the initiator of the share is set
248
-		if ($share->getSharedBy() === null) {
249
-			throw new \InvalidArgumentException('SharedBy should be set');
250
-		}
251
-
252
-		// Cannot share with yourself
253
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
254
-			$share->getSharedWith() === $share->getSharedBy()) {
255
-			throw new \InvalidArgumentException('Can’t share with yourself');
256
-		}
257
-
258
-		// The path should be set
259
-		if ($share->getNode() === null) {
260
-			throw new \InvalidArgumentException('Path should be set');
261
-		}
262
-
263
-		// And it should be a file or a folder
264
-		if (!($share->getNode() instanceof \OCP\Files\File) &&
265
-				!($share->getNode() instanceof \OCP\Files\Folder)) {
266
-			throw new \InvalidArgumentException('Path should be either a file or a folder');
267
-		}
268
-
269
-		// And you can't share your rootfolder
270
-		if ($this->userManager->userExists($share->getSharedBy())) {
271
-			$sharedPath = $this->rootFolder->getUserFolder($share->getSharedBy())->getPath();
272
-		} else {
273
-			$sharedPath = $this->rootFolder->getUserFolder($share->getShareOwner())->getPath();
274
-		}
275
-		if ($sharedPath === $share->getNode()->getPath()) {
276
-			throw new \InvalidArgumentException('You can’t share your root folder');
277
-		}
278
-
279
-		// Check if we actually have share permissions
280
-		if (!$share->getNode()->isShareable()) {
281
-			$message_t = $this->l->t('You are not allowed to share %s', [$share->getNode()->getPath()]);
282
-			throw new GenericShareException($message_t, $message_t, 404);
283
-		}
284
-
285
-		// Permissions should be set
286
-		if ($share->getPermissions() === null) {
287
-			throw new \InvalidArgumentException('A share requires permissions');
288
-		}
289
-
290
-		/*
75
+    /** @var IProviderFactory */
76
+    private $factory;
77
+    /** @var ILogger */
78
+    private $logger;
79
+    /** @var IConfig */
80
+    private $config;
81
+    /** @var ISecureRandom */
82
+    private $secureRandom;
83
+    /** @var IHasher */
84
+    private $hasher;
85
+    /** @var IMountManager */
86
+    private $mountManager;
87
+    /** @var IGroupManager */
88
+    private $groupManager;
89
+    /** @var IL10N */
90
+    private $l;
91
+    /** @var IFactory */
92
+    private $l10nFactory;
93
+    /** @var IUserManager */
94
+    private $userManager;
95
+    /** @var IRootFolder */
96
+    private $rootFolder;
97
+    /** @var CappedMemoryCache */
98
+    private $sharingDisabledForUsersCache;
99
+    /** @var EventDispatcher */
100
+    private $eventDispatcher;
101
+    /** @var LegacyHooks */
102
+    private $legacyHooks;
103
+    /** @var IMailer */
104
+    private $mailer;
105
+    /** @var IURLGenerator */
106
+    private $urlGenerator;
107
+    /** @var \OC_Defaults */
108
+    private $defaults;
109
+
110
+
111
+    /**
112
+     * Manager constructor.
113
+     *
114
+     * @param ILogger $logger
115
+     * @param IConfig $config
116
+     * @param ISecureRandom $secureRandom
117
+     * @param IHasher $hasher
118
+     * @param IMountManager $mountManager
119
+     * @param IGroupManager $groupManager
120
+     * @param IL10N $l
121
+     * @param IFactory $l10nFactory
122
+     * @param IProviderFactory $factory
123
+     * @param IUserManager $userManager
124
+     * @param IRootFolder $rootFolder
125
+     * @param EventDispatcher $eventDispatcher
126
+     * @param IMailer $mailer
127
+     * @param IURLGenerator $urlGenerator
128
+     * @param \OC_Defaults $defaults
129
+     */
130
+    public function __construct(
131
+            ILogger $logger,
132
+            IConfig $config,
133
+            ISecureRandom $secureRandom,
134
+            IHasher $hasher,
135
+            IMountManager $mountManager,
136
+            IGroupManager $groupManager,
137
+            IL10N $l,
138
+            IFactory $l10nFactory,
139
+            IProviderFactory $factory,
140
+            IUserManager $userManager,
141
+            IRootFolder $rootFolder,
142
+            EventDispatcher $eventDispatcher,
143
+            IMailer $mailer,
144
+            IURLGenerator $urlGenerator,
145
+            \OC_Defaults $defaults
146
+    ) {
147
+        $this->logger = $logger;
148
+        $this->config = $config;
149
+        $this->secureRandom = $secureRandom;
150
+        $this->hasher = $hasher;
151
+        $this->mountManager = $mountManager;
152
+        $this->groupManager = $groupManager;
153
+        $this->l = $l;
154
+        $this->l10nFactory = $l10nFactory;
155
+        $this->factory = $factory;
156
+        $this->userManager = $userManager;
157
+        $this->rootFolder = $rootFolder;
158
+        $this->eventDispatcher = $eventDispatcher;
159
+        $this->sharingDisabledForUsersCache = new CappedMemoryCache();
160
+        $this->legacyHooks = new LegacyHooks($this->eventDispatcher);
161
+        $this->mailer = $mailer;
162
+        $this->urlGenerator = $urlGenerator;
163
+        $this->defaults = $defaults;
164
+    }
165
+
166
+    /**
167
+     * Convert from a full share id to a tuple (providerId, shareId)
168
+     *
169
+     * @param string $id
170
+     * @return string[]
171
+     */
172
+    private function splitFullId($id) {
173
+        return explode(':', $id, 2);
174
+    }
175
+
176
+    /**
177
+     * Verify if a password meets all requirements
178
+     *
179
+     * @param string $password
180
+     * @throws \Exception
181
+     */
182
+    protected function verifyPassword($password) {
183
+        if ($password === null) {
184
+            // No password is set, check if this is allowed.
185
+            if ($this->shareApiLinkEnforcePassword()) {
186
+                throw new \InvalidArgumentException('Passwords are enforced for link shares');
187
+            }
188
+
189
+            return;
190
+        }
191
+
192
+        // Let others verify the password
193
+        try {
194
+            $event = new GenericEvent($password);
195
+            $this->eventDispatcher->dispatch('OCP\PasswordPolicy::validate', $event);
196
+        } catch (HintException $e) {
197
+            throw new \Exception($e->getHint());
198
+        }
199
+    }
200
+
201
+    /**
202
+     * Check for generic requirements before creating a share
203
+     *
204
+     * @param \OCP\Share\IShare $share
205
+     * @throws \InvalidArgumentException
206
+     * @throws GenericShareException
207
+     *
208
+     * @suppress PhanUndeclaredClassMethod
209
+     */
210
+    protected function generalCreateChecks(\OCP\Share\IShare $share) {
211
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
212
+            // We expect a valid user as sharedWith for user shares
213
+            if (!$this->userManager->userExists($share->getSharedWith())) {
214
+                throw new \InvalidArgumentException('SharedWith is not a valid user');
215
+            }
216
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
217
+            // We expect a valid group as sharedWith for group shares
218
+            if (!$this->groupManager->groupExists($share->getSharedWith())) {
219
+                throw new \InvalidArgumentException('SharedWith is not a valid group');
220
+            }
221
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
222
+            if ($share->getSharedWith() !== null) {
223
+                throw new \InvalidArgumentException('SharedWith should be empty');
224
+            }
225
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_REMOTE) {
226
+            if ($share->getSharedWith() === null) {
227
+                throw new \InvalidArgumentException('SharedWith should not be empty');
228
+            }
229
+        }  else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_REMOTE_GROUP) {
230
+            if ($share->getSharedWith() === null) {
231
+                throw new \InvalidArgumentException('SharedWith should not be empty');
232
+            }
233
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
234
+            if ($share->getSharedWith() === null) {
235
+                throw new \InvalidArgumentException('SharedWith should not be empty');
236
+            }
237
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_CIRCLE) {
238
+            $circle = \OCA\Circles\Api\v1\Circles::detailsCircle($share->getSharedWith());
239
+            if ($circle === null) {
240
+                throw new \InvalidArgumentException('SharedWith is not a valid circle');
241
+            }
242
+        } else {
243
+            // We can't handle other types yet
244
+            throw new \InvalidArgumentException('unknown share type');
245
+        }
246
+
247
+        // Verify the initiator of the share is set
248
+        if ($share->getSharedBy() === null) {
249
+            throw new \InvalidArgumentException('SharedBy should be set');
250
+        }
251
+
252
+        // Cannot share with yourself
253
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
254
+            $share->getSharedWith() === $share->getSharedBy()) {
255
+            throw new \InvalidArgumentException('Can’t share with yourself');
256
+        }
257
+
258
+        // The path should be set
259
+        if ($share->getNode() === null) {
260
+            throw new \InvalidArgumentException('Path should be set');
261
+        }
262
+
263
+        // And it should be a file or a folder
264
+        if (!($share->getNode() instanceof \OCP\Files\File) &&
265
+                !($share->getNode() instanceof \OCP\Files\Folder)) {
266
+            throw new \InvalidArgumentException('Path should be either a file or a folder');
267
+        }
268
+
269
+        // And you can't share your rootfolder
270
+        if ($this->userManager->userExists($share->getSharedBy())) {
271
+            $sharedPath = $this->rootFolder->getUserFolder($share->getSharedBy())->getPath();
272
+        } else {
273
+            $sharedPath = $this->rootFolder->getUserFolder($share->getShareOwner())->getPath();
274
+        }
275
+        if ($sharedPath === $share->getNode()->getPath()) {
276
+            throw new \InvalidArgumentException('You can’t share your root folder');
277
+        }
278
+
279
+        // Check if we actually have share permissions
280
+        if (!$share->getNode()->isShareable()) {
281
+            $message_t = $this->l->t('You are not allowed to share %s', [$share->getNode()->getPath()]);
282
+            throw new GenericShareException($message_t, $message_t, 404);
283
+        }
284
+
285
+        // Permissions should be set
286
+        if ($share->getPermissions() === null) {
287
+            throw new \InvalidArgumentException('A share requires permissions');
288
+        }
289
+
290
+        /*
291 291
 		 * Quick fix for #23536
292 292
 		 * Non moveable mount points do not have update and delete permissions
293 293
 		 * while we 'most likely' do have that on the storage.
294 294
 		 */
295
-		$permissions = $share->getNode()->getPermissions();
296
-		$mount = $share->getNode()->getMountPoint();
297
-		if (!($mount instanceof MoveableMount)) {
298
-			$permissions |= \OCP\Constants::PERMISSION_DELETE | \OCP\Constants::PERMISSION_UPDATE;
299
-		}
300
-
301
-		// Check that we do not share with more permissions than we have
302
-		if ($share->getPermissions() & ~$permissions) {
303
-			$message_t = $this->l->t('Can’t increase permissions of %s', [$share->getNode()->getPath()]);
304
-			throw new GenericShareException($message_t, $message_t, 404);
305
-		}
306
-
307
-
308
-		// Check that read permissions are always set
309
-		// Link shares are allowed to have no read permissions to allow upload to hidden folders
310
-		$noReadPermissionRequired = $share->getShareType() === \OCP\Share::SHARE_TYPE_LINK
311
-			|| $share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL;
312
-		if (!$noReadPermissionRequired &&
313
-			($share->getPermissions() & \OCP\Constants::PERMISSION_READ) === 0) {
314
-			throw new \InvalidArgumentException('Shares need at least read permissions');
315
-		}
316
-
317
-		if ($share->getNode() instanceof \OCP\Files\File) {
318
-			if ($share->getPermissions() & \OCP\Constants::PERMISSION_DELETE) {
319
-				$message_t = $this->l->t('Files can’t be shared with delete permissions');
320
-				throw new GenericShareException($message_t);
321
-			}
322
-			if ($share->getPermissions() & \OCP\Constants::PERMISSION_CREATE) {
323
-				$message_t = $this->l->t('Files can’t be shared with create permissions');
324
-				throw new GenericShareException($message_t);
325
-			}
326
-		}
327
-	}
328
-
329
-	/**
330
-	 * Validate if the expiration date fits the system settings
331
-	 *
332
-	 * @param \OCP\Share\IShare $share The share to validate the expiration date of
333
-	 * @return \OCP\Share\IShare The modified share object
334
-	 * @throws GenericShareException
335
-	 * @throws \InvalidArgumentException
336
-	 * @throws \Exception
337
-	 */
338
-	protected function validateExpirationDate(\OCP\Share\IShare $share) {
339
-
340
-		$expirationDate = $share->getExpirationDate();
341
-
342
-		if ($expirationDate !== null) {
343
-			//Make sure the expiration date is a date
344
-			$expirationDate->setTime(0, 0, 0);
345
-
346
-			$date = new \DateTime();
347
-			$date->setTime(0, 0, 0);
348
-			if ($date >= $expirationDate) {
349
-				$message = $this->l->t('Expiration date is in the past');
350
-				throw new GenericShareException($message, $message, 404);
351
-			}
352
-		}
353
-
354
-		// If expiredate is empty set a default one if there is a default
355
-		$fullId = null;
356
-		try {
357
-			$fullId = $share->getFullId();
358
-		} catch (\UnexpectedValueException $e) {
359
-			// This is a new share
360
-		}
361
-
362
-		if ($fullId === null && $expirationDate === null && $this->shareApiLinkDefaultExpireDate()) {
363
-			$expirationDate = new \DateTime();
364
-			$expirationDate->setTime(0,0,0);
365
-			$expirationDate->add(new \DateInterval('P'.$this->shareApiLinkDefaultExpireDays().'D'));
366
-		}
367
-
368
-		// If we enforce the expiration date check that is does not exceed
369
-		if ($this->shareApiLinkDefaultExpireDateEnforced()) {
370
-			if ($expirationDate === null) {
371
-				throw new \InvalidArgumentException('Expiration date is enforced');
372
-			}
373
-
374
-			$date = new \DateTime();
375
-			$date->setTime(0, 0, 0);
376
-			$date->add(new \DateInterval('P' . $this->shareApiLinkDefaultExpireDays() . 'D'));
377
-			if ($date < $expirationDate) {
378
-				$message = $this->l->t('Can’t set expiration date more than %s days in the future', [$this->shareApiLinkDefaultExpireDays()]);
379
-				throw new GenericShareException($message, $message, 404);
380
-			}
381
-		}
382
-
383
-		$accepted = true;
384
-		$message = '';
385
-		\OCP\Util::emitHook('\OC\Share', 'verifyExpirationDate', [
386
-			'expirationDate' => &$expirationDate,
387
-			'accepted' => &$accepted,
388
-			'message' => &$message,
389
-			'passwordSet' => $share->getPassword() !== null,
390
-		]);
391
-
392
-		if (!$accepted) {
393
-			throw new \Exception($message);
394
-		}
395
-
396
-		$share->setExpirationDate($expirationDate);
397
-
398
-		return $share;
399
-	}
400
-
401
-	/**
402
-	 * Check for pre share requirements for user shares
403
-	 *
404
-	 * @param \OCP\Share\IShare $share
405
-	 * @throws \Exception
406
-	 */
407
-	protected function userCreateChecks(\OCP\Share\IShare $share) {
408
-		// Check if we can share with group members only
409
-		if ($this->shareWithGroupMembersOnly()) {
410
-			$sharedBy = $this->userManager->get($share->getSharedBy());
411
-			$sharedWith = $this->userManager->get($share->getSharedWith());
412
-			// Verify we can share with this user
413
-			$groups = array_intersect(
414
-					$this->groupManager->getUserGroupIds($sharedBy),
415
-					$this->groupManager->getUserGroupIds($sharedWith)
416
-			);
417
-			if (empty($groups)) {
418
-				throw new \Exception('Sharing is only allowed with group members');
419
-			}
420
-		}
421
-
422
-		/*
295
+        $permissions = $share->getNode()->getPermissions();
296
+        $mount = $share->getNode()->getMountPoint();
297
+        if (!($mount instanceof MoveableMount)) {
298
+            $permissions |= \OCP\Constants::PERMISSION_DELETE | \OCP\Constants::PERMISSION_UPDATE;
299
+        }
300
+
301
+        // Check that we do not share with more permissions than we have
302
+        if ($share->getPermissions() & ~$permissions) {
303
+            $message_t = $this->l->t('Can’t increase permissions of %s', [$share->getNode()->getPath()]);
304
+            throw new GenericShareException($message_t, $message_t, 404);
305
+        }
306
+
307
+
308
+        // Check that read permissions are always set
309
+        // Link shares are allowed to have no read permissions to allow upload to hidden folders
310
+        $noReadPermissionRequired = $share->getShareType() === \OCP\Share::SHARE_TYPE_LINK
311
+            || $share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL;
312
+        if (!$noReadPermissionRequired &&
313
+            ($share->getPermissions() & \OCP\Constants::PERMISSION_READ) === 0) {
314
+            throw new \InvalidArgumentException('Shares need at least read permissions');
315
+        }
316
+
317
+        if ($share->getNode() instanceof \OCP\Files\File) {
318
+            if ($share->getPermissions() & \OCP\Constants::PERMISSION_DELETE) {
319
+                $message_t = $this->l->t('Files can’t be shared with delete permissions');
320
+                throw new GenericShareException($message_t);
321
+            }
322
+            if ($share->getPermissions() & \OCP\Constants::PERMISSION_CREATE) {
323
+                $message_t = $this->l->t('Files can’t be shared with create permissions');
324
+                throw new GenericShareException($message_t);
325
+            }
326
+        }
327
+    }
328
+
329
+    /**
330
+     * Validate if the expiration date fits the system settings
331
+     *
332
+     * @param \OCP\Share\IShare $share The share to validate the expiration date of
333
+     * @return \OCP\Share\IShare The modified share object
334
+     * @throws GenericShareException
335
+     * @throws \InvalidArgumentException
336
+     * @throws \Exception
337
+     */
338
+    protected function validateExpirationDate(\OCP\Share\IShare $share) {
339
+
340
+        $expirationDate = $share->getExpirationDate();
341
+
342
+        if ($expirationDate !== null) {
343
+            //Make sure the expiration date is a date
344
+            $expirationDate->setTime(0, 0, 0);
345
+
346
+            $date = new \DateTime();
347
+            $date->setTime(0, 0, 0);
348
+            if ($date >= $expirationDate) {
349
+                $message = $this->l->t('Expiration date is in the past');
350
+                throw new GenericShareException($message, $message, 404);
351
+            }
352
+        }
353
+
354
+        // If expiredate is empty set a default one if there is a default
355
+        $fullId = null;
356
+        try {
357
+            $fullId = $share->getFullId();
358
+        } catch (\UnexpectedValueException $e) {
359
+            // This is a new share
360
+        }
361
+
362
+        if ($fullId === null && $expirationDate === null && $this->shareApiLinkDefaultExpireDate()) {
363
+            $expirationDate = new \DateTime();
364
+            $expirationDate->setTime(0,0,0);
365
+            $expirationDate->add(new \DateInterval('P'.$this->shareApiLinkDefaultExpireDays().'D'));
366
+        }
367
+
368
+        // If we enforce the expiration date check that is does not exceed
369
+        if ($this->shareApiLinkDefaultExpireDateEnforced()) {
370
+            if ($expirationDate === null) {
371
+                throw new \InvalidArgumentException('Expiration date is enforced');
372
+            }
373
+
374
+            $date = new \DateTime();
375
+            $date->setTime(0, 0, 0);
376
+            $date->add(new \DateInterval('P' . $this->shareApiLinkDefaultExpireDays() . 'D'));
377
+            if ($date < $expirationDate) {
378
+                $message = $this->l->t('Can’t set expiration date more than %s days in the future', [$this->shareApiLinkDefaultExpireDays()]);
379
+                throw new GenericShareException($message, $message, 404);
380
+            }
381
+        }
382
+
383
+        $accepted = true;
384
+        $message = '';
385
+        \OCP\Util::emitHook('\OC\Share', 'verifyExpirationDate', [
386
+            'expirationDate' => &$expirationDate,
387
+            'accepted' => &$accepted,
388
+            'message' => &$message,
389
+            'passwordSet' => $share->getPassword() !== null,
390
+        ]);
391
+
392
+        if (!$accepted) {
393
+            throw new \Exception($message);
394
+        }
395
+
396
+        $share->setExpirationDate($expirationDate);
397
+
398
+        return $share;
399
+    }
400
+
401
+    /**
402
+     * Check for pre share requirements for user shares
403
+     *
404
+     * @param \OCP\Share\IShare $share
405
+     * @throws \Exception
406
+     */
407
+    protected function userCreateChecks(\OCP\Share\IShare $share) {
408
+        // Check if we can share with group members only
409
+        if ($this->shareWithGroupMembersOnly()) {
410
+            $sharedBy = $this->userManager->get($share->getSharedBy());
411
+            $sharedWith = $this->userManager->get($share->getSharedWith());
412
+            // Verify we can share with this user
413
+            $groups = array_intersect(
414
+                    $this->groupManager->getUserGroupIds($sharedBy),
415
+                    $this->groupManager->getUserGroupIds($sharedWith)
416
+            );
417
+            if (empty($groups)) {
418
+                throw new \Exception('Sharing is only allowed with group members');
419
+            }
420
+        }
421
+
422
+        /*
423 423
 		 * TODO: Could be costly, fix
424 424
 		 *
425 425
 		 * Also this is not what we want in the future.. then we want to squash identical shares.
426 426
 		 */
427
-		$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_USER);
428
-		$existingShares = $provider->getSharesByPath($share->getNode());
429
-		foreach($existingShares as $existingShare) {
430
-			// Ignore if it is the same share
431
-			try {
432
-				if ($existingShare->getFullId() === $share->getFullId()) {
433
-					continue;
434
-				}
435
-			} catch (\UnexpectedValueException $e) {
436
-				//Shares are not identical
437
-			}
438
-
439
-			// Identical share already existst
440
-			if ($existingShare->getSharedWith() === $share->getSharedWith()) {
441
-				throw new \Exception('Path is already shared with this user');
442
-			}
443
-
444
-			// The share is already shared with this user via a group share
445
-			if ($existingShare->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
446
-				$group = $this->groupManager->get($existingShare->getSharedWith());
447
-				if (!is_null($group)) {
448
-					$user = $this->userManager->get($share->getSharedWith());
449
-
450
-					if ($group->inGroup($user) && $existingShare->getShareOwner() !== $share->getShareOwner()) {
451
-						throw new \Exception('Path is already shared with this user');
452
-					}
453
-				}
454
-			}
455
-		}
456
-	}
457
-
458
-	/**
459
-	 * Check for pre share requirements for group shares
460
-	 *
461
-	 * @param \OCP\Share\IShare $share
462
-	 * @throws \Exception
463
-	 */
464
-	protected function groupCreateChecks(\OCP\Share\IShare $share) {
465
-		// Verify group shares are allowed
466
-		if (!$this->allowGroupSharing()) {
467
-			throw new \Exception('Group sharing is now allowed');
468
-		}
469
-
470
-		// Verify if the user can share with this group
471
-		if ($this->shareWithGroupMembersOnly()) {
472
-			$sharedBy = $this->userManager->get($share->getSharedBy());
473
-			$sharedWith = $this->groupManager->get($share->getSharedWith());
474
-			if (is_null($sharedWith) || !$sharedWith->inGroup($sharedBy)) {
475
-				throw new \Exception('Sharing is only allowed within your own groups');
476
-			}
477
-		}
478
-
479
-		/*
427
+        $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_USER);
428
+        $existingShares = $provider->getSharesByPath($share->getNode());
429
+        foreach($existingShares as $existingShare) {
430
+            // Ignore if it is the same share
431
+            try {
432
+                if ($existingShare->getFullId() === $share->getFullId()) {
433
+                    continue;
434
+                }
435
+            } catch (\UnexpectedValueException $e) {
436
+                //Shares are not identical
437
+            }
438
+
439
+            // Identical share already existst
440
+            if ($existingShare->getSharedWith() === $share->getSharedWith()) {
441
+                throw new \Exception('Path is already shared with this user');
442
+            }
443
+
444
+            // The share is already shared with this user via a group share
445
+            if ($existingShare->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
446
+                $group = $this->groupManager->get($existingShare->getSharedWith());
447
+                if (!is_null($group)) {
448
+                    $user = $this->userManager->get($share->getSharedWith());
449
+
450
+                    if ($group->inGroup($user) && $existingShare->getShareOwner() !== $share->getShareOwner()) {
451
+                        throw new \Exception('Path is already shared with this user');
452
+                    }
453
+                }
454
+            }
455
+        }
456
+    }
457
+
458
+    /**
459
+     * Check for pre share requirements for group shares
460
+     *
461
+     * @param \OCP\Share\IShare $share
462
+     * @throws \Exception
463
+     */
464
+    protected function groupCreateChecks(\OCP\Share\IShare $share) {
465
+        // Verify group shares are allowed
466
+        if (!$this->allowGroupSharing()) {
467
+            throw new \Exception('Group sharing is now allowed');
468
+        }
469
+
470
+        // Verify if the user can share with this group
471
+        if ($this->shareWithGroupMembersOnly()) {
472
+            $sharedBy = $this->userManager->get($share->getSharedBy());
473
+            $sharedWith = $this->groupManager->get($share->getSharedWith());
474
+            if (is_null($sharedWith) || !$sharedWith->inGroup($sharedBy)) {
475
+                throw new \Exception('Sharing is only allowed within your own groups');
476
+            }
477
+        }
478
+
479
+        /*
480 480
 		 * TODO: Could be costly, fix
481 481
 		 *
482 482
 		 * Also this is not what we want in the future.. then we want to squash identical shares.
483 483
 		 */
484
-		$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
485
-		$existingShares = $provider->getSharesByPath($share->getNode());
486
-		foreach($existingShares as $existingShare) {
487
-			try {
488
-				if ($existingShare->getFullId() === $share->getFullId()) {
489
-					continue;
490
-				}
491
-			} catch (\UnexpectedValueException $e) {
492
-				//It is a new share so just continue
493
-			}
494
-
495
-			if ($existingShare->getSharedWith() === $share->getSharedWith()) {
496
-				throw new \Exception('Path is already shared with this group');
497
-			}
498
-		}
499
-	}
500
-
501
-	/**
502
-	 * Check for pre share requirements for link shares
503
-	 *
504
-	 * @param \OCP\Share\IShare $share
505
-	 * @throws \Exception
506
-	 */
507
-	protected function linkCreateChecks(\OCP\Share\IShare $share) {
508
-		// Are link shares allowed?
509
-		if (!$this->shareApiAllowLinks()) {
510
-			throw new \Exception('Link sharing is not allowed');
511
-		}
512
-
513
-		// Link shares by definition can't have share permissions
514
-		if ($share->getPermissions() & \OCP\Constants::PERMISSION_SHARE) {
515
-			throw new \InvalidArgumentException('Link shares can’t have reshare permissions');
516
-		}
517
-
518
-		// Check if public upload is allowed
519
-		if (!$this->shareApiLinkAllowPublicUpload() &&
520
-			($share->getPermissions() & (\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE))) {
521
-			throw new \InvalidArgumentException('Public upload is not allowed');
522
-		}
523
-	}
524
-
525
-	/**
526
-	 * To make sure we don't get invisible link shares we set the parent
527
-	 * of a link if it is a reshare. This is a quick word around
528
-	 * until we can properly display multiple link shares in the UI
529
-	 *
530
-	 * See: https://github.com/owncloud/core/issues/22295
531
-	 *
532
-	 * FIXME: Remove once multiple link shares can be properly displayed
533
-	 *
534
-	 * @param \OCP\Share\IShare $share
535
-	 */
536
-	protected function setLinkParent(\OCP\Share\IShare $share) {
537
-
538
-		// No sense in checking if the method is not there.
539
-		if (method_exists($share, 'setParent')) {
540
-			$storage = $share->getNode()->getStorage();
541
-			if ($storage->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
542
-				/** @var \OCA\Files_Sharing\SharedStorage $storage */
543
-				$share->setParent($storage->getShareId());
544
-			}
545
-		}
546
-	}
547
-
548
-	/**
549
-	 * @param File|Folder $path
550
-	 */
551
-	protected function pathCreateChecks($path) {
552
-		// Make sure that we do not share a path that contains a shared mountpoint
553
-		if ($path instanceof \OCP\Files\Folder) {
554
-			$mounts = $this->mountManager->findIn($path->getPath());
555
-			foreach($mounts as $mount) {
556
-				if ($mount->getStorage()->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
557
-					throw new \InvalidArgumentException('Path contains files shared with you');
558
-				}
559
-			}
560
-		}
561
-	}
562
-
563
-	/**
564
-	 * Check if the user that is sharing can actually share
565
-	 *
566
-	 * @param \OCP\Share\IShare $share
567
-	 * @throws \Exception
568
-	 */
569
-	protected function canShare(\OCP\Share\IShare $share) {
570
-		if (!$this->shareApiEnabled()) {
571
-			throw new \Exception('Sharing is disabled');
572
-		}
573
-
574
-		if ($this->sharingDisabledForUser($share->getSharedBy())) {
575
-			throw new \Exception('Sharing is disabled for you');
576
-		}
577
-	}
578
-
579
-	/**
580
-	 * Share a path
581
-	 *
582
-	 * @param \OCP\Share\IShare $share
583
-	 * @return Share The share object
584
-	 * @throws \Exception
585
-	 *
586
-	 * TODO: handle link share permissions or check them
587
-	 */
588
-	public function createShare(\OCP\Share\IShare $share) {
589
-		$this->canShare($share);
590
-
591
-		$this->generalCreateChecks($share);
592
-
593
-		// Verify if there are any issues with the path
594
-		$this->pathCreateChecks($share->getNode());
595
-
596
-		/*
484
+        $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
485
+        $existingShares = $provider->getSharesByPath($share->getNode());
486
+        foreach($existingShares as $existingShare) {
487
+            try {
488
+                if ($existingShare->getFullId() === $share->getFullId()) {
489
+                    continue;
490
+                }
491
+            } catch (\UnexpectedValueException $e) {
492
+                //It is a new share so just continue
493
+            }
494
+
495
+            if ($existingShare->getSharedWith() === $share->getSharedWith()) {
496
+                throw new \Exception('Path is already shared with this group');
497
+            }
498
+        }
499
+    }
500
+
501
+    /**
502
+     * Check for pre share requirements for link shares
503
+     *
504
+     * @param \OCP\Share\IShare $share
505
+     * @throws \Exception
506
+     */
507
+    protected function linkCreateChecks(\OCP\Share\IShare $share) {
508
+        // Are link shares allowed?
509
+        if (!$this->shareApiAllowLinks()) {
510
+            throw new \Exception('Link sharing is not allowed');
511
+        }
512
+
513
+        // Link shares by definition can't have share permissions
514
+        if ($share->getPermissions() & \OCP\Constants::PERMISSION_SHARE) {
515
+            throw new \InvalidArgumentException('Link shares can’t have reshare permissions');
516
+        }
517
+
518
+        // Check if public upload is allowed
519
+        if (!$this->shareApiLinkAllowPublicUpload() &&
520
+            ($share->getPermissions() & (\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE))) {
521
+            throw new \InvalidArgumentException('Public upload is not allowed');
522
+        }
523
+    }
524
+
525
+    /**
526
+     * To make sure we don't get invisible link shares we set the parent
527
+     * of a link if it is a reshare. This is a quick word around
528
+     * until we can properly display multiple link shares in the UI
529
+     *
530
+     * See: https://github.com/owncloud/core/issues/22295
531
+     *
532
+     * FIXME: Remove once multiple link shares can be properly displayed
533
+     *
534
+     * @param \OCP\Share\IShare $share
535
+     */
536
+    protected function setLinkParent(\OCP\Share\IShare $share) {
537
+
538
+        // No sense in checking if the method is not there.
539
+        if (method_exists($share, 'setParent')) {
540
+            $storage = $share->getNode()->getStorage();
541
+            if ($storage->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
542
+                /** @var \OCA\Files_Sharing\SharedStorage $storage */
543
+                $share->setParent($storage->getShareId());
544
+            }
545
+        }
546
+    }
547
+
548
+    /**
549
+     * @param File|Folder $path
550
+     */
551
+    protected function pathCreateChecks($path) {
552
+        // Make sure that we do not share a path that contains a shared mountpoint
553
+        if ($path instanceof \OCP\Files\Folder) {
554
+            $mounts = $this->mountManager->findIn($path->getPath());
555
+            foreach($mounts as $mount) {
556
+                if ($mount->getStorage()->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
557
+                    throw new \InvalidArgumentException('Path contains files shared with you');
558
+                }
559
+            }
560
+        }
561
+    }
562
+
563
+    /**
564
+     * Check if the user that is sharing can actually share
565
+     *
566
+     * @param \OCP\Share\IShare $share
567
+     * @throws \Exception
568
+     */
569
+    protected function canShare(\OCP\Share\IShare $share) {
570
+        if (!$this->shareApiEnabled()) {
571
+            throw new \Exception('Sharing is disabled');
572
+        }
573
+
574
+        if ($this->sharingDisabledForUser($share->getSharedBy())) {
575
+            throw new \Exception('Sharing is disabled for you');
576
+        }
577
+    }
578
+
579
+    /**
580
+     * Share a path
581
+     *
582
+     * @param \OCP\Share\IShare $share
583
+     * @return Share The share object
584
+     * @throws \Exception
585
+     *
586
+     * TODO: handle link share permissions or check them
587
+     */
588
+    public function createShare(\OCP\Share\IShare $share) {
589
+        $this->canShare($share);
590
+
591
+        $this->generalCreateChecks($share);
592
+
593
+        // Verify if there are any issues with the path
594
+        $this->pathCreateChecks($share->getNode());
595
+
596
+        /*
597 597
 		 * On creation of a share the owner is always the owner of the path
598 598
 		 * Except for mounted federated shares.
599 599
 		 */
600
-		$storage = $share->getNode()->getStorage();
601
-		if ($storage->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
602
-			$parent = $share->getNode()->getParent();
603
-			while($parent->getStorage()->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
604
-				$parent = $parent->getParent();
605
-			}
606
-			$share->setShareOwner($parent->getOwner()->getUID());
607
-		} else {
608
-			$share->setShareOwner($share->getNode()->getOwner()->getUID());
609
-		}
610
-
611
-		//Verify share type
612
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
613
-			$this->userCreateChecks($share);
614
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
615
-			$this->groupCreateChecks($share);
616
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
617
-			$this->linkCreateChecks($share);
618
-			$this->setLinkParent($share);
619
-
620
-			/*
600
+        $storage = $share->getNode()->getStorage();
601
+        if ($storage->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
602
+            $parent = $share->getNode()->getParent();
603
+            while($parent->getStorage()->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
604
+                $parent = $parent->getParent();
605
+            }
606
+            $share->setShareOwner($parent->getOwner()->getUID());
607
+        } else {
608
+            $share->setShareOwner($share->getNode()->getOwner()->getUID());
609
+        }
610
+
611
+        //Verify share type
612
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
613
+            $this->userCreateChecks($share);
614
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
615
+            $this->groupCreateChecks($share);
616
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
617
+            $this->linkCreateChecks($share);
618
+            $this->setLinkParent($share);
619
+
620
+            /*
621 621
 			 * For now ignore a set token.
622 622
 			 */
623
-			$share->setToken(
624
-				$this->secureRandom->generate(
625
-					\OC\Share\Constants::TOKEN_LENGTH,
626
-					\OCP\Security\ISecureRandom::CHAR_HUMAN_READABLE
627
-				)
628
-			);
629
-
630
-			//Verify the expiration date
631
-			$this->validateExpirationDate($share);
632
-
633
-			//Verify the password
634
-			$this->verifyPassword($share->getPassword());
635
-
636
-			// If a password is set. Hash it!
637
-			if ($share->getPassword() !== null) {
638
-				$share->setPassword($this->hasher->hash($share->getPassword()));
639
-			}
640
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
641
-			$share->setToken(
642
-				$this->secureRandom->generate(
643
-					\OC\Share\Constants::TOKEN_LENGTH,
644
-					\OCP\Security\ISecureRandom::CHAR_HUMAN_READABLE
645
-				)
646
-			);
647
-		}
648
-
649
-		// Cannot share with the owner
650
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
651
-			$share->getSharedWith() === $share->getShareOwner()) {
652
-			throw new \InvalidArgumentException('Can’t share with the share owner');
653
-		}
654
-
655
-		// Generate the target
656
-		$target = $this->config->getSystemValue('share_folder', '/') .'/'. $share->getNode()->getName();
657
-		$target = \OC\Files\Filesystem::normalizePath($target);
658
-		$share->setTarget($target);
659
-
660
-		// Pre share event
661
-		$event = new GenericEvent($share);
662
-		$a = $this->eventDispatcher->dispatch('OCP\Share::preShare', $event);
663
-		if ($event->isPropagationStopped() && $event->hasArgument('error')) {
664
-			throw new \Exception($event->getArgument('error'));
665
-		}
666
-
667
-		$oldShare = $share;
668
-		$provider = $this->factory->getProviderForType($share->getShareType());
669
-		$share = $provider->create($share);
670
-		//reuse the node we already have
671
-		$share->setNode($oldShare->getNode());
672
-
673
-		// Post share event
674
-		$event = new GenericEvent($share);
675
-		$this->eventDispatcher->dispatch('OCP\Share::postShare', $event);
676
-
677
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
678
-			$mailSend = $share->getMailSend();
679
-			if($mailSend === true) {
680
-				$user = $this->userManager->get($share->getSharedWith());
681
-				if ($user !== null) {
682
-					$emailAddress = $user->getEMailAddress();
683
-					if ($emailAddress !== null && $emailAddress !== '') {
684
-						$userLang = $this->config->getUserValue($share->getSharedWith(), 'core', 'lang', null);
685
-						$l = $this->l10nFactory->get('lib', $userLang);
686
-						$this->sendMailNotification(
687
-							$l,
688
-							$share->getNode()->getName(),
689
-							$this->urlGenerator->linkToRouteAbsolute('files.viewcontroller.showFile', ['fileid' => $share->getNode()->getId()]),
690
-							$share->getSharedBy(),
691
-							$emailAddress,
692
-							$share->getExpirationDate()
693
-						);
694
-						$this->logger->debug('Send share notification to ' . $emailAddress . ' for share with ID ' . $share->getId(), ['app' => 'share']);
695
-					} else {
696
-						$this->logger->debug('Share notification not send to ' . $share->getSharedWith() . ' because email address is not set.', ['app' => 'share']);
697
-					}
698
-				} else {
699
-					$this->logger->debug('Share notification not send to ' . $share->getSharedWith() . ' because user could not be found.', ['app' => 'share']);
700
-				}
701
-			} else {
702
-				$this->logger->debug('Share notification not send because mailsend is false.', ['app' => 'share']);
703
-			}
704
-		}
705
-
706
-		return $share;
707
-	}
708
-
709
-	/**
710
-	 * @param IL10N $l Language of the recipient
711
-	 * @param string $filename file/folder name
712
-	 * @param string $link link to the file/folder
713
-	 * @param string $initiator user ID of share sender
714
-	 * @param string $shareWith email address of share receiver
715
-	 * @param \DateTime|null $expiration
716
-	 * @throws \Exception If mail couldn't be sent
717
-	 */
718
-	protected function sendMailNotification(IL10N $l,
719
-											$filename,
720
-											$link,
721
-											$initiator,
722
-											$shareWith,
723
-											\DateTime $expiration = null) {
724
-		$initiatorUser = $this->userManager->get($initiator);
725
-		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
726
-
727
-		$message = $this->mailer->createMessage();
728
-
729
-		$emailTemplate = $this->mailer->createEMailTemplate('files_sharing.RecipientNotification', [
730
-			'filename' => $filename,
731
-			'link' => $link,
732
-			'initiator' => $initiatorDisplayName,
733
-			'expiration' => $expiration,
734
-			'shareWith' => $shareWith,
735
-		]);
736
-
737
-		$emailTemplate->setSubject($l->t('%s shared »%s« with you', array($initiatorDisplayName, $filename)));
738
-		$emailTemplate->addHeader();
739
-		$emailTemplate->addHeading($l->t('%s shared »%s« with you', [$initiatorDisplayName, $filename]), false);
740
-		$text = $l->t('%s shared »%s« with you.', [$initiatorDisplayName, $filename]);
741
-
742
-		$emailTemplate->addBodyText(
743
-			htmlspecialchars($text . ' ' . $l->t('Click the button below to open it.')),
744
-			$text
745
-		);
746
-		$emailTemplate->addBodyButton(
747
-			$l->t('Open »%s«', [$filename]),
748
-			$link
749
-		);
750
-
751
-		$message->setTo([$shareWith]);
752
-
753
-		// The "From" contains the sharers name
754
-		$instanceName = $this->defaults->getName();
755
-		$senderName = $l->t(
756
-			'%s via %s',
757
-			[
758
-				$initiatorDisplayName,
759
-				$instanceName
760
-			]
761
-		);
762
-		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
763
-
764
-		// The "Reply-To" is set to the sharer if an mail address is configured
765
-		// also the default footer contains a "Do not reply" which needs to be adjusted.
766
-		$initiatorEmail = $initiatorUser->getEMailAddress();
767
-		if($initiatorEmail !== null) {
768
-			$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
769
-			$emailTemplate->addFooter($instanceName . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : ''));
770
-		} else {
771
-			$emailTemplate->addFooter();
772
-		}
773
-
774
-		$message->useTemplate($emailTemplate);
775
-		$this->mailer->send($message);
776
-	}
777
-
778
-	/**
779
-	 * Update a share
780
-	 *
781
-	 * @param \OCP\Share\IShare $share
782
-	 * @return \OCP\Share\IShare The share object
783
-	 * @throws \InvalidArgumentException
784
-	 */
785
-	public function updateShare(\OCP\Share\IShare $share) {
786
-		$expirationDateUpdated = false;
787
-
788
-		$this->canShare($share);
789
-
790
-		try {
791
-			$originalShare = $this->getShareById($share->getFullId());
792
-		} catch (\UnexpectedValueException $e) {
793
-			throw new \InvalidArgumentException('Share does not have a full id');
794
-		}
795
-
796
-		// We can't change the share type!
797
-		if ($share->getShareType() !== $originalShare->getShareType()) {
798
-			throw new \InvalidArgumentException('Can’t change share type');
799
-		}
800
-
801
-		// We can only change the recipient on user shares
802
-		if ($share->getSharedWith() !== $originalShare->getSharedWith() &&
803
-		    $share->getShareType() !== \OCP\Share::SHARE_TYPE_USER) {
804
-			throw new \InvalidArgumentException('Can only update recipient on user shares');
805
-		}
806
-
807
-		// Cannot share with the owner
808
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
809
-			$share->getSharedWith() === $share->getShareOwner()) {
810
-			throw new \InvalidArgumentException('Can’t share with the share owner');
811
-		}
812
-
813
-		$this->generalCreateChecks($share);
814
-
815
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
816
-			$this->userCreateChecks($share);
817
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
818
-			$this->groupCreateChecks($share);
819
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
820
-			$this->linkCreateChecks($share);
821
-
822
-			$this->updateSharePasswordIfNeeded($share, $originalShare);
823
-
824
-			if ($share->getExpirationDate() != $originalShare->getExpirationDate()) {
825
-				//Verify the expiration date
826
-				$this->validateExpirationDate($share);
827
-				$expirationDateUpdated = true;
828
-			}
829
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
830
-			// The new password is not set again if it is the same as the old
831
-			// one, unless when switching from sending by Talk to sending by
832
-			// mail.
833
-			$plainTextPassword = $share->getPassword();
834
-			if (!empty($plainTextPassword) && !$this->updateSharePasswordIfNeeded($share, $originalShare) &&
835
-					!($originalShare->getSendPasswordByTalk() && !$share->getSendPasswordByTalk())) {
836
-				$plainTextPassword = null;
837
-			}
838
-			if (empty($plainTextPassword) && !$originalShare->getSendPasswordByTalk() && $share->getSendPasswordByTalk()) {
839
-				// If the same password was already sent by mail the recipient
840
-				// would already have access to the share without having to call
841
-				// the sharer to verify her identity
842
-				throw new \InvalidArgumentException('Can’t enable sending the password by Talk without setting a new password');
843
-			}
844
-		}
845
-
846
-		$this->pathCreateChecks($share->getNode());
847
-
848
-		// Now update the share!
849
-		$provider = $this->factory->getProviderForType($share->getShareType());
850
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
851
-			$share = $provider->update($share, $plainTextPassword);
852
-		} else {
853
-			$share = $provider->update($share);
854
-		}
855
-
856
-		if ($expirationDateUpdated === true) {
857
-			\OC_Hook::emit(Share::class, 'post_set_expiration_date', [
858
-				'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
859
-				'itemSource' => $share->getNode()->getId(),
860
-				'date' => $share->getExpirationDate(),
861
-				'uidOwner' => $share->getSharedBy(),
862
-			]);
863
-		}
864
-
865
-		if ($share->getPassword() !== $originalShare->getPassword()) {
866
-			\OC_Hook::emit(Share::class, 'post_update_password', [
867
-				'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
868
-				'itemSource' => $share->getNode()->getId(),
869
-				'uidOwner' => $share->getSharedBy(),
870
-				'token' => $share->getToken(),
871
-				'disabled' => is_null($share->getPassword()),
872
-			]);
873
-		}
874
-
875
-		if ($share->getPermissions() !== $originalShare->getPermissions()) {
876
-			if ($this->userManager->userExists($share->getShareOwner())) {
877
-				$userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
878
-			} else {
879
-				$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
880
-			}
881
-			\OC_Hook::emit(Share::class, 'post_update_permissions', array(
882
-				'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
883
-				'itemSource' => $share->getNode()->getId(),
884
-				'shareType' => $share->getShareType(),
885
-				'shareWith' => $share->getSharedWith(),
886
-				'uidOwner' => $share->getSharedBy(),
887
-				'permissions' => $share->getPermissions(),
888
-				'path' => $userFolder->getRelativePath($share->getNode()->getPath()),
889
-			));
890
-		}
891
-
892
-		return $share;
893
-	}
894
-
895
-	/**
896
-	 * Updates the password of the given share if it is not the same as the
897
-	 * password of the original share.
898
-	 *
899
-	 * @param \OCP\Share\IShare $share the share to update its password.
900
-	 * @param \OCP\Share\IShare $originalShare the original share to compare its
901
-	 *        password with.
902
-	 * @return boolean whether the password was updated or not.
903
-	 */
904
-	private function updateSharePasswordIfNeeded(\OCP\Share\IShare $share, \OCP\Share\IShare $originalShare) {
905
-		// Password updated.
906
-		if ($share->getPassword() !== $originalShare->getPassword()) {
907
-			//Verify the password
908
-			$this->verifyPassword($share->getPassword());
909
-
910
-			// If a password is set. Hash it!
911
-			if ($share->getPassword() !== null) {
912
-				$share->setPassword($this->hasher->hash($share->getPassword()));
913
-
914
-				return true;
915
-			}
916
-		}
917
-
918
-		return false;
919
-	}
920
-
921
-	/**
922
-	 * Delete all the children of this share
923
-	 * FIXME: remove once https://github.com/owncloud/core/pull/21660 is in
924
-	 *
925
-	 * @param \OCP\Share\IShare $share
926
-	 * @return \OCP\Share\IShare[] List of deleted shares
927
-	 */
928
-	protected function deleteChildren(\OCP\Share\IShare $share) {
929
-		$deletedShares = [];
930
-
931
-		$provider = $this->factory->getProviderForType($share->getShareType());
932
-
933
-		foreach ($provider->getChildren($share) as $child) {
934
-			$deletedChildren = $this->deleteChildren($child);
935
-			$deletedShares = array_merge($deletedShares, $deletedChildren);
936
-
937
-			$provider->delete($child);
938
-			$deletedShares[] = $child;
939
-		}
940
-
941
-		return $deletedShares;
942
-	}
943
-
944
-	/**
945
-	 * Delete a share
946
-	 *
947
-	 * @param \OCP\Share\IShare $share
948
-	 * @throws ShareNotFound
949
-	 * @throws \InvalidArgumentException
950
-	 */
951
-	public function deleteShare(\OCP\Share\IShare $share) {
952
-
953
-		try {
954
-			$share->getFullId();
955
-		} catch (\UnexpectedValueException $e) {
956
-			throw new \InvalidArgumentException('Share does not have a full id');
957
-		}
958
-
959
-		$event = new GenericEvent($share);
960
-		$this->eventDispatcher->dispatch('OCP\Share::preUnshare', $event);
961
-
962
-		// Get all children and delete them as well
963
-		$deletedShares = $this->deleteChildren($share);
964
-
965
-		// Do the actual delete
966
-		$provider = $this->factory->getProviderForType($share->getShareType());
967
-		$provider->delete($share);
968
-
969
-		// All the deleted shares caused by this delete
970
-		$deletedShares[] = $share;
971
-
972
-		// Emit post hook
973
-		$event->setArgument('deletedShares', $deletedShares);
974
-		$this->eventDispatcher->dispatch('OCP\Share::postUnshare', $event);
975
-	}
976
-
977
-
978
-	/**
979
-	 * Unshare a file as the recipient.
980
-	 * This can be different from a regular delete for example when one of
981
-	 * the users in a groups deletes that share. But the provider should
982
-	 * handle this.
983
-	 *
984
-	 * @param \OCP\Share\IShare $share
985
-	 * @param string $recipientId
986
-	 */
987
-	public function deleteFromSelf(\OCP\Share\IShare $share, $recipientId) {
988
-		list($providerId, ) = $this->splitFullId($share->getFullId());
989
-		$provider = $this->factory->getProvider($providerId);
990
-
991
-		$provider->deleteFromSelf($share, $recipientId);
992
-		$event = new GenericEvent($share);
993
-		$this->eventDispatcher->dispatch('OCP\Share::postUnshareFromSelf', $event);
994
-	}
995
-
996
-	public function restoreShare(IShare $share, string $recipientId): IShare {
997
-		list($providerId, ) = $this->splitFullId($share->getFullId());
998
-		$provider = $this->factory->getProvider($providerId);
999
-
1000
-		return $provider->restore($share, $recipientId);
1001
-	}
1002
-
1003
-	/**
1004
-	 * @inheritdoc
1005
-	 */
1006
-	public function moveShare(\OCP\Share\IShare $share, $recipientId) {
1007
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
1008
-			throw new \InvalidArgumentException('Can’t change target of link share');
1009
-		}
1010
-
1011
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER && $share->getSharedWith() !== $recipientId) {
1012
-			throw new \InvalidArgumentException('Invalid recipient');
1013
-		}
1014
-
1015
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
1016
-			$sharedWith = $this->groupManager->get($share->getSharedWith());
1017
-			if (is_null($sharedWith)) {
1018
-				throw new \InvalidArgumentException('Group "' . $share->getSharedWith() . '" does not exist');
1019
-			}
1020
-			$recipient = $this->userManager->get($recipientId);
1021
-			if (!$sharedWith->inGroup($recipient)) {
1022
-				throw new \InvalidArgumentException('Invalid recipient');
1023
-			}
1024
-		}
1025
-
1026
-		list($providerId, ) = $this->splitFullId($share->getFullId());
1027
-		$provider = $this->factory->getProvider($providerId);
1028
-
1029
-		$provider->move($share, $recipientId);
1030
-	}
1031
-
1032
-	public function getSharesInFolder($userId, Folder $node, $reshares = false) {
1033
-		$providers = $this->factory->getAllProviders();
1034
-
1035
-		return array_reduce($providers, function($shares, IShareProvider $provider) use ($userId, $node, $reshares) {
1036
-			$newShares = $provider->getSharesInFolder($userId, $node, $reshares);
1037
-			foreach ($newShares as $fid => $data) {
1038
-				if (!isset($shares[$fid])) {
1039
-					$shares[$fid] = [];
1040
-				}
1041
-
1042
-				$shares[$fid] = array_merge($shares[$fid], $data);
1043
-			}
1044
-			return $shares;
1045
-		}, []);
1046
-	}
1047
-
1048
-	/**
1049
-	 * @inheritdoc
1050
-	 */
1051
-	public function getSharesBy($userId, $shareType, $path = null, $reshares = false, $limit = 50, $offset = 0) {
1052
-		if ($path !== null &&
1053
-				!($path instanceof \OCP\Files\File) &&
1054
-				!($path instanceof \OCP\Files\Folder)) {
1055
-			throw new \InvalidArgumentException('invalid path');
1056
-		}
1057
-
1058
-		try {
1059
-			$provider = $this->factory->getProviderForType($shareType);
1060
-		} catch (ProviderException $e) {
1061
-			return [];
1062
-		}
1063
-
1064
-		$shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
1065
-
1066
-		/*
623
+            $share->setToken(
624
+                $this->secureRandom->generate(
625
+                    \OC\Share\Constants::TOKEN_LENGTH,
626
+                    \OCP\Security\ISecureRandom::CHAR_HUMAN_READABLE
627
+                )
628
+            );
629
+
630
+            //Verify the expiration date
631
+            $this->validateExpirationDate($share);
632
+
633
+            //Verify the password
634
+            $this->verifyPassword($share->getPassword());
635
+
636
+            // If a password is set. Hash it!
637
+            if ($share->getPassword() !== null) {
638
+                $share->setPassword($this->hasher->hash($share->getPassword()));
639
+            }
640
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
641
+            $share->setToken(
642
+                $this->secureRandom->generate(
643
+                    \OC\Share\Constants::TOKEN_LENGTH,
644
+                    \OCP\Security\ISecureRandom::CHAR_HUMAN_READABLE
645
+                )
646
+            );
647
+        }
648
+
649
+        // Cannot share with the owner
650
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
651
+            $share->getSharedWith() === $share->getShareOwner()) {
652
+            throw new \InvalidArgumentException('Can’t share with the share owner');
653
+        }
654
+
655
+        // Generate the target
656
+        $target = $this->config->getSystemValue('share_folder', '/') .'/'. $share->getNode()->getName();
657
+        $target = \OC\Files\Filesystem::normalizePath($target);
658
+        $share->setTarget($target);
659
+
660
+        // Pre share event
661
+        $event = new GenericEvent($share);
662
+        $a = $this->eventDispatcher->dispatch('OCP\Share::preShare', $event);
663
+        if ($event->isPropagationStopped() && $event->hasArgument('error')) {
664
+            throw new \Exception($event->getArgument('error'));
665
+        }
666
+
667
+        $oldShare = $share;
668
+        $provider = $this->factory->getProviderForType($share->getShareType());
669
+        $share = $provider->create($share);
670
+        //reuse the node we already have
671
+        $share->setNode($oldShare->getNode());
672
+
673
+        // Post share event
674
+        $event = new GenericEvent($share);
675
+        $this->eventDispatcher->dispatch('OCP\Share::postShare', $event);
676
+
677
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
678
+            $mailSend = $share->getMailSend();
679
+            if($mailSend === true) {
680
+                $user = $this->userManager->get($share->getSharedWith());
681
+                if ($user !== null) {
682
+                    $emailAddress = $user->getEMailAddress();
683
+                    if ($emailAddress !== null && $emailAddress !== '') {
684
+                        $userLang = $this->config->getUserValue($share->getSharedWith(), 'core', 'lang', null);
685
+                        $l = $this->l10nFactory->get('lib', $userLang);
686
+                        $this->sendMailNotification(
687
+                            $l,
688
+                            $share->getNode()->getName(),
689
+                            $this->urlGenerator->linkToRouteAbsolute('files.viewcontroller.showFile', ['fileid' => $share->getNode()->getId()]),
690
+                            $share->getSharedBy(),
691
+                            $emailAddress,
692
+                            $share->getExpirationDate()
693
+                        );
694
+                        $this->logger->debug('Send share notification to ' . $emailAddress . ' for share with ID ' . $share->getId(), ['app' => 'share']);
695
+                    } else {
696
+                        $this->logger->debug('Share notification not send to ' . $share->getSharedWith() . ' because email address is not set.', ['app' => 'share']);
697
+                    }
698
+                } else {
699
+                    $this->logger->debug('Share notification not send to ' . $share->getSharedWith() . ' because user could not be found.', ['app' => 'share']);
700
+                }
701
+            } else {
702
+                $this->logger->debug('Share notification not send because mailsend is false.', ['app' => 'share']);
703
+            }
704
+        }
705
+
706
+        return $share;
707
+    }
708
+
709
+    /**
710
+     * @param IL10N $l Language of the recipient
711
+     * @param string $filename file/folder name
712
+     * @param string $link link to the file/folder
713
+     * @param string $initiator user ID of share sender
714
+     * @param string $shareWith email address of share receiver
715
+     * @param \DateTime|null $expiration
716
+     * @throws \Exception If mail couldn't be sent
717
+     */
718
+    protected function sendMailNotification(IL10N $l,
719
+                                            $filename,
720
+                                            $link,
721
+                                            $initiator,
722
+                                            $shareWith,
723
+                                            \DateTime $expiration = null) {
724
+        $initiatorUser = $this->userManager->get($initiator);
725
+        $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
726
+
727
+        $message = $this->mailer->createMessage();
728
+
729
+        $emailTemplate = $this->mailer->createEMailTemplate('files_sharing.RecipientNotification', [
730
+            'filename' => $filename,
731
+            'link' => $link,
732
+            'initiator' => $initiatorDisplayName,
733
+            'expiration' => $expiration,
734
+            'shareWith' => $shareWith,
735
+        ]);
736
+
737
+        $emailTemplate->setSubject($l->t('%s shared »%s« with you', array($initiatorDisplayName, $filename)));
738
+        $emailTemplate->addHeader();
739
+        $emailTemplate->addHeading($l->t('%s shared »%s« with you', [$initiatorDisplayName, $filename]), false);
740
+        $text = $l->t('%s shared »%s« with you.', [$initiatorDisplayName, $filename]);
741
+
742
+        $emailTemplate->addBodyText(
743
+            htmlspecialchars($text . ' ' . $l->t('Click the button below to open it.')),
744
+            $text
745
+        );
746
+        $emailTemplate->addBodyButton(
747
+            $l->t('Open »%s«', [$filename]),
748
+            $link
749
+        );
750
+
751
+        $message->setTo([$shareWith]);
752
+
753
+        // The "From" contains the sharers name
754
+        $instanceName = $this->defaults->getName();
755
+        $senderName = $l->t(
756
+            '%s via %s',
757
+            [
758
+                $initiatorDisplayName,
759
+                $instanceName
760
+            ]
761
+        );
762
+        $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
763
+
764
+        // The "Reply-To" is set to the sharer if an mail address is configured
765
+        // also the default footer contains a "Do not reply" which needs to be adjusted.
766
+        $initiatorEmail = $initiatorUser->getEMailAddress();
767
+        if($initiatorEmail !== null) {
768
+            $message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
769
+            $emailTemplate->addFooter($instanceName . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : ''));
770
+        } else {
771
+            $emailTemplate->addFooter();
772
+        }
773
+
774
+        $message->useTemplate($emailTemplate);
775
+        $this->mailer->send($message);
776
+    }
777
+
778
+    /**
779
+     * Update a share
780
+     *
781
+     * @param \OCP\Share\IShare $share
782
+     * @return \OCP\Share\IShare The share object
783
+     * @throws \InvalidArgumentException
784
+     */
785
+    public function updateShare(\OCP\Share\IShare $share) {
786
+        $expirationDateUpdated = false;
787
+
788
+        $this->canShare($share);
789
+
790
+        try {
791
+            $originalShare = $this->getShareById($share->getFullId());
792
+        } catch (\UnexpectedValueException $e) {
793
+            throw new \InvalidArgumentException('Share does not have a full id');
794
+        }
795
+
796
+        // We can't change the share type!
797
+        if ($share->getShareType() !== $originalShare->getShareType()) {
798
+            throw new \InvalidArgumentException('Can’t change share type');
799
+        }
800
+
801
+        // We can only change the recipient on user shares
802
+        if ($share->getSharedWith() !== $originalShare->getSharedWith() &&
803
+            $share->getShareType() !== \OCP\Share::SHARE_TYPE_USER) {
804
+            throw new \InvalidArgumentException('Can only update recipient on user shares');
805
+        }
806
+
807
+        // Cannot share with the owner
808
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
809
+            $share->getSharedWith() === $share->getShareOwner()) {
810
+            throw new \InvalidArgumentException('Can’t share with the share owner');
811
+        }
812
+
813
+        $this->generalCreateChecks($share);
814
+
815
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
816
+            $this->userCreateChecks($share);
817
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
818
+            $this->groupCreateChecks($share);
819
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
820
+            $this->linkCreateChecks($share);
821
+
822
+            $this->updateSharePasswordIfNeeded($share, $originalShare);
823
+
824
+            if ($share->getExpirationDate() != $originalShare->getExpirationDate()) {
825
+                //Verify the expiration date
826
+                $this->validateExpirationDate($share);
827
+                $expirationDateUpdated = true;
828
+            }
829
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
830
+            // The new password is not set again if it is the same as the old
831
+            // one, unless when switching from sending by Talk to sending by
832
+            // mail.
833
+            $plainTextPassword = $share->getPassword();
834
+            if (!empty($plainTextPassword) && !$this->updateSharePasswordIfNeeded($share, $originalShare) &&
835
+                    !($originalShare->getSendPasswordByTalk() && !$share->getSendPasswordByTalk())) {
836
+                $plainTextPassword = null;
837
+            }
838
+            if (empty($plainTextPassword) && !$originalShare->getSendPasswordByTalk() && $share->getSendPasswordByTalk()) {
839
+                // If the same password was already sent by mail the recipient
840
+                // would already have access to the share without having to call
841
+                // the sharer to verify her identity
842
+                throw new \InvalidArgumentException('Can’t enable sending the password by Talk without setting a new password');
843
+            }
844
+        }
845
+
846
+        $this->pathCreateChecks($share->getNode());
847
+
848
+        // Now update the share!
849
+        $provider = $this->factory->getProviderForType($share->getShareType());
850
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
851
+            $share = $provider->update($share, $plainTextPassword);
852
+        } else {
853
+            $share = $provider->update($share);
854
+        }
855
+
856
+        if ($expirationDateUpdated === true) {
857
+            \OC_Hook::emit(Share::class, 'post_set_expiration_date', [
858
+                'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
859
+                'itemSource' => $share->getNode()->getId(),
860
+                'date' => $share->getExpirationDate(),
861
+                'uidOwner' => $share->getSharedBy(),
862
+            ]);
863
+        }
864
+
865
+        if ($share->getPassword() !== $originalShare->getPassword()) {
866
+            \OC_Hook::emit(Share::class, 'post_update_password', [
867
+                'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
868
+                'itemSource' => $share->getNode()->getId(),
869
+                'uidOwner' => $share->getSharedBy(),
870
+                'token' => $share->getToken(),
871
+                'disabled' => is_null($share->getPassword()),
872
+            ]);
873
+        }
874
+
875
+        if ($share->getPermissions() !== $originalShare->getPermissions()) {
876
+            if ($this->userManager->userExists($share->getShareOwner())) {
877
+                $userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
878
+            } else {
879
+                $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
880
+            }
881
+            \OC_Hook::emit(Share::class, 'post_update_permissions', array(
882
+                'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
883
+                'itemSource' => $share->getNode()->getId(),
884
+                'shareType' => $share->getShareType(),
885
+                'shareWith' => $share->getSharedWith(),
886
+                'uidOwner' => $share->getSharedBy(),
887
+                'permissions' => $share->getPermissions(),
888
+                'path' => $userFolder->getRelativePath($share->getNode()->getPath()),
889
+            ));
890
+        }
891
+
892
+        return $share;
893
+    }
894
+
895
+    /**
896
+     * Updates the password of the given share if it is not the same as the
897
+     * password of the original share.
898
+     *
899
+     * @param \OCP\Share\IShare $share the share to update its password.
900
+     * @param \OCP\Share\IShare $originalShare the original share to compare its
901
+     *        password with.
902
+     * @return boolean whether the password was updated or not.
903
+     */
904
+    private function updateSharePasswordIfNeeded(\OCP\Share\IShare $share, \OCP\Share\IShare $originalShare) {
905
+        // Password updated.
906
+        if ($share->getPassword() !== $originalShare->getPassword()) {
907
+            //Verify the password
908
+            $this->verifyPassword($share->getPassword());
909
+
910
+            // If a password is set. Hash it!
911
+            if ($share->getPassword() !== null) {
912
+                $share->setPassword($this->hasher->hash($share->getPassword()));
913
+
914
+                return true;
915
+            }
916
+        }
917
+
918
+        return false;
919
+    }
920
+
921
+    /**
922
+     * Delete all the children of this share
923
+     * FIXME: remove once https://github.com/owncloud/core/pull/21660 is in
924
+     *
925
+     * @param \OCP\Share\IShare $share
926
+     * @return \OCP\Share\IShare[] List of deleted shares
927
+     */
928
+    protected function deleteChildren(\OCP\Share\IShare $share) {
929
+        $deletedShares = [];
930
+
931
+        $provider = $this->factory->getProviderForType($share->getShareType());
932
+
933
+        foreach ($provider->getChildren($share) as $child) {
934
+            $deletedChildren = $this->deleteChildren($child);
935
+            $deletedShares = array_merge($deletedShares, $deletedChildren);
936
+
937
+            $provider->delete($child);
938
+            $deletedShares[] = $child;
939
+        }
940
+
941
+        return $deletedShares;
942
+    }
943
+
944
+    /**
945
+     * Delete a share
946
+     *
947
+     * @param \OCP\Share\IShare $share
948
+     * @throws ShareNotFound
949
+     * @throws \InvalidArgumentException
950
+     */
951
+    public function deleteShare(\OCP\Share\IShare $share) {
952
+
953
+        try {
954
+            $share->getFullId();
955
+        } catch (\UnexpectedValueException $e) {
956
+            throw new \InvalidArgumentException('Share does not have a full id');
957
+        }
958
+
959
+        $event = new GenericEvent($share);
960
+        $this->eventDispatcher->dispatch('OCP\Share::preUnshare', $event);
961
+
962
+        // Get all children and delete them as well
963
+        $deletedShares = $this->deleteChildren($share);
964
+
965
+        // Do the actual delete
966
+        $provider = $this->factory->getProviderForType($share->getShareType());
967
+        $provider->delete($share);
968
+
969
+        // All the deleted shares caused by this delete
970
+        $deletedShares[] = $share;
971
+
972
+        // Emit post hook
973
+        $event->setArgument('deletedShares', $deletedShares);
974
+        $this->eventDispatcher->dispatch('OCP\Share::postUnshare', $event);
975
+    }
976
+
977
+
978
+    /**
979
+     * Unshare a file as the recipient.
980
+     * This can be different from a regular delete for example when one of
981
+     * the users in a groups deletes that share. But the provider should
982
+     * handle this.
983
+     *
984
+     * @param \OCP\Share\IShare $share
985
+     * @param string $recipientId
986
+     */
987
+    public function deleteFromSelf(\OCP\Share\IShare $share, $recipientId) {
988
+        list($providerId, ) = $this->splitFullId($share->getFullId());
989
+        $provider = $this->factory->getProvider($providerId);
990
+
991
+        $provider->deleteFromSelf($share, $recipientId);
992
+        $event = new GenericEvent($share);
993
+        $this->eventDispatcher->dispatch('OCP\Share::postUnshareFromSelf', $event);
994
+    }
995
+
996
+    public function restoreShare(IShare $share, string $recipientId): IShare {
997
+        list($providerId, ) = $this->splitFullId($share->getFullId());
998
+        $provider = $this->factory->getProvider($providerId);
999
+
1000
+        return $provider->restore($share, $recipientId);
1001
+    }
1002
+
1003
+    /**
1004
+     * @inheritdoc
1005
+     */
1006
+    public function moveShare(\OCP\Share\IShare $share, $recipientId) {
1007
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
1008
+            throw new \InvalidArgumentException('Can’t change target of link share');
1009
+        }
1010
+
1011
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER && $share->getSharedWith() !== $recipientId) {
1012
+            throw new \InvalidArgumentException('Invalid recipient');
1013
+        }
1014
+
1015
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
1016
+            $sharedWith = $this->groupManager->get($share->getSharedWith());
1017
+            if (is_null($sharedWith)) {
1018
+                throw new \InvalidArgumentException('Group "' . $share->getSharedWith() . '" does not exist');
1019
+            }
1020
+            $recipient = $this->userManager->get($recipientId);
1021
+            if (!$sharedWith->inGroup($recipient)) {
1022
+                throw new \InvalidArgumentException('Invalid recipient');
1023
+            }
1024
+        }
1025
+
1026
+        list($providerId, ) = $this->splitFullId($share->getFullId());
1027
+        $provider = $this->factory->getProvider($providerId);
1028
+
1029
+        $provider->move($share, $recipientId);
1030
+    }
1031
+
1032
+    public function getSharesInFolder($userId, Folder $node, $reshares = false) {
1033
+        $providers = $this->factory->getAllProviders();
1034
+
1035
+        return array_reduce($providers, function($shares, IShareProvider $provider) use ($userId, $node, $reshares) {
1036
+            $newShares = $provider->getSharesInFolder($userId, $node, $reshares);
1037
+            foreach ($newShares as $fid => $data) {
1038
+                if (!isset($shares[$fid])) {
1039
+                    $shares[$fid] = [];
1040
+                }
1041
+
1042
+                $shares[$fid] = array_merge($shares[$fid], $data);
1043
+            }
1044
+            return $shares;
1045
+        }, []);
1046
+    }
1047
+
1048
+    /**
1049
+     * @inheritdoc
1050
+     */
1051
+    public function getSharesBy($userId, $shareType, $path = null, $reshares = false, $limit = 50, $offset = 0) {
1052
+        if ($path !== null &&
1053
+                !($path instanceof \OCP\Files\File) &&
1054
+                !($path instanceof \OCP\Files\Folder)) {
1055
+            throw new \InvalidArgumentException('invalid path');
1056
+        }
1057
+
1058
+        try {
1059
+            $provider = $this->factory->getProviderForType($shareType);
1060
+        } catch (ProviderException $e) {
1061
+            return [];
1062
+        }
1063
+
1064
+        $shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
1065
+
1066
+        /*
1067 1067
 		 * Work around so we don't return expired shares but still follow
1068 1068
 		 * proper pagination.
1069 1069
 		 */
1070 1070
 
1071
-		$shares2 = [];
1072
-
1073
-		while(true) {
1074
-			$added = 0;
1075
-			foreach ($shares as $share) {
1076
-
1077
-				try {
1078
-					$this->checkExpireDate($share);
1079
-				} catch (ShareNotFound $e) {
1080
-					//Ignore since this basically means the share is deleted
1081
-					continue;
1082
-				}
1083
-
1084
-				$added++;
1085
-				$shares2[] = $share;
1086
-
1087
-				if (count($shares2) === $limit) {
1088
-					break;
1089
-				}
1090
-			}
1091
-
1092
-			// If we did not fetch more shares than the limit then there are no more shares
1093
-			if (count($shares) < $limit) {
1094
-				break;
1095
-			}
1096
-
1097
-			if (count($shares2) === $limit) {
1098
-				break;
1099
-			}
1100
-
1101
-			// If there was no limit on the select we are done
1102
-			if ($limit === -1) {
1103
-				break;
1104
-			}
1105
-
1106
-			$offset += $added;
1107
-
1108
-			// Fetch again $limit shares
1109
-			$shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
1110
-
1111
-			// No more shares means we are done
1112
-			if (empty($shares)) {
1113
-				break;
1114
-			}
1115
-		}
1116
-
1117
-		$shares = $shares2;
1118
-
1119
-		return $shares;
1120
-	}
1121
-
1122
-	/**
1123
-	 * @inheritdoc
1124
-	 */
1125
-	public function getSharedWith($userId, $shareType, $node = null, $limit = 50, $offset = 0) {
1126
-		try {
1127
-			$provider = $this->factory->getProviderForType($shareType);
1128
-		} catch (ProviderException $e) {
1129
-			return [];
1130
-		}
1131
-
1132
-		$shares = $provider->getSharedWith($userId, $shareType, $node, $limit, $offset);
1133
-
1134
-		// remove all shares which are already expired
1135
-		foreach ($shares as $key => $share) {
1136
-			try {
1137
-				$this->checkExpireDate($share);
1138
-			} catch (ShareNotFound $e) {
1139
-				unset($shares[$key]);
1140
-			}
1141
-		}
1142
-
1143
-		return $shares;
1144
-	}
1145
-
1146
-	/**
1147
-	 * @inheritdoc
1148
-	 */
1149
-	public function getDeletedSharedWith($userId, $shareType, $node = null, $limit = 50, $offset = 0) {
1150
-		$shares = $this->getSharedWith($userId, $shareType, $node, $limit, $offset);
1151
-
1152
-		// Only get deleted shares
1153
-		$shares = array_filter($shares, function(IShare $share) {
1154
-			return $share->getPermissions() === 0;
1155
-		});
1156
-
1157
-		// Only get shares where the owner still exists
1158
-		$shares = array_filter($shares, function (IShare $share) {
1159
-			return $this->userManager->userExists($share->getShareOwner());
1160
-		});
1161
-
1162
-		return $shares;
1163
-	}
1164
-
1165
-	/**
1166
-	 * @inheritdoc
1167
-	 */
1168
-	public function getShareById($id, $recipient = null) {
1169
-		if ($id === null) {
1170
-			throw new ShareNotFound();
1171
-		}
1172
-
1173
-		list($providerId, $id) = $this->splitFullId($id);
1174
-
1175
-		try {
1176
-			$provider = $this->factory->getProvider($providerId);
1177
-		} catch (ProviderException $e) {
1178
-			throw new ShareNotFound();
1179
-		}
1180
-
1181
-		$share = $provider->getShareById($id, $recipient);
1182
-
1183
-		$this->checkExpireDate($share);
1184
-
1185
-		return $share;
1186
-	}
1187
-
1188
-	/**
1189
-	 * Get all the shares for a given path
1190
-	 *
1191
-	 * @param \OCP\Files\Node $path
1192
-	 * @param int $page
1193
-	 * @param int $perPage
1194
-	 *
1195
-	 * @return Share[]
1196
-	 */
1197
-	public function getSharesByPath(\OCP\Files\Node $path, $page=0, $perPage=50) {
1198
-		return [];
1199
-	}
1200
-
1201
-	/**
1202
-	 * Get the share by token possible with password
1203
-	 *
1204
-	 * @param string $token
1205
-	 * @return Share
1206
-	 *
1207
-	 * @throws ShareNotFound
1208
-	 */
1209
-	public function getShareByToken($token) {
1210
-		$share = null;
1211
-		try {
1212
-			if($this->shareApiAllowLinks()) {
1213
-				$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_LINK);
1214
-				$share = $provider->getShareByToken($token);
1215
-			}
1216
-		} catch (ProviderException $e) {
1217
-		} catch (ShareNotFound $e) {
1218
-		}
1219
-
1220
-
1221
-		// If it is not a link share try to fetch a federated share by token
1222
-		if ($share === null) {
1223
-			try {
1224
-				$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_REMOTE);
1225
-				$share = $provider->getShareByToken($token);
1226
-			} catch (ProviderException $e) {
1227
-			} catch (ShareNotFound $e) {
1228
-			}
1229
-		}
1230
-
1231
-		// If it is not a link share try to fetch a mail share by token
1232
-		if ($share === null && $this->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
1233
-			try {
1234
-				$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_EMAIL);
1235
-				$share = $provider->getShareByToken($token);
1236
-			} catch (ProviderException $e) {
1237
-			} catch (ShareNotFound $e) {
1238
-			}
1239
-		}
1240
-
1241
-		if ($share === null && $this->shareProviderExists(\OCP\Share::SHARE_TYPE_CIRCLE)) {
1242
-			try {
1243
-				$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_CIRCLE);
1244
-				$share = $provider->getShareByToken($token);
1245
-			} catch (ProviderException $e) {
1246
-			} catch (ShareNotFound $e) {
1247
-			}
1248
-		}
1249
-
1250
-		if ($share === null) {
1251
-			throw new ShareNotFound($this->l->t('The requested share does not exist anymore'));
1252
-		}
1253
-
1254
-		$this->checkExpireDate($share);
1255
-
1256
-		/*
1071
+        $shares2 = [];
1072
+
1073
+        while(true) {
1074
+            $added = 0;
1075
+            foreach ($shares as $share) {
1076
+
1077
+                try {
1078
+                    $this->checkExpireDate($share);
1079
+                } catch (ShareNotFound $e) {
1080
+                    //Ignore since this basically means the share is deleted
1081
+                    continue;
1082
+                }
1083
+
1084
+                $added++;
1085
+                $shares2[] = $share;
1086
+
1087
+                if (count($shares2) === $limit) {
1088
+                    break;
1089
+                }
1090
+            }
1091
+
1092
+            // If we did not fetch more shares than the limit then there are no more shares
1093
+            if (count($shares) < $limit) {
1094
+                break;
1095
+            }
1096
+
1097
+            if (count($shares2) === $limit) {
1098
+                break;
1099
+            }
1100
+
1101
+            // If there was no limit on the select we are done
1102
+            if ($limit === -1) {
1103
+                break;
1104
+            }
1105
+
1106
+            $offset += $added;
1107
+
1108
+            // Fetch again $limit shares
1109
+            $shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
1110
+
1111
+            // No more shares means we are done
1112
+            if (empty($shares)) {
1113
+                break;
1114
+            }
1115
+        }
1116
+
1117
+        $shares = $shares2;
1118
+
1119
+        return $shares;
1120
+    }
1121
+
1122
+    /**
1123
+     * @inheritdoc
1124
+     */
1125
+    public function getSharedWith($userId, $shareType, $node = null, $limit = 50, $offset = 0) {
1126
+        try {
1127
+            $provider = $this->factory->getProviderForType($shareType);
1128
+        } catch (ProviderException $e) {
1129
+            return [];
1130
+        }
1131
+
1132
+        $shares = $provider->getSharedWith($userId, $shareType, $node, $limit, $offset);
1133
+
1134
+        // remove all shares which are already expired
1135
+        foreach ($shares as $key => $share) {
1136
+            try {
1137
+                $this->checkExpireDate($share);
1138
+            } catch (ShareNotFound $e) {
1139
+                unset($shares[$key]);
1140
+            }
1141
+        }
1142
+
1143
+        return $shares;
1144
+    }
1145
+
1146
+    /**
1147
+     * @inheritdoc
1148
+     */
1149
+    public function getDeletedSharedWith($userId, $shareType, $node = null, $limit = 50, $offset = 0) {
1150
+        $shares = $this->getSharedWith($userId, $shareType, $node, $limit, $offset);
1151
+
1152
+        // Only get deleted shares
1153
+        $shares = array_filter($shares, function(IShare $share) {
1154
+            return $share->getPermissions() === 0;
1155
+        });
1156
+
1157
+        // Only get shares where the owner still exists
1158
+        $shares = array_filter($shares, function (IShare $share) {
1159
+            return $this->userManager->userExists($share->getShareOwner());
1160
+        });
1161
+
1162
+        return $shares;
1163
+    }
1164
+
1165
+    /**
1166
+     * @inheritdoc
1167
+     */
1168
+    public function getShareById($id, $recipient = null) {
1169
+        if ($id === null) {
1170
+            throw new ShareNotFound();
1171
+        }
1172
+
1173
+        list($providerId, $id) = $this->splitFullId($id);
1174
+
1175
+        try {
1176
+            $provider = $this->factory->getProvider($providerId);
1177
+        } catch (ProviderException $e) {
1178
+            throw new ShareNotFound();
1179
+        }
1180
+
1181
+        $share = $provider->getShareById($id, $recipient);
1182
+
1183
+        $this->checkExpireDate($share);
1184
+
1185
+        return $share;
1186
+    }
1187
+
1188
+    /**
1189
+     * Get all the shares for a given path
1190
+     *
1191
+     * @param \OCP\Files\Node $path
1192
+     * @param int $page
1193
+     * @param int $perPage
1194
+     *
1195
+     * @return Share[]
1196
+     */
1197
+    public function getSharesByPath(\OCP\Files\Node $path, $page=0, $perPage=50) {
1198
+        return [];
1199
+    }
1200
+
1201
+    /**
1202
+     * Get the share by token possible with password
1203
+     *
1204
+     * @param string $token
1205
+     * @return Share
1206
+     *
1207
+     * @throws ShareNotFound
1208
+     */
1209
+    public function getShareByToken($token) {
1210
+        $share = null;
1211
+        try {
1212
+            if($this->shareApiAllowLinks()) {
1213
+                $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_LINK);
1214
+                $share = $provider->getShareByToken($token);
1215
+            }
1216
+        } catch (ProviderException $e) {
1217
+        } catch (ShareNotFound $e) {
1218
+        }
1219
+
1220
+
1221
+        // If it is not a link share try to fetch a federated share by token
1222
+        if ($share === null) {
1223
+            try {
1224
+                $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_REMOTE);
1225
+                $share = $provider->getShareByToken($token);
1226
+            } catch (ProviderException $e) {
1227
+            } catch (ShareNotFound $e) {
1228
+            }
1229
+        }
1230
+
1231
+        // If it is not a link share try to fetch a mail share by token
1232
+        if ($share === null && $this->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
1233
+            try {
1234
+                $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_EMAIL);
1235
+                $share = $provider->getShareByToken($token);
1236
+            } catch (ProviderException $e) {
1237
+            } catch (ShareNotFound $e) {
1238
+            }
1239
+        }
1240
+
1241
+        if ($share === null && $this->shareProviderExists(\OCP\Share::SHARE_TYPE_CIRCLE)) {
1242
+            try {
1243
+                $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_CIRCLE);
1244
+                $share = $provider->getShareByToken($token);
1245
+            } catch (ProviderException $e) {
1246
+            } catch (ShareNotFound $e) {
1247
+            }
1248
+        }
1249
+
1250
+        if ($share === null) {
1251
+            throw new ShareNotFound($this->l->t('The requested share does not exist anymore'));
1252
+        }
1253
+
1254
+        $this->checkExpireDate($share);
1255
+
1256
+        /*
1257 1257
 		 * Reduce the permissions for link shares if public upload is not enabled
1258 1258
 		 */
1259
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK &&
1260
-			!$this->shareApiLinkAllowPublicUpload()) {
1261
-			$share->setPermissions($share->getPermissions() & ~(\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE));
1262
-		}
1263
-
1264
-		return $share;
1265
-	}
1266
-
1267
-	protected function checkExpireDate($share) {
1268
-		if ($share->getExpirationDate() !== null &&
1269
-			$share->getExpirationDate() <= new \DateTime()) {
1270
-			$this->deleteShare($share);
1271
-			throw new ShareNotFound($this->l->t('The requested share does not exist anymore'));
1272
-		}
1273
-
1274
-	}
1275
-
1276
-	/**
1277
-	 * Verify the password of a public share
1278
-	 *
1279
-	 * @param \OCP\Share\IShare $share
1280
-	 * @param string $password
1281
-	 * @return bool
1282
-	 */
1283
-	public function checkPassword(\OCP\Share\IShare $share, $password) {
1284
-		$passwordProtected = $share->getShareType() !== \OCP\Share::SHARE_TYPE_LINK
1285
-			|| $share->getShareType() !== \OCP\Share::SHARE_TYPE_EMAIL;
1286
-		if (!$passwordProtected) {
1287
-			//TODO maybe exception?
1288
-			return false;
1289
-		}
1290
-
1291
-		if ($password === null || $share->getPassword() === null) {
1292
-			return false;
1293
-		}
1294
-
1295
-		$newHash = '';
1296
-		if (!$this->hasher->verify($password, $share->getPassword(), $newHash)) {
1297
-			return false;
1298
-		}
1299
-
1300
-		if (!empty($newHash)) {
1301
-			$share->setPassword($newHash);
1302
-			$provider = $this->factory->getProviderForType($share->getShareType());
1303
-			$provider->update($share);
1304
-		}
1305
-
1306
-		return true;
1307
-	}
1308
-
1309
-	/**
1310
-	 * @inheritdoc
1311
-	 */
1312
-	public function userDeleted($uid) {
1313
-		$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];
1314
-
1315
-		foreach ($types as $type) {
1316
-			try {
1317
-				$provider = $this->factory->getProviderForType($type);
1318
-			} catch (ProviderException $e) {
1319
-				continue;
1320
-			}
1321
-			$provider->userDeleted($uid, $type);
1322
-		}
1323
-	}
1324
-
1325
-	/**
1326
-	 * @inheritdoc
1327
-	 */
1328
-	public function groupDeleted($gid) {
1329
-		$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
1330
-		$provider->groupDeleted($gid);
1331
-	}
1332
-
1333
-	/**
1334
-	 * @inheritdoc
1335
-	 */
1336
-	public function userDeletedFromGroup($uid, $gid) {
1337
-		$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
1338
-		$provider->userDeletedFromGroup($uid, $gid);
1339
-	}
1340
-
1341
-	/**
1342
-	 * Get access list to a path. This means
1343
-	 * all the users that can access a given path.
1344
-	 *
1345
-	 * Consider:
1346
-	 * -root
1347
-	 * |-folder1 (23)
1348
-	 *  |-folder2 (32)
1349
-	 *   |-fileA (42)
1350
-	 *
1351
-	 * fileA is shared with user1 and user1@server1
1352
-	 * folder2 is shared with group2 (user4 is a member of group2)
1353
-	 * folder1 is shared with user2 (renamed to "folder (1)") and user2@server2
1354
-	 *
1355
-	 * Then the access list to '/folder1/folder2/fileA' with $currentAccess is:
1356
-	 * [
1357
-	 *  users  => [
1358
-	 *      'user1' => ['node_id' => 42, 'node_path' => '/fileA'],
1359
-	 *      'user4' => ['node_id' => 32, 'node_path' => '/folder2'],
1360
-	 *      'user2' => ['node_id' => 23, 'node_path' => '/folder (1)'],
1361
-	 *  ],
1362
-	 *  remote => [
1363
-	 *      'user1@server1' => ['node_id' => 42, 'token' => 'SeCr3t'],
1364
-	 *      'user2@server2' => ['node_id' => 23, 'token' => 'FooBaR'],
1365
-	 *  ],
1366
-	 *  public => bool
1367
-	 *  mail => bool
1368
-	 * ]
1369
-	 *
1370
-	 * The access list to '/folder1/folder2/fileA' **without** $currentAccess is:
1371
-	 * [
1372
-	 *  users  => ['user1', 'user2', 'user4'],
1373
-	 *  remote => bool,
1374
-	 *  public => bool
1375
-	 *  mail => bool
1376
-	 * ]
1377
-	 *
1378
-	 * This is required for encryption/activity
1379
-	 *
1380
-	 * @param \OCP\Files\Node $path
1381
-	 * @param bool $recursive Should we check all parent folders as well
1382
-	 * @param bool $currentAccess Ensure the recipient has access to the file (e.g. did not unshare it)
1383
-	 * @return array
1384
-	 */
1385
-	public function getAccessList(\OCP\Files\Node $path, $recursive = true, $currentAccess = false) {
1386
-		$owner = $path->getOwner()->getUID();
1387
-
1388
-		if ($currentAccess) {
1389
-			$al = ['users' => [], 'remote' => [], 'public' => false];
1390
-		} else {
1391
-			$al = ['users' => [], 'remote' => false, 'public' => false];
1392
-		}
1393
-		if (!$this->userManager->userExists($owner)) {
1394
-			return $al;
1395
-		}
1396
-
1397
-		//Get node for the owner
1398
-		$userFolder = $this->rootFolder->getUserFolder($owner);
1399
-		if ($path->getId() !== $userFolder->getId() && !$userFolder->isSubNode($path)) {
1400
-			$path = $userFolder->getById($path->getId())[0];
1401
-		}
1402
-
1403
-		$providers = $this->factory->getAllProviders();
1404
-
1405
-		/** @var Node[] $nodes */
1406
-		$nodes = [];
1407
-
1408
-
1409
-		if ($currentAccess) {
1410
-			$ownerPath = $path->getPath();
1411
-			$ownerPath = explode('/', $ownerPath, 4);
1412
-			if (count($ownerPath) < 4) {
1413
-				$ownerPath = '';
1414
-			} else {
1415
-				$ownerPath = $ownerPath[3];
1416
-			}
1417
-			$al['users'][$owner] = [
1418
-				'node_id' => $path->getId(),
1419
-				'node_path' => '/' . $ownerPath,
1420
-			];
1421
-		} else {
1422
-			$al['users'][] = $owner;
1423
-		}
1424
-
1425
-		// Collect all the shares
1426
-		while ($path->getPath() !== $userFolder->getPath()) {
1427
-			$nodes[] = $path;
1428
-			if (!$recursive) {
1429
-				break;
1430
-			}
1431
-			$path = $path->getParent();
1432
-		}
1433
-
1434
-		foreach ($providers as $provider) {
1435
-			$tmp = $provider->getAccessList($nodes, $currentAccess);
1436
-
1437
-			foreach ($tmp as $k => $v) {
1438
-				if (isset($al[$k])) {
1439
-					if (is_array($al[$k])) {
1440
-						if ($currentAccess) {
1441
-							$al[$k] += $v;
1442
-						} else {
1443
-							$al[$k] = array_merge($al[$k], $v);
1444
-							$al[$k] = array_unique($al[$k]);
1445
-							$al[$k] = array_values($al[$k]);
1446
-						}
1447
-					} else {
1448
-						$al[$k] = $al[$k] || $v;
1449
-					}
1450
-				} else {
1451
-					$al[$k] = $v;
1452
-				}
1453
-			}
1454
-		}
1455
-
1456
-		return $al;
1457
-	}
1458
-
1459
-	/**
1460
-	 * Create a new share
1461
-	 * @return \OCP\Share\IShare
1462
-	 */
1463
-	public function newShare() {
1464
-		return new \OC\Share20\Share($this->rootFolder, $this->userManager);
1465
-	}
1466
-
1467
-	/**
1468
-	 * Is the share API enabled
1469
-	 *
1470
-	 * @return bool
1471
-	 */
1472
-	public function shareApiEnabled() {
1473
-		return $this->config->getAppValue('core', 'shareapi_enabled', 'yes') === 'yes';
1474
-	}
1475
-
1476
-	/**
1477
-	 * Is public link sharing enabled
1478
-	 *
1479
-	 * @return bool
1480
-	 */
1481
-	public function shareApiAllowLinks() {
1482
-		return $this->config->getAppValue('core', 'shareapi_allow_links', 'yes') === 'yes';
1483
-	}
1484
-
1485
-	/**
1486
-	 * Is password on public link requires
1487
-	 *
1488
-	 * @return bool
1489
-	 */
1490
-	public function shareApiLinkEnforcePassword() {
1491
-		return $this->config->getAppValue('core', 'shareapi_enforce_links_password', 'no') === 'yes';
1492
-	}
1493
-
1494
-	/**
1495
-	 * Is default expire date enabled
1496
-	 *
1497
-	 * @return bool
1498
-	 */
1499
-	public function shareApiLinkDefaultExpireDate() {
1500
-		return $this->config->getAppValue('core', 'shareapi_default_expire_date', 'no') === 'yes';
1501
-	}
1502
-
1503
-	/**
1504
-	 * Is default expire date enforced
1505
-	 *`
1506
-	 * @return bool
1507
-	 */
1508
-	public function shareApiLinkDefaultExpireDateEnforced() {
1509
-		return $this->shareApiLinkDefaultExpireDate() &&
1510
-			$this->config->getAppValue('core', 'shareapi_enforce_expire_date', 'no') === 'yes';
1511
-	}
1512
-
1513
-	/**
1514
-	 * Number of default expire days
1515
-	 *shareApiLinkAllowPublicUpload
1516
-	 * @return int
1517
-	 */
1518
-	public function shareApiLinkDefaultExpireDays() {
1519
-		return (int)$this->config->getAppValue('core', 'shareapi_expire_after_n_days', '7');
1520
-	}
1521
-
1522
-	/**
1523
-	 * Allow public upload on link shares
1524
-	 *
1525
-	 * @return bool
1526
-	 */
1527
-	public function shareApiLinkAllowPublicUpload() {
1528
-		return $this->config->getAppValue('core', 'shareapi_allow_public_upload', 'yes') === 'yes';
1529
-	}
1530
-
1531
-	/**
1532
-	 * check if user can only share with group members
1533
-	 * @return bool
1534
-	 */
1535
-	public function shareWithGroupMembersOnly() {
1536
-		return $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
1537
-	}
1538
-
1539
-	/**
1540
-	 * Check if users can share with groups
1541
-	 * @return bool
1542
-	 */
1543
-	public function allowGroupSharing() {
1544
-		return $this->config->getAppValue('core', 'shareapi_allow_group_sharing', 'yes') === 'yes';
1545
-	}
1546
-
1547
-	/**
1548
-	 * Copied from \OC_Util::isSharingDisabledForUser
1549
-	 *
1550
-	 * TODO: Deprecate fuction from OC_Util
1551
-	 *
1552
-	 * @param string $userId
1553
-	 * @return bool
1554
-	 */
1555
-	public function sharingDisabledForUser($userId) {
1556
-		if ($userId === null) {
1557
-			return false;
1558
-		}
1559
-
1560
-		if (isset($this->sharingDisabledForUsersCache[$userId])) {
1561
-			return $this->sharingDisabledForUsersCache[$userId];
1562
-		}
1563
-
1564
-		if ($this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes') {
1565
-			$groupsList = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
1566
-			$excludedGroups = json_decode($groupsList);
1567
-			if (is_null($excludedGroups)) {
1568
-				$excludedGroups = explode(',', $groupsList);
1569
-				$newValue = json_encode($excludedGroups);
1570
-				$this->config->setAppValue('core', 'shareapi_exclude_groups_list', $newValue);
1571
-			}
1572
-			$user = $this->userManager->get($userId);
1573
-			$usersGroups = $this->groupManager->getUserGroupIds($user);
1574
-			if (!empty($usersGroups)) {
1575
-				$remainingGroups = array_diff($usersGroups, $excludedGroups);
1576
-				// if the user is only in groups which are disabled for sharing then
1577
-				// sharing is also disabled for the user
1578
-				if (empty($remainingGroups)) {
1579
-					$this->sharingDisabledForUsersCache[$userId] = true;
1580
-					return true;
1581
-				}
1582
-			}
1583
-		}
1584
-
1585
-		$this->sharingDisabledForUsersCache[$userId] = false;
1586
-		return false;
1587
-	}
1588
-
1589
-	/**
1590
-	 * @inheritdoc
1591
-	 */
1592
-	public function outgoingServer2ServerSharesAllowed() {
1593
-		return $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') === 'yes';
1594
-	}
1595
-
1596
-	/**
1597
-	 * @inheritdoc
1598
-	 */
1599
-	public function outgoingServer2ServerGroupSharesAllowed() {
1600
-		return $this->config->getAppValue('files_sharing', 'outgoing_server2server_group_share_enabled', 'no') === 'yes';
1601
-	}
1602
-
1603
-	/**
1604
-	 * @inheritdoc
1605
-	 */
1606
-	public function shareProviderExists($shareType) {
1607
-		try {
1608
-			$this->factory->getProviderForType($shareType);
1609
-		} catch (ProviderException $e) {
1610
-			return false;
1611
-		}
1612
-
1613
-		return true;
1614
-	}
1259
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK &&
1260
+            !$this->shareApiLinkAllowPublicUpload()) {
1261
+            $share->setPermissions($share->getPermissions() & ~(\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE));
1262
+        }
1263
+
1264
+        return $share;
1265
+    }
1266
+
1267
+    protected function checkExpireDate($share) {
1268
+        if ($share->getExpirationDate() !== null &&
1269
+            $share->getExpirationDate() <= new \DateTime()) {
1270
+            $this->deleteShare($share);
1271
+            throw new ShareNotFound($this->l->t('The requested share does not exist anymore'));
1272
+        }
1273
+
1274
+    }
1275
+
1276
+    /**
1277
+     * Verify the password of a public share
1278
+     *
1279
+     * @param \OCP\Share\IShare $share
1280
+     * @param string $password
1281
+     * @return bool
1282
+     */
1283
+    public function checkPassword(\OCP\Share\IShare $share, $password) {
1284
+        $passwordProtected = $share->getShareType() !== \OCP\Share::SHARE_TYPE_LINK
1285
+            || $share->getShareType() !== \OCP\Share::SHARE_TYPE_EMAIL;
1286
+        if (!$passwordProtected) {
1287
+            //TODO maybe exception?
1288
+            return false;
1289
+        }
1290
+
1291
+        if ($password === null || $share->getPassword() === null) {
1292
+            return false;
1293
+        }
1294
+
1295
+        $newHash = '';
1296
+        if (!$this->hasher->verify($password, $share->getPassword(), $newHash)) {
1297
+            return false;
1298
+        }
1299
+
1300
+        if (!empty($newHash)) {
1301
+            $share->setPassword($newHash);
1302
+            $provider = $this->factory->getProviderForType($share->getShareType());
1303
+            $provider->update($share);
1304
+        }
1305
+
1306
+        return true;
1307
+    }
1308
+
1309
+    /**
1310
+     * @inheritdoc
1311
+     */
1312
+    public function userDeleted($uid) {
1313
+        $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];
1314
+
1315
+        foreach ($types as $type) {
1316
+            try {
1317
+                $provider = $this->factory->getProviderForType($type);
1318
+            } catch (ProviderException $e) {
1319
+                continue;
1320
+            }
1321
+            $provider->userDeleted($uid, $type);
1322
+        }
1323
+    }
1324
+
1325
+    /**
1326
+     * @inheritdoc
1327
+     */
1328
+    public function groupDeleted($gid) {
1329
+        $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
1330
+        $provider->groupDeleted($gid);
1331
+    }
1332
+
1333
+    /**
1334
+     * @inheritdoc
1335
+     */
1336
+    public function userDeletedFromGroup($uid, $gid) {
1337
+        $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
1338
+        $provider->userDeletedFromGroup($uid, $gid);
1339
+    }
1340
+
1341
+    /**
1342
+     * Get access list to a path. This means
1343
+     * all the users that can access a given path.
1344
+     *
1345
+     * Consider:
1346
+     * -root
1347
+     * |-folder1 (23)
1348
+     *  |-folder2 (32)
1349
+     *   |-fileA (42)
1350
+     *
1351
+     * fileA is shared with user1 and user1@server1
1352
+     * folder2 is shared with group2 (user4 is a member of group2)
1353
+     * folder1 is shared with user2 (renamed to "folder (1)") and user2@server2
1354
+     *
1355
+     * Then the access list to '/folder1/folder2/fileA' with $currentAccess is:
1356
+     * [
1357
+     *  users  => [
1358
+     *      'user1' => ['node_id' => 42, 'node_path' => '/fileA'],
1359
+     *      'user4' => ['node_id' => 32, 'node_path' => '/folder2'],
1360
+     *      'user2' => ['node_id' => 23, 'node_path' => '/folder (1)'],
1361
+     *  ],
1362
+     *  remote => [
1363
+     *      'user1@server1' => ['node_id' => 42, 'token' => 'SeCr3t'],
1364
+     *      'user2@server2' => ['node_id' => 23, 'token' => 'FooBaR'],
1365
+     *  ],
1366
+     *  public => bool
1367
+     *  mail => bool
1368
+     * ]
1369
+     *
1370
+     * The access list to '/folder1/folder2/fileA' **without** $currentAccess is:
1371
+     * [
1372
+     *  users  => ['user1', 'user2', 'user4'],
1373
+     *  remote => bool,
1374
+     *  public => bool
1375
+     *  mail => bool
1376
+     * ]
1377
+     *
1378
+     * This is required for encryption/activity
1379
+     *
1380
+     * @param \OCP\Files\Node $path
1381
+     * @param bool $recursive Should we check all parent folders as well
1382
+     * @param bool $currentAccess Ensure the recipient has access to the file (e.g. did not unshare it)
1383
+     * @return array
1384
+     */
1385
+    public function getAccessList(\OCP\Files\Node $path, $recursive = true, $currentAccess = false) {
1386
+        $owner = $path->getOwner()->getUID();
1387
+
1388
+        if ($currentAccess) {
1389
+            $al = ['users' => [], 'remote' => [], 'public' => false];
1390
+        } else {
1391
+            $al = ['users' => [], 'remote' => false, 'public' => false];
1392
+        }
1393
+        if (!$this->userManager->userExists($owner)) {
1394
+            return $al;
1395
+        }
1396
+
1397
+        //Get node for the owner
1398
+        $userFolder = $this->rootFolder->getUserFolder($owner);
1399
+        if ($path->getId() !== $userFolder->getId() && !$userFolder->isSubNode($path)) {
1400
+            $path = $userFolder->getById($path->getId())[0];
1401
+        }
1402
+
1403
+        $providers = $this->factory->getAllProviders();
1404
+
1405
+        /** @var Node[] $nodes */
1406
+        $nodes = [];
1407
+
1408
+
1409
+        if ($currentAccess) {
1410
+            $ownerPath = $path->getPath();
1411
+            $ownerPath = explode('/', $ownerPath, 4);
1412
+            if (count($ownerPath) < 4) {
1413
+                $ownerPath = '';
1414
+            } else {
1415
+                $ownerPath = $ownerPath[3];
1416
+            }
1417
+            $al['users'][$owner] = [
1418
+                'node_id' => $path->getId(),
1419
+                'node_path' => '/' . $ownerPath,
1420
+            ];
1421
+        } else {
1422
+            $al['users'][] = $owner;
1423
+        }
1424
+
1425
+        // Collect all the shares
1426
+        while ($path->getPath() !== $userFolder->getPath()) {
1427
+            $nodes[] = $path;
1428
+            if (!$recursive) {
1429
+                break;
1430
+            }
1431
+            $path = $path->getParent();
1432
+        }
1433
+
1434
+        foreach ($providers as $provider) {
1435
+            $tmp = $provider->getAccessList($nodes, $currentAccess);
1436
+
1437
+            foreach ($tmp as $k => $v) {
1438
+                if (isset($al[$k])) {
1439
+                    if (is_array($al[$k])) {
1440
+                        if ($currentAccess) {
1441
+                            $al[$k] += $v;
1442
+                        } else {
1443
+                            $al[$k] = array_merge($al[$k], $v);
1444
+                            $al[$k] = array_unique($al[$k]);
1445
+                            $al[$k] = array_values($al[$k]);
1446
+                        }
1447
+                    } else {
1448
+                        $al[$k] = $al[$k] || $v;
1449
+                    }
1450
+                } else {
1451
+                    $al[$k] = $v;
1452
+                }
1453
+            }
1454
+        }
1455
+
1456
+        return $al;
1457
+    }
1458
+
1459
+    /**
1460
+     * Create a new share
1461
+     * @return \OCP\Share\IShare
1462
+     */
1463
+    public function newShare() {
1464
+        return new \OC\Share20\Share($this->rootFolder, $this->userManager);
1465
+    }
1466
+
1467
+    /**
1468
+     * Is the share API enabled
1469
+     *
1470
+     * @return bool
1471
+     */
1472
+    public function shareApiEnabled() {
1473
+        return $this->config->getAppValue('core', 'shareapi_enabled', 'yes') === 'yes';
1474
+    }
1475
+
1476
+    /**
1477
+     * Is public link sharing enabled
1478
+     *
1479
+     * @return bool
1480
+     */
1481
+    public function shareApiAllowLinks() {
1482
+        return $this->config->getAppValue('core', 'shareapi_allow_links', 'yes') === 'yes';
1483
+    }
1484
+
1485
+    /**
1486
+     * Is password on public link requires
1487
+     *
1488
+     * @return bool
1489
+     */
1490
+    public function shareApiLinkEnforcePassword() {
1491
+        return $this->config->getAppValue('core', 'shareapi_enforce_links_password', 'no') === 'yes';
1492
+    }
1493
+
1494
+    /**
1495
+     * Is default expire date enabled
1496
+     *
1497
+     * @return bool
1498
+     */
1499
+    public function shareApiLinkDefaultExpireDate() {
1500
+        return $this->config->getAppValue('core', 'shareapi_default_expire_date', 'no') === 'yes';
1501
+    }
1502
+
1503
+    /**
1504
+     * Is default expire date enforced
1505
+     *`
1506
+     * @return bool
1507
+     */
1508
+    public function shareApiLinkDefaultExpireDateEnforced() {
1509
+        return $this->shareApiLinkDefaultExpireDate() &&
1510
+            $this->config->getAppValue('core', 'shareapi_enforce_expire_date', 'no') === 'yes';
1511
+    }
1512
+
1513
+    /**
1514
+     * Number of default expire days
1515
+     *shareApiLinkAllowPublicUpload
1516
+     * @return int
1517
+     */
1518
+    public function shareApiLinkDefaultExpireDays() {
1519
+        return (int)$this->config->getAppValue('core', 'shareapi_expire_after_n_days', '7');
1520
+    }
1521
+
1522
+    /**
1523
+     * Allow public upload on link shares
1524
+     *
1525
+     * @return bool
1526
+     */
1527
+    public function shareApiLinkAllowPublicUpload() {
1528
+        return $this->config->getAppValue('core', 'shareapi_allow_public_upload', 'yes') === 'yes';
1529
+    }
1530
+
1531
+    /**
1532
+     * check if user can only share with group members
1533
+     * @return bool
1534
+     */
1535
+    public function shareWithGroupMembersOnly() {
1536
+        return $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
1537
+    }
1538
+
1539
+    /**
1540
+     * Check if users can share with groups
1541
+     * @return bool
1542
+     */
1543
+    public function allowGroupSharing() {
1544
+        return $this->config->getAppValue('core', 'shareapi_allow_group_sharing', 'yes') === 'yes';
1545
+    }
1546
+
1547
+    /**
1548
+     * Copied from \OC_Util::isSharingDisabledForUser
1549
+     *
1550
+     * TODO: Deprecate fuction from OC_Util
1551
+     *
1552
+     * @param string $userId
1553
+     * @return bool
1554
+     */
1555
+    public function sharingDisabledForUser($userId) {
1556
+        if ($userId === null) {
1557
+            return false;
1558
+        }
1559
+
1560
+        if (isset($this->sharingDisabledForUsersCache[$userId])) {
1561
+            return $this->sharingDisabledForUsersCache[$userId];
1562
+        }
1563
+
1564
+        if ($this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes') {
1565
+            $groupsList = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
1566
+            $excludedGroups = json_decode($groupsList);
1567
+            if (is_null($excludedGroups)) {
1568
+                $excludedGroups = explode(',', $groupsList);
1569
+                $newValue = json_encode($excludedGroups);
1570
+                $this->config->setAppValue('core', 'shareapi_exclude_groups_list', $newValue);
1571
+            }
1572
+            $user = $this->userManager->get($userId);
1573
+            $usersGroups = $this->groupManager->getUserGroupIds($user);
1574
+            if (!empty($usersGroups)) {
1575
+                $remainingGroups = array_diff($usersGroups, $excludedGroups);
1576
+                // if the user is only in groups which are disabled for sharing then
1577
+                // sharing is also disabled for the user
1578
+                if (empty($remainingGroups)) {
1579
+                    $this->sharingDisabledForUsersCache[$userId] = true;
1580
+                    return true;
1581
+                }
1582
+            }
1583
+        }
1584
+
1585
+        $this->sharingDisabledForUsersCache[$userId] = false;
1586
+        return false;
1587
+    }
1588
+
1589
+    /**
1590
+     * @inheritdoc
1591
+     */
1592
+    public function outgoingServer2ServerSharesAllowed() {
1593
+        return $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') === 'yes';
1594
+    }
1595
+
1596
+    /**
1597
+     * @inheritdoc
1598
+     */
1599
+    public function outgoingServer2ServerGroupSharesAllowed() {
1600
+        return $this->config->getAppValue('files_sharing', 'outgoing_server2server_group_share_enabled', 'no') === 'yes';
1601
+    }
1602
+
1603
+    /**
1604
+     * @inheritdoc
1605
+     */
1606
+    public function shareProviderExists($shareType) {
1607
+        try {
1608
+            $this->factory->getProviderForType($shareType);
1609
+        } catch (ProviderException $e) {
1610
+            return false;
1611
+        }
1612
+
1613
+        return true;
1614
+    }
1615 1615
 
1616 1616
 }
Please login to merge, or discard this patch.
lib/private/Share20/Share.php 1 patch
Indentation   +481 added lines, -481 removed lines patch added patch discarded remove patch
@@ -33,485 +33,485 @@
 block discarded – undo
33 33
 
34 34
 class Share implements \OCP\Share\IShare {
35 35
 
36
-	/** @var string */
37
-	private $id;
38
-	/** @var string */
39
-	private $providerId;
40
-	/** @var Node */
41
-	private $node;
42
-	/** @var int */
43
-	private $fileId;
44
-	/** @var string */
45
-	private $nodeType;
46
-	/** @var int */
47
-	private $shareType;
48
-	/** @var string */
49
-	private $sharedWith;
50
-	/** @var string */
51
-	private $sharedWithDisplayName;
52
-	/** @var string */
53
-	private $sharedWithAvatar;
54
-	/** @var string */
55
-	private $sharedBy;
56
-	/** @var string */
57
-	private $shareOwner;
58
-	/** @var int */
59
-	private $permissions;
60
-	/** @var string */
61
-	private $note = '';
62
-	/** @var \DateTime */
63
-	private $expireDate;
64
-	/** @var string */
65
-	private $password;
66
-	/** @var bool */
67
-	private $sendPasswordByTalk = false;
68
-	/** @var string */
69
-	private $token;
70
-	/** @var int */
71
-	private $parent;
72
-	/** @var string */
73
-	private $target;
74
-	/** @var \DateTime */
75
-	private $shareTime;
76
-	/** @var bool */
77
-	private $mailSend;
78
-
79
-	/** @var IRootFolder */
80
-	private $rootFolder;
81
-
82
-	/** @var IUserManager */
83
-	private $userManager;
84
-
85
-	/** @var ICacheEntry|null */
86
-	private $nodeCacheEntry;
87
-
88
-	public function __construct(IRootFolder $rootFolder, IUserManager $userManager) {
89
-		$this->rootFolder = $rootFolder;
90
-		$this->userManager = $userManager;
91
-	}
92
-
93
-	/**
94
-	 * @inheritdoc
95
-	 */
96
-	public function setId($id) {
97
-		if (is_int($id)) {
98
-			$id = (string)$id;
99
-		}
100
-
101
-		if(!is_string($id)) {
102
-			throw new \InvalidArgumentException('String expected.');
103
-		}
104
-
105
-		if ($this->id !== null) {
106
-			throw new IllegalIDChangeException('Not allowed to assign a new internal id to a share');
107
-		}
108
-
109
-		$this->id = trim($id);
110
-		return $this;
111
-	}
112
-
113
-	/**
114
-	 * @inheritdoc
115
-	 */
116
-	public function getId() {
117
-		return $this->id;
118
-	}
119
-
120
-	/**
121
-	 * @inheritdoc
122
-	 */
123
-	public function getFullId() {
124
-		if ($this->providerId === null || $this->id === null) {
125
-			throw new \UnexpectedValueException;
126
-		}
127
-		return $this->providerId . ':' . $this->id;
128
-	}
129
-
130
-	/**
131
-	 * @inheritdoc
132
-	 */
133
-	public function setProviderId($id) {
134
-		if(!is_string($id)) {
135
-			throw new \InvalidArgumentException('String expected.');
136
-		}
137
-
138
-		if ($this->providerId !== null) {
139
-			throw new IllegalIDChangeException('Not allowed to assign a new provider id to a share');
140
-		}
141
-
142
-		$this->providerId = trim($id);
143
-		return $this;
144
-	}
145
-
146
-	/**
147
-	 * @inheritdoc
148
-	 */
149
-	public function setNode(Node $node) {
150
-		$this->fileId = null;
151
-		$this->nodeType = null;
152
-		$this->node = $node;
153
-		return $this;
154
-	}
155
-
156
-	/**
157
-	 * @inheritdoc
158
-	 */
159
-	public function getNode() {
160
-		if ($this->node === null) {
161
-
162
-			if ($this->shareOwner === null || $this->fileId === null) {
163
-				throw new NotFoundException();
164
-			}
165
-
166
-			// for federated shares the owner can be a remote user, in this
167
-			// case we use the initiator
168
-			if($this->userManager->userExists($this->shareOwner)) {
169
-				$userFolder = $this->rootFolder->getUserFolder($this->shareOwner);
170
-			} else {
171
-				$userFolder = $this->rootFolder->getUserFolder($this->sharedBy);
172
-			}
173
-
174
-			$nodes = $userFolder->getById($this->fileId);
175
-			if (empty($nodes)) {
176
-				throw new NotFoundException('Node for share not found, fileid: ' . $this->fileId);
177
-			}
178
-
179
-			$this->node = $nodes[0];
180
-		}
181
-
182
-		return $this->node;
183
-	}
184
-
185
-	/**
186
-	 * @inheritdoc
187
-	 */
188
-	public function setNodeId($fileId) {
189
-		$this->node = null;
190
-		$this->fileId = $fileId;
191
-		return $this;
192
-	}
193
-
194
-	/**
195
-	 * @inheritdoc
196
-	 */
197
-	public function getNodeId() {
198
-		if ($this->fileId === null) {
199
-			$this->fileId = $this->getNode()->getId();
200
-		}
201
-
202
-		return $this->fileId;
203
-	}
204
-
205
-	/**
206
-	 * @inheritdoc
207
-	 */
208
-	public function setNodeType($type) {
209
-		if ($type !== 'file' && $type !== 'folder') {
210
-			throw new \InvalidArgumentException();
211
-		}
212
-
213
-		$this->nodeType = $type;
214
-		return $this;
215
-	}
216
-
217
-	/**
218
-	 * @inheritdoc
219
-	 */
220
-	public function getNodeType() {
221
-		if ($this->nodeType === null) {
222
-			$node = $this->getNode();
223
-			$this->nodeType = $node instanceof File ? 'file' : 'folder';
224
-		}
225
-
226
-		return $this->nodeType;
227
-	}
228
-
229
-	/**
230
-	 * @inheritdoc
231
-	 */
232
-	public function setShareType($shareType) {
233
-		$this->shareType = $shareType;
234
-		return $this;
235
-	}
236
-
237
-	/**
238
-	 * @inheritdoc
239
-	 */
240
-	public function getShareType() {
241
-		return $this->shareType;
242
-	}
243
-
244
-	/**
245
-	 * @inheritdoc
246
-	 */
247
-	public function setSharedWith($sharedWith) {
248
-		if (!is_string($sharedWith)) {
249
-			throw new \InvalidArgumentException();
250
-		}
251
-		$this->sharedWith = $sharedWith;
252
-		return $this;
253
-	}
254
-
255
-	/**
256
-	 * @inheritdoc
257
-	 */
258
-	public function getSharedWith() {
259
-		return $this->sharedWith;
260
-	}
261
-
262
-	/**
263
-	 * @inheritdoc
264
-	 */
265
-	public function setSharedWithDisplayName($displayName) {
266
-		if (!is_string($displayName)) {
267
-			throw new \InvalidArgumentException();
268
-		}
269
-		$this->sharedWithDisplayName = $displayName;
270
-		return $this;
271
-	}
272
-
273
-	/**
274
-	 * @inheritdoc
275
-	 */
276
-	public function getSharedWithDisplayName() {
277
-		return $this->sharedWithDisplayName;
278
-	}
279
-
280
-	/**
281
-	 * @inheritdoc
282
-	 */
283
-	public function setSharedWithAvatar($src) {
284
-		if (!is_string($src)) {
285
-			throw new \InvalidArgumentException();
286
-		}
287
-		$this->sharedWithAvatar = $src;
288
-		return $this;
289
-	}
290
-
291
-	/**
292
-	 * @inheritdoc
293
-	 */
294
-	public function getSharedWithAvatar() {
295
-		return $this->sharedWithAvatar;
296
-	}
297
-
298
-	/**
299
-	 * @inheritdoc
300
-	 */
301
-	public function setPermissions($permissions) {
302
-		//TODO checkes
303
-
304
-		$this->permissions = $permissions;
305
-		return $this;
306
-	}
307
-
308
-	/**
309
-	 * @inheritdoc
310
-	 */
311
-	public function getPermissions() {
312
-		return $this->permissions;
313
-	}
314
-
315
-	/**
316
-	 * @inheritdoc
317
-	 */
318
-	public function setNote($note) {
319
-		$this->note = $note;
320
-		return $this;
321
-	}
322
-
323
-	/**
324
-	 * @inheritdoc
325
-	 */
326
-	public function getNote() {
327
-		if (is_string($this->note)) {
328
-			return $this->note;
329
-		}
330
-		return '';
331
-	}
332
-
333
-	/**
334
-	 * @inheritdoc
335
-	 */
336
-	public function setExpirationDate($expireDate) {
337
-		//TODO checks
338
-
339
-		$this->expireDate = $expireDate;
340
-		return $this;
341
-	}
342
-
343
-	/**
344
-	 * @inheritdoc
345
-	 */
346
-	public function getExpirationDate() {
347
-		return $this->expireDate;
348
-	}
349
-
350
-	/**
351
-	 * @inheritdoc
352
-	 */
353
-	public function setSharedBy($sharedBy) {
354
-		if (!is_string($sharedBy)) {
355
-			throw new \InvalidArgumentException();
356
-		}
357
-		//TODO checks
358
-		$this->sharedBy = $sharedBy;
359
-
360
-		return $this;
361
-	}
362
-
363
-	/**
364
-	 * @inheritdoc
365
-	 */
366
-	public function getSharedBy() {
367
-		//TODO check if set
368
-		return $this->sharedBy;
369
-	}
370
-
371
-	/**
372
-	 * @inheritdoc
373
-	 */
374
-	public function setShareOwner($shareOwner) {
375
-		if (!is_string($shareOwner)) {
376
-			throw new \InvalidArgumentException();
377
-		}
378
-		//TODO checks
379
-
380
-		$this->shareOwner = $shareOwner;
381
-		return $this;
382
-	}
383
-
384
-	/**
385
-	 * @inheritdoc
386
-	 */
387
-	public function getShareOwner() {
388
-		//TODO check if set
389
-		return $this->shareOwner;
390
-	}
391
-
392
-	/**
393
-	 * @inheritdoc
394
-	 */
395
-	public function setPassword($password) {
396
-		$this->password = $password;
397
-		return $this;
398
-	}
399
-
400
-	/**
401
-	 * @inheritdoc
402
-	 */
403
-	public function getPassword() {
404
-		return $this->password;
405
-	}
406
-
407
-	/**
408
-	 * @inheritdoc
409
-	 */
410
-	public function setSendPasswordByTalk(bool $sendPasswordByTalk) {
411
-		$this->sendPasswordByTalk = $sendPasswordByTalk;
412
-		return $this;
413
-	}
414
-
415
-	/**
416
-	 * @inheritdoc
417
-	 */
418
-	public function getSendPasswordByTalk(): bool {
419
-		return $this->sendPasswordByTalk;
420
-	}
421
-
422
-	/**
423
-	 * @inheritdoc
424
-	 */
425
-	public function setToken($token) {
426
-		$this->token = $token;
427
-		return $this;
428
-	}
429
-
430
-	/**
431
-	 * @inheritdoc
432
-	 */
433
-	public function getToken() {
434
-		return $this->token;
435
-	}
436
-
437
-	/**
438
-	 * Set the parent of this share
439
-	 *
440
-	 * @param int parent
441
-	 * @return \OCP\Share\IShare
442
-	 * @deprecated The new shares do not have parents. This is just here for legacy reasons.
443
-	 */
444
-	public function setParent($parent) {
445
-		$this->parent = $parent;
446
-		return $this;
447
-	}
448
-
449
-	/**
450
-	 * Get the parent of this share.
451
-	 *
452
-	 * @return int
453
-	 * @deprecated The new shares do not have parents. This is just here for legacy reasons.
454
-	 */
455
-	public function getParent() {
456
-		return $this->parent;
457
-	}
458
-
459
-	/**
460
-	 * @inheritdoc
461
-	 */
462
-	public function setTarget($target) {
463
-		$this->target = $target;
464
-		return $this;
465
-	}
466
-
467
-	/**
468
-	 * @inheritdoc
469
-	 */
470
-	public function getTarget() {
471
-		return $this->target;
472
-	}
473
-
474
-	/**
475
-	 * @inheritdoc
476
-	 */
477
-	public function setShareTime(\DateTime $shareTime) {
478
-		$this->shareTime = $shareTime;
479
-		return $this;
480
-	}
481
-
482
-	/**
483
-	 * @inheritdoc
484
-	 */
485
-	public function getShareTime() {
486
-		return $this->shareTime;
487
-	}
488
-
489
-	/**
490
-	 * @inheritdoc
491
-	 */
492
-	public function setMailSend($mailSend) {
493
-		$this->mailSend = $mailSend;
494
-		return $this;
495
-	}
496
-
497
-	/**
498
-	 * @inheritdoc
499
-	 */
500
-	public function getMailSend() {
501
-		return $this->mailSend;
502
-	}
503
-
504
-	/**
505
-	 * @inheritdoc
506
-	 */
507
-	public function setNodeCacheEntry(ICacheEntry $entry) {
508
-		$this->nodeCacheEntry = $entry;
509
-	}
510
-
511
-	/**
512
-	 * @inheritdoc
513
-	 */
514
-	public function getNodeCacheEntry() {
515
-		return $this->nodeCacheEntry;
516
-	}
36
+    /** @var string */
37
+    private $id;
38
+    /** @var string */
39
+    private $providerId;
40
+    /** @var Node */
41
+    private $node;
42
+    /** @var int */
43
+    private $fileId;
44
+    /** @var string */
45
+    private $nodeType;
46
+    /** @var int */
47
+    private $shareType;
48
+    /** @var string */
49
+    private $sharedWith;
50
+    /** @var string */
51
+    private $sharedWithDisplayName;
52
+    /** @var string */
53
+    private $sharedWithAvatar;
54
+    /** @var string */
55
+    private $sharedBy;
56
+    /** @var string */
57
+    private $shareOwner;
58
+    /** @var int */
59
+    private $permissions;
60
+    /** @var string */
61
+    private $note = '';
62
+    /** @var \DateTime */
63
+    private $expireDate;
64
+    /** @var string */
65
+    private $password;
66
+    /** @var bool */
67
+    private $sendPasswordByTalk = false;
68
+    /** @var string */
69
+    private $token;
70
+    /** @var int */
71
+    private $parent;
72
+    /** @var string */
73
+    private $target;
74
+    /** @var \DateTime */
75
+    private $shareTime;
76
+    /** @var bool */
77
+    private $mailSend;
78
+
79
+    /** @var IRootFolder */
80
+    private $rootFolder;
81
+
82
+    /** @var IUserManager */
83
+    private $userManager;
84
+
85
+    /** @var ICacheEntry|null */
86
+    private $nodeCacheEntry;
87
+
88
+    public function __construct(IRootFolder $rootFolder, IUserManager $userManager) {
89
+        $this->rootFolder = $rootFolder;
90
+        $this->userManager = $userManager;
91
+    }
92
+
93
+    /**
94
+     * @inheritdoc
95
+     */
96
+    public function setId($id) {
97
+        if (is_int($id)) {
98
+            $id = (string)$id;
99
+        }
100
+
101
+        if(!is_string($id)) {
102
+            throw new \InvalidArgumentException('String expected.');
103
+        }
104
+
105
+        if ($this->id !== null) {
106
+            throw new IllegalIDChangeException('Not allowed to assign a new internal id to a share');
107
+        }
108
+
109
+        $this->id = trim($id);
110
+        return $this;
111
+    }
112
+
113
+    /**
114
+     * @inheritdoc
115
+     */
116
+    public function getId() {
117
+        return $this->id;
118
+    }
119
+
120
+    /**
121
+     * @inheritdoc
122
+     */
123
+    public function getFullId() {
124
+        if ($this->providerId === null || $this->id === null) {
125
+            throw new \UnexpectedValueException;
126
+        }
127
+        return $this->providerId . ':' . $this->id;
128
+    }
129
+
130
+    /**
131
+     * @inheritdoc
132
+     */
133
+    public function setProviderId($id) {
134
+        if(!is_string($id)) {
135
+            throw new \InvalidArgumentException('String expected.');
136
+        }
137
+
138
+        if ($this->providerId !== null) {
139
+            throw new IllegalIDChangeException('Not allowed to assign a new provider id to a share');
140
+        }
141
+
142
+        $this->providerId = trim($id);
143
+        return $this;
144
+    }
145
+
146
+    /**
147
+     * @inheritdoc
148
+     */
149
+    public function setNode(Node $node) {
150
+        $this->fileId = null;
151
+        $this->nodeType = null;
152
+        $this->node = $node;
153
+        return $this;
154
+    }
155
+
156
+    /**
157
+     * @inheritdoc
158
+     */
159
+    public function getNode() {
160
+        if ($this->node === null) {
161
+
162
+            if ($this->shareOwner === null || $this->fileId === null) {
163
+                throw new NotFoundException();
164
+            }
165
+
166
+            // for federated shares the owner can be a remote user, in this
167
+            // case we use the initiator
168
+            if($this->userManager->userExists($this->shareOwner)) {
169
+                $userFolder = $this->rootFolder->getUserFolder($this->shareOwner);
170
+            } else {
171
+                $userFolder = $this->rootFolder->getUserFolder($this->sharedBy);
172
+            }
173
+
174
+            $nodes = $userFolder->getById($this->fileId);
175
+            if (empty($nodes)) {
176
+                throw new NotFoundException('Node for share not found, fileid: ' . $this->fileId);
177
+            }
178
+
179
+            $this->node = $nodes[0];
180
+        }
181
+
182
+        return $this->node;
183
+    }
184
+
185
+    /**
186
+     * @inheritdoc
187
+     */
188
+    public function setNodeId($fileId) {
189
+        $this->node = null;
190
+        $this->fileId = $fileId;
191
+        return $this;
192
+    }
193
+
194
+    /**
195
+     * @inheritdoc
196
+     */
197
+    public function getNodeId() {
198
+        if ($this->fileId === null) {
199
+            $this->fileId = $this->getNode()->getId();
200
+        }
201
+
202
+        return $this->fileId;
203
+    }
204
+
205
+    /**
206
+     * @inheritdoc
207
+     */
208
+    public function setNodeType($type) {
209
+        if ($type !== 'file' && $type !== 'folder') {
210
+            throw new \InvalidArgumentException();
211
+        }
212
+
213
+        $this->nodeType = $type;
214
+        return $this;
215
+    }
216
+
217
+    /**
218
+     * @inheritdoc
219
+     */
220
+    public function getNodeType() {
221
+        if ($this->nodeType === null) {
222
+            $node = $this->getNode();
223
+            $this->nodeType = $node instanceof File ? 'file' : 'folder';
224
+        }
225
+
226
+        return $this->nodeType;
227
+    }
228
+
229
+    /**
230
+     * @inheritdoc
231
+     */
232
+    public function setShareType($shareType) {
233
+        $this->shareType = $shareType;
234
+        return $this;
235
+    }
236
+
237
+    /**
238
+     * @inheritdoc
239
+     */
240
+    public function getShareType() {
241
+        return $this->shareType;
242
+    }
243
+
244
+    /**
245
+     * @inheritdoc
246
+     */
247
+    public function setSharedWith($sharedWith) {
248
+        if (!is_string($sharedWith)) {
249
+            throw new \InvalidArgumentException();
250
+        }
251
+        $this->sharedWith = $sharedWith;
252
+        return $this;
253
+    }
254
+
255
+    /**
256
+     * @inheritdoc
257
+     */
258
+    public function getSharedWith() {
259
+        return $this->sharedWith;
260
+    }
261
+
262
+    /**
263
+     * @inheritdoc
264
+     */
265
+    public function setSharedWithDisplayName($displayName) {
266
+        if (!is_string($displayName)) {
267
+            throw new \InvalidArgumentException();
268
+        }
269
+        $this->sharedWithDisplayName = $displayName;
270
+        return $this;
271
+    }
272
+
273
+    /**
274
+     * @inheritdoc
275
+     */
276
+    public function getSharedWithDisplayName() {
277
+        return $this->sharedWithDisplayName;
278
+    }
279
+
280
+    /**
281
+     * @inheritdoc
282
+     */
283
+    public function setSharedWithAvatar($src) {
284
+        if (!is_string($src)) {
285
+            throw new \InvalidArgumentException();
286
+        }
287
+        $this->sharedWithAvatar = $src;
288
+        return $this;
289
+    }
290
+
291
+    /**
292
+     * @inheritdoc
293
+     */
294
+    public function getSharedWithAvatar() {
295
+        return $this->sharedWithAvatar;
296
+    }
297
+
298
+    /**
299
+     * @inheritdoc
300
+     */
301
+    public function setPermissions($permissions) {
302
+        //TODO checkes
303
+
304
+        $this->permissions = $permissions;
305
+        return $this;
306
+    }
307
+
308
+    /**
309
+     * @inheritdoc
310
+     */
311
+    public function getPermissions() {
312
+        return $this->permissions;
313
+    }
314
+
315
+    /**
316
+     * @inheritdoc
317
+     */
318
+    public function setNote($note) {
319
+        $this->note = $note;
320
+        return $this;
321
+    }
322
+
323
+    /**
324
+     * @inheritdoc
325
+     */
326
+    public function getNote() {
327
+        if (is_string($this->note)) {
328
+            return $this->note;
329
+        }
330
+        return '';
331
+    }
332
+
333
+    /**
334
+     * @inheritdoc
335
+     */
336
+    public function setExpirationDate($expireDate) {
337
+        //TODO checks
338
+
339
+        $this->expireDate = $expireDate;
340
+        return $this;
341
+    }
342
+
343
+    /**
344
+     * @inheritdoc
345
+     */
346
+    public function getExpirationDate() {
347
+        return $this->expireDate;
348
+    }
349
+
350
+    /**
351
+     * @inheritdoc
352
+     */
353
+    public function setSharedBy($sharedBy) {
354
+        if (!is_string($sharedBy)) {
355
+            throw new \InvalidArgumentException();
356
+        }
357
+        //TODO checks
358
+        $this->sharedBy = $sharedBy;
359
+
360
+        return $this;
361
+    }
362
+
363
+    /**
364
+     * @inheritdoc
365
+     */
366
+    public function getSharedBy() {
367
+        //TODO check if set
368
+        return $this->sharedBy;
369
+    }
370
+
371
+    /**
372
+     * @inheritdoc
373
+     */
374
+    public function setShareOwner($shareOwner) {
375
+        if (!is_string($shareOwner)) {
376
+            throw new \InvalidArgumentException();
377
+        }
378
+        //TODO checks
379
+
380
+        $this->shareOwner = $shareOwner;
381
+        return $this;
382
+    }
383
+
384
+    /**
385
+     * @inheritdoc
386
+     */
387
+    public function getShareOwner() {
388
+        //TODO check if set
389
+        return $this->shareOwner;
390
+    }
391
+
392
+    /**
393
+     * @inheritdoc
394
+     */
395
+    public function setPassword($password) {
396
+        $this->password = $password;
397
+        return $this;
398
+    }
399
+
400
+    /**
401
+     * @inheritdoc
402
+     */
403
+    public function getPassword() {
404
+        return $this->password;
405
+    }
406
+
407
+    /**
408
+     * @inheritdoc
409
+     */
410
+    public function setSendPasswordByTalk(bool $sendPasswordByTalk) {
411
+        $this->sendPasswordByTalk = $sendPasswordByTalk;
412
+        return $this;
413
+    }
414
+
415
+    /**
416
+     * @inheritdoc
417
+     */
418
+    public function getSendPasswordByTalk(): bool {
419
+        return $this->sendPasswordByTalk;
420
+    }
421
+
422
+    /**
423
+     * @inheritdoc
424
+     */
425
+    public function setToken($token) {
426
+        $this->token = $token;
427
+        return $this;
428
+    }
429
+
430
+    /**
431
+     * @inheritdoc
432
+     */
433
+    public function getToken() {
434
+        return $this->token;
435
+    }
436
+
437
+    /**
438
+     * Set the parent of this share
439
+     *
440
+     * @param int parent
441
+     * @return \OCP\Share\IShare
442
+     * @deprecated The new shares do not have parents. This is just here for legacy reasons.
443
+     */
444
+    public function setParent($parent) {
445
+        $this->parent = $parent;
446
+        return $this;
447
+    }
448
+
449
+    /**
450
+     * Get the parent of this share.
451
+     *
452
+     * @return int
453
+     * @deprecated The new shares do not have parents. This is just here for legacy reasons.
454
+     */
455
+    public function getParent() {
456
+        return $this->parent;
457
+    }
458
+
459
+    /**
460
+     * @inheritdoc
461
+     */
462
+    public function setTarget($target) {
463
+        $this->target = $target;
464
+        return $this;
465
+    }
466
+
467
+    /**
468
+     * @inheritdoc
469
+     */
470
+    public function getTarget() {
471
+        return $this->target;
472
+    }
473
+
474
+    /**
475
+     * @inheritdoc
476
+     */
477
+    public function setShareTime(\DateTime $shareTime) {
478
+        $this->shareTime = $shareTime;
479
+        return $this;
480
+    }
481
+
482
+    /**
483
+     * @inheritdoc
484
+     */
485
+    public function getShareTime() {
486
+        return $this->shareTime;
487
+    }
488
+
489
+    /**
490
+     * @inheritdoc
491
+     */
492
+    public function setMailSend($mailSend) {
493
+        $this->mailSend = $mailSend;
494
+        return $this;
495
+    }
496
+
497
+    /**
498
+     * @inheritdoc
499
+     */
500
+    public function getMailSend() {
501
+        return $this->mailSend;
502
+    }
503
+
504
+    /**
505
+     * @inheritdoc
506
+     */
507
+    public function setNodeCacheEntry(ICacheEntry $entry) {
508
+        $this->nodeCacheEntry = $entry;
509
+    }
510
+
511
+    /**
512
+     * @inheritdoc
513
+     */
514
+    public function getNodeCacheEntry() {
515
+        return $this->nodeCacheEntry;
516
+    }
517 517
 }
Please login to merge, or discard this patch.
apps/files_sharing/lib/Controller/ShareController.php 1 patch
Indentation   +555 added lines, -556 removed lines patch added patch discarded remove patch
@@ -71,564 +71,563 @@
 block discarded – undo
71 71
  */
72 72
 class ShareController extends AuthPublicShareController {
73 73
 
74
-	/** @var IConfig */
75
-	protected $config;
76
-	/** @var IUserManager */
77
-	protected $userManager;
78
-	/** @var ILogger */
79
-	protected $logger;
80
-	/** @var \OCP\Activity\IManager */
81
-	protected $activityManager;
82
-	/** @var IPreview */
83
-	protected $previewManager;
84
-	/** @var IRootFolder */
85
-	protected $rootFolder;
86
-	/** @var FederatedShareProvider */
87
-	protected $federatedShareProvider;
88
-	/** @var EventDispatcherInterface */
89
-	protected $eventDispatcher;
90
-	/** @var IL10N */
91
-	protected $l10n;
92
-	/** @var Defaults */
93
-	protected $defaults;
94
-	/** @var ShareManager */
95
-	protected $shareManager;
96
-
97
-	/** @var Share\IShare */
98
-	protected $share;
99
-
100
-	/**
101
-	 * @param string $appName
102
-	 * @param IRequest $request
103
-	 * @param IConfig $config
104
-	 * @param IURLGenerator $urlGenerator
105
-	 * @param IUserManager $userManager
106
-	 * @param ILogger $logger
107
-	 * @param \OCP\Activity\IManager $activityManager
108
-	 * @param \OCP\Share\IManager $shareManager
109
-	 * @param ISession $session
110
-	 * @param IPreview $previewManager
111
-	 * @param IRootFolder $rootFolder
112
-	 * @param FederatedShareProvider $federatedShareProvider
113
-	 * @param EventDispatcherInterface $eventDispatcher
114
-	 * @param IL10N $l10n
115
-	 * @param Defaults $defaults
116
-	 */
117
-	public function __construct(string $appName,
118
-								IRequest $request,
119
-								IConfig $config,
120
-								IURLGenerator $urlGenerator,
121
-								IUserManager $userManager,
122
-								ILogger $logger,
123
-								\OCP\Activity\IManager $activityManager,
124
-								ShareManager $shareManager,
125
-								ISession $session,
126
-								IPreview $previewManager,
127
-								IRootFolder $rootFolder,
128
-								FederatedShareProvider $federatedShareProvider,
129
-								EventDispatcherInterface $eventDispatcher,
130
-								IL10N $l10n,
131
-								Defaults $defaults) {
132
-		parent::__construct($appName, $request, $session, $urlGenerator);
133
-
134
-		$this->config = $config;
135
-		$this->userManager = $userManager;
136
-		$this->logger = $logger;
137
-		$this->activityManager = $activityManager;
138
-		$this->previewManager = $previewManager;
139
-		$this->rootFolder = $rootFolder;
140
-		$this->federatedShareProvider = $federatedShareProvider;
141
-		$this->eventDispatcher = $eventDispatcher;
142
-		$this->l10n = $l10n;
143
-		$this->defaults = $defaults;
144
-		$this->shareManager = $shareManager;
145
-	}
146
-
147
-	/**
148
-	 * @PublicPage
149
-	 * @NoCSRFRequired
150
-	 *
151
-	 * Show the authentication page
152
-	 * The form has to submit to the authenticate method route
153
-	 */
154
-	public function showAuthenticate(): TemplateResponse {
155
-		$templateParameters = ['share' => $this->share];
156
-
157
-		$event = new GenericEvent(null, $templateParameters);
158
-		$this->eventDispatcher->dispatch('OCA\Files_Sharing::loadAdditionalScripts::publicShareAuth', $event);
159
-
160
-		return new TemplateResponse('core', 'publicshareauth', $templateParameters, 'guest');
161
-	}
162
-
163
-	/**
164
-	 * The template to show when authentication failed
165
-	 */
166
-	protected function showAuthFailed(): TemplateResponse {
167
-		$templateParameters = ['share' => $this->share, 'wrongpw' => true];
168
-
169
-		$event = new GenericEvent(null, $templateParameters);
170
-		$this->eventDispatcher->dispatch('OCA\Files_Sharing::loadAdditionalScripts::publicShareAuth', $event);
171
-
172
-		return new TemplateResponse('core', 'publicshareauth', $templateParameters, 'guest');
173
-	}
174
-
175
-	protected function verifyPassword(string $password): bool {
176
-		return $this->shareManager->checkPassword($this->share, $password);
177
-	}
178
-
179
-	protected function getPasswordHash(): string {
180
-		return $this->share->getPassword();
181
-	}
182
-
183
-	public function isValidToken(): bool {
184
-		try {
185
-			$this->share = $this->shareManager->getShareByToken($this->getToken());
186
-		} catch (ShareNotFound $e) {
187
-			return false;
188
-		}
189
-
190
-		return true;
191
-	}
192
-
193
-	protected function isPasswordProtected(): bool {
194
-		return $this->share->getPassword() !== null;
195
-	}
196
-
197
-	protected function authSucceeded() {
198
-		// For share this was always set so it is still used in other apps
199
-		$this->session->set('public_link_authenticated', (string)$this->share->getId());
200
-	}
201
-
202
-	protected function authFailed() {
203
-		$this->emitAccessShareHook($this->share, 403, 'Wrong password');
204
-	}
205
-
206
-	/**
207
-	 * throws hooks when a share is attempted to be accessed
208
-	 *
209
-	 * @param \OCP\Share\IShare|string $share the Share instance if available,
210
-	 * otherwise token
211
-	 * @param int $errorCode
212
-	 * @param string $errorMessage
213
-	 * @throws \OC\HintException
214
-	 * @throws \OC\ServerNotAvailableException
215
-	 */
216
-	protected function emitAccessShareHook($share, $errorCode = 200, $errorMessage = '') {
217
-		$itemType = $itemSource = $uidOwner = '';
218
-		$token = $share;
219
-		$exception = null;
220
-		if($share instanceof \OCP\Share\IShare) {
221
-			try {
222
-				$token = $share->getToken();
223
-				$uidOwner = $share->getSharedBy();
224
-				$itemType = $share->getNodeType();
225
-				$itemSource = $share->getNodeId();
226
-			} catch (\Exception $e) {
227
-				// we log what we know and pass on the exception afterwards
228
-				$exception = $e;
229
-			}
230
-		}
231
-		\OC_Hook::emit(Share::class, 'share_link_access', [
232
-			'itemType' => $itemType,
233
-			'itemSource' => $itemSource,
234
-			'uidOwner' => $uidOwner,
235
-			'token' => $token,
236
-			'errorCode' => $errorCode,
237
-			'errorMessage' => $errorMessage,
238
-		]);
239
-		if(!is_null($exception)) {
240
-			throw $exception;
241
-		}
242
-	}
243
-
244
-	/**
245
-	 * Validate the permissions of the share
246
-	 *
247
-	 * @param Share\IShare $share
248
-	 * @return bool
249
-	 */
250
-	private function validateShare(\OCP\Share\IShare $share) {
251
-		return $share->getNode()->isReadable() && $share->getNode()->isShareable();
252
-	}
253
-
254
-	/**
255
-	 * @PublicPage
256
-	 * @NoCSRFRequired
257
-	 *
258
-
259
-	 * @param string $path
260
-	 * @return TemplateResponse
261
-	 * @throws NotFoundException
262
-	 * @throws \Exception
263
-	 */
264
-	public function showShare($path = ''): TemplateResponse {
265
-		\OC_User::setIncognitoMode(true);
266
-
267
-		// Check whether share exists
268
-		try {
269
-			$share = $this->shareManager->getShareByToken($this->getToken());
270
-		} catch (ShareNotFound $e) {
271
-			$this->emitAccessShareHook($this->getToken(), 404, 'Share not found');
272
-			throw new NotFoundException();
273
-		}
274
-
275
-		if (!$this->validateShare($share)) {
276
-			throw new NotFoundException();
277
-		}
278
-		// We can't get the path of a file share
279
-		try {
280
-			if ($share->getNode() instanceof \OCP\Files\File && $path !== '') {
281
-				$this->emitAccessShareHook($share, 404, 'Share not found');
282
-				throw new NotFoundException();
283
-			}
284
-		} catch (\Exception $e) {
285
-			$this->emitAccessShareHook($share, 404, 'Share not found');
286
-			throw $e;
287
-		}
288
-
289
-		$shareTmpl = [];
290
-		$shareTmpl['displayName'] = $this->userManager->get($share->getShareOwner())->getDisplayName();
291
-		$shareTmpl['owner'] = $share->getShareOwner();
292
-		$shareTmpl['filename'] = $share->getNode()->getName();
293
-		$shareTmpl['directory_path'] = $share->getTarget();
294
-		$shareTmpl['note'] = $share->getNote();
295
-		$shareTmpl['mimetype'] = $share->getNode()->getMimetype();
296
-		$shareTmpl['previewSupported'] = $this->previewManager->isMimeSupported($share->getNode()->getMimetype());
297
-		$shareTmpl['dirToken'] = $this->getToken();
298
-		$shareTmpl['sharingToken'] = $this->getToken();
299
-		$shareTmpl['server2serversharing'] = $this->federatedShareProvider->isOutgoingServer2serverShareEnabled();
300
-		$shareTmpl['protected'] = $share->getPassword() !== null ? 'true' : 'false';
301
-		$shareTmpl['dir'] = '';
302
-		$shareTmpl['nonHumanFileSize'] = $share->getNode()->getSize();
303
-		$shareTmpl['fileSize'] = \OCP\Util::humanFileSize($share->getNode()->getSize());
304
-
305
-		// Show file list
306
-		$hideFileList = false;
307
-		if ($share->getNode() instanceof \OCP\Files\Folder) {
308
-			/** @var \OCP\Files\Folder $rootFolder */
309
-			$rootFolder = $share->getNode();
310
-
311
-			try {
312
-				$folderNode = $rootFolder->get($path);
313
-			} catch (\OCP\Files\NotFoundException $e) {
314
-				$this->emitAccessShareHook($share, 404, 'Share not found');
315
-				throw new NotFoundException();
316
-			}
317
-
318
-			$shareTmpl['dir'] = $rootFolder->getRelativePath($folderNode->getPath());
319
-
320
-			/*
74
+    /** @var IConfig */
75
+    protected $config;
76
+    /** @var IUserManager */
77
+    protected $userManager;
78
+    /** @var ILogger */
79
+    protected $logger;
80
+    /** @var \OCP\Activity\IManager */
81
+    protected $activityManager;
82
+    /** @var IPreview */
83
+    protected $previewManager;
84
+    /** @var IRootFolder */
85
+    protected $rootFolder;
86
+    /** @var FederatedShareProvider */
87
+    protected $federatedShareProvider;
88
+    /** @var EventDispatcherInterface */
89
+    protected $eventDispatcher;
90
+    /** @var IL10N */
91
+    protected $l10n;
92
+    /** @var Defaults */
93
+    protected $defaults;
94
+    /** @var ShareManager */
95
+    protected $shareManager;
96
+
97
+    /** @var Share\IShare */
98
+    protected $share;
99
+
100
+    /**
101
+     * @param string $appName
102
+     * @param IRequest $request
103
+     * @param IConfig $config
104
+     * @param IURLGenerator $urlGenerator
105
+     * @param IUserManager $userManager
106
+     * @param ILogger $logger
107
+     * @param \OCP\Activity\IManager $activityManager
108
+     * @param \OCP\Share\IManager $shareManager
109
+     * @param ISession $session
110
+     * @param IPreview $previewManager
111
+     * @param IRootFolder $rootFolder
112
+     * @param FederatedShareProvider $federatedShareProvider
113
+     * @param EventDispatcherInterface $eventDispatcher
114
+     * @param IL10N $l10n
115
+     * @param Defaults $defaults
116
+     */
117
+    public function __construct(string $appName,
118
+                                IRequest $request,
119
+                                IConfig $config,
120
+                                IURLGenerator $urlGenerator,
121
+                                IUserManager $userManager,
122
+                                ILogger $logger,
123
+                                \OCP\Activity\IManager $activityManager,
124
+                                ShareManager $shareManager,
125
+                                ISession $session,
126
+                                IPreview $previewManager,
127
+                                IRootFolder $rootFolder,
128
+                                FederatedShareProvider $federatedShareProvider,
129
+                                EventDispatcherInterface $eventDispatcher,
130
+                                IL10N $l10n,
131
+                                Defaults $defaults) {
132
+        parent::__construct($appName, $request, $session, $urlGenerator);
133
+
134
+        $this->config = $config;
135
+        $this->userManager = $userManager;
136
+        $this->logger = $logger;
137
+        $this->activityManager = $activityManager;
138
+        $this->previewManager = $previewManager;
139
+        $this->rootFolder = $rootFolder;
140
+        $this->federatedShareProvider = $federatedShareProvider;
141
+        $this->eventDispatcher = $eventDispatcher;
142
+        $this->l10n = $l10n;
143
+        $this->defaults = $defaults;
144
+        $this->shareManager = $shareManager;
145
+    }
146
+
147
+    /**
148
+     * @PublicPage
149
+     * @NoCSRFRequired
150
+     *
151
+     * Show the authentication page
152
+     * The form has to submit to the authenticate method route
153
+     */
154
+    public function showAuthenticate(): TemplateResponse {
155
+        $templateParameters = ['share' => $this->share];
156
+
157
+        $event = new GenericEvent(null, $templateParameters);
158
+        $this->eventDispatcher->dispatch('OCA\Files_Sharing::loadAdditionalScripts::publicShareAuth', $event);
159
+
160
+        return new TemplateResponse('core', 'publicshareauth', $templateParameters, 'guest');
161
+    }
162
+
163
+    /**
164
+     * The template to show when authentication failed
165
+     */
166
+    protected function showAuthFailed(): TemplateResponse {
167
+        $templateParameters = ['share' => $this->share, 'wrongpw' => true];
168
+
169
+        $event = new GenericEvent(null, $templateParameters);
170
+        $this->eventDispatcher->dispatch('OCA\Files_Sharing::loadAdditionalScripts::publicShareAuth', $event);
171
+
172
+        return new TemplateResponse('core', 'publicshareauth', $templateParameters, 'guest');
173
+    }
174
+
175
+    protected function verifyPassword(string $password): bool {
176
+        return $this->shareManager->checkPassword($this->share, $password);
177
+    }
178
+
179
+    protected function getPasswordHash(): string {
180
+        return $this->share->getPassword();
181
+    }
182
+
183
+    public function isValidToken(): bool {
184
+        try {
185
+            $this->share = $this->shareManager->getShareByToken($this->getToken());
186
+        } catch (ShareNotFound $e) {
187
+            return false;
188
+        }
189
+
190
+        return true;
191
+    }
192
+
193
+    protected function isPasswordProtected(): bool {
194
+        return $this->share->getPassword() !== null;
195
+    }
196
+
197
+    protected function authSucceeded() {
198
+        // For share this was always set so it is still used in other apps
199
+        $this->session->set('public_link_authenticated', (string)$this->share->getId());
200
+    }
201
+
202
+    protected function authFailed() {
203
+        $this->emitAccessShareHook($this->share, 403, 'Wrong password');
204
+    }
205
+
206
+    /**
207
+     * throws hooks when a share is attempted to be accessed
208
+     *
209
+     * @param \OCP\Share\IShare|string $share the Share instance if available,
210
+     * otherwise token
211
+     * @param int $errorCode
212
+     * @param string $errorMessage
213
+     * @throws \OC\HintException
214
+     * @throws \OC\ServerNotAvailableException
215
+     */
216
+    protected function emitAccessShareHook($share, $errorCode = 200, $errorMessage = '') {
217
+        $itemType = $itemSource = $uidOwner = '';
218
+        $token = $share;
219
+        $exception = null;
220
+        if($share instanceof \OCP\Share\IShare) {
221
+            try {
222
+                $token = $share->getToken();
223
+                $uidOwner = $share->getSharedBy();
224
+                $itemType = $share->getNodeType();
225
+                $itemSource = $share->getNodeId();
226
+            } catch (\Exception $e) {
227
+                // we log what we know and pass on the exception afterwards
228
+                $exception = $e;
229
+            }
230
+        }
231
+        \OC_Hook::emit(Share::class, 'share_link_access', [
232
+            'itemType' => $itemType,
233
+            'itemSource' => $itemSource,
234
+            'uidOwner' => $uidOwner,
235
+            'token' => $token,
236
+            'errorCode' => $errorCode,
237
+            'errorMessage' => $errorMessage,
238
+        ]);
239
+        if(!is_null($exception)) {
240
+            throw $exception;
241
+        }
242
+    }
243
+
244
+    /**
245
+     * Validate the permissions of the share
246
+     *
247
+     * @param Share\IShare $share
248
+     * @return bool
249
+     */
250
+    private function validateShare(\OCP\Share\IShare $share) {
251
+        return $share->getNode()->isReadable() && $share->getNode()->isShareable();
252
+    }
253
+
254
+    /**
255
+     * @PublicPage
256
+     * @NoCSRFRequired
257
+     *
258
+     * @param string $path
259
+     * @return TemplateResponse
260
+     * @throws NotFoundException
261
+     * @throws \Exception
262
+     */
263
+    public function showShare($path = ''): TemplateResponse {
264
+        \OC_User::setIncognitoMode(true);
265
+
266
+        // Check whether share exists
267
+        try {
268
+            $share = $this->shareManager->getShareByToken($this->getToken());
269
+        } catch (ShareNotFound $e) {
270
+            $this->emitAccessShareHook($this->getToken(), 404, 'Share not found');
271
+            throw new NotFoundException();
272
+        }
273
+
274
+        if (!$this->validateShare($share)) {
275
+            throw new NotFoundException();
276
+        }
277
+        // We can't get the path of a file share
278
+        try {
279
+            if ($share->getNode() instanceof \OCP\Files\File && $path !== '') {
280
+                $this->emitAccessShareHook($share, 404, 'Share not found');
281
+                throw new NotFoundException();
282
+            }
283
+        } catch (\Exception $e) {
284
+            $this->emitAccessShareHook($share, 404, 'Share not found');
285
+            throw $e;
286
+        }
287
+
288
+        $shareTmpl = [];
289
+        $shareTmpl['displayName'] = $this->userManager->get($share->getShareOwner())->getDisplayName();
290
+        $shareTmpl['owner'] = $share->getShareOwner();
291
+        $shareTmpl['filename'] = $share->getNode()->getName();
292
+        $shareTmpl['directory_path'] = $share->getTarget();
293
+        $shareTmpl['note'] = $share->getNote();
294
+        $shareTmpl['mimetype'] = $share->getNode()->getMimetype();
295
+        $shareTmpl['previewSupported'] = $this->previewManager->isMimeSupported($share->getNode()->getMimetype());
296
+        $shareTmpl['dirToken'] = $this->getToken();
297
+        $shareTmpl['sharingToken'] = $this->getToken();
298
+        $shareTmpl['server2serversharing'] = $this->federatedShareProvider->isOutgoingServer2serverShareEnabled();
299
+        $shareTmpl['protected'] = $share->getPassword() !== null ? 'true' : 'false';
300
+        $shareTmpl['dir'] = '';
301
+        $shareTmpl['nonHumanFileSize'] = $share->getNode()->getSize();
302
+        $shareTmpl['fileSize'] = \OCP\Util::humanFileSize($share->getNode()->getSize());
303
+
304
+        // Show file list
305
+        $hideFileList = false;
306
+        if ($share->getNode() instanceof \OCP\Files\Folder) {
307
+            /** @var \OCP\Files\Folder $rootFolder */
308
+            $rootFolder = $share->getNode();
309
+
310
+            try {
311
+                $folderNode = $rootFolder->get($path);
312
+            } catch (\OCP\Files\NotFoundException $e) {
313
+                $this->emitAccessShareHook($share, 404, 'Share not found');
314
+                throw new NotFoundException();
315
+            }
316
+
317
+            $shareTmpl['dir'] = $rootFolder->getRelativePath($folderNode->getPath());
318
+
319
+            /*
321 320
 			 * The OC_Util methods require a view. This just uses the node API
322 321
 			 */
323
-			$freeSpace = $share->getNode()->getStorage()->free_space($share->getNode()->getInternalPath());
324
-			if ($freeSpace < \OCP\Files\FileInfo::SPACE_UNLIMITED) {
325
-				$freeSpace = max($freeSpace, 0);
326
-			} else {
327
-				$freeSpace = (INF > 0) ? INF: PHP_INT_MAX; // work around https://bugs.php.net/bug.php?id=69188
328
-			}
329
-
330
-			$hideFileList = !($share->getPermissions() & \OCP\Constants::PERMISSION_READ);
331
-			$maxUploadFilesize = $freeSpace;
332
-
333
-			$folder = new Template('files', 'list', '');
334
-			$folder->assign('dir', $rootFolder->getRelativePath($folderNode->getPath()));
335
-			$folder->assign('dirToken', $this->getToken());
336
-			$folder->assign('permissions', \OCP\Constants::PERMISSION_READ);
337
-			$folder->assign('isPublic', true);
338
-			$folder->assign('hideFileList', $hideFileList);
339
-			$folder->assign('publicUploadEnabled', 'no');
340
-			$folder->assign('uploadMaxFilesize', $maxUploadFilesize);
341
-			$folder->assign('uploadMaxHumanFilesize', \OCP\Util::humanFileSize($maxUploadFilesize));
342
-			$folder->assign('freeSpace', $freeSpace);
343
-			$folder->assign('usedSpacePercent', 0);
344
-			$folder->assign('trash', false);
345
-			$shareTmpl['folder'] = $folder->fetchPage();
346
-		}
347
-
348
-		$shareTmpl['hideFileList'] = $hideFileList;
349
-		$shareTmpl['shareOwner'] = $this->userManager->get($share->getShareOwner())->getDisplayName();
350
-		$shareTmpl['downloadURL'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.downloadShare', ['token' => $this->getToken()]);
351
-		$shareTmpl['shareUrl'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $this->getToken()]);
352
-		$shareTmpl['maxSizeAnimateGif'] = $this->config->getSystemValue('max_filesize_animated_gifs_public_sharing', 10);
353
-		$shareTmpl['previewEnabled'] = $this->config->getSystemValue('enable_previews', true);
354
-		$shareTmpl['previewMaxX'] = $this->config->getSystemValue('preview_max_x', 1024);
355
-		$shareTmpl['previewMaxY'] = $this->config->getSystemValue('preview_max_y', 1024);
356
-		$shareTmpl['disclaimer'] = $this->config->getAppValue('core', 'shareapi_public_link_disclaimertext', null);
357
-		$shareTmpl['previewURL'] = $shareTmpl['downloadURL'];
358
-		$ogPreview = '';
359
-		if ($shareTmpl['previewSupported']) {
360
-			$shareTmpl['previewImage'] = $this->urlGenerator->linkToRouteAbsolute( 'files_sharing.PublicPreview.getPreview',
361
-				['x' => 200, 'y' => 200, 'file' => $shareTmpl['directory_path'], 'token' => $shareTmpl['dirToken']]);
362
-			$ogPreview = $shareTmpl['previewImage'];
363
-
364
-			// We just have direct previews for image files
365
-			if ($share->getNode()->getMimePart() === 'image') {
366
-				$shareTmpl['previewURL'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.publicpreview.directLink', ['token' => $this->getToken()]);
367
-
368
-				$ogPreview = $shareTmpl['previewURL'];
369
-
370
-				//Whatapp is kind of picky about their size requirements
371
-				if ($this->request->isUserAgent(['/^WhatsApp/'])) {
372
-					$ogPreview = $this->urlGenerator->linkToRouteAbsolute('files_sharing.PublicPreview.getPreview', [
373
-						'token' => $this->getToken(),
374
-						'x' => 256,
375
-						'y' => 256,
376
-						'a' => true,
377
-					]);
378
-				}
379
-			}
380
-		} else {
381
-			$shareTmpl['previewImage'] = $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core', 'favicon-fb.png'));
382
-			$ogPreview = $shareTmpl['previewImage'];
383
-		}
384
-
385
-		// Load files we need
386
-		\OCP\Util::addScript('files', 'file-upload');
387
-		\OCP\Util::addStyle('files_sharing', 'publicView');
388
-		\OCP\Util::addScript('files_sharing', 'public');
389
-		\OCP\Util::addScript('files', 'fileactions');
390
-		\OCP\Util::addScript('files', 'fileactionsmenu');
391
-		\OCP\Util::addScript('files', 'jquery.fileupload');
392
-		\OCP\Util::addScript('files_sharing', 'files_drop');
393
-
394
-		if (isset($shareTmpl['folder'])) {
395
-			// JS required for folders
396
-			\OCP\Util::addStyle('files', 'merged');
397
-			\OCP\Util::addScript('files', 'filesummary');
398
-			\OCP\Util::addScript('files', 'breadcrumb');
399
-			\OCP\Util::addScript('files', 'fileinfomodel');
400
-			\OCP\Util::addScript('files', 'newfilemenu');
401
-			\OCP\Util::addScript('files', 'files');
402
-			\OCP\Util::addScript('files', 'filelist');
403
-			\OCP\Util::addScript('files', 'keyboardshortcuts');
404
-		}
405
-
406
-		// OpenGraph Support: http://ogp.me/
407
-		\OCP\Util::addHeader('meta', ['property' => "og:title", 'content' => $shareTmpl['filename']]);
408
-		\OCP\Util::addHeader('meta', ['property' => "og:description", 'content' => $this->defaults->getName() . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : '')]);
409
-		\OCP\Util::addHeader('meta', ['property' => "og:site_name", 'content' => $this->defaults->getName()]);
410
-		\OCP\Util::addHeader('meta', ['property' => "og:url", 'content' => $shareTmpl['shareUrl']]);
411
-		\OCP\Util::addHeader('meta', ['property' => "og:type", 'content' => "object"]);
412
-		\OCP\Util::addHeader('meta', ['property' => "og:image", 'content' => $ogPreview]);
413
-
414
-		$this->eventDispatcher->dispatch('OCA\Files_Sharing::loadAdditionalScripts');
415
-
416
-		$csp = new \OCP\AppFramework\Http\ContentSecurityPolicy();
417
-		$csp->addAllowedFrameDomain('\'self\'');
418
-
419
-		$response = new PublicTemplateResponse($this->appName, 'public', $shareTmpl);
420
-		$response->setHeaderTitle($shareTmpl['filename']);
421
-		$response->setHeaderDetails($this->l10n->t('shared by %s', [$shareTmpl['displayName']]));
422
-		$response->setHeaderActions([
423
-			new SimpleMenuAction('download', $this->l10n->t('Download'), 'icon-download-white', $shareTmpl['downloadURL'], 0),
424
-			new SimpleMenuAction('download', $this->l10n->t('Download'), 'icon-download', $shareTmpl['downloadURL'], 10, $shareTmpl['fileSize']),
425
-			new LinkMenuAction($this->l10n->t('Direct link'), 'icon-public', $shareTmpl['previewURL']),
426
-			new ExternalShareMenuAction($this->l10n->t('Add to your Nextcloud'), 'icon-external', $shareTmpl['owner'], $shareTmpl['displayName'], $shareTmpl['filename']),
427
-		]);
428
-
429
-		$response->setContentSecurityPolicy($csp);
430
-
431
-		$this->emitAccessShareHook($share);
432
-
433
-		return $response;
434
-	}
435
-
436
-	/**
437
-	 * @PublicPage
438
-	 * @NoCSRFRequired
439
-	 *
440
-	 * @param string $token
441
-	 * @param string $files
442
-	 * @param string $path
443
-	 * @param string $downloadStartSecret
444
-	 * @return void|\OCP\AppFramework\Http\Response
445
-	 * @throws NotFoundException
446
-	 */
447
-	public function downloadShare($token, $files = null, $path = '', $downloadStartSecret = '') {
448
-		\OC_User::setIncognitoMode(true);
449
-
450
-		$share = $this->shareManager->getShareByToken($token);
451
-
452
-		if(!($share->getPermissions() & \OCP\Constants::PERMISSION_READ)) {
453
-			return new \OCP\AppFramework\Http\DataResponse('Share is read-only');
454
-		}
455
-
456
-		$files_list = null;
457
-		if (!is_null($files)) { // download selected files
458
-			$files_list = json_decode($files);
459
-			// in case we get only a single file
460
-			if ($files_list === null) {
461
-				$files_list = [$files];
462
-			}
463
-			// Just in case $files is a single int like '1234'
464
-			if (!is_array($files_list)) {
465
-				$files_list = [$files_list];
466
-			}
467
-		}
468
-
469
-
470
-		if (!$this->validateShare($share)) {
471
-			throw new NotFoundException();
472
-		}
473
-
474
-		$userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
475
-		$originalSharePath = $userFolder->getRelativePath($share->getNode()->getPath());
476
-
477
-
478
-		// Single file share
479
-		if ($share->getNode() instanceof \OCP\Files\File) {
480
-			// Single file download
481
-			$this->singleFileDownloaded($share, $share->getNode());
482
-		}
483
-		// Directory share
484
-		else {
485
-			/** @var \OCP\Files\Folder $node */
486
-			$node = $share->getNode();
487
-
488
-			// Try to get the path
489
-			if ($path !== '') {
490
-				try {
491
-					$node = $node->get($path);
492
-				} catch (NotFoundException $e) {
493
-					$this->emitAccessShareHook($share, 404, 'Share not found');
494
-					return new NotFoundResponse();
495
-				}
496
-			}
497
-
498
-			$originalSharePath = $userFolder->getRelativePath($node->getPath());
499
-
500
-			if ($node instanceof \OCP\Files\File) {
501
-				// Single file download
502
-				$this->singleFileDownloaded($share, $share->getNode());
503
-			} else if (!empty($files_list)) {
504
-				$this->fileListDownloaded($share, $files_list, $node);
505
-			} else {
506
-				// The folder is downloaded
507
-				$this->singleFileDownloaded($share, $share->getNode());
508
-			}
509
-		}
510
-
511
-		/* FIXME: We should do this all nicely in OCP */
512
-		OC_Util::tearDownFS();
513
-		OC_Util::setupFS($share->getShareOwner());
514
-
515
-		/**
516
-		 * this sets a cookie to be able to recognize the start of the download
517
-		 * the content must not be longer than 32 characters and must only contain
518
-		 * alphanumeric characters
519
-		 */
520
-		if (!empty($downloadStartSecret)
521
-			&& !isset($downloadStartSecret[32])
522
-			&& preg_match('!^[a-zA-Z0-9]+$!', $downloadStartSecret) === 1) {
523
-
524
-			// FIXME: set on the response once we use an actual app framework response
525
-			setcookie('ocDownloadStarted', $downloadStartSecret, time() + 20, '/');
526
-		}
527
-
528
-		$this->emitAccessShareHook($share);
529
-
530
-		$server_params = array( 'head' => $this->request->getMethod() === 'HEAD' );
531
-
532
-		/**
533
-		 * Http range requests support
534
-		 */
535
-		if (isset($_SERVER['HTTP_RANGE'])) {
536
-			$server_params['range'] = $this->request->getHeader('Range');
537
-		}
538
-
539
-		// download selected files
540
-		if (!is_null($files) && $files !== '') {
541
-			// FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well
542
-			// after dispatching the request which results in a "Cannot modify header information" notice.
543
-			OC_Files::get($originalSharePath, $files_list, $server_params);
544
-			exit();
545
-		} else {
546
-			// FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well
547
-			// after dispatching the request which results in a "Cannot modify header information" notice.
548
-			OC_Files::get(dirname($originalSharePath), basename($originalSharePath), $server_params);
549
-			exit();
550
-		}
551
-	}
552
-
553
-	/**
554
-	 * create activity for every downloaded file
555
-	 *
556
-	 * @param Share\IShare $share
557
-	 * @param array $files_list
558
-	 * @param \OCP\Files\Folder $node
559
-	 */
560
-	protected function fileListDownloaded(Share\IShare $share, array $files_list, \OCP\Files\Folder $node) {
561
-		foreach ($files_list as $file) {
562
-			$subNode = $node->get($file);
563
-			$this->singleFileDownloaded($share, $subNode);
564
-		}
565
-
566
-	}
567
-
568
-	/**
569
-	 * create activity if a single file was downloaded from a link share
570
-	 *
571
-	 * @param Share\IShare $share
572
-	 */
573
-	protected function singleFileDownloaded(Share\IShare $share, \OCP\Files\Node $node) {
574
-
575
-		$fileId = $node->getId();
576
-
577
-		$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
578
-		$userNodeList = $userFolder->getById($fileId);
579
-		$userNode = $userNodeList[0];
580
-		$ownerFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
581
-		$userPath = $userFolder->getRelativePath($userNode->getPath());
582
-		$ownerPath = $ownerFolder->getRelativePath($node->getPath());
583
-
584
-		$parameters = [$userPath];
585
-
586
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
587
-			if ($node instanceof \OCP\Files\File) {
588
-				$subject = Downloads::SUBJECT_SHARED_FILE_BY_EMAIL_DOWNLOADED;
589
-			} else {
590
-				$subject = Downloads::SUBJECT_SHARED_FOLDER_BY_EMAIL_DOWNLOADED;
591
-			}
592
-			$parameters[] = $share->getSharedWith();
593
-		} else {
594
-			if ($node instanceof \OCP\Files\File) {
595
-				$subject = Downloads::SUBJECT_PUBLIC_SHARED_FILE_DOWNLOADED;
596
-			} else {
597
-				$subject = Downloads::SUBJECT_PUBLIC_SHARED_FOLDER_DOWNLOADED;
598
-			}
599
-		}
600
-
601
-		$this->publishActivity($subject, $parameters, $share->getSharedBy(), $fileId, $userPath);
602
-
603
-		if ($share->getShareOwner() !== $share->getSharedBy()) {
604
-			$parameters[0] = $ownerPath;
605
-			$this->publishActivity($subject, $parameters, $share->getShareOwner(), $fileId, $ownerPath);
606
-		}
607
-	}
608
-
609
-	/**
610
-	 * publish activity
611
-	 *
612
-	 * @param string $subject
613
-	 * @param array $parameters
614
-	 * @param string $affectedUser
615
-	 * @param int $fileId
616
-	 * @param string $filePath
617
-	 */
618
-	protected function publishActivity($subject,
619
-										array $parameters,
620
-										$affectedUser,
621
-										$fileId,
622
-										$filePath) {
623
-
624
-		$event = $this->activityManager->generateEvent();
625
-		$event->setApp('files_sharing')
626
-			->setType('public_links')
627
-			->setSubject($subject, $parameters)
628
-			->setAffectedUser($affectedUser)
629
-			->setObject('files', $fileId, $filePath);
630
-		$this->activityManager->publish($event);
631
-	}
322
+            $freeSpace = $share->getNode()->getStorage()->free_space($share->getNode()->getInternalPath());
323
+            if ($freeSpace < \OCP\Files\FileInfo::SPACE_UNLIMITED) {
324
+                $freeSpace = max($freeSpace, 0);
325
+            } else {
326
+                $freeSpace = (INF > 0) ? INF: PHP_INT_MAX; // work around https://bugs.php.net/bug.php?id=69188
327
+            }
328
+
329
+            $hideFileList = !($share->getPermissions() & \OCP\Constants::PERMISSION_READ);
330
+            $maxUploadFilesize = $freeSpace;
331
+
332
+            $folder = new Template('files', 'list', '');
333
+            $folder->assign('dir', $rootFolder->getRelativePath($folderNode->getPath()));
334
+            $folder->assign('dirToken', $this->getToken());
335
+            $folder->assign('permissions', \OCP\Constants::PERMISSION_READ);
336
+            $folder->assign('isPublic', true);
337
+            $folder->assign('hideFileList', $hideFileList);
338
+            $folder->assign('publicUploadEnabled', 'no');
339
+            $folder->assign('uploadMaxFilesize', $maxUploadFilesize);
340
+            $folder->assign('uploadMaxHumanFilesize', \OCP\Util::humanFileSize($maxUploadFilesize));
341
+            $folder->assign('freeSpace', $freeSpace);
342
+            $folder->assign('usedSpacePercent', 0);
343
+            $folder->assign('trash', false);
344
+            $shareTmpl['folder'] = $folder->fetchPage();
345
+        }
346
+
347
+        $shareTmpl['hideFileList'] = $hideFileList;
348
+        $shareTmpl['shareOwner'] = $this->userManager->get($share->getShareOwner())->getDisplayName();
349
+        $shareTmpl['downloadURL'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.downloadShare', ['token' => $this->getToken()]);
350
+        $shareTmpl['shareUrl'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $this->getToken()]);
351
+        $shareTmpl['maxSizeAnimateGif'] = $this->config->getSystemValue('max_filesize_animated_gifs_public_sharing', 10);
352
+        $shareTmpl['previewEnabled'] = $this->config->getSystemValue('enable_previews', true);
353
+        $shareTmpl['previewMaxX'] = $this->config->getSystemValue('preview_max_x', 1024);
354
+        $shareTmpl['previewMaxY'] = $this->config->getSystemValue('preview_max_y', 1024);
355
+        $shareTmpl['disclaimer'] = $this->config->getAppValue('core', 'shareapi_public_link_disclaimertext', null);
356
+        $shareTmpl['previewURL'] = $shareTmpl['downloadURL'];
357
+        $ogPreview = '';
358
+        if ($shareTmpl['previewSupported']) {
359
+            $shareTmpl['previewImage'] = $this->urlGenerator->linkToRouteAbsolute( 'files_sharing.PublicPreview.getPreview',
360
+                ['x' => 200, 'y' => 200, 'file' => $shareTmpl['directory_path'], 'token' => $shareTmpl['dirToken']]);
361
+            $ogPreview = $shareTmpl['previewImage'];
362
+
363
+            // We just have direct previews for image files
364
+            if ($share->getNode()->getMimePart() === 'image') {
365
+                $shareTmpl['previewURL'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.publicpreview.directLink', ['token' => $this->getToken()]);
366
+
367
+                $ogPreview = $shareTmpl['previewURL'];
368
+
369
+                //Whatapp is kind of picky about their size requirements
370
+                if ($this->request->isUserAgent(['/^WhatsApp/'])) {
371
+                    $ogPreview = $this->urlGenerator->linkToRouteAbsolute('files_sharing.PublicPreview.getPreview', [
372
+                        'token' => $this->getToken(),
373
+                        'x' => 256,
374
+                        'y' => 256,
375
+                        'a' => true,
376
+                    ]);
377
+                }
378
+            }
379
+        } else {
380
+            $shareTmpl['previewImage'] = $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath('core', 'favicon-fb.png'));
381
+            $ogPreview = $shareTmpl['previewImage'];
382
+        }
383
+
384
+        // Load files we need
385
+        \OCP\Util::addScript('files', 'file-upload');
386
+        \OCP\Util::addStyle('files_sharing', 'publicView');
387
+        \OCP\Util::addScript('files_sharing', 'public');
388
+        \OCP\Util::addScript('files', 'fileactions');
389
+        \OCP\Util::addScript('files', 'fileactionsmenu');
390
+        \OCP\Util::addScript('files', 'jquery.fileupload');
391
+        \OCP\Util::addScript('files_sharing', 'files_drop');
392
+
393
+        if (isset($shareTmpl['folder'])) {
394
+            // JS required for folders
395
+            \OCP\Util::addStyle('files', 'merged');
396
+            \OCP\Util::addScript('files', 'filesummary');
397
+            \OCP\Util::addScript('files', 'breadcrumb');
398
+            \OCP\Util::addScript('files', 'fileinfomodel');
399
+            \OCP\Util::addScript('files', 'newfilemenu');
400
+            \OCP\Util::addScript('files', 'files');
401
+            \OCP\Util::addScript('files', 'filelist');
402
+            \OCP\Util::addScript('files', 'keyboardshortcuts');
403
+        }
404
+
405
+        // OpenGraph Support: http://ogp.me/
406
+        \OCP\Util::addHeader('meta', ['property' => "og:title", 'content' => $shareTmpl['filename']]);
407
+        \OCP\Util::addHeader('meta', ['property' => "og:description", 'content' => $this->defaults->getName() . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : '')]);
408
+        \OCP\Util::addHeader('meta', ['property' => "og:site_name", 'content' => $this->defaults->getName()]);
409
+        \OCP\Util::addHeader('meta', ['property' => "og:url", 'content' => $shareTmpl['shareUrl']]);
410
+        \OCP\Util::addHeader('meta', ['property' => "og:type", 'content' => "object"]);
411
+        \OCP\Util::addHeader('meta', ['property' => "og:image", 'content' => $ogPreview]);
412
+
413
+        $this->eventDispatcher->dispatch('OCA\Files_Sharing::loadAdditionalScripts');
414
+
415
+        $csp = new \OCP\AppFramework\Http\ContentSecurityPolicy();
416
+        $csp->addAllowedFrameDomain('\'self\'');
417
+
418
+        $response = new PublicTemplateResponse($this->appName, 'public', $shareTmpl);
419
+        $response->setHeaderTitle($shareTmpl['filename']);
420
+        $response->setHeaderDetails($this->l10n->t('shared by %s', [$shareTmpl['displayName']]));
421
+        $response->setHeaderActions([
422
+            new SimpleMenuAction('download', $this->l10n->t('Download'), 'icon-download-white', $shareTmpl['downloadURL'], 0),
423
+            new SimpleMenuAction('download', $this->l10n->t('Download'), 'icon-download', $shareTmpl['downloadURL'], 10, $shareTmpl['fileSize']),
424
+            new LinkMenuAction($this->l10n->t('Direct link'), 'icon-public', $shareTmpl['previewURL']),
425
+            new ExternalShareMenuAction($this->l10n->t('Add to your Nextcloud'), 'icon-external', $shareTmpl['owner'], $shareTmpl['displayName'], $shareTmpl['filename']),
426
+        ]);
427
+
428
+        $response->setContentSecurityPolicy($csp);
429
+
430
+        $this->emitAccessShareHook($share);
431
+
432
+        return $response;
433
+    }
434
+
435
+    /**
436
+     * @PublicPage
437
+     * @NoCSRFRequired
438
+     *
439
+     * @param string $token
440
+     * @param string $files
441
+     * @param string $path
442
+     * @param string $downloadStartSecret
443
+     * @return void|\OCP\AppFramework\Http\Response
444
+     * @throws NotFoundException
445
+     */
446
+    public function downloadShare($token, $files = null, $path = '', $downloadStartSecret = '') {
447
+        \OC_User::setIncognitoMode(true);
448
+
449
+        $share = $this->shareManager->getShareByToken($token);
450
+
451
+        if(!($share->getPermissions() & \OCP\Constants::PERMISSION_READ)) {
452
+            return new \OCP\AppFramework\Http\DataResponse('Share is read-only');
453
+        }
454
+
455
+        $files_list = null;
456
+        if (!is_null($files)) { // download selected files
457
+            $files_list = json_decode($files);
458
+            // in case we get only a single file
459
+            if ($files_list === null) {
460
+                $files_list = [$files];
461
+            }
462
+            // Just in case $files is a single int like '1234'
463
+            if (!is_array($files_list)) {
464
+                $files_list = [$files_list];
465
+            }
466
+        }
467
+
468
+
469
+        if (!$this->validateShare($share)) {
470
+            throw new NotFoundException();
471
+        }
472
+
473
+        $userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
474
+        $originalSharePath = $userFolder->getRelativePath($share->getNode()->getPath());
475
+
476
+
477
+        // Single file share
478
+        if ($share->getNode() instanceof \OCP\Files\File) {
479
+            // Single file download
480
+            $this->singleFileDownloaded($share, $share->getNode());
481
+        }
482
+        // Directory share
483
+        else {
484
+            /** @var \OCP\Files\Folder $node */
485
+            $node = $share->getNode();
486
+
487
+            // Try to get the path
488
+            if ($path !== '') {
489
+                try {
490
+                    $node = $node->get($path);
491
+                } catch (NotFoundException $e) {
492
+                    $this->emitAccessShareHook($share, 404, 'Share not found');
493
+                    return new NotFoundResponse();
494
+                }
495
+            }
496
+
497
+            $originalSharePath = $userFolder->getRelativePath($node->getPath());
498
+
499
+            if ($node instanceof \OCP\Files\File) {
500
+                // Single file download
501
+                $this->singleFileDownloaded($share, $share->getNode());
502
+            } else if (!empty($files_list)) {
503
+                $this->fileListDownloaded($share, $files_list, $node);
504
+            } else {
505
+                // The folder is downloaded
506
+                $this->singleFileDownloaded($share, $share->getNode());
507
+            }
508
+        }
509
+
510
+        /* FIXME: We should do this all nicely in OCP */
511
+        OC_Util::tearDownFS();
512
+        OC_Util::setupFS($share->getShareOwner());
513
+
514
+        /**
515
+         * this sets a cookie to be able to recognize the start of the download
516
+         * the content must not be longer than 32 characters and must only contain
517
+         * alphanumeric characters
518
+         */
519
+        if (!empty($downloadStartSecret)
520
+            && !isset($downloadStartSecret[32])
521
+            && preg_match('!^[a-zA-Z0-9]+$!', $downloadStartSecret) === 1) {
522
+
523
+            // FIXME: set on the response once we use an actual app framework response
524
+            setcookie('ocDownloadStarted', $downloadStartSecret, time() + 20, '/');
525
+        }
526
+
527
+        $this->emitAccessShareHook($share);
528
+
529
+        $server_params = array( 'head' => $this->request->getMethod() === 'HEAD' );
530
+
531
+        /**
532
+         * Http range requests support
533
+         */
534
+        if (isset($_SERVER['HTTP_RANGE'])) {
535
+            $server_params['range'] = $this->request->getHeader('Range');
536
+        }
537
+
538
+        // download selected files
539
+        if (!is_null($files) && $files !== '') {
540
+            // FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well
541
+            // after dispatching the request which results in a "Cannot modify header information" notice.
542
+            OC_Files::get($originalSharePath, $files_list, $server_params);
543
+            exit();
544
+        } else {
545
+            // FIXME: The exit is required here because otherwise the AppFramework is trying to add headers as well
546
+            // after dispatching the request which results in a "Cannot modify header information" notice.
547
+            OC_Files::get(dirname($originalSharePath), basename($originalSharePath), $server_params);
548
+            exit();
549
+        }
550
+    }
551
+
552
+    /**
553
+     * create activity for every downloaded file
554
+     *
555
+     * @param Share\IShare $share
556
+     * @param array $files_list
557
+     * @param \OCP\Files\Folder $node
558
+     */
559
+    protected function fileListDownloaded(Share\IShare $share, array $files_list, \OCP\Files\Folder $node) {
560
+        foreach ($files_list as $file) {
561
+            $subNode = $node->get($file);
562
+            $this->singleFileDownloaded($share, $subNode);
563
+        }
564
+
565
+    }
566
+
567
+    /**
568
+     * create activity if a single file was downloaded from a link share
569
+     *
570
+     * @param Share\IShare $share
571
+     */
572
+    protected function singleFileDownloaded(Share\IShare $share, \OCP\Files\Node $node) {
573
+
574
+        $fileId = $node->getId();
575
+
576
+        $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
577
+        $userNodeList = $userFolder->getById($fileId);
578
+        $userNode = $userNodeList[0];
579
+        $ownerFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
580
+        $userPath = $userFolder->getRelativePath($userNode->getPath());
581
+        $ownerPath = $ownerFolder->getRelativePath($node->getPath());
582
+
583
+        $parameters = [$userPath];
584
+
585
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
586
+            if ($node instanceof \OCP\Files\File) {
587
+                $subject = Downloads::SUBJECT_SHARED_FILE_BY_EMAIL_DOWNLOADED;
588
+            } else {
589
+                $subject = Downloads::SUBJECT_SHARED_FOLDER_BY_EMAIL_DOWNLOADED;
590
+            }
591
+            $parameters[] = $share->getSharedWith();
592
+        } else {
593
+            if ($node instanceof \OCP\Files\File) {
594
+                $subject = Downloads::SUBJECT_PUBLIC_SHARED_FILE_DOWNLOADED;
595
+            } else {
596
+                $subject = Downloads::SUBJECT_PUBLIC_SHARED_FOLDER_DOWNLOADED;
597
+            }
598
+        }
599
+
600
+        $this->publishActivity($subject, $parameters, $share->getSharedBy(), $fileId, $userPath);
601
+
602
+        if ($share->getShareOwner() !== $share->getSharedBy()) {
603
+            $parameters[0] = $ownerPath;
604
+            $this->publishActivity($subject, $parameters, $share->getShareOwner(), $fileId, $ownerPath);
605
+        }
606
+    }
607
+
608
+    /**
609
+     * publish activity
610
+     *
611
+     * @param string $subject
612
+     * @param array $parameters
613
+     * @param string $affectedUser
614
+     * @param int $fileId
615
+     * @param string $filePath
616
+     */
617
+    protected function publishActivity($subject,
618
+                                        array $parameters,
619
+                                        $affectedUser,
620
+                                        $fileId,
621
+                                        $filePath) {
622
+
623
+        $event = $this->activityManager->generateEvent();
624
+        $event->setApp('files_sharing')
625
+            ->setType('public_links')
626
+            ->setSubject($subject, $parameters)
627
+            ->setAffectedUser($affectedUser)
628
+            ->setObject('files', $fileId, $filePath);
629
+        $this->activityManager->publish($event);
630
+    }
632 631
 
633 632
 
634 633
 }
Please login to merge, or discard this patch.
core/Migrations/Version14000Date20180710092004.php 1 patch
Indentation   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -31,18 +31,18 @@
 block discarded – undo
31 31
 
32 32
 class Version14000Date20180710092004 extends SimpleMigrationStep {
33 33
 
34
-	public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) {
35
-		/** @var ISchemaWrapper $schema */
36
-		$schema = $schemaClosure();
34
+    public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) {
35
+        /** @var ISchemaWrapper $schema */
36
+        $schema = $schemaClosure();
37 37
 
38
-		$table = $schema->getTable('share');
38
+        $table = $schema->getTable('share');
39 39
 
40
-		if (!$table->hasColumn('password_by_talk')) {
41
-			$table->addColumn('password_by_talk', Type::BOOLEAN, [
42
-				'default' => 0,
43
-			]);
44
-		}
40
+        if (!$table->hasColumn('password_by_talk')) {
41
+            $table->addColumn('password_by_talk', Type::BOOLEAN, [
42
+                'default' => 0,
43
+            ]);
44
+        }
45 45
 
46
-		return $schema;
47
-	}
46
+        return $schema;
47
+    }
48 48
 }
Please login to merge, or discard this patch.