Passed
Push — master ( 16be14...3c693d )
by Roeland
16:02 queued 12s
created
lib/public/Share/IShare.php 1 patch
Indentation   +533 added lines, -533 removed lines patch added patch discarded remove patch
@@ -42,537 +42,537 @@
 block discarded – undo
42 42
  */
43 43
 interface IShare {
44 44
 
45
-	/**
46
-	 * @since 17.0.0
47
-	 */
48
-	public const TYPE_USER = 0;
49
-
50
-	/**
51
-	 * @since 17.0.0
52
-	 */
53
-	public const TYPE_GROUP = 1;
54
-
55
-	/**
56
-	 * @internal
57
-	 * @since 18.0.0
58
-	 */
59
-	public const TYPE_USERGROUP = 2;
60
-
61
-	/**
62
-	 * @since 17.0.0
63
-	 */
64
-	public const TYPE_LINK = 3;
65
-
66
-	/**
67
-	 * @since 17.0.0
68
-	 */
69
-	public const TYPE_EMAIL = 4;
70
-
71
-	/**
72
-	 * ToDo Check if it is still in use otherwise remove it
73
-	 * @since 17.0.0
74
-	 */
75
-	// public const TYPE_CONTACT = 5;
76
-
77
-	/**
78
-	 * @since 17.0.0
79
-	 */
80
-	public const TYPE_REMOTE = 6;
81
-
82
-	/**
83
-	 * @since 17.0.0
84
-	 */
85
-	public const TYPE_CIRCLE = 7;
86
-
87
-	/**
88
-	 * @since 17.0.0
89
-	 */
90
-	public const TYPE_GUEST = 8;
91
-
92
-	/**
93
-	 * @since 17.0.0
94
-	 */
95
-	public const TYPE_REMOTE_GROUP = 9;
96
-
97
-	/**
98
-	 * @since 17.0.0
99
-	 */
100
-	public const TYPE_ROOM = 10;
101
-
102
-	/**
103
-	 * Internal type used by RoomShareProvider
104
-	 * @since 17.0.0
105
-	 */
106
-	// const TYPE_USERROOM = 11;
107
-
108
-	/**
109
-	 * @since 21.0.0
110
-	 */
111
-	public const TYPE_DECK = 12;
112
-
113
-	/**
114
-	 * @internal
115
-	 * @since 21.0.0
116
-	 */
117
-	public const TYPE_DECK_USER = 13;
118
-
119
-	/**
120
-	 * @since 18.0.0
121
-	 */
122
-	public const STATUS_PENDING = 0;
123
-
124
-	/**
125
-	 * @since 18.0.0
126
-	 */
127
-	public const STATUS_ACCEPTED = 1;
128
-
129
-	/**
130
-	 * @since 18.0.0
131
-	 */
132
-	public const STATUS_REJECTED = 2;
133
-
134
-	/**
135
-	 * Set the internal id of the share
136
-	 * It is only allowed to set the internal id of a share once.
137
-	 * Attempts to override the internal id will result in an IllegalIDChangeException
138
-	 *
139
-	 * @param string $id
140
-	 * @return \OCP\Share\IShare
141
-	 * @throws IllegalIDChangeException
142
-	 * @throws \InvalidArgumentException
143
-	 * @since 9.1.0
144
-	 */
145
-	public function setId($id);
146
-
147
-	/**
148
-	 * Get the internal id of the share.
149
-	 *
150
-	 * @return string
151
-	 * @since 9.0.0
152
-	 */
153
-	public function getId();
154
-
155
-	/**
156
-	 * Get the full share id. This is the <providerid>:<internalid>.
157
-	 * The full id is unique in the system.
158
-	 *
159
-	 * @return string
160
-	 * @since 9.0.0
161
-	 * @throws \UnexpectedValueException If the fullId could not be constructed
162
-	 */
163
-	public function getFullId();
164
-
165
-	/**
166
-	 * Set the provider id of the share
167
-	 * It is only allowed to set the provider id of a share once.
168
-	 * Attempts to override the provider id will result in an IllegalIDChangeException
169
-	 *
170
-	 * @param string $id
171
-	 * @return \OCP\Share\IShare
172
-	 * @throws IllegalIDChangeException
173
-	 * @throws \InvalidArgumentException
174
-	 * @since 9.1.0
175
-	 */
176
-	public function setProviderId($id);
177
-
178
-	/**
179
-	 * Set the node of the file/folder that is shared
180
-	 *
181
-	 * @param Node $node
182
-	 * @return \OCP\Share\IShare The modified object
183
-	 * @since 9.0.0
184
-	 */
185
-	public function setNode(Node $node);
186
-
187
-	/**
188
-	 * Get the node of the file/folder that is shared
189
-	 *
190
-	 * @return File|Folder
191
-	 * @since 9.0.0
192
-	 * @throws NotFoundException
193
-	 */
194
-	public function getNode();
195
-
196
-	/**
197
-	 * Set file id for lazy evaluation of the node
198
-	 * @param int $fileId
199
-	 * @return \OCP\Share\IShare The modified object
200
-	 * @since 9.0.0
201
-	 */
202
-	public function setNodeId($fileId);
203
-
204
-	/**
205
-	 * Get the fileid of the node of this share
206
-	 * @return int
207
-	 * @since 9.0.0
208
-	 * @throws NotFoundException
209
-	 */
210
-	public function getNodeId();
211
-
212
-	/**
213
-	 * Set the type of node (file/folder)
214
-	 *
215
-	 * @param string $type
216
-	 * @return \OCP\Share\IShare The modified object
217
-	 * @since 9.0.0
218
-	 */
219
-	public function setNodeType($type);
220
-
221
-	/**
222
-	 * Get the type of node (file/folder)
223
-	 *
224
-	 * @return string
225
-	 * @since 9.0.0
226
-	 * @throws NotFoundException
227
-	 */
228
-	public function getNodeType();
229
-
230
-	/**
231
-	 * Set the shareType
232
-	 *
233
-	 * @param int $shareType
234
-	 * @return \OCP\Share\IShare The modified object
235
-	 * @since 9.0.0
236
-	 */
237
-	public function setShareType($shareType);
238
-
239
-	/**
240
-	 * Get the shareType
241
-	 *
242
-	 * @return int
243
-	 * @since 9.0.0
244
-	 */
245
-	public function getShareType();
246
-
247
-	/**
248
-	 * Set the receiver of this share.
249
-	 *
250
-	 * @param string $sharedWith
251
-	 * @return \OCP\Share\IShare The modified object
252
-	 * @since 9.0.0
253
-	 */
254
-	public function setSharedWith($sharedWith);
255
-
256
-	/**
257
-	 * Get the receiver of this share.
258
-	 *
259
-	 * @return string
260
-	 * @since 9.0.0
261
-	 */
262
-	public function getSharedWith();
263
-
264
-	/**
265
-	 * Set the display name of the receiver of this share.
266
-	 *
267
-	 * @param string $displayName
268
-	 * @return \OCP\Share\IShare The modified object
269
-	 * @since 14.0.0
270
-	 */
271
-	public function setSharedWithDisplayName($displayName);
272
-
273
-	/**
274
-	 * Get the display name of the receiver of this share.
275
-	 *
276
-	 * @return string
277
-	 * @since 14.0.0
278
-	 */
279
-	public function getSharedWithDisplayName();
280
-
281
-	/**
282
-	 * Set the avatar of the receiver of this share.
283
-	 *
284
-	 * @param string $src
285
-	 * @return \OCP\Share\IShare The modified object
286
-	 * @since 14.0.0
287
-	 */
288
-	public function setSharedWithAvatar($src);
289
-
290
-	/**
291
-	 * Get the avatar of the receiver of this share.
292
-	 *
293
-	 * @return string
294
-	 * @since 14.0.0
295
-	 */
296
-	public function getSharedWithAvatar();
297
-
298
-	/**
299
-	 * Set the permissions.
300
-	 * See \OCP\Constants::PERMISSION_*
301
-	 *
302
-	 * @param int $permissions
303
-	 * @return \OCP\Share\IShare The modified object
304
-	 * @since 9.0.0
305
-	 */
306
-	public function setPermissions($permissions);
307
-
308
-	/**
309
-	 * Get the share permissions
310
-	 * See \OCP\Constants::PERMISSION_*
311
-	 *
312
-	 * @return int
313
-	 * @since 9.0.0
314
-	 */
315
-	public function getPermissions();
316
-
317
-	/**
318
-	 * Set the accepted status
319
-	 * See self::STATUS_*
320
-	 *
321
-	 * @param int $status
322
-	 * @return IShare The modified object
323
-	 * @since 18.0.0
324
-	 */
325
-	public function setStatus(int $status): IShare;
326
-
327
-	/**
328
-	 * Get the accepted status
329
-	 * See self::STATUS_*
330
-	 *
331
-	 * @return int
332
-	 * @since 18.0.0
333
-	 */
334
-	public function getStatus(): int;
335
-
336
-	/**
337
-	 * Attach a note to a share
338
-	 *
339
-	 * @param string $note
340
-	 * @return \OCP\Share\IShare The modified object
341
-	 * @since 14.0.0
342
-	 */
343
-	public function setNote($note);
344
-
345
-	/**
346
-	 * Get note attached to a share
347
-	 *
348
-	 * @return string
349
-	 * @since 14.0.0
350
-	 */
351
-	public function getNote();
352
-
353
-
354
-	/**
355
-	 * Set the expiration date
356
-	 *
357
-	 * @param null|\DateTime $expireDate
358
-	 * @return \OCP\Share\IShare The modified object
359
-	 * @since 9.0.0
360
-	 */
361
-	public function setExpirationDate($expireDate);
362
-
363
-	/**
364
-	 * Get the expiration date
365
-	 *
366
-	 * @return \DateTime
367
-	 * @since 9.0.0
368
-	 */
369
-	public function getExpirationDate();
370
-
371
-	/**
372
-	 * Is the share expired ?
373
-	 *
374
-	 * @return boolean
375
-	 * @since 18.0.0
376
-	 */
377
-	public function isExpired();
378
-
379
-	/**
380
-	 * set a label for a share, some shares, e.g. public links can have a label
381
-	 *
382
-	 * @param string $label
383
-	 * @return \OCP\Share\IShare The modified object
384
-	 * @since 15.0.0
385
-	 */
386
-	public function setLabel($label);
387
-
388
-	/**
389
-	 * get label for the share, some shares, e.g. public links can have a label
390
-	 *
391
-	 * @return string
392
-	 * @since 15.0.0
393
-	 */
394
-	public function getLabel();
395
-
396
-	/**
397
-	 * Set the sharer of the path.
398
-	 *
399
-	 * @param string $sharedBy
400
-	 * @return \OCP\Share\IShare The modified object
401
-	 * @since 9.0.0
402
-	 */
403
-	public function setSharedBy($sharedBy);
404
-
405
-	/**
406
-	 * Get share sharer
407
-	 *
408
-	 * @return string
409
-	 * @since 9.0.0
410
-	 */
411
-	public function getSharedBy();
412
-
413
-	/**
414
-	 * Set the original share owner (who owns the path that is shared)
415
-	 *
416
-	 * @param string $shareOwner
417
-	 * @return \OCP\Share\IShare The modified object
418
-	 * @since 9.0.0
419
-	 */
420
-	public function setShareOwner($shareOwner);
421
-
422
-	/**
423
-	 * Get the original share owner (who owns the path that is shared)
424
-	 *
425
-	 * @return string
426
-	 * @since 9.0.0
427
-	 */
428
-	public function getShareOwner();
429
-
430
-	/**
431
-	 * Set the password for this share.
432
-	 * When the share is passed to the share manager to be created
433
-	 * or updated the password will be hashed.
434
-	 *
435
-	 * @param string $password
436
-	 * @return \OCP\Share\IShare The modified object
437
-	 * @since 9.0.0
438
-	 */
439
-	public function setPassword($password);
440
-
441
-	/**
442
-	 * Get the password of this share.
443
-	 * If this share is obtained via a shareprovider the password is
444
-	 * hashed.
445
-	 *
446
-	 * @return string
447
-	 * @since 9.0.0
448
-	 */
449
-	public function getPassword();
450
-
451
-
452
-	/**
453
-	 * Set if the recipient can start a conversation with the owner to get the
454
-	 * password using Nextcloud Talk.
455
-	 *
456
-	 * @param bool $sendPasswordByTalk
457
-	 * @return \OCP\Share\IShare The modified object
458
-	 * @since 14.0.0
459
-	 */
460
-	public function setSendPasswordByTalk(bool $sendPasswordByTalk);
461
-
462
-	/**
463
-	 * Get if the recipient can start a conversation with the owner to get the
464
-	 * password using Nextcloud Talk.
465
-	 * The returned value does not take into account other factors, like Talk
466
-	 * being enabled for the owner of the share or not; it just cover whether
467
-	 * the option is enabled for the share itself or not.
468
-	 *
469
-	 * @return bool
470
-	 * @since 14.0.0
471
-	 */
472
-	public function getSendPasswordByTalk(): bool;
473
-
474
-	/**
475
-	 * Set the public link token.
476
-	 *
477
-	 * @param string $token
478
-	 * @return \OCP\Share\IShare The modified object
479
-	 * @since 9.0.0
480
-	 */
481
-	public function setToken($token);
482
-
483
-	/**
484
-	 * Get the public link token.
485
-	 *
486
-	 * @return string
487
-	 * @since 9.0.0
488
-	 */
489
-	public function getToken();
490
-
491
-	/**
492
-	 * Set the target path of this share relative to the recipients user folder.
493
-	 *
494
-	 * @param string $target
495
-	 * @return \OCP\Share\IShare The modified object
496
-	 * @since 9.0.0
497
-	 */
498
-	public function setTarget($target);
499
-
500
-	/**
501
-	 * Get the target path of this share relative to the recipients user folder.
502
-	 *
503
-	 * @return string
504
-	 * @since 9.0.0
505
-	 */
506
-	public function getTarget();
507
-
508
-	/**
509
-	 * Set the time this share was created
510
-	 *
511
-	 * @param \DateTime $shareTime
512
-	 * @return \OCP\Share\IShare The modified object
513
-	 * @since 9.0.0
514
-	 */
515
-	public function setShareTime(\DateTime $shareTime);
516
-
517
-	/**
518
-	 * Get the timestamp this share was created
519
-	 *
520
-	 * @return \DateTime
521
-	 * @since 9.0.0
522
-	 */
523
-	public function getShareTime();
524
-
525
-	/**
526
-	 * Set if the recipient is informed by mail about the share.
527
-	 *
528
-	 * @param bool $mailSend
529
-	 * @return \OCP\Share\IShare The modified object
530
-	 * @since 9.0.0
531
-	 */
532
-	public function setMailSend($mailSend);
533
-
534
-	/**
535
-	 * Get if the recipient informed by mail about the share.
536
-	 *
537
-	 * @return bool
538
-	 * @since 9.0.0
539
-	 */
540
-	public function getMailSend();
541
-
542
-	/**
543
-	 * Set the cache entry for the shared node
544
-	 *
545
-	 * @param ICacheEntry $entry
546
-	 * @since 11.0.0
547
-	 */
548
-	public function setNodeCacheEntry(ICacheEntry $entry);
549
-
550
-	/**
551
-	 * Get the cache entry for the shared node
552
-	 *
553
-	 * @return null|ICacheEntry
554
-	 * @since 11.0.0
555
-	 */
556
-	public function getNodeCacheEntry();
557
-
558
-	/**
559
-	 * Sets a shares hide download state
560
-	 * This is mainly for public shares. It will signal that the share page should
561
-	 * hide download buttons etc.
562
-	 *
563
-	 * @param bool $hide
564
-	 * @return IShare
565
-	 * @since 15.0.0
566
-	 */
567
-	public function setHideDownload(bool $hide): IShare;
568
-
569
-	/**
570
-	 * Gets a shares hide download state
571
-	 * This is mainly for public shares. It will signal that the share page should
572
-	 * hide download buttons etc.
573
-	 *
574
-	 * @return bool
575
-	 * @since 15.0.0
576
-	 */
577
-	public function getHideDownload(): bool;
45
+    /**
46
+     * @since 17.0.0
47
+     */
48
+    public const TYPE_USER = 0;
49
+
50
+    /**
51
+     * @since 17.0.0
52
+     */
53
+    public const TYPE_GROUP = 1;
54
+
55
+    /**
56
+     * @internal
57
+     * @since 18.0.0
58
+     */
59
+    public const TYPE_USERGROUP = 2;
60
+
61
+    /**
62
+     * @since 17.0.0
63
+     */
64
+    public const TYPE_LINK = 3;
65
+
66
+    /**
67
+     * @since 17.0.0
68
+     */
69
+    public const TYPE_EMAIL = 4;
70
+
71
+    /**
72
+     * ToDo Check if it is still in use otherwise remove it
73
+     * @since 17.0.0
74
+     */
75
+    // public const TYPE_CONTACT = 5;
76
+
77
+    /**
78
+     * @since 17.0.0
79
+     */
80
+    public const TYPE_REMOTE = 6;
81
+
82
+    /**
83
+     * @since 17.0.0
84
+     */
85
+    public const TYPE_CIRCLE = 7;
86
+
87
+    /**
88
+     * @since 17.0.0
89
+     */
90
+    public const TYPE_GUEST = 8;
91
+
92
+    /**
93
+     * @since 17.0.0
94
+     */
95
+    public const TYPE_REMOTE_GROUP = 9;
96
+
97
+    /**
98
+     * @since 17.0.0
99
+     */
100
+    public const TYPE_ROOM = 10;
101
+
102
+    /**
103
+     * Internal type used by RoomShareProvider
104
+     * @since 17.0.0
105
+     */
106
+    // const TYPE_USERROOM = 11;
107
+
108
+    /**
109
+     * @since 21.0.0
110
+     */
111
+    public const TYPE_DECK = 12;
112
+
113
+    /**
114
+     * @internal
115
+     * @since 21.0.0
116
+     */
117
+    public const TYPE_DECK_USER = 13;
118
+
119
+    /**
120
+     * @since 18.0.0
121
+     */
122
+    public const STATUS_PENDING = 0;
123
+
124
+    /**
125
+     * @since 18.0.0
126
+     */
127
+    public const STATUS_ACCEPTED = 1;
128
+
129
+    /**
130
+     * @since 18.0.0
131
+     */
132
+    public const STATUS_REJECTED = 2;
133
+
134
+    /**
135
+     * Set the internal id of the share
136
+     * It is only allowed to set the internal id of a share once.
137
+     * Attempts to override the internal id will result in an IllegalIDChangeException
138
+     *
139
+     * @param string $id
140
+     * @return \OCP\Share\IShare
141
+     * @throws IllegalIDChangeException
142
+     * @throws \InvalidArgumentException
143
+     * @since 9.1.0
144
+     */
145
+    public function setId($id);
146
+
147
+    /**
148
+     * Get the internal id of the share.
149
+     *
150
+     * @return string
151
+     * @since 9.0.0
152
+     */
153
+    public function getId();
154
+
155
+    /**
156
+     * Get the full share id. This is the <providerid>:<internalid>.
157
+     * The full id is unique in the system.
158
+     *
159
+     * @return string
160
+     * @since 9.0.0
161
+     * @throws \UnexpectedValueException If the fullId could not be constructed
162
+     */
163
+    public function getFullId();
164
+
165
+    /**
166
+     * Set the provider id of the share
167
+     * It is only allowed to set the provider id of a share once.
168
+     * Attempts to override the provider id will result in an IllegalIDChangeException
169
+     *
170
+     * @param string $id
171
+     * @return \OCP\Share\IShare
172
+     * @throws IllegalIDChangeException
173
+     * @throws \InvalidArgumentException
174
+     * @since 9.1.0
175
+     */
176
+    public function setProviderId($id);
177
+
178
+    /**
179
+     * Set the node of the file/folder that is shared
180
+     *
181
+     * @param Node $node
182
+     * @return \OCP\Share\IShare The modified object
183
+     * @since 9.0.0
184
+     */
185
+    public function setNode(Node $node);
186
+
187
+    /**
188
+     * Get the node of the file/folder that is shared
189
+     *
190
+     * @return File|Folder
191
+     * @since 9.0.0
192
+     * @throws NotFoundException
193
+     */
194
+    public function getNode();
195
+
196
+    /**
197
+     * Set file id for lazy evaluation of the node
198
+     * @param int $fileId
199
+     * @return \OCP\Share\IShare The modified object
200
+     * @since 9.0.0
201
+     */
202
+    public function setNodeId($fileId);
203
+
204
+    /**
205
+     * Get the fileid of the node of this share
206
+     * @return int
207
+     * @since 9.0.0
208
+     * @throws NotFoundException
209
+     */
210
+    public function getNodeId();
211
+
212
+    /**
213
+     * Set the type of node (file/folder)
214
+     *
215
+     * @param string $type
216
+     * @return \OCP\Share\IShare The modified object
217
+     * @since 9.0.0
218
+     */
219
+    public function setNodeType($type);
220
+
221
+    /**
222
+     * Get the type of node (file/folder)
223
+     *
224
+     * @return string
225
+     * @since 9.0.0
226
+     * @throws NotFoundException
227
+     */
228
+    public function getNodeType();
229
+
230
+    /**
231
+     * Set the shareType
232
+     *
233
+     * @param int $shareType
234
+     * @return \OCP\Share\IShare The modified object
235
+     * @since 9.0.0
236
+     */
237
+    public function setShareType($shareType);
238
+
239
+    /**
240
+     * Get the shareType
241
+     *
242
+     * @return int
243
+     * @since 9.0.0
244
+     */
245
+    public function getShareType();
246
+
247
+    /**
248
+     * Set the receiver of this share.
249
+     *
250
+     * @param string $sharedWith
251
+     * @return \OCP\Share\IShare The modified object
252
+     * @since 9.0.0
253
+     */
254
+    public function setSharedWith($sharedWith);
255
+
256
+    /**
257
+     * Get the receiver of this share.
258
+     *
259
+     * @return string
260
+     * @since 9.0.0
261
+     */
262
+    public function getSharedWith();
263
+
264
+    /**
265
+     * Set the display name of the receiver of this share.
266
+     *
267
+     * @param string $displayName
268
+     * @return \OCP\Share\IShare The modified object
269
+     * @since 14.0.0
270
+     */
271
+    public function setSharedWithDisplayName($displayName);
272
+
273
+    /**
274
+     * Get the display name of the receiver of this share.
275
+     *
276
+     * @return string
277
+     * @since 14.0.0
278
+     */
279
+    public function getSharedWithDisplayName();
280
+
281
+    /**
282
+     * Set the avatar of the receiver of this share.
283
+     *
284
+     * @param string $src
285
+     * @return \OCP\Share\IShare The modified object
286
+     * @since 14.0.0
287
+     */
288
+    public function setSharedWithAvatar($src);
289
+
290
+    /**
291
+     * Get the avatar of the receiver of this share.
292
+     *
293
+     * @return string
294
+     * @since 14.0.0
295
+     */
296
+    public function getSharedWithAvatar();
297
+
298
+    /**
299
+     * Set the permissions.
300
+     * See \OCP\Constants::PERMISSION_*
301
+     *
302
+     * @param int $permissions
303
+     * @return \OCP\Share\IShare The modified object
304
+     * @since 9.0.0
305
+     */
306
+    public function setPermissions($permissions);
307
+
308
+    /**
309
+     * Get the share permissions
310
+     * See \OCP\Constants::PERMISSION_*
311
+     *
312
+     * @return int
313
+     * @since 9.0.0
314
+     */
315
+    public function getPermissions();
316
+
317
+    /**
318
+     * Set the accepted status
319
+     * See self::STATUS_*
320
+     *
321
+     * @param int $status
322
+     * @return IShare The modified object
323
+     * @since 18.0.0
324
+     */
325
+    public function setStatus(int $status): IShare;
326
+
327
+    /**
328
+     * Get the accepted status
329
+     * See self::STATUS_*
330
+     *
331
+     * @return int
332
+     * @since 18.0.0
333
+     */
334
+    public function getStatus(): int;
335
+
336
+    /**
337
+     * Attach a note to a share
338
+     *
339
+     * @param string $note
340
+     * @return \OCP\Share\IShare The modified object
341
+     * @since 14.0.0
342
+     */
343
+    public function setNote($note);
344
+
345
+    /**
346
+     * Get note attached to a share
347
+     *
348
+     * @return string
349
+     * @since 14.0.0
350
+     */
351
+    public function getNote();
352
+
353
+
354
+    /**
355
+     * Set the expiration date
356
+     *
357
+     * @param null|\DateTime $expireDate
358
+     * @return \OCP\Share\IShare The modified object
359
+     * @since 9.0.0
360
+     */
361
+    public function setExpirationDate($expireDate);
362
+
363
+    /**
364
+     * Get the expiration date
365
+     *
366
+     * @return \DateTime
367
+     * @since 9.0.0
368
+     */
369
+    public function getExpirationDate();
370
+
371
+    /**
372
+     * Is the share expired ?
373
+     *
374
+     * @return boolean
375
+     * @since 18.0.0
376
+     */
377
+    public function isExpired();
378
+
379
+    /**
380
+     * set a label for a share, some shares, e.g. public links can have a label
381
+     *
382
+     * @param string $label
383
+     * @return \OCP\Share\IShare The modified object
384
+     * @since 15.0.0
385
+     */
386
+    public function setLabel($label);
387
+
388
+    /**
389
+     * get label for the share, some shares, e.g. public links can have a label
390
+     *
391
+     * @return string
392
+     * @since 15.0.0
393
+     */
394
+    public function getLabel();
395
+
396
+    /**
397
+     * Set the sharer of the path.
398
+     *
399
+     * @param string $sharedBy
400
+     * @return \OCP\Share\IShare The modified object
401
+     * @since 9.0.0
402
+     */
403
+    public function setSharedBy($sharedBy);
404
+
405
+    /**
406
+     * Get share sharer
407
+     *
408
+     * @return string
409
+     * @since 9.0.0
410
+     */
411
+    public function getSharedBy();
412
+
413
+    /**
414
+     * Set the original share owner (who owns the path that is shared)
415
+     *
416
+     * @param string $shareOwner
417
+     * @return \OCP\Share\IShare The modified object
418
+     * @since 9.0.0
419
+     */
420
+    public function setShareOwner($shareOwner);
421
+
422
+    /**
423
+     * Get the original share owner (who owns the path that is shared)
424
+     *
425
+     * @return string
426
+     * @since 9.0.0
427
+     */
428
+    public function getShareOwner();
429
+
430
+    /**
431
+     * Set the password for this share.
432
+     * When the share is passed to the share manager to be created
433
+     * or updated the password will be hashed.
434
+     *
435
+     * @param string $password
436
+     * @return \OCP\Share\IShare The modified object
437
+     * @since 9.0.0
438
+     */
439
+    public function setPassword($password);
440
+
441
+    /**
442
+     * Get the password of this share.
443
+     * If this share is obtained via a shareprovider the password is
444
+     * hashed.
445
+     *
446
+     * @return string
447
+     * @since 9.0.0
448
+     */
449
+    public function getPassword();
450
+
451
+
452
+    /**
453
+     * Set if the recipient can start a conversation with the owner to get the
454
+     * password using Nextcloud Talk.
455
+     *
456
+     * @param bool $sendPasswordByTalk
457
+     * @return \OCP\Share\IShare The modified object
458
+     * @since 14.0.0
459
+     */
460
+    public function setSendPasswordByTalk(bool $sendPasswordByTalk);
461
+
462
+    /**
463
+     * Get if the recipient can start a conversation with the owner to get the
464
+     * password using Nextcloud Talk.
465
+     * The returned value does not take into account other factors, like Talk
466
+     * being enabled for the owner of the share or not; it just cover whether
467
+     * the option is enabled for the share itself or not.
468
+     *
469
+     * @return bool
470
+     * @since 14.0.0
471
+     */
472
+    public function getSendPasswordByTalk(): bool;
473
+
474
+    /**
475
+     * Set the public link token.
476
+     *
477
+     * @param string $token
478
+     * @return \OCP\Share\IShare The modified object
479
+     * @since 9.0.0
480
+     */
481
+    public function setToken($token);
482
+
483
+    /**
484
+     * Get the public link token.
485
+     *
486
+     * @return string
487
+     * @since 9.0.0
488
+     */
489
+    public function getToken();
490
+
491
+    /**
492
+     * Set the target path of this share relative to the recipients user folder.
493
+     *
494
+     * @param string $target
495
+     * @return \OCP\Share\IShare The modified object
496
+     * @since 9.0.0
497
+     */
498
+    public function setTarget($target);
499
+
500
+    /**
501
+     * Get the target path of this share relative to the recipients user folder.
502
+     *
503
+     * @return string
504
+     * @since 9.0.0
505
+     */
506
+    public function getTarget();
507
+
508
+    /**
509
+     * Set the time this share was created
510
+     *
511
+     * @param \DateTime $shareTime
512
+     * @return \OCP\Share\IShare The modified object
513
+     * @since 9.0.0
514
+     */
515
+    public function setShareTime(\DateTime $shareTime);
516
+
517
+    /**
518
+     * Get the timestamp this share was created
519
+     *
520
+     * @return \DateTime
521
+     * @since 9.0.0
522
+     */
523
+    public function getShareTime();
524
+
525
+    /**
526
+     * Set if the recipient is informed by mail about the share.
527
+     *
528
+     * @param bool $mailSend
529
+     * @return \OCP\Share\IShare The modified object
530
+     * @since 9.0.0
531
+     */
532
+    public function setMailSend($mailSend);
533
+
534
+    /**
535
+     * Get if the recipient informed by mail about the share.
536
+     *
537
+     * @return bool
538
+     * @since 9.0.0
539
+     */
540
+    public function getMailSend();
541
+
542
+    /**
543
+     * Set the cache entry for the shared node
544
+     *
545
+     * @param ICacheEntry $entry
546
+     * @since 11.0.0
547
+     */
548
+    public function setNodeCacheEntry(ICacheEntry $entry);
549
+
550
+    /**
551
+     * Get the cache entry for the shared node
552
+     *
553
+     * @return null|ICacheEntry
554
+     * @since 11.0.0
555
+     */
556
+    public function getNodeCacheEntry();
557
+
558
+    /**
559
+     * Sets a shares hide download state
560
+     * This is mainly for public shares. It will signal that the share page should
561
+     * hide download buttons etc.
562
+     *
563
+     * @param bool $hide
564
+     * @return IShare
565
+     * @since 15.0.0
566
+     */
567
+    public function setHideDownload(bool $hide): IShare;
568
+
569
+    /**
570
+     * Gets a shares hide download state
571
+     * This is mainly for public shares. It will signal that the share page should
572
+     * hide download buttons etc.
573
+     *
574
+     * @return bool
575
+     * @since 15.0.0
576
+     */
577
+    public function getHideDownload(): bool;
578 578
 }
Please login to merge, or discard this patch.
lib/public/Share/IProviderFactory.php 1 patch
Indentation   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -32,31 +32,31 @@
 block discarded – undo
32 32
  */
33 33
 interface IProviderFactory {
34 34
 
35
-	/**
36
-	 * @param string $id
37
-	 * @return IShareProvider
38
-	 * @throws ProviderException
39
-	 * @since 9.0.0
40
-	 */
41
-	public function getProvider($id);
35
+    /**
36
+     * @param string $id
37
+     * @return IShareProvider
38
+     * @throws ProviderException
39
+     * @since 9.0.0
40
+     */
41
+    public function getProvider($id);
42 42
 
43
-	/**
44
-	 * @param int $shareType
45
-	 * @return IShareProvider
46
-	 * @throws ProviderException
47
-	 * @since 9.0.0
48
-	 */
49
-	public function getProviderForType($shareType);
43
+    /**
44
+     * @param int $shareType
45
+     * @return IShareProvider
46
+     * @throws ProviderException
47
+     * @since 9.0.0
48
+     */
49
+    public function getProviderForType($shareType);
50 50
 
51
-	/**
52
-	 * @return IShareProvider[]
53
-	 * @since 11.0.0
54
-	 */
55
-	public function getAllProviders();
51
+    /**
52
+     * @return IShareProvider[]
53
+     * @since 11.0.0
54
+     */
55
+    public function getAllProviders();
56 56
 
57
-	/**
58
-	 * @since 21.0.0
59
-	 * @param string $shareProvier
60
-	 */
61
-	public function registerProvider(string $shareProvier): void;
57
+    /**
58
+     * @since 21.0.0
59
+     * @param string $shareProvier
60
+     */
61
+    public function registerProvider(string $shareProvier): void;
62 62
 }
Please login to merge, or discard this patch.
lib/public/Share/IManager.php 1 patch
Indentation   +390 added lines, -390 removed lines patch added patch discarded remove patch
@@ -43,394 +43,394 @@
 block discarded – undo
43 43
  */
44 44
 interface IManager {
45 45
 
46
-	/**
47
-	 * Create a Share
48
-	 *
49
-	 * @param IShare $share
50
-	 * @return IShare The share object
51
-	 * @throws \Exception
52
-	 * @since 9.0.0
53
-	 */
54
-	public function createShare(IShare $share);
55
-
56
-	/**
57
-	 * Update a share.
58
-	 * The target of the share can't be changed this way: use moveShare
59
-	 * The share can't be removed this way (permission 0): use deleteShare
60
-	 * The state can't be changed this way: use acceptShare
61
-	 *
62
-	 * @param IShare $share
63
-	 * @return IShare The share object
64
-	 * @throws \InvalidArgumentException
65
-	 * @since 9.0.0
66
-	 */
67
-	public function updateShare(IShare $share);
68
-
69
-	/**
70
-	 * Accept a share.
71
-	 *
72
-	 * @param IShare $share
73
-	 * @param string $recipientId
74
-	 * @return IShare The share object
75
-	 * @throws \InvalidArgumentException
76
-	 * @since 18.0.0
77
-	 */
78
-	public function acceptShare(IShare $share, string $recipientId): IShare;
79
-
80
-	/**
81
-	 * Delete a share
82
-	 *
83
-	 * @param IShare $share
84
-	 * @throws ShareNotFound
85
-	 * @throws \InvalidArgumentException
86
-	 * @since 9.0.0
87
-	 */
88
-	public function deleteShare(IShare $share);
89
-
90
-	/**
91
-	 * Unshare a file as the recipient.
92
-	 * This can be different from a regular delete for example when one of
93
-	 * the users in a groups deletes that share. But the provider should
94
-	 * handle this.
95
-	 *
96
-	 * @param IShare $share
97
-	 * @param string $recipientId
98
-	 * @since 9.0.0
99
-	 */
100
-	public function deleteFromSelf(IShare $share, $recipientId);
101
-
102
-	/**
103
-	 * Restore the share when it has been deleted
104
-	 * Certain share types can be restored when they have been deleted
105
-	 * but the provider should properly handle this\
106
-	 *
107
-	 * @param IShare $share The share to restore
108
-	 * @param string $recipientId The user to restore the share for
109
-	 * @return IShare The restored share object
110
-	 * @throws GenericShareException In case restoring the share failed
111
-	 *
112
-	 * @since 14.0.0
113
-	 */
114
-	public function restoreShare(IShare $share, string $recipientId): IShare;
115
-
116
-	/**
117
-	 * Move the share as a recipient of the share.
118
-	 * This is updating the share target. So where the recipient has the share mounted.
119
-	 *
120
-	 * @param IShare $share
121
-	 * @param string $recipientId
122
-	 * @return IShare
123
-	 * @throws \InvalidArgumentException If $share is a link share or the $recipient does not match
124
-	 * @since 9.0.0
125
-	 */
126
-	public function moveShare(IShare $share, $recipientId);
127
-
128
-	/**
129
-	 * Get all shares shared by (initiated) by the provided user in a folder.
130
-	 *
131
-	 * @param string $userId
132
-	 * @param Folder $node
133
-	 * @param bool $reshares
134
-	 * @return IShare[][] [$fileId => IShare[], ...]
135
-	 * @since 11.0.0
136
-	 */
137
-	public function getSharesInFolder($userId, Folder $node, $reshares = false);
138
-
139
-	/**
140
-	 * Get shares shared by (initiated) by the provided user.
141
-	 *
142
-	 * @param string $userId
143
-	 * @param int $shareType
144
-	 * @param Node|null $path
145
-	 * @param bool $reshares
146
-	 * @param int $limit The maximum number of returned results, -1 for all results
147
-	 * @param int $offset
148
-	 * @return IShare[]
149
-	 * @since 9.0.0
150
-	 */
151
-	public function getSharesBy($userId, $shareType, $path = null, $reshares = false, $limit = 50, $offset = 0);
152
-
153
-	/**
154
-	 * Get shares shared with $user.
155
-	 * Filter by $node if provided
156
-	 *
157
-	 * @param string $userId
158
-	 * @param int $shareType
159
-	 * @param Node|null $node
160
-	 * @param int $limit The maximum number of shares returned, -1 for all
161
-	 * @param int $offset
162
-	 * @return IShare[]
163
-	 * @since 9.0.0
164
-	 */
165
-	public function getSharedWith($userId, $shareType, $node = null, $limit = 50, $offset = 0);
166
-
167
-	/**
168
-	 * Get deleted shares shared with $user.
169
-	 * Filter by $node if provided
170
-	 *
171
-	 * @param string $userId
172
-	 * @param int $shareType
173
-	 * @param Node|null $node
174
-	 * @param int $limit The maximum number of shares returned, -1 for all
175
-	 * @param int $offset
176
-	 * @return IShare[]
177
-	 * @since 14.0.0
178
-	 */
179
-	public function getDeletedSharedWith($userId, $shareType, $node = null, $limit = 50, $offset = 0);
180
-
181
-	/**
182
-	 * Retrieve a share by the share id.
183
-	 * If the recipient is set make sure to retrieve the file for that user.
184
-	 * This makes sure that if a user has moved/deleted a group share this
185
-	 * is reflected.
186
-	 *
187
-	 * @param string $id
188
-	 * @param string|null $recipient userID of the recipient
189
-	 * @return IShare
190
-	 * @throws ShareNotFound
191
-	 * @since 9.0.0
192
-	 */
193
-	public function getShareById($id, $recipient = null);
194
-
195
-	/**
196
-	 * Get the share by token possible with password
197
-	 *
198
-	 * @param string $token
199
-	 * @return IShare
200
-	 * @throws ShareNotFound
201
-	 * @since 9.0.0
202
-	 */
203
-	public function getShareByToken($token);
204
-
205
-	/**
206
-	 * Verify the password of a public share
207
-	 *
208
-	 * @param IShare $share
209
-	 * @param string $password
210
-	 * @return bool
211
-	 * @since 9.0.0
212
-	 */
213
-	public function checkPassword(IShare $share, $password);
214
-
215
-	/**
216
-	 * The user with UID is deleted.
217
-	 * All share providers have to cleanup the shares with this user as well
218
-	 * as shares owned by this user.
219
-	 * Shares only initiated by this user are fine.
220
-	 *
221
-	 * @param string $uid
222
-	 * @since 9.1.0
223
-	 */
224
-	public function userDeleted($uid);
225
-
226
-	/**
227
-	 * The group with $gid is deleted
228
-	 * We need to clear up all shares to this group
229
-	 *
230
-	 * @param string $gid
231
-	 * @since 9.1.0
232
-	 */
233
-	public function groupDeleted($gid);
234
-
235
-	/**
236
-	 * The user $uid is deleted from the group $gid
237
-	 * All user specific group shares have to be removed
238
-	 *
239
-	 * @param string $uid
240
-	 * @param string $gid
241
-	 * @since 9.1.0
242
-	 */
243
-	public function userDeletedFromGroup($uid, $gid);
244
-
245
-	/**
246
-	 * Get access list to a path. This means
247
-	 * all the users that can access a given path.
248
-	 *
249
-	 * Consider:
250
-	 * -root
251
-	 * |-folder1 (23)
252
-	 *  |-folder2 (32)
253
-	 *   |-fileA (42)
254
-	 *
255
-	 * fileA is shared with user1 and user1@server1
256
-	 * folder2 is shared with group2 (user4 is a member of group2)
257
-	 * folder1 is shared with user2 (renamed to "folder (1)") and user2@server2
258
-	 *
259
-	 * Then the access list to '/folder1/folder2/fileA' with $currentAccess is:
260
-	 * [
261
-	 *  users  => [
262
-	 *      'user1' => ['node_id' => 42, 'node_path' => '/fileA'],
263
-	 *      'user4' => ['node_id' => 32, 'node_path' => '/folder2'],
264
-	 *      'user2' => ['node_id' => 23, 'node_path' => '/folder (1)'],
265
-	 *  ],
266
-	 *  remote => [
267
-	 *      'user1@server1' => ['node_id' => 42, 'token' => 'SeCr3t'],
268
-	 *      'user2@server2' => ['node_id' => 23, 'token' => 'FooBaR'],
269
-	 *  ],
270
-	 *  public => bool
271
-	 *  mail => bool
272
-	 * ]
273
-	 *
274
-	 * The access list to '/folder1/folder2/fileA' **without** $currentAccess is:
275
-	 * [
276
-	 *  users  => ['user1', 'user2', 'user4'],
277
-	 *  remote => bool,
278
-	 *  public => bool
279
-	 *  mail => bool
280
-	 * ]
281
-	 *
282
-	 * This is required for encryption/activity
283
-	 *
284
-	 * @param \OCP\Files\Node $path
285
-	 * @param bool $recursive Should we check all parent folders as well
286
-	 * @param bool $currentAccess Should the user have currently access to the file
287
-	 * @return array
288
-	 * @since 12
289
-	 */
290
-	public function getAccessList(\OCP\Files\Node $path, $recursive = true, $currentAccess = false);
291
-
292
-	/**
293
-	 * Instantiates a new share object. This is to be passed to
294
-	 * createShare.
295
-	 *
296
-	 * @return IShare
297
-	 * @since 9.0.0
298
-	 */
299
-	public function newShare();
300
-
301
-	/**
302
-	 * Is the share API enabled
303
-	 *
304
-	 * @return bool
305
-	 * @since 9.0.0
306
-	 */
307
-	public function shareApiEnabled();
308
-
309
-	/**
310
-	 * Is public link sharing enabled
311
-	 *
312
-	 * @return bool
313
-	 * @since 9.0.0
314
-	 */
315
-	public function shareApiAllowLinks();
316
-
317
-	/**
318
-	 * Is password on public link requires
319
-	 *
320
-	 * @return bool
321
-	 * @since 9.0.0
322
-	 */
323
-	public function shareApiLinkEnforcePassword();
324
-
325
-	/**
326
-	 * Is default expire date enabled
327
-	 *
328
-	 * @return bool
329
-	 * @since 9.0.0
330
-	 */
331
-	public function shareApiLinkDefaultExpireDate();
332
-
333
-	/**
334
-	 * Is default expire date enforced
335
-	 *`
336
-	 * @return bool
337
-	 * @since 9.0.0
338
-	 */
339
-	public function shareApiLinkDefaultExpireDateEnforced();
340
-
341
-	/**
342
-	 * Number of default expire days
343
-	 *
344
-	 * @return int
345
-	 * @since 9.0.0
346
-	 */
347
-	public function shareApiLinkDefaultExpireDays();
348
-
349
-	/**
350
-	 * Allow public upload on link shares
351
-	 *
352
-	 * @return bool
353
-	 * @since 9.0.0
354
-	 */
355
-	public function shareApiLinkAllowPublicUpload();
356
-
357
-	/**
358
-	 * check if user can only share with group members
359
-	 * @return bool
360
-	 * @since 9.0.0
361
-	 */
362
-	public function shareWithGroupMembersOnly();
363
-
364
-	/**
365
-	 * Check if users can share with groups
366
-	 * @return bool
367
-	 * @since 9.0.1
368
-	 */
369
-	public function allowGroupSharing();
370
-
371
-	/**
372
-	 * Check if user enumeration is allowed
373
-	 *
374
-	 * @return bool
375
-	 * @since 19.0.0
376
-	 */
377
-	public function allowEnumeration(): bool;
378
-
379
-	/**
380
-	 * Check if user enumeration is limited to the users groups
381
-	 *
382
-	 * @return bool
383
-	 * @since 19.0.0
384
-	 */
385
-	public function limitEnumerationToGroups(): bool;
386
-
387
-	/**
388
-	 * Check if sharing is disabled for the given user
389
-	 *
390
-	 * @param string $userId
391
-	 * @return bool
392
-	 * @since 9.0.0
393
-	 */
394
-	public function sharingDisabledForUser($userId);
395
-
396
-	/**
397
-	 * Check if outgoing server2server shares are allowed
398
-	 * @return bool
399
-	 * @since 9.0.0
400
-	 */
401
-	public function outgoingServer2ServerSharesAllowed();
402
-
403
-	/**
404
-	 * Check if outgoing server2server shares are allowed
405
-	 * @return bool
406
-	 * @since 14.0.0
407
-	 */
408
-	public function outgoingServer2ServerGroupSharesAllowed();
409
-
410
-
411
-	/**
412
-	 * Check if a given share provider exists
413
-	 * @param int $shareType
414
-	 * @return bool
415
-	 * @since 11.0.0
416
-	 */
417
-	public function shareProviderExists($shareType);
418
-
419
-	/**
420
-	 * @param string $shareProviderClass
421
-	 * @since 21.0.0
422
-	 */
423
-	public function registerShareProvider(string $shareProviderClass): void;
424
-
425
-	/**
426
-	 * @Internal
427
-	 *
428
-	 * Get all the shares as iterable to reduce memory overhead
429
-	 * Note, since this opens up database cursors the iterable should
430
-	 * be fully itterated.
431
-	 *
432
-	 * @return iterable
433
-	 * @since 18.0.0
434
-	 */
435
-	public function getAllShares(): iterable;
46
+    /**
47
+     * Create a Share
48
+     *
49
+     * @param IShare $share
50
+     * @return IShare The share object
51
+     * @throws \Exception
52
+     * @since 9.0.0
53
+     */
54
+    public function createShare(IShare $share);
55
+
56
+    /**
57
+     * Update a share.
58
+     * The target of the share can't be changed this way: use moveShare
59
+     * The share can't be removed this way (permission 0): use deleteShare
60
+     * The state can't be changed this way: use acceptShare
61
+     *
62
+     * @param IShare $share
63
+     * @return IShare The share object
64
+     * @throws \InvalidArgumentException
65
+     * @since 9.0.0
66
+     */
67
+    public function updateShare(IShare $share);
68
+
69
+    /**
70
+     * Accept a share.
71
+     *
72
+     * @param IShare $share
73
+     * @param string $recipientId
74
+     * @return IShare The share object
75
+     * @throws \InvalidArgumentException
76
+     * @since 18.0.0
77
+     */
78
+    public function acceptShare(IShare $share, string $recipientId): IShare;
79
+
80
+    /**
81
+     * Delete a share
82
+     *
83
+     * @param IShare $share
84
+     * @throws ShareNotFound
85
+     * @throws \InvalidArgumentException
86
+     * @since 9.0.0
87
+     */
88
+    public function deleteShare(IShare $share);
89
+
90
+    /**
91
+     * Unshare a file as the recipient.
92
+     * This can be different from a regular delete for example when one of
93
+     * the users in a groups deletes that share. But the provider should
94
+     * handle this.
95
+     *
96
+     * @param IShare $share
97
+     * @param string $recipientId
98
+     * @since 9.0.0
99
+     */
100
+    public function deleteFromSelf(IShare $share, $recipientId);
101
+
102
+    /**
103
+     * Restore the share when it has been deleted
104
+     * Certain share types can be restored when they have been deleted
105
+     * but the provider should properly handle this\
106
+     *
107
+     * @param IShare $share The share to restore
108
+     * @param string $recipientId The user to restore the share for
109
+     * @return IShare The restored share object
110
+     * @throws GenericShareException In case restoring the share failed
111
+     *
112
+     * @since 14.0.0
113
+     */
114
+    public function restoreShare(IShare $share, string $recipientId): IShare;
115
+
116
+    /**
117
+     * Move the share as a recipient of the share.
118
+     * This is updating the share target. So where the recipient has the share mounted.
119
+     *
120
+     * @param IShare $share
121
+     * @param string $recipientId
122
+     * @return IShare
123
+     * @throws \InvalidArgumentException If $share is a link share or the $recipient does not match
124
+     * @since 9.0.0
125
+     */
126
+    public function moveShare(IShare $share, $recipientId);
127
+
128
+    /**
129
+     * Get all shares shared by (initiated) by the provided user in a folder.
130
+     *
131
+     * @param string $userId
132
+     * @param Folder $node
133
+     * @param bool $reshares
134
+     * @return IShare[][] [$fileId => IShare[], ...]
135
+     * @since 11.0.0
136
+     */
137
+    public function getSharesInFolder($userId, Folder $node, $reshares = false);
138
+
139
+    /**
140
+     * Get shares shared by (initiated) by the provided user.
141
+     *
142
+     * @param string $userId
143
+     * @param int $shareType
144
+     * @param Node|null $path
145
+     * @param bool $reshares
146
+     * @param int $limit The maximum number of returned results, -1 for all results
147
+     * @param int $offset
148
+     * @return IShare[]
149
+     * @since 9.0.0
150
+     */
151
+    public function getSharesBy($userId, $shareType, $path = null, $reshares = false, $limit = 50, $offset = 0);
152
+
153
+    /**
154
+     * Get shares shared with $user.
155
+     * Filter by $node if provided
156
+     *
157
+     * @param string $userId
158
+     * @param int $shareType
159
+     * @param Node|null $node
160
+     * @param int $limit The maximum number of shares returned, -1 for all
161
+     * @param int $offset
162
+     * @return IShare[]
163
+     * @since 9.0.0
164
+     */
165
+    public function getSharedWith($userId, $shareType, $node = null, $limit = 50, $offset = 0);
166
+
167
+    /**
168
+     * Get deleted shares shared with $user.
169
+     * Filter by $node if provided
170
+     *
171
+     * @param string $userId
172
+     * @param int $shareType
173
+     * @param Node|null $node
174
+     * @param int $limit The maximum number of shares returned, -1 for all
175
+     * @param int $offset
176
+     * @return IShare[]
177
+     * @since 14.0.0
178
+     */
179
+    public function getDeletedSharedWith($userId, $shareType, $node = null, $limit = 50, $offset = 0);
180
+
181
+    /**
182
+     * Retrieve a share by the share id.
183
+     * If the recipient is set make sure to retrieve the file for that user.
184
+     * This makes sure that if a user has moved/deleted a group share this
185
+     * is reflected.
186
+     *
187
+     * @param string $id
188
+     * @param string|null $recipient userID of the recipient
189
+     * @return IShare
190
+     * @throws ShareNotFound
191
+     * @since 9.0.0
192
+     */
193
+    public function getShareById($id, $recipient = null);
194
+
195
+    /**
196
+     * Get the share by token possible with password
197
+     *
198
+     * @param string $token
199
+     * @return IShare
200
+     * @throws ShareNotFound
201
+     * @since 9.0.0
202
+     */
203
+    public function getShareByToken($token);
204
+
205
+    /**
206
+     * Verify the password of a public share
207
+     *
208
+     * @param IShare $share
209
+     * @param string $password
210
+     * @return bool
211
+     * @since 9.0.0
212
+     */
213
+    public function checkPassword(IShare $share, $password);
214
+
215
+    /**
216
+     * The user with UID is deleted.
217
+     * All share providers have to cleanup the shares with this user as well
218
+     * as shares owned by this user.
219
+     * Shares only initiated by this user are fine.
220
+     *
221
+     * @param string $uid
222
+     * @since 9.1.0
223
+     */
224
+    public function userDeleted($uid);
225
+
226
+    /**
227
+     * The group with $gid is deleted
228
+     * We need to clear up all shares to this group
229
+     *
230
+     * @param string $gid
231
+     * @since 9.1.0
232
+     */
233
+    public function groupDeleted($gid);
234
+
235
+    /**
236
+     * The user $uid is deleted from the group $gid
237
+     * All user specific group shares have to be removed
238
+     *
239
+     * @param string $uid
240
+     * @param string $gid
241
+     * @since 9.1.0
242
+     */
243
+    public function userDeletedFromGroup($uid, $gid);
244
+
245
+    /**
246
+     * Get access list to a path. This means
247
+     * all the users that can access a given path.
248
+     *
249
+     * Consider:
250
+     * -root
251
+     * |-folder1 (23)
252
+     *  |-folder2 (32)
253
+     *   |-fileA (42)
254
+     *
255
+     * fileA is shared with user1 and user1@server1
256
+     * folder2 is shared with group2 (user4 is a member of group2)
257
+     * folder1 is shared with user2 (renamed to "folder (1)") and user2@server2
258
+     *
259
+     * Then the access list to '/folder1/folder2/fileA' with $currentAccess is:
260
+     * [
261
+     *  users  => [
262
+     *      'user1' => ['node_id' => 42, 'node_path' => '/fileA'],
263
+     *      'user4' => ['node_id' => 32, 'node_path' => '/folder2'],
264
+     *      'user2' => ['node_id' => 23, 'node_path' => '/folder (1)'],
265
+     *  ],
266
+     *  remote => [
267
+     *      'user1@server1' => ['node_id' => 42, 'token' => 'SeCr3t'],
268
+     *      'user2@server2' => ['node_id' => 23, 'token' => 'FooBaR'],
269
+     *  ],
270
+     *  public => bool
271
+     *  mail => bool
272
+     * ]
273
+     *
274
+     * The access list to '/folder1/folder2/fileA' **without** $currentAccess is:
275
+     * [
276
+     *  users  => ['user1', 'user2', 'user4'],
277
+     *  remote => bool,
278
+     *  public => bool
279
+     *  mail => bool
280
+     * ]
281
+     *
282
+     * This is required for encryption/activity
283
+     *
284
+     * @param \OCP\Files\Node $path
285
+     * @param bool $recursive Should we check all parent folders as well
286
+     * @param bool $currentAccess Should the user have currently access to the file
287
+     * @return array
288
+     * @since 12
289
+     */
290
+    public function getAccessList(\OCP\Files\Node $path, $recursive = true, $currentAccess = false);
291
+
292
+    /**
293
+     * Instantiates a new share object. This is to be passed to
294
+     * createShare.
295
+     *
296
+     * @return IShare
297
+     * @since 9.0.0
298
+     */
299
+    public function newShare();
300
+
301
+    /**
302
+     * Is the share API enabled
303
+     *
304
+     * @return bool
305
+     * @since 9.0.0
306
+     */
307
+    public function shareApiEnabled();
308
+
309
+    /**
310
+     * Is public link sharing enabled
311
+     *
312
+     * @return bool
313
+     * @since 9.0.0
314
+     */
315
+    public function shareApiAllowLinks();
316
+
317
+    /**
318
+     * Is password on public link requires
319
+     *
320
+     * @return bool
321
+     * @since 9.0.0
322
+     */
323
+    public function shareApiLinkEnforcePassword();
324
+
325
+    /**
326
+     * Is default expire date enabled
327
+     *
328
+     * @return bool
329
+     * @since 9.0.0
330
+     */
331
+    public function shareApiLinkDefaultExpireDate();
332
+
333
+    /**
334
+     * Is default expire date enforced
335
+     *`
336
+     * @return bool
337
+     * @since 9.0.0
338
+     */
339
+    public function shareApiLinkDefaultExpireDateEnforced();
340
+
341
+    /**
342
+     * Number of default expire days
343
+     *
344
+     * @return int
345
+     * @since 9.0.0
346
+     */
347
+    public function shareApiLinkDefaultExpireDays();
348
+
349
+    /**
350
+     * Allow public upload on link shares
351
+     *
352
+     * @return bool
353
+     * @since 9.0.0
354
+     */
355
+    public function shareApiLinkAllowPublicUpload();
356
+
357
+    /**
358
+     * check if user can only share with group members
359
+     * @return bool
360
+     * @since 9.0.0
361
+     */
362
+    public function shareWithGroupMembersOnly();
363
+
364
+    /**
365
+     * Check if users can share with groups
366
+     * @return bool
367
+     * @since 9.0.1
368
+     */
369
+    public function allowGroupSharing();
370
+
371
+    /**
372
+     * Check if user enumeration is allowed
373
+     *
374
+     * @return bool
375
+     * @since 19.0.0
376
+     */
377
+    public function allowEnumeration(): bool;
378
+
379
+    /**
380
+     * Check if user enumeration is limited to the users groups
381
+     *
382
+     * @return bool
383
+     * @since 19.0.0
384
+     */
385
+    public function limitEnumerationToGroups(): bool;
386
+
387
+    /**
388
+     * Check if sharing is disabled for the given user
389
+     *
390
+     * @param string $userId
391
+     * @return bool
392
+     * @since 9.0.0
393
+     */
394
+    public function sharingDisabledForUser($userId);
395
+
396
+    /**
397
+     * Check if outgoing server2server shares are allowed
398
+     * @return bool
399
+     * @since 9.0.0
400
+     */
401
+    public function outgoingServer2ServerSharesAllowed();
402
+
403
+    /**
404
+     * Check if outgoing server2server shares are allowed
405
+     * @return bool
406
+     * @since 14.0.0
407
+     */
408
+    public function outgoingServer2ServerGroupSharesAllowed();
409
+
410
+
411
+    /**
412
+     * Check if a given share provider exists
413
+     * @param int $shareType
414
+     * @return bool
415
+     * @since 11.0.0
416
+     */
417
+    public function shareProviderExists($shareType);
418
+
419
+    /**
420
+     * @param string $shareProviderClass
421
+     * @since 21.0.0
422
+     */
423
+    public function registerShareProvider(string $shareProviderClass): void;
424
+
425
+    /**
426
+     * @Internal
427
+     *
428
+     * Get all the shares as iterable to reduce memory overhead
429
+     * Note, since this opens up database cursors the iterable should
430
+     * be fully itterated.
431
+     *
432
+     * @return iterable
433
+     * @since 18.0.0
434
+     */
435
+    public function getAllShares(): iterable;
436 436
 }
Please login to merge, or discard this patch.
lib/private/Share/Constants.php 1 patch
Indentation   +54 added lines, -54 removed lines patch added patch discarded remove patch
@@ -31,62 +31,62 @@
 block discarded – undo
31 31
 
32 32
 class Constants {
33 33
 
34
-	/**
35
-	 * @deprecated 17.0.0 - use IShare::TYPE_USER instead
36
-	 */
37
-	public const SHARE_TYPE_USER = 0;
38
-	/**
39
-	 * @deprecated 17.0.0 - use IShare::TYPE_GROUP instead
40
-	 */
41
-	public const SHARE_TYPE_GROUP = 1;
42
-	// const SHARE_TYPE_USERGROUP = 2; // Internal type used by DefaultShareProvider
43
-	/**
44
-	 * @deprecated 17.0.0 - use IShare::TYPE_LINK instead
45
-	 */
46
-	public const SHARE_TYPE_LINK = 3;
47
-	/**
48
-	 * @deprecated 17.0.0 - use IShare::TYPE_EMAIL instead
49
-	 */
50
-	public const SHARE_TYPE_EMAIL = 4;
51
-	public const SHARE_TYPE_CONTACT = 5; // ToDo Check if it is still in use otherwise remove it
52
-	/**
53
-	 * @deprecated 17.0.0 - use IShare::TYPE_REMOTE instead
54
-	 */
55
-	public const SHARE_TYPE_REMOTE = 6;
56
-	/**
57
-	 * @deprecated 17.0.0 - use IShare::TYPE_CIRCLE instead
58
-	 */
59
-	public const SHARE_TYPE_CIRCLE = 7;
60
-	/**
61
-	 * @deprecated 17.0.0 - use IShare::TYPE_GUEST instead
62
-	 */
63
-	public const SHARE_TYPE_GUEST = 8;
64
-	/**
65
-	 * @deprecated 17.0.0 - use IShare::REMOTE_GROUP instead
66
-	 */
67
-	public const SHARE_TYPE_REMOTE_GROUP = 9;
68
-	/**
69
-	 * @deprecated 17.0.0 - use IShare::TYPE_ROOM instead
70
-	 */
71
-	public const SHARE_TYPE_ROOM = 10;
72
-	// const SHARE_TYPE_USERROOM = 11; // Internal type used by RoomShareProvider
73
-	/**
74
-	 * @deprecated 21.0.0 - use IShare::TYPE_DECK instead
75
-	 */
76
-	public const SHARE_TYPE_DECK = 12;
77
-	// const SHARE_TYPE_DECK_USER = 13; // Internal type used by DeckShareProvider
34
+    /**
35
+     * @deprecated 17.0.0 - use IShare::TYPE_USER instead
36
+     */
37
+    public const SHARE_TYPE_USER = 0;
38
+    /**
39
+     * @deprecated 17.0.0 - use IShare::TYPE_GROUP instead
40
+     */
41
+    public const SHARE_TYPE_GROUP = 1;
42
+    // const SHARE_TYPE_USERGROUP = 2; // Internal type used by DefaultShareProvider
43
+    /**
44
+     * @deprecated 17.0.0 - use IShare::TYPE_LINK instead
45
+     */
46
+    public const SHARE_TYPE_LINK = 3;
47
+    /**
48
+     * @deprecated 17.0.0 - use IShare::TYPE_EMAIL instead
49
+     */
50
+    public const SHARE_TYPE_EMAIL = 4;
51
+    public const SHARE_TYPE_CONTACT = 5; // ToDo Check if it is still in use otherwise remove it
52
+    /**
53
+     * @deprecated 17.0.0 - use IShare::TYPE_REMOTE instead
54
+     */
55
+    public const SHARE_TYPE_REMOTE = 6;
56
+    /**
57
+     * @deprecated 17.0.0 - use IShare::TYPE_CIRCLE instead
58
+     */
59
+    public const SHARE_TYPE_CIRCLE = 7;
60
+    /**
61
+     * @deprecated 17.0.0 - use IShare::TYPE_GUEST instead
62
+     */
63
+    public const SHARE_TYPE_GUEST = 8;
64
+    /**
65
+     * @deprecated 17.0.0 - use IShare::REMOTE_GROUP instead
66
+     */
67
+    public const SHARE_TYPE_REMOTE_GROUP = 9;
68
+    /**
69
+     * @deprecated 17.0.0 - use IShare::TYPE_ROOM instead
70
+     */
71
+    public const SHARE_TYPE_ROOM = 10;
72
+    // const SHARE_TYPE_USERROOM = 11; // Internal type used by RoomShareProvider
73
+    /**
74
+     * @deprecated 21.0.0 - use IShare::TYPE_DECK instead
75
+     */
76
+    public const SHARE_TYPE_DECK = 12;
77
+    // const SHARE_TYPE_DECK_USER = 13; // Internal type used by DeckShareProvider
78 78
 
79
-	public const FORMAT_NONE = -1;
80
-	public const FORMAT_STATUSES = -2;
81
-	public const FORMAT_SOURCES = -3;  // ToDo Check if it is still in use otherwise remove it
79
+    public const FORMAT_NONE = -1;
80
+    public const FORMAT_STATUSES = -2;
81
+    public const FORMAT_SOURCES = -3;  // ToDo Check if it is still in use otherwise remove it
82 82
 
83
-	public const RESPONSE_FORMAT = 'json'; // default resonse format for ocs calls
83
+    public const RESPONSE_FORMAT = 'json'; // default resonse format for ocs calls
84 84
 
85
-	public const TOKEN_LENGTH = 15; // old (oc7) length is 32, keep token length in db at least that for compatibility
85
+    public const TOKEN_LENGTH = 15; // old (oc7) length is 32, keep token length in db at least that for compatibility
86 86
 
87
-	protected static $shareTypeUserAndGroups = -1;
88
-	protected static $shareTypeGroupUserUnique = 2;
89
-	protected static $backends = [];
90
-	protected static $backendTypes = [];
91
-	protected static $isResharingAllowed;
87
+    protected static $shareTypeUserAndGroups = -1;
88
+    protected static $shareTypeGroupUserUnique = 2;
89
+    protected static $backends = [];
90
+    protected static $backendTypes = [];
91
+    protected static $isResharingAllowed;
92 92
 }
Please login to merge, or discard this patch.
lib/private/Share20/Manager.php 1 patch
Indentation   +1799 added lines, -1799 removed lines patch added patch discarded remove patch
@@ -77,1826 +77,1826 @@
 block discarded – undo
77 77
  */
78 78
 class Manager implements IManager {
79 79
 
80
-	/** @var IProviderFactory */
81
-	private $factory;
82
-	/** @var ILogger */
83
-	private $logger;
84
-	/** @var IConfig */
85
-	private $config;
86
-	/** @var ISecureRandom */
87
-	private $secureRandom;
88
-	/** @var IHasher */
89
-	private $hasher;
90
-	/** @var IMountManager */
91
-	private $mountManager;
92
-	/** @var IGroupManager */
93
-	private $groupManager;
94
-	/** @var IL10N */
95
-	private $l;
96
-	/** @var IFactory */
97
-	private $l10nFactory;
98
-	/** @var IUserManager */
99
-	private $userManager;
100
-	/** @var IRootFolder */
101
-	private $rootFolder;
102
-	/** @var CappedMemoryCache */
103
-	private $sharingDisabledForUsersCache;
104
-	/** @var EventDispatcherInterface */
105
-	private $legacyDispatcher;
106
-	/** @var LegacyHooks */
107
-	private $legacyHooks;
108
-	/** @var IMailer */
109
-	private $mailer;
110
-	/** @var IURLGenerator */
111
-	private $urlGenerator;
112
-	/** @var \OC_Defaults */
113
-	private $defaults;
114
-	/** @var IEventDispatcher */
115
-	private $dispatcher;
116
-
117
-
118
-	/**
119
-	 * Manager constructor.
120
-	 *
121
-	 * @param ILogger $logger
122
-	 * @param IConfig $config
123
-	 * @param ISecureRandom $secureRandom
124
-	 * @param IHasher $hasher
125
-	 * @param IMountManager $mountManager
126
-	 * @param IGroupManager $groupManager
127
-	 * @param IL10N $l
128
-	 * @param IFactory $l10nFactory
129
-	 * @param IProviderFactory $factory
130
-	 * @param IUserManager $userManager
131
-	 * @param IRootFolder $rootFolder
132
-	 * @param EventDispatcherInterface $eventDispatcher
133
-	 * @param IMailer $mailer
134
-	 * @param IURLGenerator $urlGenerator
135
-	 * @param \OC_Defaults $defaults
136
-	 */
137
-	public function __construct(
138
-			ILogger $logger,
139
-			IConfig $config,
140
-			ISecureRandom $secureRandom,
141
-			IHasher $hasher,
142
-			IMountManager $mountManager,
143
-			IGroupManager $groupManager,
144
-			IL10N $l,
145
-			IFactory $l10nFactory,
146
-			IProviderFactory $factory,
147
-			IUserManager $userManager,
148
-			IRootFolder $rootFolder,
149
-			EventDispatcherInterface $legacyDispatcher,
150
-			IMailer $mailer,
151
-			IURLGenerator $urlGenerator,
152
-			\OC_Defaults $defaults,
153
-			IEventDispatcher $dispatcher
154
-	) {
155
-		$this->logger = $logger;
156
-		$this->config = $config;
157
-		$this->secureRandom = $secureRandom;
158
-		$this->hasher = $hasher;
159
-		$this->mountManager = $mountManager;
160
-		$this->groupManager = $groupManager;
161
-		$this->l = $l;
162
-		$this->l10nFactory = $l10nFactory;
163
-		$this->factory = $factory;
164
-		$this->userManager = $userManager;
165
-		$this->rootFolder = $rootFolder;
166
-		$this->legacyDispatcher = $legacyDispatcher;
167
-		$this->sharingDisabledForUsersCache = new CappedMemoryCache();
168
-		$this->legacyHooks = new LegacyHooks($this->legacyDispatcher);
169
-		$this->mailer = $mailer;
170
-		$this->urlGenerator = $urlGenerator;
171
-		$this->defaults = $defaults;
172
-		$this->dispatcher = $dispatcher;
173
-	}
174
-
175
-	/**
176
-	 * Convert from a full share id to a tuple (providerId, shareId)
177
-	 *
178
-	 * @param string $id
179
-	 * @return string[]
180
-	 */
181
-	private function splitFullId($id) {
182
-		return explode(':', $id, 2);
183
-	}
184
-
185
-	/**
186
-	 * Verify if a password meets all requirements
187
-	 *
188
-	 * @param string $password
189
-	 * @throws \Exception
190
-	 */
191
-	protected function verifyPassword($password) {
192
-		if ($password === null) {
193
-			// No password is set, check if this is allowed.
194
-			if ($this->shareApiLinkEnforcePassword()) {
195
-				throw new \InvalidArgumentException('Passwords are enforced for link shares');
196
-			}
197
-
198
-			return;
199
-		}
200
-
201
-		// Let others verify the password
202
-		try {
203
-			$this->legacyDispatcher->dispatch(new ValidatePasswordPolicyEvent($password));
204
-		} catch (HintException $e) {
205
-			throw new \Exception($e->getHint());
206
-		}
207
-	}
208
-
209
-	/**
210
-	 * Check for generic requirements before creating a share
211
-	 *
212
-	 * @param IShare $share
213
-	 * @throws \InvalidArgumentException
214
-	 * @throws GenericShareException
215
-	 *
216
-	 * @suppress PhanUndeclaredClassMethod
217
-	 */
218
-	protected function generalCreateChecks(IShare $share) {
219
-		if ($share->getShareType() === IShare::TYPE_USER) {
220
-			// We expect a valid user as sharedWith for user shares
221
-			if (!$this->userManager->userExists($share->getSharedWith())) {
222
-				throw new \InvalidArgumentException('SharedWith is not a valid user');
223
-			}
224
-		} elseif ($share->getShareType() === IShare::TYPE_GROUP) {
225
-			// We expect a valid group as sharedWith for group shares
226
-			if (!$this->groupManager->groupExists($share->getSharedWith())) {
227
-				throw new \InvalidArgumentException('SharedWith is not a valid group');
228
-			}
229
-		} elseif ($share->getShareType() === IShare::TYPE_LINK) {
230
-			if ($share->getSharedWith() !== null) {
231
-				throw new \InvalidArgumentException('SharedWith should be empty');
232
-			}
233
-		} elseif ($share->getShareType() === IShare::TYPE_REMOTE) {
234
-			if ($share->getSharedWith() === null) {
235
-				throw new \InvalidArgumentException('SharedWith should not be empty');
236
-			}
237
-		} elseif ($share->getShareType() === IShare::TYPE_REMOTE_GROUP) {
238
-			if ($share->getSharedWith() === null) {
239
-				throw new \InvalidArgumentException('SharedWith should not be empty');
240
-			}
241
-		} elseif ($share->getShareType() === IShare::TYPE_EMAIL) {
242
-			if ($share->getSharedWith() === null) {
243
-				throw new \InvalidArgumentException('SharedWith should not be empty');
244
-			}
245
-		} elseif ($share->getShareType() === IShare::TYPE_CIRCLE) {
246
-			$circle = \OCA\Circles\Api\v1\Circles::detailsCircle($share->getSharedWith());
247
-			if ($circle === null) {
248
-				throw new \InvalidArgumentException('SharedWith is not a valid circle');
249
-			}
250
-		} elseif ($share->getShareType() === IShare::TYPE_ROOM) {
251
-		} elseif ($share->getShareType() === IShare::TYPE_DECK) {
252
-		} else {
253
-			// We can't handle other types yet
254
-			throw new \InvalidArgumentException('unknown share type');
255
-		}
256
-
257
-		// Verify the initiator of the share is set
258
-		if ($share->getSharedBy() === null) {
259
-			throw new \InvalidArgumentException('SharedBy should be set');
260
-		}
261
-
262
-		// Cannot share with yourself
263
-		if ($share->getShareType() === IShare::TYPE_USER &&
264
-			$share->getSharedWith() === $share->getSharedBy()) {
265
-			throw new \InvalidArgumentException('Can’t share with yourself');
266
-		}
267
-
268
-		// The path should be set
269
-		if ($share->getNode() === null) {
270
-			throw new \InvalidArgumentException('Path should be set');
271
-		}
272
-
273
-		// And it should be a file or a folder
274
-		if (!($share->getNode() instanceof \OCP\Files\File) &&
275
-				!($share->getNode() instanceof \OCP\Files\Folder)) {
276
-			throw new \InvalidArgumentException('Path should be either a file or a folder');
277
-		}
278
-
279
-		// And you can't share your rootfolder
280
-		if ($this->userManager->userExists($share->getSharedBy())) {
281
-			$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
282
-		} else {
283
-			$userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
284
-		}
285
-		if ($userFolder->getId() === $share->getNode()->getId()) {
286
-			throw new \InvalidArgumentException('You can’t share your root folder');
287
-		}
288
-
289
-		// Check if we actually have share permissions
290
-		if (!$share->getNode()->isShareable()) {
291
-			$message_t = $this->l->t('You are not allowed to share %s', [$share->getNode()->getName()]);
292
-			throw new GenericShareException($message_t, $message_t, 404);
293
-		}
294
-
295
-		// Permissions should be set
296
-		if ($share->getPermissions() === null) {
297
-			throw new \InvalidArgumentException('A share requires permissions');
298
-		}
299
-
300
-		$isFederatedShare = $share->getNode()->getStorage()->instanceOfStorage('\OCA\Files_Sharing\External\Storage');
301
-		$permissions = 0;
302
-
303
-		if (!$isFederatedShare && $share->getNode()->getOwner() && $share->getNode()->getOwner()->getUID() !== $share->getSharedBy()) {
304
-			$userMounts = array_filter($userFolder->getById($share->getNode()->getId()), function ($mount) {
305
-				// We need to filter since there might be other mountpoints that contain the file
306
-				// e.g. if the user has access to the same external storage that the file is originating from
307
-				return $mount->getStorage()->instanceOfStorage(ISharedStorage::class);
308
-			});
309
-			$userMount = array_shift($userMounts);
310
-			if ($userMount === null) {
311
-				throw new GenericShareException('Could not get proper share mount for ' . $share->getNode()->getId() . '. Failing since else the next calls are called with null');
312
-			}
313
-			$mount = $userMount->getMountPoint();
314
-			// When it's a reshare use the parent share permissions as maximum
315
-			$userMountPointId = $mount->getStorageRootId();
316
-			$userMountPoints = $userFolder->getById($userMountPointId);
317
-			$userMountPoint = array_shift($userMountPoints);
318
-
319
-			if ($userMountPoint === null) {
320
-				throw new GenericShareException('Could not get proper user mount for ' . $userMountPointId . '. Failing since else the next calls are called with null');
321
-			}
322
-
323
-			/* Check if this is an incoming share */
324
-			$incomingShares = $this->getSharedWith($share->getSharedBy(), IShare::TYPE_USER, $userMountPoint, -1, 0);
325
-			$incomingShares = array_merge($incomingShares, $this->getSharedWith($share->getSharedBy(), IShare::TYPE_GROUP, $userMountPoint, -1, 0));
326
-			$incomingShares = array_merge($incomingShares, $this->getSharedWith($share->getSharedBy(), IShare::TYPE_CIRCLE, $userMountPoint, -1, 0));
327
-			$incomingShares = array_merge($incomingShares, $this->getSharedWith($share->getSharedBy(), IShare::TYPE_ROOM, $userMountPoint, -1, 0));
328
-
329
-			/** @var IShare[] $incomingShares */
330
-			if (!empty($incomingShares)) {
331
-				foreach ($incomingShares as $incomingShare) {
332
-					$permissions |= $incomingShare->getPermissions();
333
-				}
334
-			}
335
-		} else {
336
-			/*
80
+    /** @var IProviderFactory */
81
+    private $factory;
82
+    /** @var ILogger */
83
+    private $logger;
84
+    /** @var IConfig */
85
+    private $config;
86
+    /** @var ISecureRandom */
87
+    private $secureRandom;
88
+    /** @var IHasher */
89
+    private $hasher;
90
+    /** @var IMountManager */
91
+    private $mountManager;
92
+    /** @var IGroupManager */
93
+    private $groupManager;
94
+    /** @var IL10N */
95
+    private $l;
96
+    /** @var IFactory */
97
+    private $l10nFactory;
98
+    /** @var IUserManager */
99
+    private $userManager;
100
+    /** @var IRootFolder */
101
+    private $rootFolder;
102
+    /** @var CappedMemoryCache */
103
+    private $sharingDisabledForUsersCache;
104
+    /** @var EventDispatcherInterface */
105
+    private $legacyDispatcher;
106
+    /** @var LegacyHooks */
107
+    private $legacyHooks;
108
+    /** @var IMailer */
109
+    private $mailer;
110
+    /** @var IURLGenerator */
111
+    private $urlGenerator;
112
+    /** @var \OC_Defaults */
113
+    private $defaults;
114
+    /** @var IEventDispatcher */
115
+    private $dispatcher;
116
+
117
+
118
+    /**
119
+     * Manager constructor.
120
+     *
121
+     * @param ILogger $logger
122
+     * @param IConfig $config
123
+     * @param ISecureRandom $secureRandom
124
+     * @param IHasher $hasher
125
+     * @param IMountManager $mountManager
126
+     * @param IGroupManager $groupManager
127
+     * @param IL10N $l
128
+     * @param IFactory $l10nFactory
129
+     * @param IProviderFactory $factory
130
+     * @param IUserManager $userManager
131
+     * @param IRootFolder $rootFolder
132
+     * @param EventDispatcherInterface $eventDispatcher
133
+     * @param IMailer $mailer
134
+     * @param IURLGenerator $urlGenerator
135
+     * @param \OC_Defaults $defaults
136
+     */
137
+    public function __construct(
138
+            ILogger $logger,
139
+            IConfig $config,
140
+            ISecureRandom $secureRandom,
141
+            IHasher $hasher,
142
+            IMountManager $mountManager,
143
+            IGroupManager $groupManager,
144
+            IL10N $l,
145
+            IFactory $l10nFactory,
146
+            IProviderFactory $factory,
147
+            IUserManager $userManager,
148
+            IRootFolder $rootFolder,
149
+            EventDispatcherInterface $legacyDispatcher,
150
+            IMailer $mailer,
151
+            IURLGenerator $urlGenerator,
152
+            \OC_Defaults $defaults,
153
+            IEventDispatcher $dispatcher
154
+    ) {
155
+        $this->logger = $logger;
156
+        $this->config = $config;
157
+        $this->secureRandom = $secureRandom;
158
+        $this->hasher = $hasher;
159
+        $this->mountManager = $mountManager;
160
+        $this->groupManager = $groupManager;
161
+        $this->l = $l;
162
+        $this->l10nFactory = $l10nFactory;
163
+        $this->factory = $factory;
164
+        $this->userManager = $userManager;
165
+        $this->rootFolder = $rootFolder;
166
+        $this->legacyDispatcher = $legacyDispatcher;
167
+        $this->sharingDisabledForUsersCache = new CappedMemoryCache();
168
+        $this->legacyHooks = new LegacyHooks($this->legacyDispatcher);
169
+        $this->mailer = $mailer;
170
+        $this->urlGenerator = $urlGenerator;
171
+        $this->defaults = $defaults;
172
+        $this->dispatcher = $dispatcher;
173
+    }
174
+
175
+    /**
176
+     * Convert from a full share id to a tuple (providerId, shareId)
177
+     *
178
+     * @param string $id
179
+     * @return string[]
180
+     */
181
+    private function splitFullId($id) {
182
+        return explode(':', $id, 2);
183
+    }
184
+
185
+    /**
186
+     * Verify if a password meets all requirements
187
+     *
188
+     * @param string $password
189
+     * @throws \Exception
190
+     */
191
+    protected function verifyPassword($password) {
192
+        if ($password === null) {
193
+            // No password is set, check if this is allowed.
194
+            if ($this->shareApiLinkEnforcePassword()) {
195
+                throw new \InvalidArgumentException('Passwords are enforced for link shares');
196
+            }
197
+
198
+            return;
199
+        }
200
+
201
+        // Let others verify the password
202
+        try {
203
+            $this->legacyDispatcher->dispatch(new ValidatePasswordPolicyEvent($password));
204
+        } catch (HintException $e) {
205
+            throw new \Exception($e->getHint());
206
+        }
207
+    }
208
+
209
+    /**
210
+     * Check for generic requirements before creating a share
211
+     *
212
+     * @param IShare $share
213
+     * @throws \InvalidArgumentException
214
+     * @throws GenericShareException
215
+     *
216
+     * @suppress PhanUndeclaredClassMethod
217
+     */
218
+    protected function generalCreateChecks(IShare $share) {
219
+        if ($share->getShareType() === IShare::TYPE_USER) {
220
+            // We expect a valid user as sharedWith for user shares
221
+            if (!$this->userManager->userExists($share->getSharedWith())) {
222
+                throw new \InvalidArgumentException('SharedWith is not a valid user');
223
+            }
224
+        } elseif ($share->getShareType() === IShare::TYPE_GROUP) {
225
+            // We expect a valid group as sharedWith for group shares
226
+            if (!$this->groupManager->groupExists($share->getSharedWith())) {
227
+                throw new \InvalidArgumentException('SharedWith is not a valid group');
228
+            }
229
+        } elseif ($share->getShareType() === IShare::TYPE_LINK) {
230
+            if ($share->getSharedWith() !== null) {
231
+                throw new \InvalidArgumentException('SharedWith should be empty');
232
+            }
233
+        } elseif ($share->getShareType() === IShare::TYPE_REMOTE) {
234
+            if ($share->getSharedWith() === null) {
235
+                throw new \InvalidArgumentException('SharedWith should not be empty');
236
+            }
237
+        } elseif ($share->getShareType() === IShare::TYPE_REMOTE_GROUP) {
238
+            if ($share->getSharedWith() === null) {
239
+                throw new \InvalidArgumentException('SharedWith should not be empty');
240
+            }
241
+        } elseif ($share->getShareType() === IShare::TYPE_EMAIL) {
242
+            if ($share->getSharedWith() === null) {
243
+                throw new \InvalidArgumentException('SharedWith should not be empty');
244
+            }
245
+        } elseif ($share->getShareType() === IShare::TYPE_CIRCLE) {
246
+            $circle = \OCA\Circles\Api\v1\Circles::detailsCircle($share->getSharedWith());
247
+            if ($circle === null) {
248
+                throw new \InvalidArgumentException('SharedWith is not a valid circle');
249
+            }
250
+        } elseif ($share->getShareType() === IShare::TYPE_ROOM) {
251
+        } elseif ($share->getShareType() === IShare::TYPE_DECK) {
252
+        } else {
253
+            // We can't handle other types yet
254
+            throw new \InvalidArgumentException('unknown share type');
255
+        }
256
+
257
+        // Verify the initiator of the share is set
258
+        if ($share->getSharedBy() === null) {
259
+            throw new \InvalidArgumentException('SharedBy should be set');
260
+        }
261
+
262
+        // Cannot share with yourself
263
+        if ($share->getShareType() === IShare::TYPE_USER &&
264
+            $share->getSharedWith() === $share->getSharedBy()) {
265
+            throw new \InvalidArgumentException('Can’t share with yourself');
266
+        }
267
+
268
+        // The path should be set
269
+        if ($share->getNode() === null) {
270
+            throw new \InvalidArgumentException('Path should be set');
271
+        }
272
+
273
+        // And it should be a file or a folder
274
+        if (!($share->getNode() instanceof \OCP\Files\File) &&
275
+                !($share->getNode() instanceof \OCP\Files\Folder)) {
276
+            throw new \InvalidArgumentException('Path should be either a file or a folder');
277
+        }
278
+
279
+        // And you can't share your rootfolder
280
+        if ($this->userManager->userExists($share->getSharedBy())) {
281
+            $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
282
+        } else {
283
+            $userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
284
+        }
285
+        if ($userFolder->getId() === $share->getNode()->getId()) {
286
+            throw new \InvalidArgumentException('You can’t share your root folder');
287
+        }
288
+
289
+        // Check if we actually have share permissions
290
+        if (!$share->getNode()->isShareable()) {
291
+            $message_t = $this->l->t('You are not allowed to share %s', [$share->getNode()->getName()]);
292
+            throw new GenericShareException($message_t, $message_t, 404);
293
+        }
294
+
295
+        // Permissions should be set
296
+        if ($share->getPermissions() === null) {
297
+            throw new \InvalidArgumentException('A share requires permissions');
298
+        }
299
+
300
+        $isFederatedShare = $share->getNode()->getStorage()->instanceOfStorage('\OCA\Files_Sharing\External\Storage');
301
+        $permissions = 0;
302
+
303
+        if (!$isFederatedShare && $share->getNode()->getOwner() && $share->getNode()->getOwner()->getUID() !== $share->getSharedBy()) {
304
+            $userMounts = array_filter($userFolder->getById($share->getNode()->getId()), function ($mount) {
305
+                // We need to filter since there might be other mountpoints that contain the file
306
+                // e.g. if the user has access to the same external storage that the file is originating from
307
+                return $mount->getStorage()->instanceOfStorage(ISharedStorage::class);
308
+            });
309
+            $userMount = array_shift($userMounts);
310
+            if ($userMount === null) {
311
+                throw new GenericShareException('Could not get proper share mount for ' . $share->getNode()->getId() . '. Failing since else the next calls are called with null');
312
+            }
313
+            $mount = $userMount->getMountPoint();
314
+            // When it's a reshare use the parent share permissions as maximum
315
+            $userMountPointId = $mount->getStorageRootId();
316
+            $userMountPoints = $userFolder->getById($userMountPointId);
317
+            $userMountPoint = array_shift($userMountPoints);
318
+
319
+            if ($userMountPoint === null) {
320
+                throw new GenericShareException('Could not get proper user mount for ' . $userMountPointId . '. Failing since else the next calls are called with null');
321
+            }
322
+
323
+            /* Check if this is an incoming share */
324
+            $incomingShares = $this->getSharedWith($share->getSharedBy(), IShare::TYPE_USER, $userMountPoint, -1, 0);
325
+            $incomingShares = array_merge($incomingShares, $this->getSharedWith($share->getSharedBy(), IShare::TYPE_GROUP, $userMountPoint, -1, 0));
326
+            $incomingShares = array_merge($incomingShares, $this->getSharedWith($share->getSharedBy(), IShare::TYPE_CIRCLE, $userMountPoint, -1, 0));
327
+            $incomingShares = array_merge($incomingShares, $this->getSharedWith($share->getSharedBy(), IShare::TYPE_ROOM, $userMountPoint, -1, 0));
328
+
329
+            /** @var IShare[] $incomingShares */
330
+            if (!empty($incomingShares)) {
331
+                foreach ($incomingShares as $incomingShare) {
332
+                    $permissions |= $incomingShare->getPermissions();
333
+                }
334
+            }
335
+        } else {
336
+            /*
337 337
 			 * Quick fix for #23536
338 338
 			 * Non moveable mount points do not have update and delete permissions
339 339
 			 * while we 'most likely' do have that on the storage.
340 340
 			 */
341
-			$permissions = $share->getNode()->getPermissions();
342
-			if (!($share->getNode()->getMountPoint() instanceof MoveableMount)) {
343
-				$permissions |= \OCP\Constants::PERMISSION_DELETE | \OCP\Constants::PERMISSION_UPDATE;
344
-			}
345
-		}
346
-
347
-		// Check that we do not share with more permissions than we have
348
-		if ($share->getPermissions() & ~$permissions) {
349
-			$path = $userFolder->getRelativePath($share->getNode()->getPath());
350
-			$message_t = $this->l->t('Can’t increase permissions of %s', [$path]);
351
-			throw new GenericShareException($message_t, $message_t, 404);
352
-		}
353
-
354
-
355
-		// Check that read permissions are always set
356
-		// Link shares are allowed to have no read permissions to allow upload to hidden folders
357
-		$noReadPermissionRequired = $share->getShareType() === IShare::TYPE_LINK
358
-			|| $share->getShareType() === IShare::TYPE_EMAIL;
359
-		if (!$noReadPermissionRequired &&
360
-			($share->getPermissions() & \OCP\Constants::PERMISSION_READ) === 0) {
361
-			throw new \InvalidArgumentException('Shares need at least read permissions');
362
-		}
363
-
364
-		if ($share->getNode() instanceof \OCP\Files\File) {
365
-			if ($share->getPermissions() & \OCP\Constants::PERMISSION_DELETE) {
366
-				$message_t = $this->l->t('Files can’t be shared with delete permissions');
367
-				throw new GenericShareException($message_t);
368
-			}
369
-			if ($share->getPermissions() & \OCP\Constants::PERMISSION_CREATE) {
370
-				$message_t = $this->l->t('Files can’t be shared with create permissions');
371
-				throw new GenericShareException($message_t);
372
-			}
373
-		}
374
-	}
375
-
376
-	/**
377
-	 * Validate if the expiration date fits the system settings
378
-	 *
379
-	 * @param IShare $share The share to validate the expiration date of
380
-	 * @return IShare The modified share object
381
-	 * @throws GenericShareException
382
-	 * @throws \InvalidArgumentException
383
-	 * @throws \Exception
384
-	 */
385
-	protected function validateExpirationDateInternal(IShare $share) {
386
-		$expirationDate = $share->getExpirationDate();
387
-
388
-		if ($expirationDate !== null) {
389
-			//Make sure the expiration date is a date
390
-			$expirationDate->setTime(0, 0, 0);
391
-
392
-			$date = new \DateTime();
393
-			$date->setTime(0, 0, 0);
394
-			if ($date >= $expirationDate) {
395
-				$message = $this->l->t('Expiration date is in the past');
396
-				throw new GenericShareException($message, $message, 404);
397
-			}
398
-		}
399
-
400
-		// If expiredate is empty set a default one if there is a default
401
-		$fullId = null;
402
-		try {
403
-			$fullId = $share->getFullId();
404
-		} catch (\UnexpectedValueException $e) {
405
-			// This is a new share
406
-		}
407
-
408
-		if ($fullId === null && $expirationDate === null && $this->shareApiInternalDefaultExpireDate()) {
409
-			$expirationDate = new \DateTime();
410
-			$expirationDate->setTime(0,0,0);
411
-
412
-			$days = (int)$this->config->getAppValue('core', 'internal_defaultExpDays', (string)$this->shareApiInternalDefaultExpireDays());
413
-			if ($days > $this->shareApiInternalDefaultExpireDays()) {
414
-				$days = $this->shareApiInternalDefaultExpireDays();
415
-			}
416
-			$expirationDate->add(new \DateInterval('P'.$days.'D'));
417
-		}
418
-
419
-		// If we enforce the expiration date check that is does not exceed
420
-		if ($this->shareApiInternalDefaultExpireDateEnforced()) {
421
-			if ($expirationDate === null) {
422
-				throw new \InvalidArgumentException('Expiration date is enforced');
423
-			}
424
-
425
-			$date = new \DateTime();
426
-			$date->setTime(0, 0, 0);
427
-			$date->add(new \DateInterval('P' . $this->shareApiInternalDefaultExpireDays() . 'D'));
428
-			if ($date < $expirationDate) {
429
-				$message = $this->l->t('Can’t set expiration date more than %s days in the future', [$this->shareApiInternalDefaultExpireDays()]);
430
-				throw new GenericShareException($message, $message, 404);
431
-			}
432
-		}
433
-
434
-		$accepted = true;
435
-		$message = '';
436
-		\OCP\Util::emitHook('\OC\Share', 'verifyExpirationDate', [
437
-			'expirationDate' => &$expirationDate,
438
-			'accepted' => &$accepted,
439
-			'message' => &$message,
440
-			'passwordSet' => $share->getPassword() !== null,
441
-		]);
442
-
443
-		if (!$accepted) {
444
-			throw new \Exception($message);
445
-		}
446
-
447
-		$share->setExpirationDate($expirationDate);
448
-
449
-		return $share;
450
-	}
451
-
452
-	/**
453
-	 * Validate if the expiration date fits the system settings
454
-	 *
455
-	 * @param IShare $share The share to validate the expiration date of
456
-	 * @return IShare The modified share object
457
-	 * @throws GenericShareException
458
-	 * @throws \InvalidArgumentException
459
-	 * @throws \Exception
460
-	 */
461
-	protected function validateExpirationDate(IShare $share) {
462
-		$expirationDate = $share->getExpirationDate();
463
-
464
-		if ($expirationDate !== null) {
465
-			//Make sure the expiration date is a date
466
-			$expirationDate->setTime(0, 0, 0);
467
-
468
-			$date = new \DateTime();
469
-			$date->setTime(0, 0, 0);
470
-			if ($date >= $expirationDate) {
471
-				$message = $this->l->t('Expiration date is in the past');
472
-				throw new GenericShareException($message, $message, 404);
473
-			}
474
-		}
475
-
476
-		// If expiredate is empty set a default one if there is a default
477
-		$fullId = null;
478
-		try {
479
-			$fullId = $share->getFullId();
480
-		} catch (\UnexpectedValueException $e) {
481
-			// This is a new share
482
-		}
483
-
484
-		if ($fullId === null && $expirationDate === null && $this->shareApiLinkDefaultExpireDate()) {
485
-			$expirationDate = new \DateTime();
486
-			$expirationDate->setTime(0,0,0);
487
-
488
-			$days = (int)$this->config->getAppValue('core', 'link_defaultExpDays', $this->shareApiLinkDefaultExpireDays());
489
-			if ($days > $this->shareApiLinkDefaultExpireDays()) {
490
-				$days = $this->shareApiLinkDefaultExpireDays();
491
-			}
492
-			$expirationDate->add(new \DateInterval('P'.$days.'D'));
493
-		}
494
-
495
-		// If we enforce the expiration date check that is does not exceed
496
-		if ($this->shareApiLinkDefaultExpireDateEnforced()) {
497
-			if ($expirationDate === null) {
498
-				throw new \InvalidArgumentException('Expiration date is enforced');
499
-			}
500
-
501
-			$date = new \DateTime();
502
-			$date->setTime(0, 0, 0);
503
-			$date->add(new \DateInterval('P' . $this->shareApiLinkDefaultExpireDays() . 'D'));
504
-			if ($date < $expirationDate) {
505
-				$message = $this->l->t('Can’t set expiration date more than %s days in the future', [$this->shareApiLinkDefaultExpireDays()]);
506
-				throw new GenericShareException($message, $message, 404);
507
-			}
508
-		}
509
-
510
-		$accepted = true;
511
-		$message = '';
512
-		\OCP\Util::emitHook('\OC\Share', 'verifyExpirationDate', [
513
-			'expirationDate' => &$expirationDate,
514
-			'accepted' => &$accepted,
515
-			'message' => &$message,
516
-			'passwordSet' => $share->getPassword() !== null,
517
-		]);
518
-
519
-		if (!$accepted) {
520
-			throw new \Exception($message);
521
-		}
522
-
523
-		$share->setExpirationDate($expirationDate);
524
-
525
-		return $share;
526
-	}
527
-
528
-	/**
529
-	 * Check for pre share requirements for user shares
530
-	 *
531
-	 * @param IShare $share
532
-	 * @throws \Exception
533
-	 */
534
-	protected function userCreateChecks(IShare $share) {
535
-		// Check if we can share with group members only
536
-		if ($this->shareWithGroupMembersOnly()) {
537
-			$sharedBy = $this->userManager->get($share->getSharedBy());
538
-			$sharedWith = $this->userManager->get($share->getSharedWith());
539
-			// Verify we can share with this user
540
-			$groups = array_intersect(
541
-					$this->groupManager->getUserGroupIds($sharedBy),
542
-					$this->groupManager->getUserGroupIds($sharedWith)
543
-			);
544
-			if (empty($groups)) {
545
-				throw new \Exception('Sharing is only allowed with group members');
546
-			}
547
-		}
548
-
549
-		/*
341
+            $permissions = $share->getNode()->getPermissions();
342
+            if (!($share->getNode()->getMountPoint() instanceof MoveableMount)) {
343
+                $permissions |= \OCP\Constants::PERMISSION_DELETE | \OCP\Constants::PERMISSION_UPDATE;
344
+            }
345
+        }
346
+
347
+        // Check that we do not share with more permissions than we have
348
+        if ($share->getPermissions() & ~$permissions) {
349
+            $path = $userFolder->getRelativePath($share->getNode()->getPath());
350
+            $message_t = $this->l->t('Can’t increase permissions of %s', [$path]);
351
+            throw new GenericShareException($message_t, $message_t, 404);
352
+        }
353
+
354
+
355
+        // Check that read permissions are always set
356
+        // Link shares are allowed to have no read permissions to allow upload to hidden folders
357
+        $noReadPermissionRequired = $share->getShareType() === IShare::TYPE_LINK
358
+            || $share->getShareType() === IShare::TYPE_EMAIL;
359
+        if (!$noReadPermissionRequired &&
360
+            ($share->getPermissions() & \OCP\Constants::PERMISSION_READ) === 0) {
361
+            throw new \InvalidArgumentException('Shares need at least read permissions');
362
+        }
363
+
364
+        if ($share->getNode() instanceof \OCP\Files\File) {
365
+            if ($share->getPermissions() & \OCP\Constants::PERMISSION_DELETE) {
366
+                $message_t = $this->l->t('Files can’t be shared with delete permissions');
367
+                throw new GenericShareException($message_t);
368
+            }
369
+            if ($share->getPermissions() & \OCP\Constants::PERMISSION_CREATE) {
370
+                $message_t = $this->l->t('Files can’t be shared with create permissions');
371
+                throw new GenericShareException($message_t);
372
+            }
373
+        }
374
+    }
375
+
376
+    /**
377
+     * Validate if the expiration date fits the system settings
378
+     *
379
+     * @param IShare $share The share to validate the expiration date of
380
+     * @return IShare The modified share object
381
+     * @throws GenericShareException
382
+     * @throws \InvalidArgumentException
383
+     * @throws \Exception
384
+     */
385
+    protected function validateExpirationDateInternal(IShare $share) {
386
+        $expirationDate = $share->getExpirationDate();
387
+
388
+        if ($expirationDate !== null) {
389
+            //Make sure the expiration date is a date
390
+            $expirationDate->setTime(0, 0, 0);
391
+
392
+            $date = new \DateTime();
393
+            $date->setTime(0, 0, 0);
394
+            if ($date >= $expirationDate) {
395
+                $message = $this->l->t('Expiration date is in the past');
396
+                throw new GenericShareException($message, $message, 404);
397
+            }
398
+        }
399
+
400
+        // If expiredate is empty set a default one if there is a default
401
+        $fullId = null;
402
+        try {
403
+            $fullId = $share->getFullId();
404
+        } catch (\UnexpectedValueException $e) {
405
+            // This is a new share
406
+        }
407
+
408
+        if ($fullId === null && $expirationDate === null && $this->shareApiInternalDefaultExpireDate()) {
409
+            $expirationDate = new \DateTime();
410
+            $expirationDate->setTime(0,0,0);
411
+
412
+            $days = (int)$this->config->getAppValue('core', 'internal_defaultExpDays', (string)$this->shareApiInternalDefaultExpireDays());
413
+            if ($days > $this->shareApiInternalDefaultExpireDays()) {
414
+                $days = $this->shareApiInternalDefaultExpireDays();
415
+            }
416
+            $expirationDate->add(new \DateInterval('P'.$days.'D'));
417
+        }
418
+
419
+        // If we enforce the expiration date check that is does not exceed
420
+        if ($this->shareApiInternalDefaultExpireDateEnforced()) {
421
+            if ($expirationDate === null) {
422
+                throw new \InvalidArgumentException('Expiration date is enforced');
423
+            }
424
+
425
+            $date = new \DateTime();
426
+            $date->setTime(0, 0, 0);
427
+            $date->add(new \DateInterval('P' . $this->shareApiInternalDefaultExpireDays() . 'D'));
428
+            if ($date < $expirationDate) {
429
+                $message = $this->l->t('Can’t set expiration date more than %s days in the future', [$this->shareApiInternalDefaultExpireDays()]);
430
+                throw new GenericShareException($message, $message, 404);
431
+            }
432
+        }
433
+
434
+        $accepted = true;
435
+        $message = '';
436
+        \OCP\Util::emitHook('\OC\Share', 'verifyExpirationDate', [
437
+            'expirationDate' => &$expirationDate,
438
+            'accepted' => &$accepted,
439
+            'message' => &$message,
440
+            'passwordSet' => $share->getPassword() !== null,
441
+        ]);
442
+
443
+        if (!$accepted) {
444
+            throw new \Exception($message);
445
+        }
446
+
447
+        $share->setExpirationDate($expirationDate);
448
+
449
+        return $share;
450
+    }
451
+
452
+    /**
453
+     * Validate if the expiration date fits the system settings
454
+     *
455
+     * @param IShare $share The share to validate the expiration date of
456
+     * @return IShare The modified share object
457
+     * @throws GenericShareException
458
+     * @throws \InvalidArgumentException
459
+     * @throws \Exception
460
+     */
461
+    protected function validateExpirationDate(IShare $share) {
462
+        $expirationDate = $share->getExpirationDate();
463
+
464
+        if ($expirationDate !== null) {
465
+            //Make sure the expiration date is a date
466
+            $expirationDate->setTime(0, 0, 0);
467
+
468
+            $date = new \DateTime();
469
+            $date->setTime(0, 0, 0);
470
+            if ($date >= $expirationDate) {
471
+                $message = $this->l->t('Expiration date is in the past');
472
+                throw new GenericShareException($message, $message, 404);
473
+            }
474
+        }
475
+
476
+        // If expiredate is empty set a default one if there is a default
477
+        $fullId = null;
478
+        try {
479
+            $fullId = $share->getFullId();
480
+        } catch (\UnexpectedValueException $e) {
481
+            // This is a new share
482
+        }
483
+
484
+        if ($fullId === null && $expirationDate === null && $this->shareApiLinkDefaultExpireDate()) {
485
+            $expirationDate = new \DateTime();
486
+            $expirationDate->setTime(0,0,0);
487
+
488
+            $days = (int)$this->config->getAppValue('core', 'link_defaultExpDays', $this->shareApiLinkDefaultExpireDays());
489
+            if ($days > $this->shareApiLinkDefaultExpireDays()) {
490
+                $days = $this->shareApiLinkDefaultExpireDays();
491
+            }
492
+            $expirationDate->add(new \DateInterval('P'.$days.'D'));
493
+        }
494
+
495
+        // If we enforce the expiration date check that is does not exceed
496
+        if ($this->shareApiLinkDefaultExpireDateEnforced()) {
497
+            if ($expirationDate === null) {
498
+                throw new \InvalidArgumentException('Expiration date is enforced');
499
+            }
500
+
501
+            $date = new \DateTime();
502
+            $date->setTime(0, 0, 0);
503
+            $date->add(new \DateInterval('P' . $this->shareApiLinkDefaultExpireDays() . 'D'));
504
+            if ($date < $expirationDate) {
505
+                $message = $this->l->t('Can’t set expiration date more than %s days in the future', [$this->shareApiLinkDefaultExpireDays()]);
506
+                throw new GenericShareException($message, $message, 404);
507
+            }
508
+        }
509
+
510
+        $accepted = true;
511
+        $message = '';
512
+        \OCP\Util::emitHook('\OC\Share', 'verifyExpirationDate', [
513
+            'expirationDate' => &$expirationDate,
514
+            'accepted' => &$accepted,
515
+            'message' => &$message,
516
+            'passwordSet' => $share->getPassword() !== null,
517
+        ]);
518
+
519
+        if (!$accepted) {
520
+            throw new \Exception($message);
521
+        }
522
+
523
+        $share->setExpirationDate($expirationDate);
524
+
525
+        return $share;
526
+    }
527
+
528
+    /**
529
+     * Check for pre share requirements for user shares
530
+     *
531
+     * @param IShare $share
532
+     * @throws \Exception
533
+     */
534
+    protected function userCreateChecks(IShare $share) {
535
+        // Check if we can share with group members only
536
+        if ($this->shareWithGroupMembersOnly()) {
537
+            $sharedBy = $this->userManager->get($share->getSharedBy());
538
+            $sharedWith = $this->userManager->get($share->getSharedWith());
539
+            // Verify we can share with this user
540
+            $groups = array_intersect(
541
+                    $this->groupManager->getUserGroupIds($sharedBy),
542
+                    $this->groupManager->getUserGroupIds($sharedWith)
543
+            );
544
+            if (empty($groups)) {
545
+                throw new \Exception('Sharing is only allowed with group members');
546
+            }
547
+        }
548
+
549
+        /*
550 550
 		 * TODO: Could be costly, fix
551 551
 		 *
552 552
 		 * Also this is not what we want in the future.. then we want to squash identical shares.
553 553
 		 */
554
-		$provider = $this->factory->getProviderForType(IShare::TYPE_USER);
555
-		$existingShares = $provider->getSharesByPath($share->getNode());
556
-		foreach ($existingShares as $existingShare) {
557
-			// Ignore if it is the same share
558
-			try {
559
-				if ($existingShare->getFullId() === $share->getFullId()) {
560
-					continue;
561
-				}
562
-			} catch (\UnexpectedValueException $e) {
563
-				//Shares are not identical
564
-			}
565
-
566
-			// Identical share already existst
567
-			if ($existingShare->getSharedWith() === $share->getSharedWith() && $existingShare->getShareType() === $share->getShareType()) {
568
-				throw new \Exception('Path is already shared with this user');
569
-			}
570
-
571
-			// The share is already shared with this user via a group share
572
-			if ($existingShare->getShareType() === IShare::TYPE_GROUP) {
573
-				$group = $this->groupManager->get($existingShare->getSharedWith());
574
-				if (!is_null($group)) {
575
-					$user = $this->userManager->get($share->getSharedWith());
576
-
577
-					if ($group->inGroup($user) && $existingShare->getShareOwner() !== $share->getShareOwner()) {
578
-						throw new \Exception('Path is already shared with this user');
579
-					}
580
-				}
581
-			}
582
-		}
583
-	}
584
-
585
-	/**
586
-	 * Check for pre share requirements for group shares
587
-	 *
588
-	 * @param IShare $share
589
-	 * @throws \Exception
590
-	 */
591
-	protected function groupCreateChecks(IShare $share) {
592
-		// Verify group shares are allowed
593
-		if (!$this->allowGroupSharing()) {
594
-			throw new \Exception('Group sharing is now allowed');
595
-		}
596
-
597
-		// Verify if the user can share with this group
598
-		if ($this->shareWithGroupMembersOnly()) {
599
-			$sharedBy = $this->userManager->get($share->getSharedBy());
600
-			$sharedWith = $this->groupManager->get($share->getSharedWith());
601
-			if (is_null($sharedWith) || !$sharedWith->inGroup($sharedBy)) {
602
-				throw new \Exception('Sharing is only allowed within your own groups');
603
-			}
604
-		}
605
-
606
-		/*
554
+        $provider = $this->factory->getProviderForType(IShare::TYPE_USER);
555
+        $existingShares = $provider->getSharesByPath($share->getNode());
556
+        foreach ($existingShares as $existingShare) {
557
+            // Ignore if it is the same share
558
+            try {
559
+                if ($existingShare->getFullId() === $share->getFullId()) {
560
+                    continue;
561
+                }
562
+            } catch (\UnexpectedValueException $e) {
563
+                //Shares are not identical
564
+            }
565
+
566
+            // Identical share already existst
567
+            if ($existingShare->getSharedWith() === $share->getSharedWith() && $existingShare->getShareType() === $share->getShareType()) {
568
+                throw new \Exception('Path is already shared with this user');
569
+            }
570
+
571
+            // The share is already shared with this user via a group share
572
+            if ($existingShare->getShareType() === IShare::TYPE_GROUP) {
573
+                $group = $this->groupManager->get($existingShare->getSharedWith());
574
+                if (!is_null($group)) {
575
+                    $user = $this->userManager->get($share->getSharedWith());
576
+
577
+                    if ($group->inGroup($user) && $existingShare->getShareOwner() !== $share->getShareOwner()) {
578
+                        throw new \Exception('Path is already shared with this user');
579
+                    }
580
+                }
581
+            }
582
+        }
583
+    }
584
+
585
+    /**
586
+     * Check for pre share requirements for group shares
587
+     *
588
+     * @param IShare $share
589
+     * @throws \Exception
590
+     */
591
+    protected function groupCreateChecks(IShare $share) {
592
+        // Verify group shares are allowed
593
+        if (!$this->allowGroupSharing()) {
594
+            throw new \Exception('Group sharing is now allowed');
595
+        }
596
+
597
+        // Verify if the user can share with this group
598
+        if ($this->shareWithGroupMembersOnly()) {
599
+            $sharedBy = $this->userManager->get($share->getSharedBy());
600
+            $sharedWith = $this->groupManager->get($share->getSharedWith());
601
+            if (is_null($sharedWith) || !$sharedWith->inGroup($sharedBy)) {
602
+                throw new \Exception('Sharing is only allowed within your own groups');
603
+            }
604
+        }
605
+
606
+        /*
607 607
 		 * TODO: Could be costly, fix
608 608
 		 *
609 609
 		 * Also this is not what we want in the future.. then we want to squash identical shares.
610 610
 		 */
611
-		$provider = $this->factory->getProviderForType(IShare::TYPE_GROUP);
612
-		$existingShares = $provider->getSharesByPath($share->getNode());
613
-		foreach ($existingShares as $existingShare) {
614
-			try {
615
-				if ($existingShare->getFullId() === $share->getFullId()) {
616
-					continue;
617
-				}
618
-			} catch (\UnexpectedValueException $e) {
619
-				//It is a new share so just continue
620
-			}
621
-
622
-			if ($existingShare->getSharedWith() === $share->getSharedWith() && $existingShare->getShareType() === $share->getShareType()) {
623
-				throw new \Exception('Path is already shared with this group');
624
-			}
625
-		}
626
-	}
627
-
628
-	/**
629
-	 * Check for pre share requirements for link shares
630
-	 *
631
-	 * @param IShare $share
632
-	 * @throws \Exception
633
-	 */
634
-	protected function linkCreateChecks(IShare $share) {
635
-		// Are link shares allowed?
636
-		if (!$this->shareApiAllowLinks()) {
637
-			throw new \Exception('Link sharing is not allowed');
638
-		}
639
-
640
-		// Check if public upload is allowed
641
-		if (!$this->shareApiLinkAllowPublicUpload() &&
642
-			($share->getPermissions() & (\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE))) {
643
-			throw new \InvalidArgumentException('Public upload is not allowed');
644
-		}
645
-	}
646
-
647
-	/**
648
-	 * To make sure we don't get invisible link shares we set the parent
649
-	 * of a link if it is a reshare. This is a quick word around
650
-	 * until we can properly display multiple link shares in the UI
651
-	 *
652
-	 * See: https://github.com/owncloud/core/issues/22295
653
-	 *
654
-	 * FIXME: Remove once multiple link shares can be properly displayed
655
-	 *
656
-	 * @param IShare $share
657
-	 */
658
-	protected function setLinkParent(IShare $share) {
659
-
660
-		// No sense in checking if the method is not there.
661
-		if (method_exists($share, 'setParent')) {
662
-			$storage = $share->getNode()->getStorage();
663
-			if ($storage->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
664
-				/** @var \OCA\Files_Sharing\SharedStorage $storage */
665
-				$share->setParent($storage->getShareId());
666
-			}
667
-		}
668
-	}
669
-
670
-	/**
671
-	 * @param File|Folder $path
672
-	 */
673
-	protected function pathCreateChecks($path) {
674
-		// Make sure that we do not share a path that contains a shared mountpoint
675
-		if ($path instanceof \OCP\Files\Folder) {
676
-			$mounts = $this->mountManager->findIn($path->getPath());
677
-			foreach ($mounts as $mount) {
678
-				if ($mount->getStorage()->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
679
-					throw new \InvalidArgumentException('Path contains files shared with you');
680
-				}
681
-			}
682
-		}
683
-	}
684
-
685
-	/**
686
-	 * Check if the user that is sharing can actually share
687
-	 *
688
-	 * @param IShare $share
689
-	 * @throws \Exception
690
-	 */
691
-	protected function canShare(IShare $share) {
692
-		if (!$this->shareApiEnabled()) {
693
-			throw new \Exception('Sharing is disabled');
694
-		}
695
-
696
-		if ($this->sharingDisabledForUser($share->getSharedBy())) {
697
-			throw new \Exception('Sharing is disabled for you');
698
-		}
699
-	}
700
-
701
-	/**
702
-	 * Share a path
703
-	 *
704
-	 * @param IShare $share
705
-	 * @return IShare The share object
706
-	 * @throws \Exception
707
-	 *
708
-	 * TODO: handle link share permissions or check them
709
-	 */
710
-	public function createShare(IShare $share) {
711
-		$this->canShare($share);
712
-
713
-		$this->generalCreateChecks($share);
714
-
715
-		// Verify if there are any issues with the path
716
-		$this->pathCreateChecks($share->getNode());
717
-
718
-		/*
611
+        $provider = $this->factory->getProviderForType(IShare::TYPE_GROUP);
612
+        $existingShares = $provider->getSharesByPath($share->getNode());
613
+        foreach ($existingShares as $existingShare) {
614
+            try {
615
+                if ($existingShare->getFullId() === $share->getFullId()) {
616
+                    continue;
617
+                }
618
+            } catch (\UnexpectedValueException $e) {
619
+                //It is a new share so just continue
620
+            }
621
+
622
+            if ($existingShare->getSharedWith() === $share->getSharedWith() && $existingShare->getShareType() === $share->getShareType()) {
623
+                throw new \Exception('Path is already shared with this group');
624
+            }
625
+        }
626
+    }
627
+
628
+    /**
629
+     * Check for pre share requirements for link shares
630
+     *
631
+     * @param IShare $share
632
+     * @throws \Exception
633
+     */
634
+    protected function linkCreateChecks(IShare $share) {
635
+        // Are link shares allowed?
636
+        if (!$this->shareApiAllowLinks()) {
637
+            throw new \Exception('Link sharing is not allowed');
638
+        }
639
+
640
+        // Check if public upload is allowed
641
+        if (!$this->shareApiLinkAllowPublicUpload() &&
642
+            ($share->getPermissions() & (\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE))) {
643
+            throw new \InvalidArgumentException('Public upload is not allowed');
644
+        }
645
+    }
646
+
647
+    /**
648
+     * To make sure we don't get invisible link shares we set the parent
649
+     * of a link if it is a reshare. This is a quick word around
650
+     * until we can properly display multiple link shares in the UI
651
+     *
652
+     * See: https://github.com/owncloud/core/issues/22295
653
+     *
654
+     * FIXME: Remove once multiple link shares can be properly displayed
655
+     *
656
+     * @param IShare $share
657
+     */
658
+    protected function setLinkParent(IShare $share) {
659
+
660
+        // No sense in checking if the method is not there.
661
+        if (method_exists($share, 'setParent')) {
662
+            $storage = $share->getNode()->getStorage();
663
+            if ($storage->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
664
+                /** @var \OCA\Files_Sharing\SharedStorage $storage */
665
+                $share->setParent($storage->getShareId());
666
+            }
667
+        }
668
+    }
669
+
670
+    /**
671
+     * @param File|Folder $path
672
+     */
673
+    protected function pathCreateChecks($path) {
674
+        // Make sure that we do not share a path that contains a shared mountpoint
675
+        if ($path instanceof \OCP\Files\Folder) {
676
+            $mounts = $this->mountManager->findIn($path->getPath());
677
+            foreach ($mounts as $mount) {
678
+                if ($mount->getStorage()->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
679
+                    throw new \InvalidArgumentException('Path contains files shared with you');
680
+                }
681
+            }
682
+        }
683
+    }
684
+
685
+    /**
686
+     * Check if the user that is sharing can actually share
687
+     *
688
+     * @param IShare $share
689
+     * @throws \Exception
690
+     */
691
+    protected function canShare(IShare $share) {
692
+        if (!$this->shareApiEnabled()) {
693
+            throw new \Exception('Sharing is disabled');
694
+        }
695
+
696
+        if ($this->sharingDisabledForUser($share->getSharedBy())) {
697
+            throw new \Exception('Sharing is disabled for you');
698
+        }
699
+    }
700
+
701
+    /**
702
+     * Share a path
703
+     *
704
+     * @param IShare $share
705
+     * @return IShare The share object
706
+     * @throws \Exception
707
+     *
708
+     * TODO: handle link share permissions or check them
709
+     */
710
+    public function createShare(IShare $share) {
711
+        $this->canShare($share);
712
+
713
+        $this->generalCreateChecks($share);
714
+
715
+        // Verify if there are any issues with the path
716
+        $this->pathCreateChecks($share->getNode());
717
+
718
+        /*
719 719
 		 * On creation of a share the owner is always the owner of the path
720 720
 		 * Except for mounted federated shares.
721 721
 		 */
722
-		$storage = $share->getNode()->getStorage();
723
-		if ($storage->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
724
-			$parent = $share->getNode()->getParent();
725
-			while ($parent->getStorage()->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
726
-				$parent = $parent->getParent();
727
-			}
728
-			$share->setShareOwner($parent->getOwner()->getUID());
729
-		} else {
730
-			if ($share->getNode()->getOwner()) {
731
-				$share->setShareOwner($share->getNode()->getOwner()->getUID());
732
-			} else {
733
-				$share->setShareOwner($share->getSharedBy());
734
-			}
735
-		}
736
-
737
-		//Verify share type
738
-		if ($share->getShareType() === IShare::TYPE_USER) {
739
-			$this->userCreateChecks($share);
740
-
741
-			//Verify the expiration date
742
-			$share = $this->validateExpirationDateInternal($share);
743
-		} elseif ($share->getShareType() === IShare::TYPE_GROUP) {
744
-			$this->groupCreateChecks($share);
745
-
746
-			//Verify the expiration date
747
-			$share = $this->validateExpirationDateInternal($share);
748
-		} elseif ($share->getShareType() === IShare::TYPE_LINK) {
749
-			$this->linkCreateChecks($share);
750
-			$this->setLinkParent($share);
751
-
752
-			/*
722
+        $storage = $share->getNode()->getStorage();
723
+        if ($storage->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
724
+            $parent = $share->getNode()->getParent();
725
+            while ($parent->getStorage()->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
726
+                $parent = $parent->getParent();
727
+            }
728
+            $share->setShareOwner($parent->getOwner()->getUID());
729
+        } else {
730
+            if ($share->getNode()->getOwner()) {
731
+                $share->setShareOwner($share->getNode()->getOwner()->getUID());
732
+            } else {
733
+                $share->setShareOwner($share->getSharedBy());
734
+            }
735
+        }
736
+
737
+        //Verify share type
738
+        if ($share->getShareType() === IShare::TYPE_USER) {
739
+            $this->userCreateChecks($share);
740
+
741
+            //Verify the expiration date
742
+            $share = $this->validateExpirationDateInternal($share);
743
+        } elseif ($share->getShareType() === IShare::TYPE_GROUP) {
744
+            $this->groupCreateChecks($share);
745
+
746
+            //Verify the expiration date
747
+            $share = $this->validateExpirationDateInternal($share);
748
+        } elseif ($share->getShareType() === IShare::TYPE_LINK) {
749
+            $this->linkCreateChecks($share);
750
+            $this->setLinkParent($share);
751
+
752
+            /*
753 753
 			 * For now ignore a set token.
754 754
 			 */
755
-			$share->setToken(
756
-				$this->secureRandom->generate(
757
-					\OC\Share\Constants::TOKEN_LENGTH,
758
-					\OCP\Security\ISecureRandom::CHAR_HUMAN_READABLE
759
-				)
760
-			);
761
-
762
-			//Verify the expiration date
763
-			$share = $this->validateExpirationDate($share);
764
-
765
-			//Verify the password
766
-			$this->verifyPassword($share->getPassword());
767
-
768
-			// If a password is set. Hash it!
769
-			if ($share->getPassword() !== null) {
770
-				$share->setPassword($this->hasher->hash($share->getPassword()));
771
-			}
772
-		} elseif ($share->getShareType() === IShare::TYPE_EMAIL) {
773
-			$share->setToken(
774
-				$this->secureRandom->generate(
775
-					\OC\Share\Constants::TOKEN_LENGTH,
776
-					\OCP\Security\ISecureRandom::CHAR_HUMAN_READABLE
777
-				)
778
-			);
779
-		}
780
-
781
-		// Cannot share with the owner
782
-		if ($share->getShareType() === IShare::TYPE_USER &&
783
-			$share->getSharedWith() === $share->getShareOwner()) {
784
-			throw new \InvalidArgumentException('Can’t share with the share owner');
785
-		}
786
-
787
-		// Generate the target
788
-		$target = $this->config->getSystemValue('share_folder', '/') .'/'. $share->getNode()->getName();
789
-		$target = \OC\Files\Filesystem::normalizePath($target);
790
-		$share->setTarget($target);
791
-
792
-		// Pre share event
793
-		$event = new GenericEvent($share);
794
-		$this->legacyDispatcher->dispatch('OCP\Share::preShare', $event);
795
-		if ($event->isPropagationStopped() && $event->hasArgument('error')) {
796
-			throw new \Exception($event->getArgument('error'));
797
-		}
798
-
799
-		$oldShare = $share;
800
-		$provider = $this->factory->getProviderForType($share->getShareType());
801
-		$share = $provider->create($share);
802
-		//reuse the node we already have
803
-		$share->setNode($oldShare->getNode());
804
-
805
-		// Reset the target if it is null for the new share
806
-		if ($share->getTarget() === '') {
807
-			$share->setTarget($target);
808
-		}
809
-
810
-		// Post share event
811
-		$event = new GenericEvent($share);
812
-		$this->legacyDispatcher->dispatch('OCP\Share::postShare', $event);
813
-
814
-		$this->dispatcher->dispatchTyped(new Share\Events\ShareCreatedEvent($share));
815
-
816
-		if ($this->config->getSystemValueBool('sharing.enable_share_mail', true)
817
-			&& $share->getShareType() === IShare::TYPE_USER) {
818
-			$mailSend = $share->getMailSend();
819
-			if ($mailSend === true) {
820
-				$user = $this->userManager->get($share->getSharedWith());
821
-				if ($user !== null) {
822
-					$emailAddress = $user->getEMailAddress();
823
-					if ($emailAddress !== null && $emailAddress !== '') {
824
-						$userLang = $this->l10nFactory->getUserLanguage($user);
825
-						$l = $this->l10nFactory->get('lib', $userLang);
826
-						$this->sendMailNotification(
827
-							$l,
828
-							$share->getNode()->getName(),
829
-							$this->urlGenerator->linkToRouteAbsolute('files_sharing.Accept.accept', ['shareId' => $share->getFullId()]),
830
-							$share->getSharedBy(),
831
-							$emailAddress,
832
-							$share->getExpirationDate()
833
-						);
834
-						$this->logger->debug('Sent share notification to ' . $emailAddress . ' for share with ID ' . $share->getId(), ['app' => 'share']);
835
-					} else {
836
-						$this->logger->debug('Share notification not sent to ' . $share->getSharedWith() . ' because email address is not set.', ['app' => 'share']);
837
-					}
838
-				} else {
839
-					$this->logger->debug('Share notification not sent to ' . $share->getSharedWith() . ' because user could not be found.', ['app' => 'share']);
840
-				}
841
-			} else {
842
-				$this->logger->debug('Share notification not sent because mailsend is false.', ['app' => 'share']);
843
-			}
844
-		}
845
-
846
-		return $share;
847
-	}
848
-
849
-	/**
850
-	 * Send mail notifications
851
-	 *
852
-	 * This method will catch and log mail transmission errors
853
-	 *
854
-	 * @param IL10N $l Language of the recipient
855
-	 * @param string $filename file/folder name
856
-	 * @param string $link link to the file/folder
857
-	 * @param string $initiator user ID of share sender
858
-	 * @param string $shareWith email address of share receiver
859
-	 * @param \DateTime|null $expiration
860
-	 */
861
-	protected function sendMailNotification(IL10N $l,
862
-											$filename,
863
-											$link,
864
-											$initiator,
865
-											$shareWith,
866
-											\DateTime $expiration = null) {
867
-		$initiatorUser = $this->userManager->get($initiator);
868
-		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
869
-
870
-		$message = $this->mailer->createMessage();
871
-
872
-		$emailTemplate = $this->mailer->createEMailTemplate('files_sharing.RecipientNotification', [
873
-			'filename' => $filename,
874
-			'link' => $link,
875
-			'initiator' => $initiatorDisplayName,
876
-			'expiration' => $expiration,
877
-			'shareWith' => $shareWith,
878
-		]);
879
-
880
-		$emailTemplate->setSubject($l->t('%1$s shared »%2$s« with you', [$initiatorDisplayName, $filename]));
881
-		$emailTemplate->addHeader();
882
-		$emailTemplate->addHeading($l->t('%1$s shared »%2$s« with you', [$initiatorDisplayName, $filename]), false);
883
-		$text = $l->t('%1$s shared »%2$s« with you.', [$initiatorDisplayName, $filename]);
884
-
885
-		$emailTemplate->addBodyText(
886
-			htmlspecialchars($text . ' ' . $l->t('Click the button below to open it.')),
887
-			$text
888
-		);
889
-		$emailTemplate->addBodyButton(
890
-			$l->t('Open »%s«', [$filename]),
891
-			$link
892
-		);
893
-
894
-		$message->setTo([$shareWith]);
895
-
896
-		// The "From" contains the sharers name
897
-		$instanceName = $this->defaults->getName();
898
-		$senderName = $l->t(
899
-			'%1$s via %2$s',
900
-			[
901
-				$initiatorDisplayName,
902
-				$instanceName
903
-			]
904
-		);
905
-		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
906
-
907
-		// The "Reply-To" is set to the sharer if an mail address is configured
908
-		// also the default footer contains a "Do not reply" which needs to be adjusted.
909
-		$initiatorEmail = $initiatorUser->getEMailAddress();
910
-		if ($initiatorEmail !== null) {
911
-			$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
912
-			$emailTemplate->addFooter($instanceName . ($this->defaults->getSlogan($l->getLanguageCode()) !== '' ? ' - ' . $this->defaults->getSlogan($l->getLanguageCode()) : ''));
913
-		} else {
914
-			$emailTemplate->addFooter('', $l->getLanguageCode());
915
-		}
916
-
917
-		$message->useTemplate($emailTemplate);
918
-		try {
919
-			$failedRecipients = $this->mailer->send($message);
920
-			if (!empty($failedRecipients)) {
921
-				$this->logger->error('Share notification mail could not be sent to: ' . implode(', ', $failedRecipients));
922
-				return;
923
-			}
924
-		} catch (\Exception $e) {
925
-			$this->logger->logException($e, ['message' => 'Share notification mail could not be sent']);
926
-		}
927
-	}
928
-
929
-	/**
930
-	 * Update a share
931
-	 *
932
-	 * @param IShare $share
933
-	 * @return IShare The share object
934
-	 * @throws \InvalidArgumentException
935
-	 */
936
-	public function updateShare(IShare $share) {
937
-		$expirationDateUpdated = false;
938
-
939
-		$this->canShare($share);
940
-
941
-		try {
942
-			$originalShare = $this->getShareById($share->getFullId());
943
-		} catch (\UnexpectedValueException $e) {
944
-			throw new \InvalidArgumentException('Share does not have a full id');
945
-		}
946
-
947
-		// We can't change the share type!
948
-		if ($share->getShareType() !== $originalShare->getShareType()) {
949
-			throw new \InvalidArgumentException('Can’t change share type');
950
-		}
951
-
952
-		// We can only change the recipient on user shares
953
-		if ($share->getSharedWith() !== $originalShare->getSharedWith() &&
954
-			$share->getShareType() !== IShare::TYPE_USER) {
955
-			throw new \InvalidArgumentException('Can only update recipient on user shares');
956
-		}
957
-
958
-		// Cannot share with the owner
959
-		if ($share->getShareType() === IShare::TYPE_USER &&
960
-			$share->getSharedWith() === $share->getShareOwner()) {
961
-			throw new \InvalidArgumentException('Can’t share with the share owner');
962
-		}
963
-
964
-		$this->generalCreateChecks($share);
965
-
966
-		if ($share->getShareType() === IShare::TYPE_USER) {
967
-			$this->userCreateChecks($share);
968
-
969
-			if ($share->getExpirationDate() != $originalShare->getExpirationDate()) {
970
-				//Verify the expiration date
971
-				$this->validateExpirationDate($share);
972
-				$expirationDateUpdated = true;
973
-			}
974
-		} elseif ($share->getShareType() === IShare::TYPE_GROUP) {
975
-			$this->groupCreateChecks($share);
976
-
977
-			if ($share->getExpirationDate() != $originalShare->getExpirationDate()) {
978
-				//Verify the expiration date
979
-				$this->validateExpirationDate($share);
980
-				$expirationDateUpdated = true;
981
-			}
982
-		} elseif ($share->getShareType() === IShare::TYPE_LINK) {
983
-			$this->linkCreateChecks($share);
984
-
985
-			$plainTextPassword = $share->getPassword();
986
-
987
-			$this->updateSharePasswordIfNeeded($share, $originalShare);
988
-
989
-			if (empty($plainTextPassword) && $share->getSendPasswordByTalk()) {
990
-				throw new \InvalidArgumentException('Can’t enable sending the password by Talk with an empty password');
991
-			}
992
-
993
-			if ($share->getExpirationDate() != $originalShare->getExpirationDate()) {
994
-				//Verify the expiration date
995
-				$this->validateExpirationDate($share);
996
-				$expirationDateUpdated = true;
997
-			}
998
-		} elseif ($share->getShareType() === IShare::TYPE_EMAIL) {
999
-			// The new password is not set again if it is the same as the old
1000
-			// one.
1001
-			$plainTextPassword = $share->getPassword();
1002
-			if (!empty($plainTextPassword) && !$this->updateSharePasswordIfNeeded($share, $originalShare)) {
1003
-				$plainTextPassword = null;
1004
-			}
1005
-			if (empty($plainTextPassword) && !$originalShare->getSendPasswordByTalk() && $share->getSendPasswordByTalk()) {
1006
-				// If the same password was already sent by mail the recipient
1007
-				// would already have access to the share without having to call
1008
-				// the sharer to verify her identity
1009
-				throw new \InvalidArgumentException('Can’t enable sending the password by Talk without setting a new password');
1010
-			} elseif (empty($plainTextPassword) && $originalShare->getSendPasswordByTalk() && !$share->getSendPasswordByTalk()) {
1011
-				throw new \InvalidArgumentException('Can’t disable sending the password by Talk without setting a new password');
1012
-			}
1013
-		}
1014
-
1015
-		$this->pathCreateChecks($share->getNode());
1016
-
1017
-		// Now update the share!
1018
-		$provider = $this->factory->getProviderForType($share->getShareType());
1019
-		if ($share->getShareType() === IShare::TYPE_EMAIL) {
1020
-			$share = $provider->update($share, $plainTextPassword);
1021
-		} else {
1022
-			$share = $provider->update($share);
1023
-		}
1024
-
1025
-		if ($expirationDateUpdated === true) {
1026
-			\OC_Hook::emit(Share::class, 'post_set_expiration_date', [
1027
-				'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
1028
-				'itemSource' => $share->getNode()->getId(),
1029
-				'date' => $share->getExpirationDate(),
1030
-				'uidOwner' => $share->getSharedBy(),
1031
-			]);
1032
-		}
1033
-
1034
-		if ($share->getPassword() !== $originalShare->getPassword()) {
1035
-			\OC_Hook::emit(Share::class, 'post_update_password', [
1036
-				'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
1037
-				'itemSource' => $share->getNode()->getId(),
1038
-				'uidOwner' => $share->getSharedBy(),
1039
-				'token' => $share->getToken(),
1040
-				'disabled' => is_null($share->getPassword()),
1041
-			]);
1042
-		}
1043
-
1044
-		if ($share->getPermissions() !== $originalShare->getPermissions()) {
1045
-			if ($this->userManager->userExists($share->getShareOwner())) {
1046
-				$userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
1047
-			} else {
1048
-				$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
1049
-			}
1050
-			\OC_Hook::emit(Share::class, 'post_update_permissions', [
1051
-				'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
1052
-				'itemSource' => $share->getNode()->getId(),
1053
-				'shareType' => $share->getShareType(),
1054
-				'shareWith' => $share->getSharedWith(),
1055
-				'uidOwner' => $share->getSharedBy(),
1056
-				'permissions' => $share->getPermissions(),
1057
-				'path' => $userFolder->getRelativePath($share->getNode()->getPath()),
1058
-			]);
1059
-		}
1060
-
1061
-		return $share;
1062
-	}
1063
-
1064
-	/**
1065
-	 * Accept a share.
1066
-	 *
1067
-	 * @param IShare $share
1068
-	 * @param string $recipientId
1069
-	 * @return IShare The share object
1070
-	 * @throws \InvalidArgumentException
1071
-	 * @since 9.0.0
1072
-	 */
1073
-	public function acceptShare(IShare $share, string $recipientId): IShare {
1074
-		[$providerId, ] = $this->splitFullId($share->getFullId());
1075
-		$provider = $this->factory->getProvider($providerId);
1076
-
1077
-		if (!method_exists($provider, 'acceptShare')) {
1078
-			// TODO FIX ME
1079
-			throw new \InvalidArgumentException('Share provider does not support accepting');
1080
-		}
1081
-		$provider->acceptShare($share, $recipientId);
1082
-		$event = new GenericEvent($share);
1083
-		$this->legacyDispatcher->dispatch('OCP\Share::postAcceptShare', $event);
1084
-
1085
-		return $share;
1086
-	}
1087
-
1088
-	/**
1089
-	 * Updates the password of the given share if it is not the same as the
1090
-	 * password of the original share.
1091
-	 *
1092
-	 * @param IShare $share the share to update its password.
1093
-	 * @param IShare $originalShare the original share to compare its
1094
-	 *        password with.
1095
-	 * @return boolean whether the password was updated or not.
1096
-	 */
1097
-	private function updateSharePasswordIfNeeded(IShare $share, IShare $originalShare) {
1098
-		$passwordsAreDifferent = ($share->getPassword() !== $originalShare->getPassword()) &&
1099
-									(($share->getPassword() !== null && $originalShare->getPassword() === null) ||
1100
-									 ($share->getPassword() === null && $originalShare->getPassword() !== null) ||
1101
-									 ($share->getPassword() !== null && $originalShare->getPassword() !== null &&
1102
-										!$this->hasher->verify($share->getPassword(), $originalShare->getPassword())));
1103
-
1104
-		// Password updated.
1105
-		if ($passwordsAreDifferent) {
1106
-			//Verify the password
1107
-			$this->verifyPassword($share->getPassword());
1108
-
1109
-			// If a password is set. Hash it!
1110
-			if ($share->getPassword() !== null) {
1111
-				$share->setPassword($this->hasher->hash($share->getPassword()));
1112
-
1113
-				return true;
1114
-			}
1115
-		} else {
1116
-			// Reset the password to the original one, as it is either the same
1117
-			// as the "new" password or a hashed version of it.
1118
-			$share->setPassword($originalShare->getPassword());
1119
-		}
1120
-
1121
-		return false;
1122
-	}
1123
-
1124
-	/**
1125
-	 * Delete all the children of this share
1126
-	 * FIXME: remove once https://github.com/owncloud/core/pull/21660 is in
1127
-	 *
1128
-	 * @param IShare $share
1129
-	 * @return IShare[] List of deleted shares
1130
-	 */
1131
-	protected function deleteChildren(IShare $share) {
1132
-		$deletedShares = [];
1133
-
1134
-		$provider = $this->factory->getProviderForType($share->getShareType());
1135
-
1136
-		foreach ($provider->getChildren($share) as $child) {
1137
-			$deletedChildren = $this->deleteChildren($child);
1138
-			$deletedShares = array_merge($deletedShares, $deletedChildren);
1139
-
1140
-			$provider->delete($child);
1141
-			$deletedShares[] = $child;
1142
-		}
1143
-
1144
-		return $deletedShares;
1145
-	}
1146
-
1147
-	/**
1148
-	 * Delete a share
1149
-	 *
1150
-	 * @param IShare $share
1151
-	 * @throws ShareNotFound
1152
-	 * @throws \InvalidArgumentException
1153
-	 */
1154
-	public function deleteShare(IShare $share) {
1155
-		try {
1156
-			$share->getFullId();
1157
-		} catch (\UnexpectedValueException $e) {
1158
-			throw new \InvalidArgumentException('Share does not have a full id');
1159
-		}
1160
-
1161
-		$event = new GenericEvent($share);
1162
-		$this->legacyDispatcher->dispatch('OCP\Share::preUnshare', $event);
1163
-
1164
-		// Get all children and delete them as well
1165
-		$deletedShares = $this->deleteChildren($share);
1166
-
1167
-		// Do the actual delete
1168
-		$provider = $this->factory->getProviderForType($share->getShareType());
1169
-		$provider->delete($share);
1170
-
1171
-		// All the deleted shares caused by this delete
1172
-		$deletedShares[] = $share;
1173
-
1174
-		// Emit post hook
1175
-		$event->setArgument('deletedShares', $deletedShares);
1176
-		$this->legacyDispatcher->dispatch('OCP\Share::postUnshare', $event);
1177
-	}
1178
-
1179
-
1180
-	/**
1181
-	 * Unshare a file as the recipient.
1182
-	 * This can be different from a regular delete for example when one of
1183
-	 * the users in a groups deletes that share. But the provider should
1184
-	 * handle this.
1185
-	 *
1186
-	 * @param IShare $share
1187
-	 * @param string $recipientId
1188
-	 */
1189
-	public function deleteFromSelf(IShare $share, $recipientId) {
1190
-		list($providerId, ) = $this->splitFullId($share->getFullId());
1191
-		$provider = $this->factory->getProvider($providerId);
1192
-
1193
-		$provider->deleteFromSelf($share, $recipientId);
1194
-		$event = new GenericEvent($share);
1195
-		$this->legacyDispatcher->dispatch('OCP\Share::postUnshareFromSelf', $event);
1196
-	}
1197
-
1198
-	public function restoreShare(IShare $share, string $recipientId): IShare {
1199
-		list($providerId, ) = $this->splitFullId($share->getFullId());
1200
-		$provider = $this->factory->getProvider($providerId);
1201
-
1202
-		return $provider->restore($share, $recipientId);
1203
-	}
1204
-
1205
-	/**
1206
-	 * @inheritdoc
1207
-	 */
1208
-	public function moveShare(IShare $share, $recipientId) {
1209
-		if ($share->getShareType() === IShare::TYPE_LINK) {
1210
-			throw new \InvalidArgumentException('Can’t change target of link share');
1211
-		}
1212
-
1213
-		if ($share->getShareType() === IShare::TYPE_USER && $share->getSharedWith() !== $recipientId) {
1214
-			throw new \InvalidArgumentException('Invalid recipient');
1215
-		}
1216
-
1217
-		if ($share->getShareType() === IShare::TYPE_GROUP) {
1218
-			$sharedWith = $this->groupManager->get($share->getSharedWith());
1219
-			if (is_null($sharedWith)) {
1220
-				throw new \InvalidArgumentException('Group "' . $share->getSharedWith() . '" does not exist');
1221
-			}
1222
-			$recipient = $this->userManager->get($recipientId);
1223
-			if (!$sharedWith->inGroup($recipient)) {
1224
-				throw new \InvalidArgumentException('Invalid recipient');
1225
-			}
1226
-		}
1227
-
1228
-		list($providerId, ) = $this->splitFullId($share->getFullId());
1229
-		$provider = $this->factory->getProvider($providerId);
1230
-
1231
-		return $provider->move($share, $recipientId);
1232
-	}
1233
-
1234
-	public function getSharesInFolder($userId, Folder $node, $reshares = false) {
1235
-		$providers = $this->factory->getAllProviders();
1236
-
1237
-		return array_reduce($providers, function ($shares, IShareProvider $provider) use ($userId, $node, $reshares) {
1238
-			$newShares = $provider->getSharesInFolder($userId, $node, $reshares);
1239
-			foreach ($newShares as $fid => $data) {
1240
-				if (!isset($shares[$fid])) {
1241
-					$shares[$fid] = [];
1242
-				}
1243
-
1244
-				$shares[$fid] = array_merge($shares[$fid], $data);
1245
-			}
1246
-			return $shares;
1247
-		}, []);
1248
-	}
1249
-
1250
-	/**
1251
-	 * @inheritdoc
1252
-	 */
1253
-	public function getSharesBy($userId, $shareType, $path = null, $reshares = false, $limit = 50, $offset = 0) {
1254
-		if ($path !== null &&
1255
-				!($path instanceof \OCP\Files\File) &&
1256
-				!($path instanceof \OCP\Files\Folder)) {
1257
-			throw new \InvalidArgumentException('invalid path');
1258
-		}
1259
-
1260
-		try {
1261
-			$provider = $this->factory->getProviderForType($shareType);
1262
-		} catch (ProviderException $e) {
1263
-			return [];
1264
-		}
1265
-
1266
-		$shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
1267
-
1268
-		/*
755
+            $share->setToken(
756
+                $this->secureRandom->generate(
757
+                    \OC\Share\Constants::TOKEN_LENGTH,
758
+                    \OCP\Security\ISecureRandom::CHAR_HUMAN_READABLE
759
+                )
760
+            );
761
+
762
+            //Verify the expiration date
763
+            $share = $this->validateExpirationDate($share);
764
+
765
+            //Verify the password
766
+            $this->verifyPassword($share->getPassword());
767
+
768
+            // If a password is set. Hash it!
769
+            if ($share->getPassword() !== null) {
770
+                $share->setPassword($this->hasher->hash($share->getPassword()));
771
+            }
772
+        } elseif ($share->getShareType() === IShare::TYPE_EMAIL) {
773
+            $share->setToken(
774
+                $this->secureRandom->generate(
775
+                    \OC\Share\Constants::TOKEN_LENGTH,
776
+                    \OCP\Security\ISecureRandom::CHAR_HUMAN_READABLE
777
+                )
778
+            );
779
+        }
780
+
781
+        // Cannot share with the owner
782
+        if ($share->getShareType() === IShare::TYPE_USER &&
783
+            $share->getSharedWith() === $share->getShareOwner()) {
784
+            throw new \InvalidArgumentException('Can’t share with the share owner');
785
+        }
786
+
787
+        // Generate the target
788
+        $target = $this->config->getSystemValue('share_folder', '/') .'/'. $share->getNode()->getName();
789
+        $target = \OC\Files\Filesystem::normalizePath($target);
790
+        $share->setTarget($target);
791
+
792
+        // Pre share event
793
+        $event = new GenericEvent($share);
794
+        $this->legacyDispatcher->dispatch('OCP\Share::preShare', $event);
795
+        if ($event->isPropagationStopped() && $event->hasArgument('error')) {
796
+            throw new \Exception($event->getArgument('error'));
797
+        }
798
+
799
+        $oldShare = $share;
800
+        $provider = $this->factory->getProviderForType($share->getShareType());
801
+        $share = $provider->create($share);
802
+        //reuse the node we already have
803
+        $share->setNode($oldShare->getNode());
804
+
805
+        // Reset the target if it is null for the new share
806
+        if ($share->getTarget() === '') {
807
+            $share->setTarget($target);
808
+        }
809
+
810
+        // Post share event
811
+        $event = new GenericEvent($share);
812
+        $this->legacyDispatcher->dispatch('OCP\Share::postShare', $event);
813
+
814
+        $this->dispatcher->dispatchTyped(new Share\Events\ShareCreatedEvent($share));
815
+
816
+        if ($this->config->getSystemValueBool('sharing.enable_share_mail', true)
817
+            && $share->getShareType() === IShare::TYPE_USER) {
818
+            $mailSend = $share->getMailSend();
819
+            if ($mailSend === true) {
820
+                $user = $this->userManager->get($share->getSharedWith());
821
+                if ($user !== null) {
822
+                    $emailAddress = $user->getEMailAddress();
823
+                    if ($emailAddress !== null && $emailAddress !== '') {
824
+                        $userLang = $this->l10nFactory->getUserLanguage($user);
825
+                        $l = $this->l10nFactory->get('lib', $userLang);
826
+                        $this->sendMailNotification(
827
+                            $l,
828
+                            $share->getNode()->getName(),
829
+                            $this->urlGenerator->linkToRouteAbsolute('files_sharing.Accept.accept', ['shareId' => $share->getFullId()]),
830
+                            $share->getSharedBy(),
831
+                            $emailAddress,
832
+                            $share->getExpirationDate()
833
+                        );
834
+                        $this->logger->debug('Sent share notification to ' . $emailAddress . ' for share with ID ' . $share->getId(), ['app' => 'share']);
835
+                    } else {
836
+                        $this->logger->debug('Share notification not sent to ' . $share->getSharedWith() . ' because email address is not set.', ['app' => 'share']);
837
+                    }
838
+                } else {
839
+                    $this->logger->debug('Share notification not sent to ' . $share->getSharedWith() . ' because user could not be found.', ['app' => 'share']);
840
+                }
841
+            } else {
842
+                $this->logger->debug('Share notification not sent because mailsend is false.', ['app' => 'share']);
843
+            }
844
+        }
845
+
846
+        return $share;
847
+    }
848
+
849
+    /**
850
+     * Send mail notifications
851
+     *
852
+     * This method will catch and log mail transmission errors
853
+     *
854
+     * @param IL10N $l Language of the recipient
855
+     * @param string $filename file/folder name
856
+     * @param string $link link to the file/folder
857
+     * @param string $initiator user ID of share sender
858
+     * @param string $shareWith email address of share receiver
859
+     * @param \DateTime|null $expiration
860
+     */
861
+    protected function sendMailNotification(IL10N $l,
862
+                                            $filename,
863
+                                            $link,
864
+                                            $initiator,
865
+                                            $shareWith,
866
+                                            \DateTime $expiration = null) {
867
+        $initiatorUser = $this->userManager->get($initiator);
868
+        $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
869
+
870
+        $message = $this->mailer->createMessage();
871
+
872
+        $emailTemplate = $this->mailer->createEMailTemplate('files_sharing.RecipientNotification', [
873
+            'filename' => $filename,
874
+            'link' => $link,
875
+            'initiator' => $initiatorDisplayName,
876
+            'expiration' => $expiration,
877
+            'shareWith' => $shareWith,
878
+        ]);
879
+
880
+        $emailTemplate->setSubject($l->t('%1$s shared »%2$s« with you', [$initiatorDisplayName, $filename]));
881
+        $emailTemplate->addHeader();
882
+        $emailTemplate->addHeading($l->t('%1$s shared »%2$s« with you', [$initiatorDisplayName, $filename]), false);
883
+        $text = $l->t('%1$s shared »%2$s« with you.', [$initiatorDisplayName, $filename]);
884
+
885
+        $emailTemplate->addBodyText(
886
+            htmlspecialchars($text . ' ' . $l->t('Click the button below to open it.')),
887
+            $text
888
+        );
889
+        $emailTemplate->addBodyButton(
890
+            $l->t('Open »%s«', [$filename]),
891
+            $link
892
+        );
893
+
894
+        $message->setTo([$shareWith]);
895
+
896
+        // The "From" contains the sharers name
897
+        $instanceName = $this->defaults->getName();
898
+        $senderName = $l->t(
899
+            '%1$s via %2$s',
900
+            [
901
+                $initiatorDisplayName,
902
+                $instanceName
903
+            ]
904
+        );
905
+        $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
906
+
907
+        // The "Reply-To" is set to the sharer if an mail address is configured
908
+        // also the default footer contains a "Do not reply" which needs to be adjusted.
909
+        $initiatorEmail = $initiatorUser->getEMailAddress();
910
+        if ($initiatorEmail !== null) {
911
+            $message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
912
+            $emailTemplate->addFooter($instanceName . ($this->defaults->getSlogan($l->getLanguageCode()) !== '' ? ' - ' . $this->defaults->getSlogan($l->getLanguageCode()) : ''));
913
+        } else {
914
+            $emailTemplate->addFooter('', $l->getLanguageCode());
915
+        }
916
+
917
+        $message->useTemplate($emailTemplate);
918
+        try {
919
+            $failedRecipients = $this->mailer->send($message);
920
+            if (!empty($failedRecipients)) {
921
+                $this->logger->error('Share notification mail could not be sent to: ' . implode(', ', $failedRecipients));
922
+                return;
923
+            }
924
+        } catch (\Exception $e) {
925
+            $this->logger->logException($e, ['message' => 'Share notification mail could not be sent']);
926
+        }
927
+    }
928
+
929
+    /**
930
+     * Update a share
931
+     *
932
+     * @param IShare $share
933
+     * @return IShare The share object
934
+     * @throws \InvalidArgumentException
935
+     */
936
+    public function updateShare(IShare $share) {
937
+        $expirationDateUpdated = false;
938
+
939
+        $this->canShare($share);
940
+
941
+        try {
942
+            $originalShare = $this->getShareById($share->getFullId());
943
+        } catch (\UnexpectedValueException $e) {
944
+            throw new \InvalidArgumentException('Share does not have a full id');
945
+        }
946
+
947
+        // We can't change the share type!
948
+        if ($share->getShareType() !== $originalShare->getShareType()) {
949
+            throw new \InvalidArgumentException('Can’t change share type');
950
+        }
951
+
952
+        // We can only change the recipient on user shares
953
+        if ($share->getSharedWith() !== $originalShare->getSharedWith() &&
954
+            $share->getShareType() !== IShare::TYPE_USER) {
955
+            throw new \InvalidArgumentException('Can only update recipient on user shares');
956
+        }
957
+
958
+        // Cannot share with the owner
959
+        if ($share->getShareType() === IShare::TYPE_USER &&
960
+            $share->getSharedWith() === $share->getShareOwner()) {
961
+            throw new \InvalidArgumentException('Can’t share with the share owner');
962
+        }
963
+
964
+        $this->generalCreateChecks($share);
965
+
966
+        if ($share->getShareType() === IShare::TYPE_USER) {
967
+            $this->userCreateChecks($share);
968
+
969
+            if ($share->getExpirationDate() != $originalShare->getExpirationDate()) {
970
+                //Verify the expiration date
971
+                $this->validateExpirationDate($share);
972
+                $expirationDateUpdated = true;
973
+            }
974
+        } elseif ($share->getShareType() === IShare::TYPE_GROUP) {
975
+            $this->groupCreateChecks($share);
976
+
977
+            if ($share->getExpirationDate() != $originalShare->getExpirationDate()) {
978
+                //Verify the expiration date
979
+                $this->validateExpirationDate($share);
980
+                $expirationDateUpdated = true;
981
+            }
982
+        } elseif ($share->getShareType() === IShare::TYPE_LINK) {
983
+            $this->linkCreateChecks($share);
984
+
985
+            $plainTextPassword = $share->getPassword();
986
+
987
+            $this->updateSharePasswordIfNeeded($share, $originalShare);
988
+
989
+            if (empty($plainTextPassword) && $share->getSendPasswordByTalk()) {
990
+                throw new \InvalidArgumentException('Can’t enable sending the password by Talk with an empty password');
991
+            }
992
+
993
+            if ($share->getExpirationDate() != $originalShare->getExpirationDate()) {
994
+                //Verify the expiration date
995
+                $this->validateExpirationDate($share);
996
+                $expirationDateUpdated = true;
997
+            }
998
+        } elseif ($share->getShareType() === IShare::TYPE_EMAIL) {
999
+            // The new password is not set again if it is the same as the old
1000
+            // one.
1001
+            $plainTextPassword = $share->getPassword();
1002
+            if (!empty($plainTextPassword) && !$this->updateSharePasswordIfNeeded($share, $originalShare)) {
1003
+                $plainTextPassword = null;
1004
+            }
1005
+            if (empty($plainTextPassword) && !$originalShare->getSendPasswordByTalk() && $share->getSendPasswordByTalk()) {
1006
+                // If the same password was already sent by mail the recipient
1007
+                // would already have access to the share without having to call
1008
+                // the sharer to verify her identity
1009
+                throw new \InvalidArgumentException('Can’t enable sending the password by Talk without setting a new password');
1010
+            } elseif (empty($plainTextPassword) && $originalShare->getSendPasswordByTalk() && !$share->getSendPasswordByTalk()) {
1011
+                throw new \InvalidArgumentException('Can’t disable sending the password by Talk without setting a new password');
1012
+            }
1013
+        }
1014
+
1015
+        $this->pathCreateChecks($share->getNode());
1016
+
1017
+        // Now update the share!
1018
+        $provider = $this->factory->getProviderForType($share->getShareType());
1019
+        if ($share->getShareType() === IShare::TYPE_EMAIL) {
1020
+            $share = $provider->update($share, $plainTextPassword);
1021
+        } else {
1022
+            $share = $provider->update($share);
1023
+        }
1024
+
1025
+        if ($expirationDateUpdated === true) {
1026
+            \OC_Hook::emit(Share::class, 'post_set_expiration_date', [
1027
+                'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
1028
+                'itemSource' => $share->getNode()->getId(),
1029
+                'date' => $share->getExpirationDate(),
1030
+                'uidOwner' => $share->getSharedBy(),
1031
+            ]);
1032
+        }
1033
+
1034
+        if ($share->getPassword() !== $originalShare->getPassword()) {
1035
+            \OC_Hook::emit(Share::class, 'post_update_password', [
1036
+                'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
1037
+                'itemSource' => $share->getNode()->getId(),
1038
+                'uidOwner' => $share->getSharedBy(),
1039
+                'token' => $share->getToken(),
1040
+                'disabled' => is_null($share->getPassword()),
1041
+            ]);
1042
+        }
1043
+
1044
+        if ($share->getPermissions() !== $originalShare->getPermissions()) {
1045
+            if ($this->userManager->userExists($share->getShareOwner())) {
1046
+                $userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
1047
+            } else {
1048
+                $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
1049
+            }
1050
+            \OC_Hook::emit(Share::class, 'post_update_permissions', [
1051
+                'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
1052
+                'itemSource' => $share->getNode()->getId(),
1053
+                'shareType' => $share->getShareType(),
1054
+                'shareWith' => $share->getSharedWith(),
1055
+                'uidOwner' => $share->getSharedBy(),
1056
+                'permissions' => $share->getPermissions(),
1057
+                'path' => $userFolder->getRelativePath($share->getNode()->getPath()),
1058
+            ]);
1059
+        }
1060
+
1061
+        return $share;
1062
+    }
1063
+
1064
+    /**
1065
+     * Accept a share.
1066
+     *
1067
+     * @param IShare $share
1068
+     * @param string $recipientId
1069
+     * @return IShare The share object
1070
+     * @throws \InvalidArgumentException
1071
+     * @since 9.0.0
1072
+     */
1073
+    public function acceptShare(IShare $share, string $recipientId): IShare {
1074
+        [$providerId, ] = $this->splitFullId($share->getFullId());
1075
+        $provider = $this->factory->getProvider($providerId);
1076
+
1077
+        if (!method_exists($provider, 'acceptShare')) {
1078
+            // TODO FIX ME
1079
+            throw new \InvalidArgumentException('Share provider does not support accepting');
1080
+        }
1081
+        $provider->acceptShare($share, $recipientId);
1082
+        $event = new GenericEvent($share);
1083
+        $this->legacyDispatcher->dispatch('OCP\Share::postAcceptShare', $event);
1084
+
1085
+        return $share;
1086
+    }
1087
+
1088
+    /**
1089
+     * Updates the password of the given share if it is not the same as the
1090
+     * password of the original share.
1091
+     *
1092
+     * @param IShare $share the share to update its password.
1093
+     * @param IShare $originalShare the original share to compare its
1094
+     *        password with.
1095
+     * @return boolean whether the password was updated or not.
1096
+     */
1097
+    private function updateSharePasswordIfNeeded(IShare $share, IShare $originalShare) {
1098
+        $passwordsAreDifferent = ($share->getPassword() !== $originalShare->getPassword()) &&
1099
+                                    (($share->getPassword() !== null && $originalShare->getPassword() === null) ||
1100
+                                     ($share->getPassword() === null && $originalShare->getPassword() !== null) ||
1101
+                                     ($share->getPassword() !== null && $originalShare->getPassword() !== null &&
1102
+                                        !$this->hasher->verify($share->getPassword(), $originalShare->getPassword())));
1103
+
1104
+        // Password updated.
1105
+        if ($passwordsAreDifferent) {
1106
+            //Verify the password
1107
+            $this->verifyPassword($share->getPassword());
1108
+
1109
+            // If a password is set. Hash it!
1110
+            if ($share->getPassword() !== null) {
1111
+                $share->setPassword($this->hasher->hash($share->getPassword()));
1112
+
1113
+                return true;
1114
+            }
1115
+        } else {
1116
+            // Reset the password to the original one, as it is either the same
1117
+            // as the "new" password or a hashed version of it.
1118
+            $share->setPassword($originalShare->getPassword());
1119
+        }
1120
+
1121
+        return false;
1122
+    }
1123
+
1124
+    /**
1125
+     * Delete all the children of this share
1126
+     * FIXME: remove once https://github.com/owncloud/core/pull/21660 is in
1127
+     *
1128
+     * @param IShare $share
1129
+     * @return IShare[] List of deleted shares
1130
+     */
1131
+    protected function deleteChildren(IShare $share) {
1132
+        $deletedShares = [];
1133
+
1134
+        $provider = $this->factory->getProviderForType($share->getShareType());
1135
+
1136
+        foreach ($provider->getChildren($share) as $child) {
1137
+            $deletedChildren = $this->deleteChildren($child);
1138
+            $deletedShares = array_merge($deletedShares, $deletedChildren);
1139
+
1140
+            $provider->delete($child);
1141
+            $deletedShares[] = $child;
1142
+        }
1143
+
1144
+        return $deletedShares;
1145
+    }
1146
+
1147
+    /**
1148
+     * Delete a share
1149
+     *
1150
+     * @param IShare $share
1151
+     * @throws ShareNotFound
1152
+     * @throws \InvalidArgumentException
1153
+     */
1154
+    public function deleteShare(IShare $share) {
1155
+        try {
1156
+            $share->getFullId();
1157
+        } catch (\UnexpectedValueException $e) {
1158
+            throw new \InvalidArgumentException('Share does not have a full id');
1159
+        }
1160
+
1161
+        $event = new GenericEvent($share);
1162
+        $this->legacyDispatcher->dispatch('OCP\Share::preUnshare', $event);
1163
+
1164
+        // Get all children and delete them as well
1165
+        $deletedShares = $this->deleteChildren($share);
1166
+
1167
+        // Do the actual delete
1168
+        $provider = $this->factory->getProviderForType($share->getShareType());
1169
+        $provider->delete($share);
1170
+
1171
+        // All the deleted shares caused by this delete
1172
+        $deletedShares[] = $share;
1173
+
1174
+        // Emit post hook
1175
+        $event->setArgument('deletedShares', $deletedShares);
1176
+        $this->legacyDispatcher->dispatch('OCP\Share::postUnshare', $event);
1177
+    }
1178
+
1179
+
1180
+    /**
1181
+     * Unshare a file as the recipient.
1182
+     * This can be different from a regular delete for example when one of
1183
+     * the users in a groups deletes that share. But the provider should
1184
+     * handle this.
1185
+     *
1186
+     * @param IShare $share
1187
+     * @param string $recipientId
1188
+     */
1189
+    public function deleteFromSelf(IShare $share, $recipientId) {
1190
+        list($providerId, ) = $this->splitFullId($share->getFullId());
1191
+        $provider = $this->factory->getProvider($providerId);
1192
+
1193
+        $provider->deleteFromSelf($share, $recipientId);
1194
+        $event = new GenericEvent($share);
1195
+        $this->legacyDispatcher->dispatch('OCP\Share::postUnshareFromSelf', $event);
1196
+    }
1197
+
1198
+    public function restoreShare(IShare $share, string $recipientId): IShare {
1199
+        list($providerId, ) = $this->splitFullId($share->getFullId());
1200
+        $provider = $this->factory->getProvider($providerId);
1201
+
1202
+        return $provider->restore($share, $recipientId);
1203
+    }
1204
+
1205
+    /**
1206
+     * @inheritdoc
1207
+     */
1208
+    public function moveShare(IShare $share, $recipientId) {
1209
+        if ($share->getShareType() === IShare::TYPE_LINK) {
1210
+            throw new \InvalidArgumentException('Can’t change target of link share');
1211
+        }
1212
+
1213
+        if ($share->getShareType() === IShare::TYPE_USER && $share->getSharedWith() !== $recipientId) {
1214
+            throw new \InvalidArgumentException('Invalid recipient');
1215
+        }
1216
+
1217
+        if ($share->getShareType() === IShare::TYPE_GROUP) {
1218
+            $sharedWith = $this->groupManager->get($share->getSharedWith());
1219
+            if (is_null($sharedWith)) {
1220
+                throw new \InvalidArgumentException('Group "' . $share->getSharedWith() . '" does not exist');
1221
+            }
1222
+            $recipient = $this->userManager->get($recipientId);
1223
+            if (!$sharedWith->inGroup($recipient)) {
1224
+                throw new \InvalidArgumentException('Invalid recipient');
1225
+            }
1226
+        }
1227
+
1228
+        list($providerId, ) = $this->splitFullId($share->getFullId());
1229
+        $provider = $this->factory->getProvider($providerId);
1230
+
1231
+        return $provider->move($share, $recipientId);
1232
+    }
1233
+
1234
+    public function getSharesInFolder($userId, Folder $node, $reshares = false) {
1235
+        $providers = $this->factory->getAllProviders();
1236
+
1237
+        return array_reduce($providers, function ($shares, IShareProvider $provider) use ($userId, $node, $reshares) {
1238
+            $newShares = $provider->getSharesInFolder($userId, $node, $reshares);
1239
+            foreach ($newShares as $fid => $data) {
1240
+                if (!isset($shares[$fid])) {
1241
+                    $shares[$fid] = [];
1242
+                }
1243
+
1244
+                $shares[$fid] = array_merge($shares[$fid], $data);
1245
+            }
1246
+            return $shares;
1247
+        }, []);
1248
+    }
1249
+
1250
+    /**
1251
+     * @inheritdoc
1252
+     */
1253
+    public function getSharesBy($userId, $shareType, $path = null, $reshares = false, $limit = 50, $offset = 0) {
1254
+        if ($path !== null &&
1255
+                !($path instanceof \OCP\Files\File) &&
1256
+                !($path instanceof \OCP\Files\Folder)) {
1257
+            throw new \InvalidArgumentException('invalid path');
1258
+        }
1259
+
1260
+        try {
1261
+            $provider = $this->factory->getProviderForType($shareType);
1262
+        } catch (ProviderException $e) {
1263
+            return [];
1264
+        }
1265
+
1266
+        $shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
1267
+
1268
+        /*
1269 1269
 		 * Work around so we don't return expired shares but still follow
1270 1270
 		 * proper pagination.
1271 1271
 		 */
1272 1272
 
1273
-		$shares2 = [];
1274
-
1275
-		while (true) {
1276
-			$added = 0;
1277
-			foreach ($shares as $share) {
1278
-				try {
1279
-					$this->checkExpireDate($share);
1280
-				} catch (ShareNotFound $e) {
1281
-					//Ignore since this basically means the share is deleted
1282
-					continue;
1283
-				}
1284
-
1285
-				$added++;
1286
-				$shares2[] = $share;
1287
-
1288
-				if (count($shares2) === $limit) {
1289
-					break;
1290
-				}
1291
-			}
1292
-
1293
-			// If we did not fetch more shares than the limit then there are no more shares
1294
-			if (count($shares) < $limit) {
1295
-				break;
1296
-			}
1297
-
1298
-			if (count($shares2) === $limit) {
1299
-				break;
1300
-			}
1301
-
1302
-			// If there was no limit on the select we are done
1303
-			if ($limit === -1) {
1304
-				break;
1305
-			}
1306
-
1307
-			$offset += $added;
1308
-
1309
-			// Fetch again $limit shares
1310
-			$shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
1311
-
1312
-			// No more shares means we are done
1313
-			if (empty($shares)) {
1314
-				break;
1315
-			}
1316
-		}
1317
-
1318
-		$shares = $shares2;
1319
-
1320
-		return $shares;
1321
-	}
1322
-
1323
-	/**
1324
-	 * @inheritdoc
1325
-	 */
1326
-	public function getSharedWith($userId, $shareType, $node = null, $limit = 50, $offset = 0) {
1327
-		try {
1328
-			$provider = $this->factory->getProviderForType($shareType);
1329
-		} catch (ProviderException $e) {
1330
-			return [];
1331
-		}
1332
-
1333
-		$shares = $provider->getSharedWith($userId, $shareType, $node, $limit, $offset);
1334
-
1335
-		// remove all shares which are already expired
1336
-		foreach ($shares as $key => $share) {
1337
-			try {
1338
-				$this->checkExpireDate($share);
1339
-			} catch (ShareNotFound $e) {
1340
-				unset($shares[$key]);
1341
-			}
1342
-		}
1343
-
1344
-		return $shares;
1345
-	}
1346
-
1347
-	/**
1348
-	 * @inheritdoc
1349
-	 */
1350
-	public function getDeletedSharedWith($userId, $shareType, $node = null, $limit = 50, $offset = 0) {
1351
-		$shares = $this->getSharedWith($userId, $shareType, $node, $limit, $offset);
1352
-
1353
-		// Only get deleted shares
1354
-		$shares = array_filter($shares, function (IShare $share) {
1355
-			return $share->getPermissions() === 0;
1356
-		});
1357
-
1358
-		// Only get shares where the owner still exists
1359
-		$shares = array_filter($shares, function (IShare $share) {
1360
-			return $this->userManager->userExists($share->getShareOwner());
1361
-		});
1362
-
1363
-		return $shares;
1364
-	}
1365
-
1366
-	/**
1367
-	 * @inheritdoc
1368
-	 */
1369
-	public function getShareById($id, $recipient = null) {
1370
-		if ($id === null) {
1371
-			throw new ShareNotFound();
1372
-		}
1373
-
1374
-		list($providerId, $id) = $this->splitFullId($id);
1375
-
1376
-		try {
1377
-			$provider = $this->factory->getProvider($providerId);
1378
-		} catch (ProviderException $e) {
1379
-			throw new ShareNotFound();
1380
-		}
1381
-
1382
-		$share = $provider->getShareById($id, $recipient);
1383
-
1384
-		$this->checkExpireDate($share);
1385
-
1386
-		return $share;
1387
-	}
1388
-
1389
-	/**
1390
-	 * Get all the shares for a given path
1391
-	 *
1392
-	 * @param \OCP\Files\Node $path
1393
-	 * @param int $page
1394
-	 * @param int $perPage
1395
-	 *
1396
-	 * @return Share[]
1397
-	 */
1398
-	public function getSharesByPath(\OCP\Files\Node $path, $page = 0, $perPage = 50) {
1399
-		return [];
1400
-	}
1401
-
1402
-	/**
1403
-	 * Get the share by token possible with password
1404
-	 *
1405
-	 * @param string $token
1406
-	 * @return IShare
1407
-	 *
1408
-	 * @throws ShareNotFound
1409
-	 */
1410
-	public function getShareByToken($token) {
1411
-		// tokens can't be valid local user names
1412
-		if ($this->userManager->userExists($token)) {
1413
-			throw new ShareNotFound();
1414
-		}
1415
-		$share = null;
1416
-		try {
1417
-			if ($this->shareApiAllowLinks()) {
1418
-				$provider = $this->factory->getProviderForType(IShare::TYPE_LINK);
1419
-				$share = $provider->getShareByToken($token);
1420
-			}
1421
-		} catch (ProviderException $e) {
1422
-		} catch (ShareNotFound $e) {
1423
-		}
1424
-
1425
-
1426
-		// If it is not a link share try to fetch a federated share by token
1427
-		if ($share === null) {
1428
-			try {
1429
-				$provider = $this->factory->getProviderForType(IShare::TYPE_REMOTE);
1430
-				$share = $provider->getShareByToken($token);
1431
-			} catch (ProviderException $e) {
1432
-			} catch (ShareNotFound $e) {
1433
-			}
1434
-		}
1435
-
1436
-		// If it is not a link share try to fetch a mail share by token
1437
-		if ($share === null && $this->shareProviderExists(IShare::TYPE_EMAIL)) {
1438
-			try {
1439
-				$provider = $this->factory->getProviderForType(IShare::TYPE_EMAIL);
1440
-				$share = $provider->getShareByToken($token);
1441
-			} catch (ProviderException $e) {
1442
-			} catch (ShareNotFound $e) {
1443
-			}
1444
-		}
1445
-
1446
-		if ($share === null && $this->shareProviderExists(IShare::TYPE_CIRCLE)) {
1447
-			try {
1448
-				$provider = $this->factory->getProviderForType(IShare::TYPE_CIRCLE);
1449
-				$share = $provider->getShareByToken($token);
1450
-			} catch (ProviderException $e) {
1451
-			} catch (ShareNotFound $e) {
1452
-			}
1453
-		}
1454
-
1455
-		if ($share === null && $this->shareProviderExists(IShare::TYPE_ROOM)) {
1456
-			try {
1457
-				$provider = $this->factory->getProviderForType(IShare::TYPE_ROOM);
1458
-				$share = $provider->getShareByToken($token);
1459
-			} catch (ProviderException $e) {
1460
-			} catch (ShareNotFound $e) {
1461
-			}
1462
-		}
1463
-
1464
-		if ($share === null) {
1465
-			throw new ShareNotFound($this->l->t('The requested share does not exist anymore'));
1466
-		}
1467
-
1468
-		$this->checkExpireDate($share);
1469
-
1470
-		/*
1273
+        $shares2 = [];
1274
+
1275
+        while (true) {
1276
+            $added = 0;
1277
+            foreach ($shares as $share) {
1278
+                try {
1279
+                    $this->checkExpireDate($share);
1280
+                } catch (ShareNotFound $e) {
1281
+                    //Ignore since this basically means the share is deleted
1282
+                    continue;
1283
+                }
1284
+
1285
+                $added++;
1286
+                $shares2[] = $share;
1287
+
1288
+                if (count($shares2) === $limit) {
1289
+                    break;
1290
+                }
1291
+            }
1292
+
1293
+            // If we did not fetch more shares than the limit then there are no more shares
1294
+            if (count($shares) < $limit) {
1295
+                break;
1296
+            }
1297
+
1298
+            if (count($shares2) === $limit) {
1299
+                break;
1300
+            }
1301
+
1302
+            // If there was no limit on the select we are done
1303
+            if ($limit === -1) {
1304
+                break;
1305
+            }
1306
+
1307
+            $offset += $added;
1308
+
1309
+            // Fetch again $limit shares
1310
+            $shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
1311
+
1312
+            // No more shares means we are done
1313
+            if (empty($shares)) {
1314
+                break;
1315
+            }
1316
+        }
1317
+
1318
+        $shares = $shares2;
1319
+
1320
+        return $shares;
1321
+    }
1322
+
1323
+    /**
1324
+     * @inheritdoc
1325
+     */
1326
+    public function getSharedWith($userId, $shareType, $node = null, $limit = 50, $offset = 0) {
1327
+        try {
1328
+            $provider = $this->factory->getProviderForType($shareType);
1329
+        } catch (ProviderException $e) {
1330
+            return [];
1331
+        }
1332
+
1333
+        $shares = $provider->getSharedWith($userId, $shareType, $node, $limit, $offset);
1334
+
1335
+        // remove all shares which are already expired
1336
+        foreach ($shares as $key => $share) {
1337
+            try {
1338
+                $this->checkExpireDate($share);
1339
+            } catch (ShareNotFound $e) {
1340
+                unset($shares[$key]);
1341
+            }
1342
+        }
1343
+
1344
+        return $shares;
1345
+    }
1346
+
1347
+    /**
1348
+     * @inheritdoc
1349
+     */
1350
+    public function getDeletedSharedWith($userId, $shareType, $node = null, $limit = 50, $offset = 0) {
1351
+        $shares = $this->getSharedWith($userId, $shareType, $node, $limit, $offset);
1352
+
1353
+        // Only get deleted shares
1354
+        $shares = array_filter($shares, function (IShare $share) {
1355
+            return $share->getPermissions() === 0;
1356
+        });
1357
+
1358
+        // Only get shares where the owner still exists
1359
+        $shares = array_filter($shares, function (IShare $share) {
1360
+            return $this->userManager->userExists($share->getShareOwner());
1361
+        });
1362
+
1363
+        return $shares;
1364
+    }
1365
+
1366
+    /**
1367
+     * @inheritdoc
1368
+     */
1369
+    public function getShareById($id, $recipient = null) {
1370
+        if ($id === null) {
1371
+            throw new ShareNotFound();
1372
+        }
1373
+
1374
+        list($providerId, $id) = $this->splitFullId($id);
1375
+
1376
+        try {
1377
+            $provider = $this->factory->getProvider($providerId);
1378
+        } catch (ProviderException $e) {
1379
+            throw new ShareNotFound();
1380
+        }
1381
+
1382
+        $share = $provider->getShareById($id, $recipient);
1383
+
1384
+        $this->checkExpireDate($share);
1385
+
1386
+        return $share;
1387
+    }
1388
+
1389
+    /**
1390
+     * Get all the shares for a given path
1391
+     *
1392
+     * @param \OCP\Files\Node $path
1393
+     * @param int $page
1394
+     * @param int $perPage
1395
+     *
1396
+     * @return Share[]
1397
+     */
1398
+    public function getSharesByPath(\OCP\Files\Node $path, $page = 0, $perPage = 50) {
1399
+        return [];
1400
+    }
1401
+
1402
+    /**
1403
+     * Get the share by token possible with password
1404
+     *
1405
+     * @param string $token
1406
+     * @return IShare
1407
+     *
1408
+     * @throws ShareNotFound
1409
+     */
1410
+    public function getShareByToken($token) {
1411
+        // tokens can't be valid local user names
1412
+        if ($this->userManager->userExists($token)) {
1413
+            throw new ShareNotFound();
1414
+        }
1415
+        $share = null;
1416
+        try {
1417
+            if ($this->shareApiAllowLinks()) {
1418
+                $provider = $this->factory->getProviderForType(IShare::TYPE_LINK);
1419
+                $share = $provider->getShareByToken($token);
1420
+            }
1421
+        } catch (ProviderException $e) {
1422
+        } catch (ShareNotFound $e) {
1423
+        }
1424
+
1425
+
1426
+        // If it is not a link share try to fetch a federated share by token
1427
+        if ($share === null) {
1428
+            try {
1429
+                $provider = $this->factory->getProviderForType(IShare::TYPE_REMOTE);
1430
+                $share = $provider->getShareByToken($token);
1431
+            } catch (ProviderException $e) {
1432
+            } catch (ShareNotFound $e) {
1433
+            }
1434
+        }
1435
+
1436
+        // If it is not a link share try to fetch a mail share by token
1437
+        if ($share === null && $this->shareProviderExists(IShare::TYPE_EMAIL)) {
1438
+            try {
1439
+                $provider = $this->factory->getProviderForType(IShare::TYPE_EMAIL);
1440
+                $share = $provider->getShareByToken($token);
1441
+            } catch (ProviderException $e) {
1442
+            } catch (ShareNotFound $e) {
1443
+            }
1444
+        }
1445
+
1446
+        if ($share === null && $this->shareProviderExists(IShare::TYPE_CIRCLE)) {
1447
+            try {
1448
+                $provider = $this->factory->getProviderForType(IShare::TYPE_CIRCLE);
1449
+                $share = $provider->getShareByToken($token);
1450
+            } catch (ProviderException $e) {
1451
+            } catch (ShareNotFound $e) {
1452
+            }
1453
+        }
1454
+
1455
+        if ($share === null && $this->shareProviderExists(IShare::TYPE_ROOM)) {
1456
+            try {
1457
+                $provider = $this->factory->getProviderForType(IShare::TYPE_ROOM);
1458
+                $share = $provider->getShareByToken($token);
1459
+            } catch (ProviderException $e) {
1460
+            } catch (ShareNotFound $e) {
1461
+            }
1462
+        }
1463
+
1464
+        if ($share === null) {
1465
+            throw new ShareNotFound($this->l->t('The requested share does not exist anymore'));
1466
+        }
1467
+
1468
+        $this->checkExpireDate($share);
1469
+
1470
+        /*
1471 1471
 		 * Reduce the permissions for link shares if public upload is not enabled
1472 1472
 		 */
1473
-		if ($share->getShareType() === IShare::TYPE_LINK &&
1474
-			!$this->shareApiLinkAllowPublicUpload()) {
1475
-			$share->setPermissions($share->getPermissions() & ~(\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE));
1476
-		}
1477
-
1478
-		return $share;
1479
-	}
1480
-
1481
-	protected function checkExpireDate($share) {
1482
-		if ($share->isExpired()) {
1483
-			$this->deleteShare($share);
1484
-			throw new ShareNotFound($this->l->t('The requested share does not exist anymore'));
1485
-		}
1486
-	}
1487
-
1488
-	/**
1489
-	 * Verify the password of a public share
1490
-	 *
1491
-	 * @param IShare $share
1492
-	 * @param string $password
1493
-	 * @return bool
1494
-	 */
1495
-	public function checkPassword(IShare $share, $password) {
1496
-		$passwordProtected = $share->getShareType() !== IShare::TYPE_LINK
1497
-							 || $share->getShareType() !== IShare::TYPE_EMAIL
1498
-							 || $share->getShareType() !== IShare::TYPE_CIRCLE;
1499
-		if (!$passwordProtected) {
1500
-			//TODO maybe exception?
1501
-			return false;
1502
-		}
1503
-
1504
-		if ($password === null || $share->getPassword() === null) {
1505
-			return false;
1506
-		}
1507
-
1508
-		$newHash = '';
1509
-		if (!$this->hasher->verify($password, $share->getPassword(), $newHash)) {
1510
-			return false;
1511
-		}
1512
-
1513
-		if (!empty($newHash)) {
1514
-			$share->setPassword($newHash);
1515
-			$provider = $this->factory->getProviderForType($share->getShareType());
1516
-			$provider->update($share);
1517
-		}
1518
-
1519
-		return true;
1520
-	}
1521
-
1522
-	/**
1523
-	 * @inheritdoc
1524
-	 */
1525
-	public function userDeleted($uid) {
1526
-		$types = [IShare::TYPE_USER, IShare::TYPE_GROUP, IShare::TYPE_LINK, IShare::TYPE_REMOTE, IShare::TYPE_EMAIL];
1527
-
1528
-		foreach ($types as $type) {
1529
-			try {
1530
-				$provider = $this->factory->getProviderForType($type);
1531
-			} catch (ProviderException $e) {
1532
-				continue;
1533
-			}
1534
-			$provider->userDeleted($uid, $type);
1535
-		}
1536
-	}
1537
-
1538
-	/**
1539
-	 * @inheritdoc
1540
-	 */
1541
-	public function groupDeleted($gid) {
1542
-		$provider = $this->factory->getProviderForType(IShare::TYPE_GROUP);
1543
-		$provider->groupDeleted($gid);
1544
-
1545
-		$excludedGroups = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
1546
-		if ($excludedGroups === '') {
1547
-			return;
1548
-		}
1549
-
1550
-		$excludedGroups = json_decode($excludedGroups, true);
1551
-		if (json_last_error() !== JSON_ERROR_NONE) {
1552
-			return;
1553
-		}
1554
-
1555
-		$excludedGroups = array_diff($excludedGroups, [$gid]);
1556
-		$this->config->setAppValue('core', 'shareapi_exclude_groups_list', json_encode($excludedGroups));
1557
-	}
1558
-
1559
-	/**
1560
-	 * @inheritdoc
1561
-	 */
1562
-	public function userDeletedFromGroup($uid, $gid) {
1563
-		$provider = $this->factory->getProviderForType(IShare::TYPE_GROUP);
1564
-		$provider->userDeletedFromGroup($uid, $gid);
1565
-	}
1566
-
1567
-	/**
1568
-	 * Get access list to a path. This means
1569
-	 * all the users that can access a given path.
1570
-	 *
1571
-	 * Consider:
1572
-	 * -root
1573
-	 * |-folder1 (23)
1574
-	 *  |-folder2 (32)
1575
-	 *   |-fileA (42)
1576
-	 *
1577
-	 * fileA is shared with user1 and user1@server1
1578
-	 * folder2 is shared with group2 (user4 is a member of group2)
1579
-	 * folder1 is shared with user2 (renamed to "folder (1)") and user2@server2
1580
-	 *
1581
-	 * Then the access list to '/folder1/folder2/fileA' with $currentAccess is:
1582
-	 * [
1583
-	 *  users  => [
1584
-	 *      'user1' => ['node_id' => 42, 'node_path' => '/fileA'],
1585
-	 *      'user4' => ['node_id' => 32, 'node_path' => '/folder2'],
1586
-	 *      'user2' => ['node_id' => 23, 'node_path' => '/folder (1)'],
1587
-	 *  ],
1588
-	 *  remote => [
1589
-	 *      'user1@server1' => ['node_id' => 42, 'token' => 'SeCr3t'],
1590
-	 *      'user2@server2' => ['node_id' => 23, 'token' => 'FooBaR'],
1591
-	 *  ],
1592
-	 *  public => bool
1593
-	 *  mail => bool
1594
-	 * ]
1595
-	 *
1596
-	 * The access list to '/folder1/folder2/fileA' **without** $currentAccess is:
1597
-	 * [
1598
-	 *  users  => ['user1', 'user2', 'user4'],
1599
-	 *  remote => bool,
1600
-	 *  public => bool
1601
-	 *  mail => bool
1602
-	 * ]
1603
-	 *
1604
-	 * This is required for encryption/activity
1605
-	 *
1606
-	 * @param \OCP\Files\Node $path
1607
-	 * @param bool $recursive Should we check all parent folders as well
1608
-	 * @param bool $currentAccess Ensure the recipient has access to the file (e.g. did not unshare it)
1609
-	 * @return array
1610
-	 */
1611
-	public function getAccessList(\OCP\Files\Node $path, $recursive = true, $currentAccess = false) {
1612
-		$owner = $path->getOwner();
1613
-
1614
-		if ($owner === null) {
1615
-			return [];
1616
-		}
1617
-
1618
-		$owner = $owner->getUID();
1619
-
1620
-		if ($currentAccess) {
1621
-			$al = ['users' => [], 'remote' => [], 'public' => false];
1622
-		} else {
1623
-			$al = ['users' => [], 'remote' => false, 'public' => false];
1624
-		}
1625
-		if (!$this->userManager->userExists($owner)) {
1626
-			return $al;
1627
-		}
1628
-
1629
-		//Get node for the owner and correct the owner in case of external storages
1630
-		$userFolder = $this->rootFolder->getUserFolder($owner);
1631
-		if ($path->getId() !== $userFolder->getId() && !$userFolder->isSubNode($path)) {
1632
-			$nodes = $userFolder->getById($path->getId());
1633
-			$path = array_shift($nodes);
1634
-			if ($path->getOwner() === null) {
1635
-				return [];
1636
-			}
1637
-			$owner = $path->getOwner()->getUID();
1638
-		}
1639
-
1640
-		$providers = $this->factory->getAllProviders();
1641
-
1642
-		/** @var Node[] $nodes */
1643
-		$nodes = [];
1644
-
1645
-
1646
-		if ($currentAccess) {
1647
-			$ownerPath = $path->getPath();
1648
-			$ownerPath = explode('/', $ownerPath, 4);
1649
-			if (count($ownerPath) < 4) {
1650
-				$ownerPath = '';
1651
-			} else {
1652
-				$ownerPath = $ownerPath[3];
1653
-			}
1654
-			$al['users'][$owner] = [
1655
-				'node_id' => $path->getId(),
1656
-				'node_path' => '/' . $ownerPath,
1657
-			];
1658
-		} else {
1659
-			$al['users'][] = $owner;
1660
-		}
1661
-
1662
-		// Collect all the shares
1663
-		while ($path->getPath() !== $userFolder->getPath()) {
1664
-			$nodes[] = $path;
1665
-			if (!$recursive) {
1666
-				break;
1667
-			}
1668
-			$path = $path->getParent();
1669
-		}
1670
-
1671
-		foreach ($providers as $provider) {
1672
-			$tmp = $provider->getAccessList($nodes, $currentAccess);
1673
-
1674
-			foreach ($tmp as $k => $v) {
1675
-				if (isset($al[$k])) {
1676
-					if (is_array($al[$k])) {
1677
-						if ($currentAccess) {
1678
-							$al[$k] += $v;
1679
-						} else {
1680
-							$al[$k] = array_merge($al[$k], $v);
1681
-							$al[$k] = array_unique($al[$k]);
1682
-							$al[$k] = array_values($al[$k]);
1683
-						}
1684
-					} else {
1685
-						$al[$k] = $al[$k] || $v;
1686
-					}
1687
-				} else {
1688
-					$al[$k] = $v;
1689
-				}
1690
-			}
1691
-		}
1692
-
1693
-		return $al;
1694
-	}
1695
-
1696
-	/**
1697
-	 * Create a new share
1698
-	 *
1699
-	 * @return IShare
1700
-	 */
1701
-	public function newShare() {
1702
-		return new \OC\Share20\Share($this->rootFolder, $this->userManager);
1703
-	}
1704
-
1705
-	/**
1706
-	 * Is the share API enabled
1707
-	 *
1708
-	 * @return bool
1709
-	 */
1710
-	public function shareApiEnabled() {
1711
-		return $this->config->getAppValue('core', 'shareapi_enabled', 'yes') === 'yes';
1712
-	}
1713
-
1714
-	/**
1715
-	 * Is public link sharing enabled
1716
-	 *
1717
-	 * @return bool
1718
-	 */
1719
-	public function shareApiAllowLinks() {
1720
-		return $this->config->getAppValue('core', 'shareapi_allow_links', 'yes') === 'yes';
1721
-	}
1722
-
1723
-	/**
1724
-	 * Is password on public link requires
1725
-	 *
1726
-	 * @return bool
1727
-	 */
1728
-	public function shareApiLinkEnforcePassword() {
1729
-		return $this->config->getAppValue('core', 'shareapi_enforce_links_password', 'no') === 'yes';
1730
-	}
1731
-
1732
-	/**
1733
-	 * Is default link expire date enabled
1734
-	 *
1735
-	 * @return bool
1736
-	 */
1737
-	public function shareApiLinkDefaultExpireDate() {
1738
-		return $this->config->getAppValue('core', 'shareapi_default_expire_date', 'no') === 'yes';
1739
-	}
1740
-
1741
-	/**
1742
-	 * Is default link expire date enforced
1743
-	 *`
1744
-	 * @return bool
1745
-	 */
1746
-	public function shareApiLinkDefaultExpireDateEnforced() {
1747
-		return $this->shareApiLinkDefaultExpireDate() &&
1748
-			$this->config->getAppValue('core', 'shareapi_enforce_expire_date', 'no') === 'yes';
1749
-	}
1750
-
1751
-
1752
-	/**
1753
-	 * Number of default link expire days
1754
-	 * @return int
1755
-	 */
1756
-	public function shareApiLinkDefaultExpireDays() {
1757
-		return (int)$this->config->getAppValue('core', 'shareapi_expire_after_n_days', '7');
1758
-	}
1759
-
1760
-	/**
1761
-	 * Is default internal expire date enabled
1762
-	 *
1763
-	 * @return bool
1764
-	 */
1765
-	public function shareApiInternalDefaultExpireDate(): bool {
1766
-		return $this->config->getAppValue('core', 'shareapi_default_internal_expire_date', 'no') === 'yes';
1767
-	}
1768
-
1769
-	/**
1770
-	 * Is default expire date enforced
1771
-	 *`
1772
-	 * @return bool
1773
-	 */
1774
-	public function shareApiInternalDefaultExpireDateEnforced(): bool {
1775
-		return $this->shareApiInternalDefaultExpireDate() &&
1776
-			$this->config->getAppValue('core', 'shareapi_enforce_internal_expire_date', 'no') === 'yes';
1777
-	}
1778
-
1779
-
1780
-	/**
1781
-	 * Number of default expire days
1782
-	 * @return int
1783
-	 */
1784
-	public function shareApiInternalDefaultExpireDays(): int {
1785
-		return (int)$this->config->getAppValue('core', 'shareapi_internal_expire_after_n_days', '7');
1786
-	}
1787
-
1788
-	/**
1789
-	 * Allow public upload on link shares
1790
-	 *
1791
-	 * @return bool
1792
-	 */
1793
-	public function shareApiLinkAllowPublicUpload() {
1794
-		return $this->config->getAppValue('core', 'shareapi_allow_public_upload', 'yes') === 'yes';
1795
-	}
1796
-
1797
-	/**
1798
-	 * check if user can only share with group members
1799
-	 * @return bool
1800
-	 */
1801
-	public function shareWithGroupMembersOnly() {
1802
-		return $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
1803
-	}
1804
-
1805
-	/**
1806
-	 * Check if users can share with groups
1807
-	 * @return bool
1808
-	 */
1809
-	public function allowGroupSharing() {
1810
-		return $this->config->getAppValue('core', 'shareapi_allow_group_sharing', 'yes') === 'yes';
1811
-	}
1812
-
1813
-	public function allowEnumeration(): bool {
1814
-		return $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes';
1815
-	}
1816
-
1817
-	public function limitEnumerationToGroups(): bool {
1818
-		return $this->allowEnumeration() &&
1819
-			$this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes';
1820
-	}
1821
-
1822
-	/**
1823
-	 * Copied from \OC_Util::isSharingDisabledForUser
1824
-	 *
1825
-	 * TODO: Deprecate fuction from OC_Util
1826
-	 *
1827
-	 * @param string $userId
1828
-	 * @return bool
1829
-	 */
1830
-	public function sharingDisabledForUser($userId) {
1831
-		if ($userId === null) {
1832
-			return false;
1833
-		}
1834
-
1835
-		if (isset($this->sharingDisabledForUsersCache[$userId])) {
1836
-			return $this->sharingDisabledForUsersCache[$userId];
1837
-		}
1838
-
1839
-		if ($this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes') {
1840
-			$groupsList = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
1841
-			$excludedGroups = json_decode($groupsList);
1842
-			if (is_null($excludedGroups)) {
1843
-				$excludedGroups = explode(',', $groupsList);
1844
-				$newValue = json_encode($excludedGroups);
1845
-				$this->config->setAppValue('core', 'shareapi_exclude_groups_list', $newValue);
1846
-			}
1847
-			$user = $this->userManager->get($userId);
1848
-			$usersGroups = $this->groupManager->getUserGroupIds($user);
1849
-			if (!empty($usersGroups)) {
1850
-				$remainingGroups = array_diff($usersGroups, $excludedGroups);
1851
-				// if the user is only in groups which are disabled for sharing then
1852
-				// sharing is also disabled for the user
1853
-				if (empty($remainingGroups)) {
1854
-					$this->sharingDisabledForUsersCache[$userId] = true;
1855
-					return true;
1856
-				}
1857
-			}
1858
-		}
1859
-
1860
-		$this->sharingDisabledForUsersCache[$userId] = false;
1861
-		return false;
1862
-	}
1863
-
1864
-	/**
1865
-	 * @inheritdoc
1866
-	 */
1867
-	public function outgoingServer2ServerSharesAllowed() {
1868
-		return $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') === 'yes';
1869
-	}
1870
-
1871
-	/**
1872
-	 * @inheritdoc
1873
-	 */
1874
-	public function outgoingServer2ServerGroupSharesAllowed() {
1875
-		return $this->config->getAppValue('files_sharing', 'outgoing_server2server_group_share_enabled', 'no') === 'yes';
1876
-	}
1877
-
1878
-	/**
1879
-	 * @inheritdoc
1880
-	 */
1881
-	public function shareProviderExists($shareType) {
1882
-		try {
1883
-			$this->factory->getProviderForType($shareType);
1884
-		} catch (ProviderException $e) {
1885
-			return false;
1886
-		}
1887
-
1888
-		return true;
1889
-	}
1890
-
1891
-	public function registerShareProvider(string $shareProviderClass): void {
1892
-		$this->factory->registerProvider($shareProviderClass);
1893
-	}
1894
-
1895
-	public function getAllShares(): iterable {
1896
-		$providers = $this->factory->getAllProviders();
1897
-
1898
-		foreach ($providers as $provider) {
1899
-			yield from $provider->getAllShares();
1900
-		}
1901
-	}
1473
+        if ($share->getShareType() === IShare::TYPE_LINK &&
1474
+            !$this->shareApiLinkAllowPublicUpload()) {
1475
+            $share->setPermissions($share->getPermissions() & ~(\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE));
1476
+        }
1477
+
1478
+        return $share;
1479
+    }
1480
+
1481
+    protected function checkExpireDate($share) {
1482
+        if ($share->isExpired()) {
1483
+            $this->deleteShare($share);
1484
+            throw new ShareNotFound($this->l->t('The requested share does not exist anymore'));
1485
+        }
1486
+    }
1487
+
1488
+    /**
1489
+     * Verify the password of a public share
1490
+     *
1491
+     * @param IShare $share
1492
+     * @param string $password
1493
+     * @return bool
1494
+     */
1495
+    public function checkPassword(IShare $share, $password) {
1496
+        $passwordProtected = $share->getShareType() !== IShare::TYPE_LINK
1497
+                             || $share->getShareType() !== IShare::TYPE_EMAIL
1498
+                             || $share->getShareType() !== IShare::TYPE_CIRCLE;
1499
+        if (!$passwordProtected) {
1500
+            //TODO maybe exception?
1501
+            return false;
1502
+        }
1503
+
1504
+        if ($password === null || $share->getPassword() === null) {
1505
+            return false;
1506
+        }
1507
+
1508
+        $newHash = '';
1509
+        if (!$this->hasher->verify($password, $share->getPassword(), $newHash)) {
1510
+            return false;
1511
+        }
1512
+
1513
+        if (!empty($newHash)) {
1514
+            $share->setPassword($newHash);
1515
+            $provider = $this->factory->getProviderForType($share->getShareType());
1516
+            $provider->update($share);
1517
+        }
1518
+
1519
+        return true;
1520
+    }
1521
+
1522
+    /**
1523
+     * @inheritdoc
1524
+     */
1525
+    public function userDeleted($uid) {
1526
+        $types = [IShare::TYPE_USER, IShare::TYPE_GROUP, IShare::TYPE_LINK, IShare::TYPE_REMOTE, IShare::TYPE_EMAIL];
1527
+
1528
+        foreach ($types as $type) {
1529
+            try {
1530
+                $provider = $this->factory->getProviderForType($type);
1531
+            } catch (ProviderException $e) {
1532
+                continue;
1533
+            }
1534
+            $provider->userDeleted($uid, $type);
1535
+        }
1536
+    }
1537
+
1538
+    /**
1539
+     * @inheritdoc
1540
+     */
1541
+    public function groupDeleted($gid) {
1542
+        $provider = $this->factory->getProviderForType(IShare::TYPE_GROUP);
1543
+        $provider->groupDeleted($gid);
1544
+
1545
+        $excludedGroups = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
1546
+        if ($excludedGroups === '') {
1547
+            return;
1548
+        }
1549
+
1550
+        $excludedGroups = json_decode($excludedGroups, true);
1551
+        if (json_last_error() !== JSON_ERROR_NONE) {
1552
+            return;
1553
+        }
1554
+
1555
+        $excludedGroups = array_diff($excludedGroups, [$gid]);
1556
+        $this->config->setAppValue('core', 'shareapi_exclude_groups_list', json_encode($excludedGroups));
1557
+    }
1558
+
1559
+    /**
1560
+     * @inheritdoc
1561
+     */
1562
+    public function userDeletedFromGroup($uid, $gid) {
1563
+        $provider = $this->factory->getProviderForType(IShare::TYPE_GROUP);
1564
+        $provider->userDeletedFromGroup($uid, $gid);
1565
+    }
1566
+
1567
+    /**
1568
+     * Get access list to a path. This means
1569
+     * all the users that can access a given path.
1570
+     *
1571
+     * Consider:
1572
+     * -root
1573
+     * |-folder1 (23)
1574
+     *  |-folder2 (32)
1575
+     *   |-fileA (42)
1576
+     *
1577
+     * fileA is shared with user1 and user1@server1
1578
+     * folder2 is shared with group2 (user4 is a member of group2)
1579
+     * folder1 is shared with user2 (renamed to "folder (1)") and user2@server2
1580
+     *
1581
+     * Then the access list to '/folder1/folder2/fileA' with $currentAccess is:
1582
+     * [
1583
+     *  users  => [
1584
+     *      'user1' => ['node_id' => 42, 'node_path' => '/fileA'],
1585
+     *      'user4' => ['node_id' => 32, 'node_path' => '/folder2'],
1586
+     *      'user2' => ['node_id' => 23, 'node_path' => '/folder (1)'],
1587
+     *  ],
1588
+     *  remote => [
1589
+     *      'user1@server1' => ['node_id' => 42, 'token' => 'SeCr3t'],
1590
+     *      'user2@server2' => ['node_id' => 23, 'token' => 'FooBaR'],
1591
+     *  ],
1592
+     *  public => bool
1593
+     *  mail => bool
1594
+     * ]
1595
+     *
1596
+     * The access list to '/folder1/folder2/fileA' **without** $currentAccess is:
1597
+     * [
1598
+     *  users  => ['user1', 'user2', 'user4'],
1599
+     *  remote => bool,
1600
+     *  public => bool
1601
+     *  mail => bool
1602
+     * ]
1603
+     *
1604
+     * This is required for encryption/activity
1605
+     *
1606
+     * @param \OCP\Files\Node $path
1607
+     * @param bool $recursive Should we check all parent folders as well
1608
+     * @param bool $currentAccess Ensure the recipient has access to the file (e.g. did not unshare it)
1609
+     * @return array
1610
+     */
1611
+    public function getAccessList(\OCP\Files\Node $path, $recursive = true, $currentAccess = false) {
1612
+        $owner = $path->getOwner();
1613
+
1614
+        if ($owner === null) {
1615
+            return [];
1616
+        }
1617
+
1618
+        $owner = $owner->getUID();
1619
+
1620
+        if ($currentAccess) {
1621
+            $al = ['users' => [], 'remote' => [], 'public' => false];
1622
+        } else {
1623
+            $al = ['users' => [], 'remote' => false, 'public' => false];
1624
+        }
1625
+        if (!$this->userManager->userExists($owner)) {
1626
+            return $al;
1627
+        }
1628
+
1629
+        //Get node for the owner and correct the owner in case of external storages
1630
+        $userFolder = $this->rootFolder->getUserFolder($owner);
1631
+        if ($path->getId() !== $userFolder->getId() && !$userFolder->isSubNode($path)) {
1632
+            $nodes = $userFolder->getById($path->getId());
1633
+            $path = array_shift($nodes);
1634
+            if ($path->getOwner() === null) {
1635
+                return [];
1636
+            }
1637
+            $owner = $path->getOwner()->getUID();
1638
+        }
1639
+
1640
+        $providers = $this->factory->getAllProviders();
1641
+
1642
+        /** @var Node[] $nodes */
1643
+        $nodes = [];
1644
+
1645
+
1646
+        if ($currentAccess) {
1647
+            $ownerPath = $path->getPath();
1648
+            $ownerPath = explode('/', $ownerPath, 4);
1649
+            if (count($ownerPath) < 4) {
1650
+                $ownerPath = '';
1651
+            } else {
1652
+                $ownerPath = $ownerPath[3];
1653
+            }
1654
+            $al['users'][$owner] = [
1655
+                'node_id' => $path->getId(),
1656
+                'node_path' => '/' . $ownerPath,
1657
+            ];
1658
+        } else {
1659
+            $al['users'][] = $owner;
1660
+        }
1661
+
1662
+        // Collect all the shares
1663
+        while ($path->getPath() !== $userFolder->getPath()) {
1664
+            $nodes[] = $path;
1665
+            if (!$recursive) {
1666
+                break;
1667
+            }
1668
+            $path = $path->getParent();
1669
+        }
1670
+
1671
+        foreach ($providers as $provider) {
1672
+            $tmp = $provider->getAccessList($nodes, $currentAccess);
1673
+
1674
+            foreach ($tmp as $k => $v) {
1675
+                if (isset($al[$k])) {
1676
+                    if (is_array($al[$k])) {
1677
+                        if ($currentAccess) {
1678
+                            $al[$k] += $v;
1679
+                        } else {
1680
+                            $al[$k] = array_merge($al[$k], $v);
1681
+                            $al[$k] = array_unique($al[$k]);
1682
+                            $al[$k] = array_values($al[$k]);
1683
+                        }
1684
+                    } else {
1685
+                        $al[$k] = $al[$k] || $v;
1686
+                    }
1687
+                } else {
1688
+                    $al[$k] = $v;
1689
+                }
1690
+            }
1691
+        }
1692
+
1693
+        return $al;
1694
+    }
1695
+
1696
+    /**
1697
+     * Create a new share
1698
+     *
1699
+     * @return IShare
1700
+     */
1701
+    public function newShare() {
1702
+        return new \OC\Share20\Share($this->rootFolder, $this->userManager);
1703
+    }
1704
+
1705
+    /**
1706
+     * Is the share API enabled
1707
+     *
1708
+     * @return bool
1709
+     */
1710
+    public function shareApiEnabled() {
1711
+        return $this->config->getAppValue('core', 'shareapi_enabled', 'yes') === 'yes';
1712
+    }
1713
+
1714
+    /**
1715
+     * Is public link sharing enabled
1716
+     *
1717
+     * @return bool
1718
+     */
1719
+    public function shareApiAllowLinks() {
1720
+        return $this->config->getAppValue('core', 'shareapi_allow_links', 'yes') === 'yes';
1721
+    }
1722
+
1723
+    /**
1724
+     * Is password on public link requires
1725
+     *
1726
+     * @return bool
1727
+     */
1728
+    public function shareApiLinkEnforcePassword() {
1729
+        return $this->config->getAppValue('core', 'shareapi_enforce_links_password', 'no') === 'yes';
1730
+    }
1731
+
1732
+    /**
1733
+     * Is default link expire date enabled
1734
+     *
1735
+     * @return bool
1736
+     */
1737
+    public function shareApiLinkDefaultExpireDate() {
1738
+        return $this->config->getAppValue('core', 'shareapi_default_expire_date', 'no') === 'yes';
1739
+    }
1740
+
1741
+    /**
1742
+     * Is default link expire date enforced
1743
+     *`
1744
+     * @return bool
1745
+     */
1746
+    public function shareApiLinkDefaultExpireDateEnforced() {
1747
+        return $this->shareApiLinkDefaultExpireDate() &&
1748
+            $this->config->getAppValue('core', 'shareapi_enforce_expire_date', 'no') === 'yes';
1749
+    }
1750
+
1751
+
1752
+    /**
1753
+     * Number of default link expire days
1754
+     * @return int
1755
+     */
1756
+    public function shareApiLinkDefaultExpireDays() {
1757
+        return (int)$this->config->getAppValue('core', 'shareapi_expire_after_n_days', '7');
1758
+    }
1759
+
1760
+    /**
1761
+     * Is default internal expire date enabled
1762
+     *
1763
+     * @return bool
1764
+     */
1765
+    public function shareApiInternalDefaultExpireDate(): bool {
1766
+        return $this->config->getAppValue('core', 'shareapi_default_internal_expire_date', 'no') === 'yes';
1767
+    }
1768
+
1769
+    /**
1770
+     * Is default expire date enforced
1771
+     *`
1772
+     * @return bool
1773
+     */
1774
+    public function shareApiInternalDefaultExpireDateEnforced(): bool {
1775
+        return $this->shareApiInternalDefaultExpireDate() &&
1776
+            $this->config->getAppValue('core', 'shareapi_enforce_internal_expire_date', 'no') === 'yes';
1777
+    }
1778
+
1779
+
1780
+    /**
1781
+     * Number of default expire days
1782
+     * @return int
1783
+     */
1784
+    public function shareApiInternalDefaultExpireDays(): int {
1785
+        return (int)$this->config->getAppValue('core', 'shareapi_internal_expire_after_n_days', '7');
1786
+    }
1787
+
1788
+    /**
1789
+     * Allow public upload on link shares
1790
+     *
1791
+     * @return bool
1792
+     */
1793
+    public function shareApiLinkAllowPublicUpload() {
1794
+        return $this->config->getAppValue('core', 'shareapi_allow_public_upload', 'yes') === 'yes';
1795
+    }
1796
+
1797
+    /**
1798
+     * check if user can only share with group members
1799
+     * @return bool
1800
+     */
1801
+    public function shareWithGroupMembersOnly() {
1802
+        return $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
1803
+    }
1804
+
1805
+    /**
1806
+     * Check if users can share with groups
1807
+     * @return bool
1808
+     */
1809
+    public function allowGroupSharing() {
1810
+        return $this->config->getAppValue('core', 'shareapi_allow_group_sharing', 'yes') === 'yes';
1811
+    }
1812
+
1813
+    public function allowEnumeration(): bool {
1814
+        return $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes';
1815
+    }
1816
+
1817
+    public function limitEnumerationToGroups(): bool {
1818
+        return $this->allowEnumeration() &&
1819
+            $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes';
1820
+    }
1821
+
1822
+    /**
1823
+     * Copied from \OC_Util::isSharingDisabledForUser
1824
+     *
1825
+     * TODO: Deprecate fuction from OC_Util
1826
+     *
1827
+     * @param string $userId
1828
+     * @return bool
1829
+     */
1830
+    public function sharingDisabledForUser($userId) {
1831
+        if ($userId === null) {
1832
+            return false;
1833
+        }
1834
+
1835
+        if (isset($this->sharingDisabledForUsersCache[$userId])) {
1836
+            return $this->sharingDisabledForUsersCache[$userId];
1837
+        }
1838
+
1839
+        if ($this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes') {
1840
+            $groupsList = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
1841
+            $excludedGroups = json_decode($groupsList);
1842
+            if (is_null($excludedGroups)) {
1843
+                $excludedGroups = explode(',', $groupsList);
1844
+                $newValue = json_encode($excludedGroups);
1845
+                $this->config->setAppValue('core', 'shareapi_exclude_groups_list', $newValue);
1846
+            }
1847
+            $user = $this->userManager->get($userId);
1848
+            $usersGroups = $this->groupManager->getUserGroupIds($user);
1849
+            if (!empty($usersGroups)) {
1850
+                $remainingGroups = array_diff($usersGroups, $excludedGroups);
1851
+                // if the user is only in groups which are disabled for sharing then
1852
+                // sharing is also disabled for the user
1853
+                if (empty($remainingGroups)) {
1854
+                    $this->sharingDisabledForUsersCache[$userId] = true;
1855
+                    return true;
1856
+                }
1857
+            }
1858
+        }
1859
+
1860
+        $this->sharingDisabledForUsersCache[$userId] = false;
1861
+        return false;
1862
+    }
1863
+
1864
+    /**
1865
+     * @inheritdoc
1866
+     */
1867
+    public function outgoingServer2ServerSharesAllowed() {
1868
+        return $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') === 'yes';
1869
+    }
1870
+
1871
+    /**
1872
+     * @inheritdoc
1873
+     */
1874
+    public function outgoingServer2ServerGroupSharesAllowed() {
1875
+        return $this->config->getAppValue('files_sharing', 'outgoing_server2server_group_share_enabled', 'no') === 'yes';
1876
+    }
1877
+
1878
+    /**
1879
+     * @inheritdoc
1880
+     */
1881
+    public function shareProviderExists($shareType) {
1882
+        try {
1883
+            $this->factory->getProviderForType($shareType);
1884
+        } catch (ProviderException $e) {
1885
+            return false;
1886
+        }
1887
+
1888
+        return true;
1889
+    }
1890
+
1891
+    public function registerShareProvider(string $shareProviderClass): void {
1892
+        $this->factory->registerProvider($shareProviderClass);
1893
+    }
1894
+
1895
+    public function getAllShares(): iterable {
1896
+        $providers = $this->factory->getAllProviders();
1897
+
1898
+        foreach ($providers as $provider) {
1899
+            yield from $provider->getAllShares();
1900
+        }
1901
+    }
1902 1902
 }
Please login to merge, or discard this patch.
lib/private/Share20/ProviderFactory.php 1 patch
Indentation   +296 added lines, -296 removed lines patch added patch discarded remove patch
@@ -53,309 +53,309 @@
 block discarded – undo
53 53
  */
54 54
 class ProviderFactory implements IProviderFactory {
55 55
 
56
-	/** @var IServerContainer */
57
-	private $serverContainer;
58
-	/** @var DefaultShareProvider */
59
-	private $defaultProvider = null;
60
-	/** @var FederatedShareProvider */
61
-	private $federatedProvider = null;
62
-	/** @var  ShareByMailProvider */
63
-	private $shareByMailProvider;
64
-	/** @var  \OCA\Circles\ShareByCircleProvider */
65
-	private $shareByCircleProvider = null;
66
-	/** @var bool */
67
-	private $circlesAreNotAvailable = false;
68
-	/** @var \OCA\Talk\Share\RoomShareProvider */
69
-	private $roomShareProvider = null;
70
-
71
-	private $registeredShareProviders = [];
72
-
73
-	private $shareProviders = [];
74
-
75
-	/**
76
-	 * IProviderFactory constructor.
77
-	 *
78
-	 * @param IServerContainer $serverContainer
79
-	 */
80
-	public function __construct(IServerContainer $serverContainer) {
81
-		$this->serverContainer = $serverContainer;
82
-	}
83
-
84
-	public function registerProvider(string $shareProviderClass): void {
85
-		$this->registeredShareProviders[] = $shareProviderClass;
86
-	}
87
-
88
-	/**
89
-	 * Create the default share provider.
90
-	 *
91
-	 * @return DefaultShareProvider
92
-	 */
93
-	protected function defaultShareProvider() {
94
-		if ($this->defaultProvider === null) {
95
-			$this->defaultProvider = new DefaultShareProvider(
96
-				$this->serverContainer->getDatabaseConnection(),
97
-				$this->serverContainer->getUserManager(),
98
-				$this->serverContainer->getGroupManager(),
99
-				$this->serverContainer->getLazyRootFolder(),
100
-				$this->serverContainer->getMailer(),
101
-				$this->serverContainer->query(Defaults::class),
102
-				$this->serverContainer->getL10NFactory(),
103
-				$this->serverContainer->getURLGenerator(),
104
-				$this->serverContainer->getConfig()
105
-			);
106
-		}
107
-
108
-		return $this->defaultProvider;
109
-	}
110
-
111
-	/**
112
-	 * Create the federated share provider
113
-	 *
114
-	 * @return FederatedShareProvider
115
-	 */
116
-	protected function federatedShareProvider() {
117
-		if ($this->federatedProvider === null) {
118
-			/*
56
+    /** @var IServerContainer */
57
+    private $serverContainer;
58
+    /** @var DefaultShareProvider */
59
+    private $defaultProvider = null;
60
+    /** @var FederatedShareProvider */
61
+    private $federatedProvider = null;
62
+    /** @var  ShareByMailProvider */
63
+    private $shareByMailProvider;
64
+    /** @var  \OCA\Circles\ShareByCircleProvider */
65
+    private $shareByCircleProvider = null;
66
+    /** @var bool */
67
+    private $circlesAreNotAvailable = false;
68
+    /** @var \OCA\Talk\Share\RoomShareProvider */
69
+    private $roomShareProvider = null;
70
+
71
+    private $registeredShareProviders = [];
72
+
73
+    private $shareProviders = [];
74
+
75
+    /**
76
+     * IProviderFactory constructor.
77
+     *
78
+     * @param IServerContainer $serverContainer
79
+     */
80
+    public function __construct(IServerContainer $serverContainer) {
81
+        $this->serverContainer = $serverContainer;
82
+    }
83
+
84
+    public function registerProvider(string $shareProviderClass): void {
85
+        $this->registeredShareProviders[] = $shareProviderClass;
86
+    }
87
+
88
+    /**
89
+     * Create the default share provider.
90
+     *
91
+     * @return DefaultShareProvider
92
+     */
93
+    protected function defaultShareProvider() {
94
+        if ($this->defaultProvider === null) {
95
+            $this->defaultProvider = new DefaultShareProvider(
96
+                $this->serverContainer->getDatabaseConnection(),
97
+                $this->serverContainer->getUserManager(),
98
+                $this->serverContainer->getGroupManager(),
99
+                $this->serverContainer->getLazyRootFolder(),
100
+                $this->serverContainer->getMailer(),
101
+                $this->serverContainer->query(Defaults::class),
102
+                $this->serverContainer->getL10NFactory(),
103
+                $this->serverContainer->getURLGenerator(),
104
+                $this->serverContainer->getConfig()
105
+            );
106
+        }
107
+
108
+        return $this->defaultProvider;
109
+    }
110
+
111
+    /**
112
+     * Create the federated share provider
113
+     *
114
+     * @return FederatedShareProvider
115
+     */
116
+    protected function federatedShareProvider() {
117
+        if ($this->federatedProvider === null) {
118
+            /*
119 119
 			 * Check if the app is enabled
120 120
 			 */
121
-			$appManager = $this->serverContainer->getAppManager();
122
-			if (!$appManager->isEnabledForUser('federatedfilesharing')) {
123
-				return null;
124
-			}
121
+            $appManager = $this->serverContainer->getAppManager();
122
+            if (!$appManager->isEnabledForUser('federatedfilesharing')) {
123
+                return null;
124
+            }
125 125
 
126
-			/*
126
+            /*
127 127
 			 * TODO: add factory to federated sharing app
128 128
 			 */
129
-			$l = $this->serverContainer->getL10N('federatedfilesharing');
130
-			$addressHandler = new AddressHandler(
131
-				$this->serverContainer->getURLGenerator(),
132
-				$l,
133
-				$this->serverContainer->getCloudIdManager()
134
-			);
135
-			$notifications = new Notifications(
136
-				$addressHandler,
137
-				$this->serverContainer->getHTTPClientService(),
138
-				$this->serverContainer->query(\OCP\OCS\IDiscoveryService::class),
139
-				$this->serverContainer->getJobList(),
140
-				\OC::$server->getCloudFederationProviderManager(),
141
-				\OC::$server->getCloudFederationFactory(),
142
-				$this->serverContainer->query(IEventDispatcher::class)
143
-			);
144
-			$tokenHandler = new TokenHandler(
145
-				$this->serverContainer->getSecureRandom()
146
-			);
147
-
148
-			$this->federatedProvider = new FederatedShareProvider(
149
-				$this->serverContainer->getDatabaseConnection(),
150
-				$addressHandler,
151
-				$notifications,
152
-				$tokenHandler,
153
-				$l,
154
-				$this->serverContainer->getLogger(),
155
-				$this->serverContainer->getLazyRootFolder(),
156
-				$this->serverContainer->getConfig(),
157
-				$this->serverContainer->getUserManager(),
158
-				$this->serverContainer->getCloudIdManager(),
159
-				$this->serverContainer->getGlobalScaleConfig(),
160
-				$this->serverContainer->getCloudFederationProviderManager()
161
-			);
162
-		}
163
-
164
-		return $this->federatedProvider;
165
-	}
166
-
167
-	/**
168
-	 * Create the federated share provider
169
-	 *
170
-	 * @return ShareByMailProvider
171
-	 */
172
-	protected function getShareByMailProvider() {
173
-		if ($this->shareByMailProvider === null) {
174
-			/*
129
+            $l = $this->serverContainer->getL10N('federatedfilesharing');
130
+            $addressHandler = new AddressHandler(
131
+                $this->serverContainer->getURLGenerator(),
132
+                $l,
133
+                $this->serverContainer->getCloudIdManager()
134
+            );
135
+            $notifications = new Notifications(
136
+                $addressHandler,
137
+                $this->serverContainer->getHTTPClientService(),
138
+                $this->serverContainer->query(\OCP\OCS\IDiscoveryService::class),
139
+                $this->serverContainer->getJobList(),
140
+                \OC::$server->getCloudFederationProviderManager(),
141
+                \OC::$server->getCloudFederationFactory(),
142
+                $this->serverContainer->query(IEventDispatcher::class)
143
+            );
144
+            $tokenHandler = new TokenHandler(
145
+                $this->serverContainer->getSecureRandom()
146
+            );
147
+
148
+            $this->federatedProvider = new FederatedShareProvider(
149
+                $this->serverContainer->getDatabaseConnection(),
150
+                $addressHandler,
151
+                $notifications,
152
+                $tokenHandler,
153
+                $l,
154
+                $this->serverContainer->getLogger(),
155
+                $this->serverContainer->getLazyRootFolder(),
156
+                $this->serverContainer->getConfig(),
157
+                $this->serverContainer->getUserManager(),
158
+                $this->serverContainer->getCloudIdManager(),
159
+                $this->serverContainer->getGlobalScaleConfig(),
160
+                $this->serverContainer->getCloudFederationProviderManager()
161
+            );
162
+        }
163
+
164
+        return $this->federatedProvider;
165
+    }
166
+
167
+    /**
168
+     * Create the federated share provider
169
+     *
170
+     * @return ShareByMailProvider
171
+     */
172
+    protected function getShareByMailProvider() {
173
+        if ($this->shareByMailProvider === null) {
174
+            /*
175 175
 			 * Check if the app is enabled
176 176
 			 */
177
-			$appManager = $this->serverContainer->getAppManager();
178
-			if (!$appManager->isEnabledForUser('sharebymail')) {
179
-				return null;
180
-			}
181
-
182
-			$settingsManager = new SettingsManager($this->serverContainer->getConfig());
183
-
184
-			$this->shareByMailProvider = new ShareByMailProvider(
185
-				$this->serverContainer->getDatabaseConnection(),
186
-				$this->serverContainer->getSecureRandom(),
187
-				$this->serverContainer->getUserManager(),
188
-				$this->serverContainer->getLazyRootFolder(),
189
-				$this->serverContainer->getL10N('sharebymail'),
190
-				$this->serverContainer->getLogger(),
191
-				$this->serverContainer->getMailer(),
192
-				$this->serverContainer->getURLGenerator(),
193
-				$this->serverContainer->getActivityManager(),
194
-				$settingsManager,
195
-				$this->serverContainer->query(Defaults::class),
196
-				$this->serverContainer->getHasher(),
197
-				$this->serverContainer->get(IEventDispatcher::class)
198
-			);
199
-		}
200
-
201
-		return $this->shareByMailProvider;
202
-	}
203
-
204
-
205
-	/**
206
-	 * Create the circle share provider
207
-	 *
208
-	 * @return FederatedShareProvider
209
-	 *
210
-	 * @suppress PhanUndeclaredClassMethod
211
-	 */
212
-	protected function getShareByCircleProvider() {
213
-		if ($this->circlesAreNotAvailable) {
214
-			return null;
215
-		}
216
-
217
-		if (!$this->serverContainer->getAppManager()->isEnabledForUser('circles') ||
218
-			!class_exists('\OCA\Circles\ShareByCircleProvider')
219
-		) {
220
-			$this->circlesAreNotAvailable = true;
221
-			return null;
222
-		}
223
-
224
-		if ($this->shareByCircleProvider === null) {
225
-			$this->shareByCircleProvider = new \OCA\Circles\ShareByCircleProvider(
226
-				$this->serverContainer->getDatabaseConnection(),
227
-				$this->serverContainer->getSecureRandom(),
228
-				$this->serverContainer->getUserManager(),
229
-				$this->serverContainer->getLazyRootFolder(),
230
-				$this->serverContainer->getL10N('circles'),
231
-				$this->serverContainer->getLogger(),
232
-				$this->serverContainer->getURLGenerator()
233
-			);
234
-		}
235
-
236
-		return $this->shareByCircleProvider;
237
-	}
238
-
239
-	/**
240
-	 * Create the room share provider
241
-	 *
242
-	 * @return RoomShareProvider
243
-	 */
244
-	protected function getRoomShareProvider() {
245
-		if ($this->roomShareProvider === null) {
246
-			/*
177
+            $appManager = $this->serverContainer->getAppManager();
178
+            if (!$appManager->isEnabledForUser('sharebymail')) {
179
+                return null;
180
+            }
181
+
182
+            $settingsManager = new SettingsManager($this->serverContainer->getConfig());
183
+
184
+            $this->shareByMailProvider = new ShareByMailProvider(
185
+                $this->serverContainer->getDatabaseConnection(),
186
+                $this->serverContainer->getSecureRandom(),
187
+                $this->serverContainer->getUserManager(),
188
+                $this->serverContainer->getLazyRootFolder(),
189
+                $this->serverContainer->getL10N('sharebymail'),
190
+                $this->serverContainer->getLogger(),
191
+                $this->serverContainer->getMailer(),
192
+                $this->serverContainer->getURLGenerator(),
193
+                $this->serverContainer->getActivityManager(),
194
+                $settingsManager,
195
+                $this->serverContainer->query(Defaults::class),
196
+                $this->serverContainer->getHasher(),
197
+                $this->serverContainer->get(IEventDispatcher::class)
198
+            );
199
+        }
200
+
201
+        return $this->shareByMailProvider;
202
+    }
203
+
204
+
205
+    /**
206
+     * Create the circle share provider
207
+     *
208
+     * @return FederatedShareProvider
209
+     *
210
+     * @suppress PhanUndeclaredClassMethod
211
+     */
212
+    protected function getShareByCircleProvider() {
213
+        if ($this->circlesAreNotAvailable) {
214
+            return null;
215
+        }
216
+
217
+        if (!$this->serverContainer->getAppManager()->isEnabledForUser('circles') ||
218
+            !class_exists('\OCA\Circles\ShareByCircleProvider')
219
+        ) {
220
+            $this->circlesAreNotAvailable = true;
221
+            return null;
222
+        }
223
+
224
+        if ($this->shareByCircleProvider === null) {
225
+            $this->shareByCircleProvider = new \OCA\Circles\ShareByCircleProvider(
226
+                $this->serverContainer->getDatabaseConnection(),
227
+                $this->serverContainer->getSecureRandom(),
228
+                $this->serverContainer->getUserManager(),
229
+                $this->serverContainer->getLazyRootFolder(),
230
+                $this->serverContainer->getL10N('circles'),
231
+                $this->serverContainer->getLogger(),
232
+                $this->serverContainer->getURLGenerator()
233
+            );
234
+        }
235
+
236
+        return $this->shareByCircleProvider;
237
+    }
238
+
239
+    /**
240
+     * Create the room share provider
241
+     *
242
+     * @return RoomShareProvider
243
+     */
244
+    protected function getRoomShareProvider() {
245
+        if ($this->roomShareProvider === null) {
246
+            /*
247 247
 			 * Check if the app is enabled
248 248
 			 */
249
-			$appManager = $this->serverContainer->getAppManager();
250
-			if (!$appManager->isEnabledForUser('spreed')) {
251
-				return null;
252
-			}
253
-
254
-			try {
255
-				$this->roomShareProvider = $this->serverContainer->query('\OCA\Talk\Share\RoomShareProvider');
256
-			} catch (\OCP\AppFramework\QueryException $e) {
257
-				return null;
258
-			}
259
-		}
260
-
261
-		return $this->roomShareProvider;
262
-	}
263
-
264
-	/**
265
-	 * @inheritdoc
266
-	 */
267
-	public function getProvider($id) {
268
-		$provider = null;
269
-		if (isset($this->shareProviders[$id])) {
270
-			return $this->shareProviders[$id];
271
-		}
272
-
273
-		if ($id === 'ocinternal') {
274
-			$provider = $this->defaultShareProvider();
275
-		} elseif ($id === 'ocFederatedSharing') {
276
-			$provider = $this->federatedShareProvider();
277
-		} elseif ($id === 'ocMailShare') {
278
-			$provider = $this->getShareByMailProvider();
279
-		} elseif ($id === 'ocCircleShare') {
280
-			$provider = $this->getShareByCircleProvider();
281
-		} elseif ($id === 'ocRoomShare') {
282
-			$provider = $this->getRoomShareProvider();
283
-		}
284
-
285
-		foreach ($this->registeredShareProviders as $shareProvider) {
286
-			/** @var IShareProvider $instance */
287
-			$instance = $this->serverContainer->get($shareProvider);
288
-			$this->shareProviders[$instance->identifier()] = $instance;
289
-		}
290
-
291
-		if (isset($this->shareProviders[$id])) {
292
-			$provider = $this->shareProviders[$id];
293
-		}
294
-
295
-		if ($provider === null) {
296
-			throw new ProviderException('No provider with id .' . $id . ' found.');
297
-		}
298
-
299
-		return $provider;
300
-	}
301
-
302
-	/**
303
-	 * @inheritdoc
304
-	 */
305
-	public function getProviderForType($shareType) {
306
-		$provider = null;
307
-
308
-		if ($shareType === IShare::TYPE_USER ||
309
-			$shareType === IShare::TYPE_GROUP ||
310
-			$shareType === IShare::TYPE_LINK
311
-		) {
312
-			$provider = $this->defaultShareProvider();
313
-		} elseif ($shareType === IShare::TYPE_REMOTE || $shareType === IShare::TYPE_REMOTE_GROUP) {
314
-			$provider = $this->federatedShareProvider();
315
-		} elseif ($shareType === IShare::TYPE_EMAIL) {
316
-			$provider = $this->getShareByMailProvider();
317
-		} elseif ($shareType === IShare::TYPE_CIRCLE) {
318
-			$provider = $this->getShareByCircleProvider();
319
-		} elseif ($shareType === IShare::TYPE_ROOM) {
320
-			$provider = $this->getRoomShareProvider();
321
-		} elseif ($shareType === IShare::TYPE_DECK) {
322
-			$provider = $this->getProvider('deck');
323
-		}
324
-
325
-
326
-		if ($provider === null) {
327
-			throw new ProviderException('No share provider for share type ' . $shareType);
328
-		}
329
-
330
-		return $provider;
331
-	}
332
-
333
-	public function getAllProviders() {
334
-		$shares = [$this->defaultShareProvider(), $this->federatedShareProvider()];
335
-		$shareByMail = $this->getShareByMailProvider();
336
-		if ($shareByMail !== null) {
337
-			$shares[] = $shareByMail;
338
-		}
339
-		$shareByCircle = $this->getShareByCircleProvider();
340
-		if ($shareByCircle !== null) {
341
-			$shares[] = $shareByCircle;
342
-		}
343
-		$roomShare = $this->getRoomShareProvider();
344
-		if ($roomShare !== null) {
345
-			$shares[] = $roomShare;
346
-		}
347
-
348
-		foreach ($this->registeredShareProviders as $shareProvider) {
349
-			/** @var IShareProvider $instance */
350
-			$instance = $this->serverContainer->get($shareProvider);
351
-			if (!isset($this->shareProviders[$instance->identifier()])) {
352
-				$this->shareProviders[$instance->identifier()] = $instance;
353
-			}
354
-			$shares[] = $this->shareProviders[$instance->identifier()];
355
-		}
356
-
357
-
358
-
359
-		return $shares;
360
-	}
249
+            $appManager = $this->serverContainer->getAppManager();
250
+            if (!$appManager->isEnabledForUser('spreed')) {
251
+                return null;
252
+            }
253
+
254
+            try {
255
+                $this->roomShareProvider = $this->serverContainer->query('\OCA\Talk\Share\RoomShareProvider');
256
+            } catch (\OCP\AppFramework\QueryException $e) {
257
+                return null;
258
+            }
259
+        }
260
+
261
+        return $this->roomShareProvider;
262
+    }
263
+
264
+    /**
265
+     * @inheritdoc
266
+     */
267
+    public function getProvider($id) {
268
+        $provider = null;
269
+        if (isset($this->shareProviders[$id])) {
270
+            return $this->shareProviders[$id];
271
+        }
272
+
273
+        if ($id === 'ocinternal') {
274
+            $provider = $this->defaultShareProvider();
275
+        } elseif ($id === 'ocFederatedSharing') {
276
+            $provider = $this->federatedShareProvider();
277
+        } elseif ($id === 'ocMailShare') {
278
+            $provider = $this->getShareByMailProvider();
279
+        } elseif ($id === 'ocCircleShare') {
280
+            $provider = $this->getShareByCircleProvider();
281
+        } elseif ($id === 'ocRoomShare') {
282
+            $provider = $this->getRoomShareProvider();
283
+        }
284
+
285
+        foreach ($this->registeredShareProviders as $shareProvider) {
286
+            /** @var IShareProvider $instance */
287
+            $instance = $this->serverContainer->get($shareProvider);
288
+            $this->shareProviders[$instance->identifier()] = $instance;
289
+        }
290
+
291
+        if (isset($this->shareProviders[$id])) {
292
+            $provider = $this->shareProviders[$id];
293
+        }
294
+
295
+        if ($provider === null) {
296
+            throw new ProviderException('No provider with id .' . $id . ' found.');
297
+        }
298
+
299
+        return $provider;
300
+    }
301
+
302
+    /**
303
+     * @inheritdoc
304
+     */
305
+    public function getProviderForType($shareType) {
306
+        $provider = null;
307
+
308
+        if ($shareType === IShare::TYPE_USER ||
309
+            $shareType === IShare::TYPE_GROUP ||
310
+            $shareType === IShare::TYPE_LINK
311
+        ) {
312
+            $provider = $this->defaultShareProvider();
313
+        } elseif ($shareType === IShare::TYPE_REMOTE || $shareType === IShare::TYPE_REMOTE_GROUP) {
314
+            $provider = $this->federatedShareProvider();
315
+        } elseif ($shareType === IShare::TYPE_EMAIL) {
316
+            $provider = $this->getShareByMailProvider();
317
+        } elseif ($shareType === IShare::TYPE_CIRCLE) {
318
+            $provider = $this->getShareByCircleProvider();
319
+        } elseif ($shareType === IShare::TYPE_ROOM) {
320
+            $provider = $this->getRoomShareProvider();
321
+        } elseif ($shareType === IShare::TYPE_DECK) {
322
+            $provider = $this->getProvider('deck');
323
+        }
324
+
325
+
326
+        if ($provider === null) {
327
+            throw new ProviderException('No share provider for share type ' . $shareType);
328
+        }
329
+
330
+        return $provider;
331
+    }
332
+
333
+    public function getAllProviders() {
334
+        $shares = [$this->defaultShareProvider(), $this->federatedShareProvider()];
335
+        $shareByMail = $this->getShareByMailProvider();
336
+        if ($shareByMail !== null) {
337
+            $shares[] = $shareByMail;
338
+        }
339
+        $shareByCircle = $this->getShareByCircleProvider();
340
+        if ($shareByCircle !== null) {
341
+            $shares[] = $shareByCircle;
342
+        }
343
+        $roomShare = $this->getRoomShareProvider();
344
+        if ($roomShare !== null) {
345
+            $shares[] = $roomShare;
346
+        }
347
+
348
+        foreach ($this->registeredShareProviders as $shareProvider) {
349
+            /** @var IShareProvider $instance */
350
+            $instance = $this->serverContainer->get($shareProvider);
351
+            if (!isset($this->shareProviders[$instance->identifier()])) {
352
+                $this->shareProviders[$instance->identifier()] = $instance;
353
+            }
354
+            $shares[] = $this->shareProviders[$instance->identifier()];
355
+        }
356
+
357
+
358
+
359
+        return $shares;
360
+    }
361 361
 }
Please login to merge, or discard this patch.
apps/dav/lib/Connector/Sabre/SharesPlugin.php 1 patch
Indentation   +178 added lines, -178 removed lines patch added patch discarded remove patch
@@ -36,182 +36,182 @@
 block discarded – undo
36 36
  * Sabre Plugin to provide share-related properties
37 37
  */
38 38
 class SharesPlugin extends \Sabre\DAV\ServerPlugin {
39
-	public const NS_OWNCLOUD = 'http://owncloud.org/ns';
40
-	public const NS_NEXTCLOUD = 'http://nextcloud.org/ns';
41
-	public const SHARETYPES_PROPERTYNAME = '{http://owncloud.org/ns}share-types';
42
-	public const SHAREES_PROPERTYNAME = '{http://nextcloud.org/ns}sharees';
43
-
44
-	/**
45
-	 * Reference to main server object
46
-	 *
47
-	 * @var \Sabre\DAV\Server
48
-	 */
49
-	private $server;
50
-
51
-	/**
52
-	 * @var \OCP\Share\IManager
53
-	 */
54
-	private $shareManager;
55
-
56
-	/**
57
-	 * @var \Sabre\DAV\Tree
58
-	 */
59
-	private $tree;
60
-
61
-	/**
62
-	 * @var string
63
-	 */
64
-	private $userId;
65
-
66
-	/**
67
-	 * @var \OCP\Files\Folder
68
-	 */
69
-	private $userFolder;
70
-
71
-	/** @var IShare[] */
72
-	private $cachedShares = [];
73
-
74
-	private $cachedFolders = [];
75
-
76
-	/**
77
-	 * @param \Sabre\DAV\Tree $tree tree
78
-	 * @param IUserSession $userSession user session
79
-	 * @param \OCP\Files\Folder $userFolder user home folder
80
-	 * @param \OCP\Share\IManager $shareManager share manager
81
-	 */
82
-	public function __construct(
83
-		\Sabre\DAV\Tree $tree,
84
-		IUserSession $userSession,
85
-		\OCP\Files\Folder $userFolder,
86
-		\OCP\Share\IManager $shareManager
87
-	) {
88
-		$this->tree = $tree;
89
-		$this->shareManager = $shareManager;
90
-		$this->userFolder = $userFolder;
91
-		$this->userId = $userSession->getUser()->getUID();
92
-	}
93
-
94
-	/**
95
-	 * This initializes the plugin.
96
-	 *
97
-	 * This function is called by \Sabre\DAV\Server, after
98
-	 * addPlugin is called.
99
-	 *
100
-	 * This method should set up the required event subscriptions.
101
-	 *
102
-	 * @param \Sabre\DAV\Server $server
103
-	 */
104
-	public function initialize(\Sabre\DAV\Server $server) {
105
-		$server->xml->namespacesMap[self::NS_OWNCLOUD] = 'oc';
106
-		$server->xml->elementMap[self::SHARETYPES_PROPERTYNAME] = ShareTypeList::class;
107
-		$server->protectedProperties[] = self::SHARETYPES_PROPERTYNAME;
108
-		$server->protectedProperties[] = self::SHAREES_PROPERTYNAME;
109
-
110
-		$this->server = $server;
111
-		$this->server->on('propFind', [$this, 'handleGetProperties']);
112
-	}
113
-
114
-	private function getShare(\OCP\Files\Node $node): array {
115
-		$result = [];
116
-		$requestedShareTypes = [
117
-			IShare::TYPE_USER,
118
-			IShare::TYPE_GROUP,
119
-			IShare::TYPE_LINK,
120
-			IShare::TYPE_REMOTE,
121
-			IShare::TYPE_EMAIL,
122
-			IShare::TYPE_ROOM,
123
-			IShare::TYPE_CIRCLE,
124
-			IShare::TYPE_DECK,
125
-		];
126
-		foreach ($requestedShareTypes as $requestedShareType) {
127
-			$shares = $this->shareManager->getSharesBy(
128
-				$this->userId,
129
-				$requestedShareType,
130
-				$node,
131
-				false,
132
-				-1
133
-			);
134
-			foreach ($shares as $share) {
135
-				$result[] = $share;
136
-			}
137
-		}
138
-		return $result;
139
-	}
140
-
141
-	private function getSharesFolder(\OCP\Files\Folder $node): array {
142
-		return $this->shareManager->getSharesInFolder(
143
-			$this->userId,
144
-			$node,
145
-			true
146
-		);
147
-	}
148
-
149
-	private function getShares(\Sabre\DAV\INode $sabreNode): array {
150
-		if (isset($this->cachedShares[$sabreNode->getId()])) {
151
-			$shares = $this->cachedShares[$sabreNode->getId()];
152
-		} else {
153
-			list($parentPath,) = \Sabre\Uri\split($sabreNode->getPath());
154
-			if ($parentPath === '') {
155
-				$parentPath = '/';
156
-			}
157
-			// if we already cached the folder this file is in we know there are no shares for this file
158
-			if (array_search($parentPath, $this->cachedFolders) === false) {
159
-				$node = $this->userFolder->get($sabreNode->getPath());
160
-				$shares = $this->getShare($node);
161
-				$this->cachedShares[$sabreNode->getId()] = $shares;
162
-			} else {
163
-				return [];
164
-			}
165
-		}
166
-
167
-		return $shares;
168
-	}
169
-
170
-	/**
171
-	 * Adds shares to propfind response
172
-	 *
173
-	 * @param PropFind $propFind propfind object
174
-	 * @param \Sabre\DAV\INode $sabreNode sabre node
175
-	 */
176
-	public function handleGetProperties(
177
-		PropFind $propFind,
178
-		\Sabre\DAV\INode $sabreNode
179
-	) {
180
-		if (!($sabreNode instanceof \OCA\DAV\Connector\Sabre\Node)) {
181
-			return;
182
-		}
183
-
184
-		// need prefetch ?
185
-		if ($sabreNode instanceof \OCA\DAV\Connector\Sabre\Directory
186
-			&& $propFind->getDepth() !== 0
187
-			&& (
188
-				!is_null($propFind->getStatus(self::SHARETYPES_PROPERTYNAME)) ||
189
-				!is_null($propFind->getStatus(self::SHAREES_PROPERTYNAME))
190
-			)
191
-		) {
192
-			$folderNode = $this->userFolder->get($sabreNode->getPath());
193
-
194
-			$this->cachedFolders[] = $sabreNode->getPath();
195
-			$childShares = $this->getSharesFolder($folderNode);
196
-			foreach ($childShares as $id => $shares) {
197
-				$this->cachedShares[$id] = $shares;
198
-			}
199
-		}
200
-
201
-		$propFind->handle(self::SHARETYPES_PROPERTYNAME, function () use ($sabreNode) {
202
-			$shares = $this->getShares($sabreNode);
203
-
204
-			$shareTypes = array_unique(array_map(function (IShare $share) {
205
-				return $share->getShareType();
206
-			}, $shares));
207
-
208
-			return new ShareTypeList($shareTypes);
209
-		});
210
-
211
-		$propFind->handle(self::SHAREES_PROPERTYNAME, function () use ($sabreNode) {
212
-			$shares = $this->getShares($sabreNode);
213
-
214
-			return new ShareeList($shares);
215
-		});
216
-	}
39
+    public const NS_OWNCLOUD = 'http://owncloud.org/ns';
40
+    public const NS_NEXTCLOUD = 'http://nextcloud.org/ns';
41
+    public const SHARETYPES_PROPERTYNAME = '{http://owncloud.org/ns}share-types';
42
+    public const SHAREES_PROPERTYNAME = '{http://nextcloud.org/ns}sharees';
43
+
44
+    /**
45
+     * Reference to main server object
46
+     *
47
+     * @var \Sabre\DAV\Server
48
+     */
49
+    private $server;
50
+
51
+    /**
52
+     * @var \OCP\Share\IManager
53
+     */
54
+    private $shareManager;
55
+
56
+    /**
57
+     * @var \Sabre\DAV\Tree
58
+     */
59
+    private $tree;
60
+
61
+    /**
62
+     * @var string
63
+     */
64
+    private $userId;
65
+
66
+    /**
67
+     * @var \OCP\Files\Folder
68
+     */
69
+    private $userFolder;
70
+
71
+    /** @var IShare[] */
72
+    private $cachedShares = [];
73
+
74
+    private $cachedFolders = [];
75
+
76
+    /**
77
+     * @param \Sabre\DAV\Tree $tree tree
78
+     * @param IUserSession $userSession user session
79
+     * @param \OCP\Files\Folder $userFolder user home folder
80
+     * @param \OCP\Share\IManager $shareManager share manager
81
+     */
82
+    public function __construct(
83
+        \Sabre\DAV\Tree $tree,
84
+        IUserSession $userSession,
85
+        \OCP\Files\Folder $userFolder,
86
+        \OCP\Share\IManager $shareManager
87
+    ) {
88
+        $this->tree = $tree;
89
+        $this->shareManager = $shareManager;
90
+        $this->userFolder = $userFolder;
91
+        $this->userId = $userSession->getUser()->getUID();
92
+    }
93
+
94
+    /**
95
+     * This initializes the plugin.
96
+     *
97
+     * This function is called by \Sabre\DAV\Server, after
98
+     * addPlugin is called.
99
+     *
100
+     * This method should set up the required event subscriptions.
101
+     *
102
+     * @param \Sabre\DAV\Server $server
103
+     */
104
+    public function initialize(\Sabre\DAV\Server $server) {
105
+        $server->xml->namespacesMap[self::NS_OWNCLOUD] = 'oc';
106
+        $server->xml->elementMap[self::SHARETYPES_PROPERTYNAME] = ShareTypeList::class;
107
+        $server->protectedProperties[] = self::SHARETYPES_PROPERTYNAME;
108
+        $server->protectedProperties[] = self::SHAREES_PROPERTYNAME;
109
+
110
+        $this->server = $server;
111
+        $this->server->on('propFind', [$this, 'handleGetProperties']);
112
+    }
113
+
114
+    private function getShare(\OCP\Files\Node $node): array {
115
+        $result = [];
116
+        $requestedShareTypes = [
117
+            IShare::TYPE_USER,
118
+            IShare::TYPE_GROUP,
119
+            IShare::TYPE_LINK,
120
+            IShare::TYPE_REMOTE,
121
+            IShare::TYPE_EMAIL,
122
+            IShare::TYPE_ROOM,
123
+            IShare::TYPE_CIRCLE,
124
+            IShare::TYPE_DECK,
125
+        ];
126
+        foreach ($requestedShareTypes as $requestedShareType) {
127
+            $shares = $this->shareManager->getSharesBy(
128
+                $this->userId,
129
+                $requestedShareType,
130
+                $node,
131
+                false,
132
+                -1
133
+            );
134
+            foreach ($shares as $share) {
135
+                $result[] = $share;
136
+            }
137
+        }
138
+        return $result;
139
+    }
140
+
141
+    private function getSharesFolder(\OCP\Files\Folder $node): array {
142
+        return $this->shareManager->getSharesInFolder(
143
+            $this->userId,
144
+            $node,
145
+            true
146
+        );
147
+    }
148
+
149
+    private function getShares(\Sabre\DAV\INode $sabreNode): array {
150
+        if (isset($this->cachedShares[$sabreNode->getId()])) {
151
+            $shares = $this->cachedShares[$sabreNode->getId()];
152
+        } else {
153
+            list($parentPath,) = \Sabre\Uri\split($sabreNode->getPath());
154
+            if ($parentPath === '') {
155
+                $parentPath = '/';
156
+            }
157
+            // if we already cached the folder this file is in we know there are no shares for this file
158
+            if (array_search($parentPath, $this->cachedFolders) === false) {
159
+                $node = $this->userFolder->get($sabreNode->getPath());
160
+                $shares = $this->getShare($node);
161
+                $this->cachedShares[$sabreNode->getId()] = $shares;
162
+            } else {
163
+                return [];
164
+            }
165
+        }
166
+
167
+        return $shares;
168
+    }
169
+
170
+    /**
171
+     * Adds shares to propfind response
172
+     *
173
+     * @param PropFind $propFind propfind object
174
+     * @param \Sabre\DAV\INode $sabreNode sabre node
175
+     */
176
+    public function handleGetProperties(
177
+        PropFind $propFind,
178
+        \Sabre\DAV\INode $sabreNode
179
+    ) {
180
+        if (!($sabreNode instanceof \OCA\DAV\Connector\Sabre\Node)) {
181
+            return;
182
+        }
183
+
184
+        // need prefetch ?
185
+        if ($sabreNode instanceof \OCA\DAV\Connector\Sabre\Directory
186
+            && $propFind->getDepth() !== 0
187
+            && (
188
+                !is_null($propFind->getStatus(self::SHARETYPES_PROPERTYNAME)) ||
189
+                !is_null($propFind->getStatus(self::SHAREES_PROPERTYNAME))
190
+            )
191
+        ) {
192
+            $folderNode = $this->userFolder->get($sabreNode->getPath());
193
+
194
+            $this->cachedFolders[] = $sabreNode->getPath();
195
+            $childShares = $this->getSharesFolder($folderNode);
196
+            foreach ($childShares as $id => $shares) {
197
+                $this->cachedShares[$id] = $shares;
198
+            }
199
+        }
200
+
201
+        $propFind->handle(self::SHARETYPES_PROPERTYNAME, function () use ($sabreNode) {
202
+            $shares = $this->getShares($sabreNode);
203
+
204
+            $shareTypes = array_unique(array_map(function (IShare $share) {
205
+                return $share->getShareType();
206
+            }, $shares));
207
+
208
+            return new ShareTypeList($shareTypes);
209
+        });
210
+
211
+        $propFind->handle(self::SHAREES_PROPERTYNAME, function () use ($sabreNode) {
212
+            $shares = $this->getShares($sabreNode);
213
+
214
+            return new ShareeList($shares);
215
+        });
216
+    }
217 217
 }
Please login to merge, or discard this patch.
apps/files_sharing/lib/MountProvider.php 2 patches
Indentation   +202 added lines, -202 removed lines patch added patch discarded remove patch
@@ -39,206 +39,206 @@
 block discarded – undo
39 39
 use OCP\Share\IShare;
40 40
 
41 41
 class MountProvider implements IMountProvider {
42
-	/**
43
-	 * @var \OCP\IConfig
44
-	 */
45
-	protected $config;
46
-
47
-	/**
48
-	 * @var IManager
49
-	 */
50
-	protected $shareManager;
51
-
52
-	/**
53
-	 * @var ILogger
54
-	 */
55
-	protected $logger;
56
-
57
-	/**
58
-	 * @param \OCP\IConfig $config
59
-	 * @param IManager $shareManager
60
-	 * @param ILogger $logger
61
-	 */
62
-	public function __construct(IConfig $config, IManager $shareManager, ILogger $logger) {
63
-		$this->config = $config;
64
-		$this->shareManager = $shareManager;
65
-		$this->logger = $logger;
66
-	}
67
-
68
-
69
-	/**
70
-	 * Get all mountpoints applicable for the user and check for shares where we need to update the etags
71
-	 *
72
-	 * @param \OCP\IUser $user
73
-	 * @param \OCP\Files\Storage\IStorageFactory $loader
74
-	 * @return \OCP\Files\Mount\IMountPoint[]
75
-	 */
76
-	public function getMountsForUser(IUser $user, IStorageFactory $loader) {
77
-		$shares = $this->shareManager->getSharedWith($user->getUID(), IShare::TYPE_USER, null, -1);
78
-		$shares = array_merge($shares, $this->shareManager->getSharedWith($user->getUID(), IShare::TYPE_GROUP, null, -1));
79
-		$shares = array_merge($shares, $this->shareManager->getSharedWith($user->getUID(), IShare::TYPE_CIRCLE, null, -1));
80
-		$shares = array_merge($shares, $this->shareManager->getSharedWith($user->getUID(), IShare::TYPE_ROOM, null, -1));
81
-		$shares = array_merge($shares, $this->shareManager->getSharedWith($user->getUID(), IShare::TYPE_DECK, null, -1));
82
-
83
-
84
-		// filter out excluded shares and group shares that includes self
85
-		$shares = array_filter($shares, function (\OCP\Share\IShare $share) use ($user) {
86
-			return $share->getPermissions() > 0 && $share->getShareOwner() !== $user->getUID();
87
-		});
88
-
89
-		$superShares = $this->buildSuperShares($shares, $user);
90
-
91
-		$mounts = [];
92
-		$view = new View('/' . $user->getUID() . '/files');
93
-		$ownerViews = [];
94
-		$sharingDisabledForUser = $this->shareManager->sharingDisabledForUser($user->getUID());
95
-		$foldersExistCache = new CappedMemoryCache();
96
-		foreach ($superShares as $share) {
97
-			try {
98
-				/** @var \OCP\Share\IShare $parentShare */
99
-				$parentShare = $share[0];
100
-
101
-				if ($parentShare->getStatus() !== IShare::STATUS_ACCEPTED &&
102
-					($parentShare->getShareType() === IShare::TYPE_GROUP ||
103
-						$parentShare->getShareType() === IShare::TYPE_USERGROUP ||
104
-						$parentShare->getShareType() === IShare::TYPE_USER)) {
105
-					continue;
106
-				}
107
-
108
-				$owner = $parentShare->getShareOwner();
109
-				if (!isset($ownerViews[$owner])) {
110
-					$ownerViews[$owner] = new View('/' . $parentShare->getShareOwner() . '/files');
111
-				}
112
-				$mount = new SharedMount(
113
-					'\OCA\Files_Sharing\SharedStorage',
114
-					$mounts,
115
-					[
116
-						'user' => $user->getUID(),
117
-						// parent share
118
-						'superShare' => $parentShare,
119
-						// children/component of the superShare
120
-						'groupedShares' => $share[1],
121
-						'ownerView' => $ownerViews[$owner],
122
-						'sharingDisabledForUser' => $sharingDisabledForUser
123
-					],
124
-					$loader,
125
-					$view,
126
-					$foldersExistCache
127
-				);
128
-				$mounts[$mount->getMountPoint()] = $mount;
129
-			} catch (\Exception $e) {
130
-				$this->logger->logException($e);
131
-				$this->logger->error('Error while trying to create shared mount');
132
-			}
133
-		}
134
-
135
-		// array_filter removes the null values from the array
136
-		return array_values(array_filter($mounts));
137
-	}
138
-
139
-	/**
140
-	 * Groups shares by path (nodeId) and target path
141
-	 *
142
-	 * @param \OCP\Share\IShare[] $shares
143
-	 * @return \OCP\Share\IShare[][] array of grouped shares, each element in the
144
-	 * array is a group which itself is an array of shares
145
-	 */
146
-	private function groupShares(array $shares) {
147
-		$tmp = [];
148
-
149
-		foreach ($shares as $share) {
150
-			if (!isset($tmp[$share->getNodeId()])) {
151
-				$tmp[$share->getNodeId()] = [];
152
-			}
153
-			$tmp[$share->getNodeId()][] = $share;
154
-		}
155
-
156
-		$result = [];
157
-		// sort by stime, the super share will be based on the least recent share
158
-		foreach ($tmp as &$tmp2) {
159
-			@usort($tmp2, function ($a, $b) {
160
-				$aTime = $a->getShareTime()->getTimestamp();
161
-				$bTime = $b->getShareTime()->getTimestamp();
162
-				if ($aTime === $bTime) {
163
-					return $a->getId() < $b->getId() ? -1 : 1;
164
-				}
165
-				return $aTime < $bTime ? -1 : 1;
166
-			});
167
-			$result[] = $tmp2;
168
-		}
169
-
170
-		return array_values($result);
171
-	}
172
-
173
-	/**
174
-	 * Build super shares (virtual share) by grouping them by node id and target,
175
-	 * then for each group compute the super share and return it along with the matching
176
-	 * grouped shares. The most permissive permissions are used based on the permissions
177
-	 * of all shares within the group.
178
-	 *
179
-	 * @param \OCP\Share\IShare[] $allShares
180
-	 * @param \OCP\IUser $user user
181
-	 * @return array Tuple of [superShare, groupedShares]
182
-	 */
183
-	private function buildSuperShares(array $allShares, \OCP\IUser $user) {
184
-		$result = [];
185
-
186
-		$groupedShares = $this->groupShares($allShares);
187
-
188
-		/** @var \OCP\Share\IShare[] $shares */
189
-		foreach ($groupedShares as $shares) {
190
-			if (count($shares) === 0) {
191
-				continue;
192
-			}
193
-
194
-			$superShare = $this->shareManager->newShare();
195
-
196
-			// compute super share based on first entry of the group
197
-			$superShare->setId($shares[0]->getId())
198
-				->setShareOwner($shares[0]->getShareOwner())
199
-				->setNodeId($shares[0]->getNodeId())
200
-				->setShareType($shares[0]->getShareType())
201
-				->setTarget($shares[0]->getTarget());
202
-
203
-			// use most permissive permissions
204
-			$permissions = 0;
205
-			$status = IShare::STATUS_PENDING;
206
-			foreach ($shares as $share) {
207
-				$permissions |= $share->getPermissions();
208
-				$status = max($status, $share->getStatus());
209
-
210
-				if ($share->getTarget() !== $superShare->getTarget()) {
211
-					// adjust target, for database consistency
212
-					$share->setTarget($superShare->getTarget());
213
-					try {
214
-						$this->shareManager->moveShare($share, $user->getUID());
215
-					} catch (\InvalidArgumentException $e) {
216
-						// ignore as it is not important and we don't want to
217
-						// block FS setup
218
-
219
-						// the subsequent code anyway only uses the target of the
220
-						// super share
221
-
222
-						// such issue can usually happen when dealing with
223
-						// null groups which usually appear with group backend
224
-						// caching inconsistencies
225
-						$this->logger->debug(
226
-							'Could not adjust share target for share ' . $share->getId() . ' to make it consistent: ' . $e->getMessage(),
227
-							['app' => 'files_sharing']
228
-						);
229
-					}
230
-				}
231
-				if (!is_null($share->getNodeCacheEntry())) {
232
-					$superShare->setNodeCacheEntry($share->getNodeCacheEntry());
233
-				}
234
-			}
235
-
236
-			$superShare->setPermissions($permissions)
237
-				->setStatus($status);
238
-
239
-			$result[] = [$superShare, $shares];
240
-		}
241
-
242
-		return $result;
243
-	}
42
+    /**
43
+     * @var \OCP\IConfig
44
+     */
45
+    protected $config;
46
+
47
+    /**
48
+     * @var IManager
49
+     */
50
+    protected $shareManager;
51
+
52
+    /**
53
+     * @var ILogger
54
+     */
55
+    protected $logger;
56
+
57
+    /**
58
+     * @param \OCP\IConfig $config
59
+     * @param IManager $shareManager
60
+     * @param ILogger $logger
61
+     */
62
+    public function __construct(IConfig $config, IManager $shareManager, ILogger $logger) {
63
+        $this->config = $config;
64
+        $this->shareManager = $shareManager;
65
+        $this->logger = $logger;
66
+    }
67
+
68
+
69
+    /**
70
+     * Get all mountpoints applicable for the user and check for shares where we need to update the etags
71
+     *
72
+     * @param \OCP\IUser $user
73
+     * @param \OCP\Files\Storage\IStorageFactory $loader
74
+     * @return \OCP\Files\Mount\IMountPoint[]
75
+     */
76
+    public function getMountsForUser(IUser $user, IStorageFactory $loader) {
77
+        $shares = $this->shareManager->getSharedWith($user->getUID(), IShare::TYPE_USER, null, -1);
78
+        $shares = array_merge($shares, $this->shareManager->getSharedWith($user->getUID(), IShare::TYPE_GROUP, null, -1));
79
+        $shares = array_merge($shares, $this->shareManager->getSharedWith($user->getUID(), IShare::TYPE_CIRCLE, null, -1));
80
+        $shares = array_merge($shares, $this->shareManager->getSharedWith($user->getUID(), IShare::TYPE_ROOM, null, -1));
81
+        $shares = array_merge($shares, $this->shareManager->getSharedWith($user->getUID(), IShare::TYPE_DECK, null, -1));
82
+
83
+
84
+        // filter out excluded shares and group shares that includes self
85
+        $shares = array_filter($shares, function (\OCP\Share\IShare $share) use ($user) {
86
+            return $share->getPermissions() > 0 && $share->getShareOwner() !== $user->getUID();
87
+        });
88
+
89
+        $superShares = $this->buildSuperShares($shares, $user);
90
+
91
+        $mounts = [];
92
+        $view = new View('/' . $user->getUID() . '/files');
93
+        $ownerViews = [];
94
+        $sharingDisabledForUser = $this->shareManager->sharingDisabledForUser($user->getUID());
95
+        $foldersExistCache = new CappedMemoryCache();
96
+        foreach ($superShares as $share) {
97
+            try {
98
+                /** @var \OCP\Share\IShare $parentShare */
99
+                $parentShare = $share[0];
100
+
101
+                if ($parentShare->getStatus() !== IShare::STATUS_ACCEPTED &&
102
+                    ($parentShare->getShareType() === IShare::TYPE_GROUP ||
103
+                        $parentShare->getShareType() === IShare::TYPE_USERGROUP ||
104
+                        $parentShare->getShareType() === IShare::TYPE_USER)) {
105
+                    continue;
106
+                }
107
+
108
+                $owner = $parentShare->getShareOwner();
109
+                if (!isset($ownerViews[$owner])) {
110
+                    $ownerViews[$owner] = new View('/' . $parentShare->getShareOwner() . '/files');
111
+                }
112
+                $mount = new SharedMount(
113
+                    '\OCA\Files_Sharing\SharedStorage',
114
+                    $mounts,
115
+                    [
116
+                        'user' => $user->getUID(),
117
+                        // parent share
118
+                        'superShare' => $parentShare,
119
+                        // children/component of the superShare
120
+                        'groupedShares' => $share[1],
121
+                        'ownerView' => $ownerViews[$owner],
122
+                        'sharingDisabledForUser' => $sharingDisabledForUser
123
+                    ],
124
+                    $loader,
125
+                    $view,
126
+                    $foldersExistCache
127
+                );
128
+                $mounts[$mount->getMountPoint()] = $mount;
129
+            } catch (\Exception $e) {
130
+                $this->logger->logException($e);
131
+                $this->logger->error('Error while trying to create shared mount');
132
+            }
133
+        }
134
+
135
+        // array_filter removes the null values from the array
136
+        return array_values(array_filter($mounts));
137
+    }
138
+
139
+    /**
140
+     * Groups shares by path (nodeId) and target path
141
+     *
142
+     * @param \OCP\Share\IShare[] $shares
143
+     * @return \OCP\Share\IShare[][] array of grouped shares, each element in the
144
+     * array is a group which itself is an array of shares
145
+     */
146
+    private function groupShares(array $shares) {
147
+        $tmp = [];
148
+
149
+        foreach ($shares as $share) {
150
+            if (!isset($tmp[$share->getNodeId()])) {
151
+                $tmp[$share->getNodeId()] = [];
152
+            }
153
+            $tmp[$share->getNodeId()][] = $share;
154
+        }
155
+
156
+        $result = [];
157
+        // sort by stime, the super share will be based on the least recent share
158
+        foreach ($tmp as &$tmp2) {
159
+            @usort($tmp2, function ($a, $b) {
160
+                $aTime = $a->getShareTime()->getTimestamp();
161
+                $bTime = $b->getShareTime()->getTimestamp();
162
+                if ($aTime === $bTime) {
163
+                    return $a->getId() < $b->getId() ? -1 : 1;
164
+                }
165
+                return $aTime < $bTime ? -1 : 1;
166
+            });
167
+            $result[] = $tmp2;
168
+        }
169
+
170
+        return array_values($result);
171
+    }
172
+
173
+    /**
174
+     * Build super shares (virtual share) by grouping them by node id and target,
175
+     * then for each group compute the super share and return it along with the matching
176
+     * grouped shares. The most permissive permissions are used based on the permissions
177
+     * of all shares within the group.
178
+     *
179
+     * @param \OCP\Share\IShare[] $allShares
180
+     * @param \OCP\IUser $user user
181
+     * @return array Tuple of [superShare, groupedShares]
182
+     */
183
+    private function buildSuperShares(array $allShares, \OCP\IUser $user) {
184
+        $result = [];
185
+
186
+        $groupedShares = $this->groupShares($allShares);
187
+
188
+        /** @var \OCP\Share\IShare[] $shares */
189
+        foreach ($groupedShares as $shares) {
190
+            if (count($shares) === 0) {
191
+                continue;
192
+            }
193
+
194
+            $superShare = $this->shareManager->newShare();
195
+
196
+            // compute super share based on first entry of the group
197
+            $superShare->setId($shares[0]->getId())
198
+                ->setShareOwner($shares[0]->getShareOwner())
199
+                ->setNodeId($shares[0]->getNodeId())
200
+                ->setShareType($shares[0]->getShareType())
201
+                ->setTarget($shares[0]->getTarget());
202
+
203
+            // use most permissive permissions
204
+            $permissions = 0;
205
+            $status = IShare::STATUS_PENDING;
206
+            foreach ($shares as $share) {
207
+                $permissions |= $share->getPermissions();
208
+                $status = max($status, $share->getStatus());
209
+
210
+                if ($share->getTarget() !== $superShare->getTarget()) {
211
+                    // adjust target, for database consistency
212
+                    $share->setTarget($superShare->getTarget());
213
+                    try {
214
+                        $this->shareManager->moveShare($share, $user->getUID());
215
+                    } catch (\InvalidArgumentException $e) {
216
+                        // ignore as it is not important and we don't want to
217
+                        // block FS setup
218
+
219
+                        // the subsequent code anyway only uses the target of the
220
+                        // super share
221
+
222
+                        // such issue can usually happen when dealing with
223
+                        // null groups which usually appear with group backend
224
+                        // caching inconsistencies
225
+                        $this->logger->debug(
226
+                            'Could not adjust share target for share ' . $share->getId() . ' to make it consistent: ' . $e->getMessage(),
227
+                            ['app' => 'files_sharing']
228
+                        );
229
+                    }
230
+                }
231
+                if (!is_null($share->getNodeCacheEntry())) {
232
+                    $superShare->setNodeCacheEntry($share->getNodeCacheEntry());
233
+                }
234
+            }
235
+
236
+            $superShare->setPermissions($permissions)
237
+                ->setStatus($status);
238
+
239
+            $result[] = [$superShare, $shares];
240
+        }
241
+
242
+        return $result;
243
+    }
244 244
 }
Please login to merge, or discard this patch.
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -82,14 +82,14 @@  discard block
 block discarded – undo
82 82
 
83 83
 
84 84
 		// filter out excluded shares and group shares that includes self
85
-		$shares = array_filter($shares, function (\OCP\Share\IShare $share) use ($user) {
85
+		$shares = array_filter($shares, function(\OCP\Share\IShare $share) use ($user) {
86 86
 			return $share->getPermissions() > 0 && $share->getShareOwner() !== $user->getUID();
87 87
 		});
88 88
 
89 89
 		$superShares = $this->buildSuperShares($shares, $user);
90 90
 
91 91
 		$mounts = [];
92
-		$view = new View('/' . $user->getUID() . '/files');
92
+		$view = new View('/'.$user->getUID().'/files');
93 93
 		$ownerViews = [];
94 94
 		$sharingDisabledForUser = $this->shareManager->sharingDisabledForUser($user->getUID());
95 95
 		$foldersExistCache = new CappedMemoryCache();
@@ -107,7 +107,7 @@  discard block
 block discarded – undo
107 107
 
108 108
 				$owner = $parentShare->getShareOwner();
109 109
 				if (!isset($ownerViews[$owner])) {
110
-					$ownerViews[$owner] = new View('/' . $parentShare->getShareOwner() . '/files');
110
+					$ownerViews[$owner] = new View('/'.$parentShare->getShareOwner().'/files');
111 111
 				}
112 112
 				$mount = new SharedMount(
113 113
 					'\OCA\Files_Sharing\SharedStorage',
@@ -156,7 +156,7 @@  discard block
 block discarded – undo
156 156
 		$result = [];
157 157
 		// sort by stime, the super share will be based on the least recent share
158 158
 		foreach ($tmp as &$tmp2) {
159
-			@usort($tmp2, function ($a, $b) {
159
+			@usort($tmp2, function($a, $b) {
160 160
 				$aTime = $a->getShareTime()->getTimestamp();
161 161
 				$bTime = $b->getShareTime()->getTimestamp();
162 162
 				if ($aTime === $bTime) {
@@ -223,7 +223,7 @@  discard block
 block discarded – undo
223 223
 						// null groups which usually appear with group backend
224 224
 						// caching inconsistencies
225 225
 						$this->logger->debug(
226
-							'Could not adjust share target for share ' . $share->getId() . ' to make it consistent: ' . $e->getMessage(),
226
+							'Could not adjust share target for share '.$share->getId().' to make it consistent: '.$e->getMessage(),
227 227
 							['app' => 'files_sharing']
228 228
 						);
229 229
 					}
Please login to merge, or discard this patch.
apps/files_sharing/lib/Controller/ShareesAPIController.php 1 patch
Indentation   +379 added lines, -379 removed lines patch added patch discarded remove patch
@@ -55,383 +55,383 @@
 block discarded – undo
55 55
 
56 56
 class ShareesAPIController extends OCSController {
57 57
 
58
-	/** @var string */
59
-	protected $userId;
60
-
61
-	/** @var IConfig */
62
-	protected $config;
63
-
64
-	/** @var IURLGenerator */
65
-	protected $urlGenerator;
66
-
67
-	/** @var IManager */
68
-	protected $shareManager;
69
-
70
-	/** @var int */
71
-	protected $offset = 0;
72
-
73
-	/** @var int */
74
-	protected $limit = 10;
75
-
76
-	/** @var array */
77
-	protected $result = [
78
-		'exact' => [
79
-			'users' => [],
80
-			'groups' => [],
81
-			'remotes' => [],
82
-			'remote_groups' => [],
83
-			'emails' => [],
84
-			'circles' => [],
85
-			'rooms' => [],
86
-			'deck' => [],
87
-		],
88
-		'users' => [],
89
-		'groups' => [],
90
-		'remotes' => [],
91
-		'remote_groups' => [],
92
-		'emails' => [],
93
-		'lookup' => [],
94
-		'circles' => [],
95
-		'rooms' => [],
96
-		'deck' => [],
97
-		'lookupEnabled' => false,
98
-	];
99
-
100
-	protected $reachedEndFor = [];
101
-	/** @var ISearch */
102
-	private $collaboratorSearch;
103
-
104
-	/**
105
-	 * @param string $UserId
106
-	 * @param string $appName
107
-	 * @param IRequest $request
108
-	 * @param IConfig $config
109
-	 * @param IURLGenerator $urlGenerator
110
-	 * @param IManager $shareManager
111
-	 * @param ISearch $collaboratorSearch
112
-	 */
113
-	public function __construct(
114
-		$UserId,
115
-		string $appName,
116
-		IRequest $request,
117
-		IConfig $config,
118
-		IURLGenerator $urlGenerator,
119
-		IManager $shareManager,
120
-		ISearch $collaboratorSearch
121
-	) {
122
-		parent::__construct($appName, $request);
123
-		$this->userId = $UserId;
124
-		$this->config = $config;
125
-		$this->urlGenerator = $urlGenerator;
126
-		$this->shareManager = $shareManager;
127
-		$this->collaboratorSearch = $collaboratorSearch;
128
-	}
129
-
130
-	/**
131
-	 * @NoAdminRequired
132
-	 *
133
-	 * @param string $search
134
-	 * @param string $itemType
135
-	 * @param int $page
136
-	 * @param int $perPage
137
-	 * @param int|int[] $shareType
138
-	 * @param bool $lookup
139
-	 * @return DataResponse
140
-	 * @throws OCSBadRequestException
141
-	 */
142
-	public function search(string $search = '', string $itemType = null, int $page = 1, int $perPage = 200, $shareType = null, bool $lookup = true): DataResponse {
143
-
144
-		// only search for string larger than a given threshold
145
-		$threshold = (int)$this->config->getSystemValue('sharing.minSearchStringLength', 0);
146
-		if (strlen($search) < $threshold) {
147
-			return new DataResponse($this->result);
148
-		}
149
-
150
-		// never return more than the max. number of results configured in the config.php
151
-		$maxResults = (int)$this->config->getSystemValue('sharing.maxAutocompleteResults', 0);
152
-		if ($maxResults > 0) {
153
-			$perPage = min($perPage, $maxResults);
154
-		}
155
-		if ($perPage <= 0) {
156
-			throw new OCSBadRequestException('Invalid perPage argument');
157
-		}
158
-		if ($page <= 0) {
159
-			throw new OCSBadRequestException('Invalid page');
160
-		}
161
-
162
-		$shareTypes = [
163
-			IShare::TYPE_USER,
164
-		];
165
-
166
-		if ($itemType === null) {
167
-			throw new OCSBadRequestException('Missing itemType');
168
-		} elseif ($itemType === 'file' || $itemType === 'folder') {
169
-			if ($this->shareManager->allowGroupSharing()) {
170
-				$shareTypes[] = IShare::TYPE_GROUP;
171
-			}
172
-
173
-			if ($this->isRemoteSharingAllowed($itemType)) {
174
-				$shareTypes[] = IShare::TYPE_REMOTE;
175
-			}
176
-
177
-			if ($this->isRemoteGroupSharingAllowed($itemType)) {
178
-				$shareTypes[] = IShare::TYPE_REMOTE_GROUP;
179
-			}
180
-
181
-			if ($this->shareManager->shareProviderExists(IShare::TYPE_EMAIL)) {
182
-				$shareTypes[] = IShare::TYPE_EMAIL;
183
-			}
184
-
185
-			if ($this->shareManager->shareProviderExists(IShare::TYPE_ROOM)) {
186
-				$shareTypes[] = IShare::TYPE_ROOM;
187
-			}
188
-
189
-			if ($this->shareManager->shareProviderExists(IShare::TYPE_DECK)) {
190
-				$shareTypes[] = IShare::TYPE_DECK;
191
-			}
192
-		} else {
193
-			$shareTypes[] = IShare::TYPE_GROUP;
194
-			$shareTypes[] = IShare::TYPE_EMAIL;
195
-		}
196
-
197
-		// FIXME: DI
198
-		if (\OC::$server->getAppManager()->isEnabledForUser('circles') && class_exists('\OCA\Circles\ShareByCircleProvider')) {
199
-			$shareTypes[] = IShare::TYPE_CIRCLE;
200
-		}
201
-
202
-		if ($this->shareManager->shareProviderExists(IShare::TYPE_DECK)) {
203
-			$shareTypes[] = IShare::TYPE_DECK;
204
-		}
205
-
206
-		if ($shareType !== null && is_array($shareType)) {
207
-			$shareTypes = array_intersect($shareTypes, $shareType);
208
-		} elseif (is_numeric($shareType)) {
209
-			$shareTypes = array_intersect($shareTypes, [(int) $shareType]);
210
-		}
211
-		sort($shareTypes);
212
-
213
-		$this->limit = (int) $perPage;
214
-		$this->offset = $perPage * ($page - 1);
215
-
216
-		// In global scale mode we always search the loogup server
217
-		if ($this->config->getSystemValueBool('gs.enabled', false)) {
218
-			$lookup = true;
219
-			$this->result['lookupEnabled'] = true;
220
-		} else {
221
-			$this->result['lookupEnabled'] = $this->config->getAppValue('files_sharing', 'lookupServerEnabled', 'yes') === 'yes';
222
-		}
223
-
224
-		list($result, $hasMoreResults) = $this->collaboratorSearch->search($search, $shareTypes, $lookup, $this->limit, $this->offset);
225
-
226
-		// extra treatment for 'exact' subarray, with a single merge expected keys might be lost
227
-		if (isset($result['exact'])) {
228
-			$result['exact'] = array_merge($this->result['exact'], $result['exact']);
229
-		}
230
-		$this->result = array_merge($this->result, $result);
231
-		$response = new DataResponse($this->result);
232
-
233
-		if ($hasMoreResults) {
234
-			$response->addHeader('Link', $this->getPaginationLink($page, [
235
-				'search' => $search,
236
-				'itemType' => $itemType,
237
-				'shareType' => $shareTypes,
238
-				'perPage' => $perPage,
239
-			]));
240
-		}
241
-
242
-		return $response;
243
-	}
244
-
245
-	/**
246
-	 * @param string $user
247
-	 * @param int $shareType
248
-	 *
249
-	 * @return Generator<array<string>>
250
-	 */
251
-	private function getAllShareesByType(string $user, int $shareType): Generator {
252
-		$offset = 0;
253
-		$pageSize = 50;
254
-
255
-		while (count($page = $this->shareManager->getSharesBy(
256
-			$user,
257
-			$shareType,
258
-			null,
259
-			false,
260
-			$pageSize,
261
-			$offset
262
-		))) {
263
-			foreach ($page as $share) {
264
-				yield [$share->getSharedWith(), $share->getSharedWithDisplayName() ?? $share->getSharedWith()];
265
-			}
266
-
267
-			$offset += $pageSize;
268
-		}
269
-	}
270
-
271
-	private function sortShareesByFrequency(array $sharees): array {
272
-		usort($sharees, function (array $s1, array $s2) {
273
-			return $s2['count'] - $s1['count'];
274
-		});
275
-		return $sharees;
276
-	}
277
-
278
-	private $searchResultTypeMap = [
279
-		IShare::TYPE_USER => 'users',
280
-		IShare::TYPE_GROUP => 'groups',
281
-		IShare::TYPE_REMOTE => 'remotes',
282
-		IShare::TYPE_REMOTE_GROUP => 'remote_groups',
283
-		IShare::TYPE_EMAIL => 'emails',
284
-	];
285
-
286
-	private function getAllSharees(string $user, array $shareTypes): ISearchResult {
287
-		$result = [];
288
-		foreach ($shareTypes as $shareType) {
289
-			$sharees = $this->getAllShareesByType($user, $shareType);
290
-			$shareTypeResults = [];
291
-			foreach ($sharees as list($sharee, $displayname)) {
292
-				if (!isset($this->searchResultTypeMap[$shareType])) {
293
-					continue;
294
-				}
295
-
296
-				if (!isset($shareTypeResults[$sharee])) {
297
-					$shareTypeResults[$sharee] = [
298
-						'count' => 1,
299
-						'label' => $displayname,
300
-						'value' => [
301
-							'shareType' => $shareType,
302
-							'shareWith' => $sharee,
303
-						],
304
-					];
305
-				} else {
306
-					$shareTypeResults[$sharee]['count']++;
307
-				}
308
-			}
309
-			$result = array_merge($result, array_values($shareTypeResults));
310
-		}
311
-
312
-		$top5 = array_slice(
313
-			$this->sortShareesByFrequency($result),
314
-			0,
315
-			5
316
-		);
317
-
318
-		$searchResult = new SearchResult();
319
-		foreach ($this->searchResultTypeMap as $int => $str) {
320
-			$searchResult->addResultSet(new SearchResultType($str), [], []);
321
-			foreach ($top5 as $x) {
322
-				if ($x['value']['shareType'] === $int) {
323
-					$searchResult->addResultSet(new SearchResultType($str), [], [$x]);
324
-				}
325
-			}
326
-		}
327
-		return $searchResult;
328
-	}
329
-
330
-	/**
331
-	 * @NoAdminRequired
332
-	 *
333
-	 * @param string $itemType
334
-	 * @return DataResponse
335
-	 * @throws OCSBadRequestException
336
-	 */
337
-	public function findRecommended(string $itemType = null, $shareType = null): DataResponse {
338
-		$shareTypes = [
339
-			IShare::TYPE_USER,
340
-		];
341
-
342
-		if ($itemType === null) {
343
-			throw new OCSBadRequestException('Missing itemType');
344
-		} elseif ($itemType === 'file' || $itemType === 'folder') {
345
-			if ($this->shareManager->allowGroupSharing()) {
346
-				$shareTypes[] = IShare::TYPE_GROUP;
347
-			}
348
-
349
-			if ($this->isRemoteSharingAllowed($itemType)) {
350
-				$shareTypes[] = IShare::TYPE_REMOTE;
351
-			}
352
-
353
-			if ($this->isRemoteGroupSharingAllowed($itemType)) {
354
-				$shareTypes[] = IShare::TYPE_REMOTE_GROUP;
355
-			}
356
-
357
-			if ($this->shareManager->shareProviderExists(IShare::TYPE_EMAIL)) {
358
-				$shareTypes[] = IShare::TYPE_EMAIL;
359
-			}
360
-
361
-			if ($this->shareManager->shareProviderExists(IShare::TYPE_ROOM)) {
362
-				$shareTypes[] = IShare::TYPE_ROOM;
363
-			}
364
-		} else {
365
-			$shareTypes[] = IShare::TYPE_GROUP;
366
-			$shareTypes[] = IShare::TYPE_EMAIL;
367
-		}
368
-
369
-		// FIXME: DI
370
-		if (\OC::$server->getAppManager()->isEnabledForUser('circles') && class_exists('\OCA\Circles\ShareByCircleProvider')) {
371
-			$shareTypes[] = IShare::TYPE_CIRCLE;
372
-		}
373
-
374
-		if (isset($_GET['shareType']) && is_array($_GET['shareType'])) {
375
-			$shareTypes = array_intersect($shareTypes, $_GET['shareType']);
376
-			sort($shareTypes);
377
-		} elseif (is_numeric($shareType)) {
378
-			$shareTypes = array_intersect($shareTypes, [(int) $shareType]);
379
-			sort($shareTypes);
380
-		}
381
-
382
-		return new DataResponse(
383
-			$this->getAllSharees($this->userId, $shareTypes)->asArray()
384
-		);
385
-	}
386
-
387
-	/**
388
-	 * Method to get out the static call for better testing
389
-	 *
390
-	 * @param string $itemType
391
-	 * @return bool
392
-	 */
393
-	protected function isRemoteSharingAllowed(string $itemType): bool {
394
-		try {
395
-			// FIXME: static foo makes unit testing unnecessarily difficult
396
-			$backend = \OC\Share\Share::getBackend($itemType);
397
-			return $backend->isShareTypeAllowed(IShare::TYPE_REMOTE);
398
-		} catch (\Exception $e) {
399
-			return false;
400
-		}
401
-	}
402
-
403
-	protected function isRemoteGroupSharingAllowed(string $itemType): bool {
404
-		try {
405
-			// FIXME: static foo makes unit testing unnecessarily difficult
406
-			$backend = \OC\Share\Share::getBackend($itemType);
407
-			return $backend->isShareTypeAllowed(IShare::TYPE_REMOTE_GROUP);
408
-		} catch (\Exception $e) {
409
-			return false;
410
-		}
411
-	}
412
-
413
-
414
-	/**
415
-	 * Generates a bunch of pagination links for the current page
416
-	 *
417
-	 * @param int $page Current page
418
-	 * @param array $params Parameters for the URL
419
-	 * @return string
420
-	 */
421
-	protected function getPaginationLink(int $page, array $params): string {
422
-		if ($this->isV2()) {
423
-			$url = $this->urlGenerator->getAbsoluteURL('/ocs/v2.php/apps/files_sharing/api/v1/sharees') . '?';
424
-		} else {
425
-			$url = $this->urlGenerator->getAbsoluteURL('/ocs/v1.php/apps/files_sharing/api/v1/sharees') . '?';
426
-		}
427
-		$params['page'] = $page + 1;
428
-		return '<' . $url . http_build_query($params) . '>; rel="next"';
429
-	}
430
-
431
-	/**
432
-	 * @return bool
433
-	 */
434
-	protected function isV2(): bool {
435
-		return $this->request->getScriptName() === '/ocs/v2.php';
436
-	}
58
+    /** @var string */
59
+    protected $userId;
60
+
61
+    /** @var IConfig */
62
+    protected $config;
63
+
64
+    /** @var IURLGenerator */
65
+    protected $urlGenerator;
66
+
67
+    /** @var IManager */
68
+    protected $shareManager;
69
+
70
+    /** @var int */
71
+    protected $offset = 0;
72
+
73
+    /** @var int */
74
+    protected $limit = 10;
75
+
76
+    /** @var array */
77
+    protected $result = [
78
+        'exact' => [
79
+            'users' => [],
80
+            'groups' => [],
81
+            'remotes' => [],
82
+            'remote_groups' => [],
83
+            'emails' => [],
84
+            'circles' => [],
85
+            'rooms' => [],
86
+            'deck' => [],
87
+        ],
88
+        'users' => [],
89
+        'groups' => [],
90
+        'remotes' => [],
91
+        'remote_groups' => [],
92
+        'emails' => [],
93
+        'lookup' => [],
94
+        'circles' => [],
95
+        'rooms' => [],
96
+        'deck' => [],
97
+        'lookupEnabled' => false,
98
+    ];
99
+
100
+    protected $reachedEndFor = [];
101
+    /** @var ISearch */
102
+    private $collaboratorSearch;
103
+
104
+    /**
105
+     * @param string $UserId
106
+     * @param string $appName
107
+     * @param IRequest $request
108
+     * @param IConfig $config
109
+     * @param IURLGenerator $urlGenerator
110
+     * @param IManager $shareManager
111
+     * @param ISearch $collaboratorSearch
112
+     */
113
+    public function __construct(
114
+        $UserId,
115
+        string $appName,
116
+        IRequest $request,
117
+        IConfig $config,
118
+        IURLGenerator $urlGenerator,
119
+        IManager $shareManager,
120
+        ISearch $collaboratorSearch
121
+    ) {
122
+        parent::__construct($appName, $request);
123
+        $this->userId = $UserId;
124
+        $this->config = $config;
125
+        $this->urlGenerator = $urlGenerator;
126
+        $this->shareManager = $shareManager;
127
+        $this->collaboratorSearch = $collaboratorSearch;
128
+    }
129
+
130
+    /**
131
+     * @NoAdminRequired
132
+     *
133
+     * @param string $search
134
+     * @param string $itemType
135
+     * @param int $page
136
+     * @param int $perPage
137
+     * @param int|int[] $shareType
138
+     * @param bool $lookup
139
+     * @return DataResponse
140
+     * @throws OCSBadRequestException
141
+     */
142
+    public function search(string $search = '', string $itemType = null, int $page = 1, int $perPage = 200, $shareType = null, bool $lookup = true): DataResponse {
143
+
144
+        // only search for string larger than a given threshold
145
+        $threshold = (int)$this->config->getSystemValue('sharing.minSearchStringLength', 0);
146
+        if (strlen($search) < $threshold) {
147
+            return new DataResponse($this->result);
148
+        }
149
+
150
+        // never return more than the max. number of results configured in the config.php
151
+        $maxResults = (int)$this->config->getSystemValue('sharing.maxAutocompleteResults', 0);
152
+        if ($maxResults > 0) {
153
+            $perPage = min($perPage, $maxResults);
154
+        }
155
+        if ($perPage <= 0) {
156
+            throw new OCSBadRequestException('Invalid perPage argument');
157
+        }
158
+        if ($page <= 0) {
159
+            throw new OCSBadRequestException('Invalid page');
160
+        }
161
+
162
+        $shareTypes = [
163
+            IShare::TYPE_USER,
164
+        ];
165
+
166
+        if ($itemType === null) {
167
+            throw new OCSBadRequestException('Missing itemType');
168
+        } elseif ($itemType === 'file' || $itemType === 'folder') {
169
+            if ($this->shareManager->allowGroupSharing()) {
170
+                $shareTypes[] = IShare::TYPE_GROUP;
171
+            }
172
+
173
+            if ($this->isRemoteSharingAllowed($itemType)) {
174
+                $shareTypes[] = IShare::TYPE_REMOTE;
175
+            }
176
+
177
+            if ($this->isRemoteGroupSharingAllowed($itemType)) {
178
+                $shareTypes[] = IShare::TYPE_REMOTE_GROUP;
179
+            }
180
+
181
+            if ($this->shareManager->shareProviderExists(IShare::TYPE_EMAIL)) {
182
+                $shareTypes[] = IShare::TYPE_EMAIL;
183
+            }
184
+
185
+            if ($this->shareManager->shareProviderExists(IShare::TYPE_ROOM)) {
186
+                $shareTypes[] = IShare::TYPE_ROOM;
187
+            }
188
+
189
+            if ($this->shareManager->shareProviderExists(IShare::TYPE_DECK)) {
190
+                $shareTypes[] = IShare::TYPE_DECK;
191
+            }
192
+        } else {
193
+            $shareTypes[] = IShare::TYPE_GROUP;
194
+            $shareTypes[] = IShare::TYPE_EMAIL;
195
+        }
196
+
197
+        // FIXME: DI
198
+        if (\OC::$server->getAppManager()->isEnabledForUser('circles') && class_exists('\OCA\Circles\ShareByCircleProvider')) {
199
+            $shareTypes[] = IShare::TYPE_CIRCLE;
200
+        }
201
+
202
+        if ($this->shareManager->shareProviderExists(IShare::TYPE_DECK)) {
203
+            $shareTypes[] = IShare::TYPE_DECK;
204
+        }
205
+
206
+        if ($shareType !== null && is_array($shareType)) {
207
+            $shareTypes = array_intersect($shareTypes, $shareType);
208
+        } elseif (is_numeric($shareType)) {
209
+            $shareTypes = array_intersect($shareTypes, [(int) $shareType]);
210
+        }
211
+        sort($shareTypes);
212
+
213
+        $this->limit = (int) $perPage;
214
+        $this->offset = $perPage * ($page - 1);
215
+
216
+        // In global scale mode we always search the loogup server
217
+        if ($this->config->getSystemValueBool('gs.enabled', false)) {
218
+            $lookup = true;
219
+            $this->result['lookupEnabled'] = true;
220
+        } else {
221
+            $this->result['lookupEnabled'] = $this->config->getAppValue('files_sharing', 'lookupServerEnabled', 'yes') === 'yes';
222
+        }
223
+
224
+        list($result, $hasMoreResults) = $this->collaboratorSearch->search($search, $shareTypes, $lookup, $this->limit, $this->offset);
225
+
226
+        // extra treatment for 'exact' subarray, with a single merge expected keys might be lost
227
+        if (isset($result['exact'])) {
228
+            $result['exact'] = array_merge($this->result['exact'], $result['exact']);
229
+        }
230
+        $this->result = array_merge($this->result, $result);
231
+        $response = new DataResponse($this->result);
232
+
233
+        if ($hasMoreResults) {
234
+            $response->addHeader('Link', $this->getPaginationLink($page, [
235
+                'search' => $search,
236
+                'itemType' => $itemType,
237
+                'shareType' => $shareTypes,
238
+                'perPage' => $perPage,
239
+            ]));
240
+        }
241
+
242
+        return $response;
243
+    }
244
+
245
+    /**
246
+     * @param string $user
247
+     * @param int $shareType
248
+     *
249
+     * @return Generator<array<string>>
250
+     */
251
+    private function getAllShareesByType(string $user, int $shareType): Generator {
252
+        $offset = 0;
253
+        $pageSize = 50;
254
+
255
+        while (count($page = $this->shareManager->getSharesBy(
256
+            $user,
257
+            $shareType,
258
+            null,
259
+            false,
260
+            $pageSize,
261
+            $offset
262
+        ))) {
263
+            foreach ($page as $share) {
264
+                yield [$share->getSharedWith(), $share->getSharedWithDisplayName() ?? $share->getSharedWith()];
265
+            }
266
+
267
+            $offset += $pageSize;
268
+        }
269
+    }
270
+
271
+    private function sortShareesByFrequency(array $sharees): array {
272
+        usort($sharees, function (array $s1, array $s2) {
273
+            return $s2['count'] - $s1['count'];
274
+        });
275
+        return $sharees;
276
+    }
277
+
278
+    private $searchResultTypeMap = [
279
+        IShare::TYPE_USER => 'users',
280
+        IShare::TYPE_GROUP => 'groups',
281
+        IShare::TYPE_REMOTE => 'remotes',
282
+        IShare::TYPE_REMOTE_GROUP => 'remote_groups',
283
+        IShare::TYPE_EMAIL => 'emails',
284
+    ];
285
+
286
+    private function getAllSharees(string $user, array $shareTypes): ISearchResult {
287
+        $result = [];
288
+        foreach ($shareTypes as $shareType) {
289
+            $sharees = $this->getAllShareesByType($user, $shareType);
290
+            $shareTypeResults = [];
291
+            foreach ($sharees as list($sharee, $displayname)) {
292
+                if (!isset($this->searchResultTypeMap[$shareType])) {
293
+                    continue;
294
+                }
295
+
296
+                if (!isset($shareTypeResults[$sharee])) {
297
+                    $shareTypeResults[$sharee] = [
298
+                        'count' => 1,
299
+                        'label' => $displayname,
300
+                        'value' => [
301
+                            'shareType' => $shareType,
302
+                            'shareWith' => $sharee,
303
+                        ],
304
+                    ];
305
+                } else {
306
+                    $shareTypeResults[$sharee]['count']++;
307
+                }
308
+            }
309
+            $result = array_merge($result, array_values($shareTypeResults));
310
+        }
311
+
312
+        $top5 = array_slice(
313
+            $this->sortShareesByFrequency($result),
314
+            0,
315
+            5
316
+        );
317
+
318
+        $searchResult = new SearchResult();
319
+        foreach ($this->searchResultTypeMap as $int => $str) {
320
+            $searchResult->addResultSet(new SearchResultType($str), [], []);
321
+            foreach ($top5 as $x) {
322
+                if ($x['value']['shareType'] === $int) {
323
+                    $searchResult->addResultSet(new SearchResultType($str), [], [$x]);
324
+                }
325
+            }
326
+        }
327
+        return $searchResult;
328
+    }
329
+
330
+    /**
331
+     * @NoAdminRequired
332
+     *
333
+     * @param string $itemType
334
+     * @return DataResponse
335
+     * @throws OCSBadRequestException
336
+     */
337
+    public function findRecommended(string $itemType = null, $shareType = null): DataResponse {
338
+        $shareTypes = [
339
+            IShare::TYPE_USER,
340
+        ];
341
+
342
+        if ($itemType === null) {
343
+            throw new OCSBadRequestException('Missing itemType');
344
+        } elseif ($itemType === 'file' || $itemType === 'folder') {
345
+            if ($this->shareManager->allowGroupSharing()) {
346
+                $shareTypes[] = IShare::TYPE_GROUP;
347
+            }
348
+
349
+            if ($this->isRemoteSharingAllowed($itemType)) {
350
+                $shareTypes[] = IShare::TYPE_REMOTE;
351
+            }
352
+
353
+            if ($this->isRemoteGroupSharingAllowed($itemType)) {
354
+                $shareTypes[] = IShare::TYPE_REMOTE_GROUP;
355
+            }
356
+
357
+            if ($this->shareManager->shareProviderExists(IShare::TYPE_EMAIL)) {
358
+                $shareTypes[] = IShare::TYPE_EMAIL;
359
+            }
360
+
361
+            if ($this->shareManager->shareProviderExists(IShare::TYPE_ROOM)) {
362
+                $shareTypes[] = IShare::TYPE_ROOM;
363
+            }
364
+        } else {
365
+            $shareTypes[] = IShare::TYPE_GROUP;
366
+            $shareTypes[] = IShare::TYPE_EMAIL;
367
+        }
368
+
369
+        // FIXME: DI
370
+        if (\OC::$server->getAppManager()->isEnabledForUser('circles') && class_exists('\OCA\Circles\ShareByCircleProvider')) {
371
+            $shareTypes[] = IShare::TYPE_CIRCLE;
372
+        }
373
+
374
+        if (isset($_GET['shareType']) && is_array($_GET['shareType'])) {
375
+            $shareTypes = array_intersect($shareTypes, $_GET['shareType']);
376
+            sort($shareTypes);
377
+        } elseif (is_numeric($shareType)) {
378
+            $shareTypes = array_intersect($shareTypes, [(int) $shareType]);
379
+            sort($shareTypes);
380
+        }
381
+
382
+        return new DataResponse(
383
+            $this->getAllSharees($this->userId, $shareTypes)->asArray()
384
+        );
385
+    }
386
+
387
+    /**
388
+     * Method to get out the static call for better testing
389
+     *
390
+     * @param string $itemType
391
+     * @return bool
392
+     */
393
+    protected function isRemoteSharingAllowed(string $itemType): bool {
394
+        try {
395
+            // FIXME: static foo makes unit testing unnecessarily difficult
396
+            $backend = \OC\Share\Share::getBackend($itemType);
397
+            return $backend->isShareTypeAllowed(IShare::TYPE_REMOTE);
398
+        } catch (\Exception $e) {
399
+            return false;
400
+        }
401
+    }
402
+
403
+    protected function isRemoteGroupSharingAllowed(string $itemType): bool {
404
+        try {
405
+            // FIXME: static foo makes unit testing unnecessarily difficult
406
+            $backend = \OC\Share\Share::getBackend($itemType);
407
+            return $backend->isShareTypeAllowed(IShare::TYPE_REMOTE_GROUP);
408
+        } catch (\Exception $e) {
409
+            return false;
410
+        }
411
+    }
412
+
413
+
414
+    /**
415
+     * Generates a bunch of pagination links for the current page
416
+     *
417
+     * @param int $page Current page
418
+     * @param array $params Parameters for the URL
419
+     * @return string
420
+     */
421
+    protected function getPaginationLink(int $page, array $params): string {
422
+        if ($this->isV2()) {
423
+            $url = $this->urlGenerator->getAbsoluteURL('/ocs/v2.php/apps/files_sharing/api/v1/sharees') . '?';
424
+        } else {
425
+            $url = $this->urlGenerator->getAbsoluteURL('/ocs/v1.php/apps/files_sharing/api/v1/sharees') . '?';
426
+        }
427
+        $params['page'] = $page + 1;
428
+        return '<' . $url . http_build_query($params) . '>; rel="next"';
429
+    }
430
+
431
+    /**
432
+     * @return bool
433
+     */
434
+    protected function isV2(): bool {
435
+        return $this->request->getScriptName() === '/ocs/v2.php';
436
+    }
437 437
 }
Please login to merge, or discard this patch.