Completed
Pull Request — master (#6255)
by Joas
15:21
created
apps/sharebymail/lib/ShareByMailProvider.php 2 patches
Indentation   +1007 added lines, -1007 removed lines patch added patch discarded remove patch
@@ -53,1025 +53,1025 @@
 block discarded – undo
53 53
  */
54 54
 class ShareByMailProvider implements IShareProvider {
55 55
 
56
-	/** @var  IDBConnection */
57
-	private $dbConnection;
58
-
59
-	/** @var ILogger */
60
-	private $logger;
61
-
62
-	/** @var ISecureRandom */
63
-	private $secureRandom;
64
-
65
-	/** @var IUserManager */
66
-	private $userManager;
67
-
68
-	/** @var IRootFolder */
69
-	private $rootFolder;
70
-
71
-	/** @var IL10N */
72
-	private $l;
73
-
74
-	/** @var IMailer */
75
-	private $mailer;
76
-
77
-	/** @var IURLGenerator */
78
-	private $urlGenerator;
79
-
80
-	/** @var IManager  */
81
-	private $activityManager;
82
-
83
-	/** @var SettingsManager */
84
-	private $settingsManager;
85
-
86
-	/** @var Defaults */
87
-	private $defaults;
88
-
89
-	/** @var IHasher */
90
-	private $hasher;
91
-
92
-	/** @var  CapabilitiesManager */
93
-	private $capabilitiesManager;
94
-
95
-	/**
96
-	 * Return the identifier of this provider.
97
-	 *
98
-	 * @return string Containing only [a-zA-Z0-9]
99
-	 */
100
-	public function identifier() {
101
-		return 'ocMailShare';
102
-	}
103
-
104
-	/**
105
-	 * DefaultShareProvider constructor.
106
-	 *
107
-	 * @param IDBConnection $connection
108
-	 * @param ISecureRandom $secureRandom
109
-	 * @param IUserManager $userManager
110
-	 * @param IRootFolder $rootFolder
111
-	 * @param IL10N $l
112
-	 * @param ILogger $logger
113
-	 * @param IMailer $mailer
114
-	 * @param IURLGenerator $urlGenerator
115
-	 * @param IManager $activityManager
116
-	 * @param SettingsManager $settingsManager
117
-	 * @param Defaults $defaults
118
-	 * @param IHasher $hasher
119
-	 * @param CapabilitiesManager $capabilitiesManager
120
-	 */
121
-	public function __construct(
122
-		IDBConnection $connection,
123
-		ISecureRandom $secureRandom,
124
-		IUserManager $userManager,
125
-		IRootFolder $rootFolder,
126
-		IL10N $l,
127
-		ILogger $logger,
128
-		IMailer $mailer,
129
-		IURLGenerator $urlGenerator,
130
-		IManager $activityManager,
131
-		SettingsManager $settingsManager,
132
-		Defaults $defaults,
133
-		IHasher $hasher,
134
-		CapabilitiesManager $capabilitiesManager
135
-	) {
136
-		$this->dbConnection = $connection;
137
-		$this->secureRandom = $secureRandom;
138
-		$this->userManager = $userManager;
139
-		$this->rootFolder = $rootFolder;
140
-		$this->l = $l;
141
-		$this->logger = $logger;
142
-		$this->mailer = $mailer;
143
-		$this->urlGenerator = $urlGenerator;
144
-		$this->activityManager = $activityManager;
145
-		$this->settingsManager = $settingsManager;
146
-		$this->defaults = $defaults;
147
-		$this->hasher = $hasher;
148
-		$this->capabilitiesManager = $capabilitiesManager;
149
-	}
150
-
151
-	/**
152
-	 * Share a path
153
-	 *
154
-	 * @param IShare $share
155
-	 * @return IShare The share object
156
-	 * @throws ShareNotFound
157
-	 * @throws \Exception
158
-	 */
159
-	public function create(IShare $share) {
160
-
161
-		$shareWith = $share->getSharedWith();
162
-		/*
56
+    /** @var  IDBConnection */
57
+    private $dbConnection;
58
+
59
+    /** @var ILogger */
60
+    private $logger;
61
+
62
+    /** @var ISecureRandom */
63
+    private $secureRandom;
64
+
65
+    /** @var IUserManager */
66
+    private $userManager;
67
+
68
+    /** @var IRootFolder */
69
+    private $rootFolder;
70
+
71
+    /** @var IL10N */
72
+    private $l;
73
+
74
+    /** @var IMailer */
75
+    private $mailer;
76
+
77
+    /** @var IURLGenerator */
78
+    private $urlGenerator;
79
+
80
+    /** @var IManager  */
81
+    private $activityManager;
82
+
83
+    /** @var SettingsManager */
84
+    private $settingsManager;
85
+
86
+    /** @var Defaults */
87
+    private $defaults;
88
+
89
+    /** @var IHasher */
90
+    private $hasher;
91
+
92
+    /** @var  CapabilitiesManager */
93
+    private $capabilitiesManager;
94
+
95
+    /**
96
+     * Return the identifier of this provider.
97
+     *
98
+     * @return string Containing only [a-zA-Z0-9]
99
+     */
100
+    public function identifier() {
101
+        return 'ocMailShare';
102
+    }
103
+
104
+    /**
105
+     * DefaultShareProvider constructor.
106
+     *
107
+     * @param IDBConnection $connection
108
+     * @param ISecureRandom $secureRandom
109
+     * @param IUserManager $userManager
110
+     * @param IRootFolder $rootFolder
111
+     * @param IL10N $l
112
+     * @param ILogger $logger
113
+     * @param IMailer $mailer
114
+     * @param IURLGenerator $urlGenerator
115
+     * @param IManager $activityManager
116
+     * @param SettingsManager $settingsManager
117
+     * @param Defaults $defaults
118
+     * @param IHasher $hasher
119
+     * @param CapabilitiesManager $capabilitiesManager
120
+     */
121
+    public function __construct(
122
+        IDBConnection $connection,
123
+        ISecureRandom $secureRandom,
124
+        IUserManager $userManager,
125
+        IRootFolder $rootFolder,
126
+        IL10N $l,
127
+        ILogger $logger,
128
+        IMailer $mailer,
129
+        IURLGenerator $urlGenerator,
130
+        IManager $activityManager,
131
+        SettingsManager $settingsManager,
132
+        Defaults $defaults,
133
+        IHasher $hasher,
134
+        CapabilitiesManager $capabilitiesManager
135
+    ) {
136
+        $this->dbConnection = $connection;
137
+        $this->secureRandom = $secureRandom;
138
+        $this->userManager = $userManager;
139
+        $this->rootFolder = $rootFolder;
140
+        $this->l = $l;
141
+        $this->logger = $logger;
142
+        $this->mailer = $mailer;
143
+        $this->urlGenerator = $urlGenerator;
144
+        $this->activityManager = $activityManager;
145
+        $this->settingsManager = $settingsManager;
146
+        $this->defaults = $defaults;
147
+        $this->hasher = $hasher;
148
+        $this->capabilitiesManager = $capabilitiesManager;
149
+    }
150
+
151
+    /**
152
+     * Share a path
153
+     *
154
+     * @param IShare $share
155
+     * @return IShare The share object
156
+     * @throws ShareNotFound
157
+     * @throws \Exception
158
+     */
159
+    public function create(IShare $share) {
160
+
161
+        $shareWith = $share->getSharedWith();
162
+        /*
163 163
 		 * Check if file is not already shared with the remote user
164 164
 		 */
165
-		$alreadyShared = $this->getSharedWith($shareWith, \OCP\Share::SHARE_TYPE_EMAIL, $share->getNode(), 1, 0);
166
-		if (!empty($alreadyShared)) {
167
-			$message = 'Sharing %s failed, this item is already shared with %s';
168
-			$message_t = $this->l->t('Sharing %s failed, this item is already shared with %s', array($share->getNode()->getName(), $shareWith));
169
-			$this->logger->debug(sprintf($message, $share->getNode()->getName(), $shareWith), ['app' => 'Federated File Sharing']);
170
-			throw new \Exception($message_t);
171
-		}
172
-
173
-		// if the admin enforces a password for all mail shares we create a
174
-		// random password and send it to the recipient
175
-		$password = '';
176
-		$passwordEnforced = $this->settingsManager->enforcePasswordProtection();
177
-		if ($passwordEnforced) {
178
-			$password = $this->autoGeneratePassword($share);
179
-		}
180
-
181
-		$shareId = $this->createMailShare($share);
182
-		$send = $this->sendPassword($share, $password);
183
-		if ($passwordEnforced && $send === false) {
184
-			$this->sendPasswordToOwner($share, $password);
185
-		}
186
-
187
-		$this->createShareActivity($share);
188
-		$data = $this->getRawShare($shareId);
189
-
190
-		return $this->createShareObject($data);
191
-
192
-	}
193
-
194
-	/**
195
-	 * auto generate password in case of password enforcement on mail shares
196
-	 *
197
-	 * @param IShare $share
198
-	 * @return string
199
-	 * @throws \Exception
200
-	 */
201
-	protected function autoGeneratePassword($share) {
202
-		$initiatorUser = $this->userManager->get($share->getSharedBy());
203
-		$initiatorEMailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
204
-		$allowPasswordByMail = $this->settingsManager->sendPasswordByMail();
205
-
206
-		if ($initiatorEMailAddress === null && !$allowPasswordByMail) {
207
-			throw new \Exception(
208
-				$this->l->t("We can't send you the auto-generated password. Please set a valid email address in your personal settings and try again.")
209
-			);
210
-		}
211
-
212
-		$passwordPolicy = $this->getPasswordPolicy();
213
-		$passwordCharset = ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS;
214
-		$passwordLength = 8;
215
-		if (!empty($passwordPolicy)) {
216
-			$passwordLength = (int)$passwordPolicy['minLength'] > 0 ? (int)$passwordPolicy['minLength'] : $passwordLength;
217
-			$passwordCharset .= $passwordPolicy['enforceSpecialCharacters'] ? ISecureRandom::CHAR_SYMBOLS : '';
218
-		}
219
-
220
-		$password = $this->secureRandom->generate($passwordLength, $passwordCharset);
221
-
222
-		$share->setPassword($this->hasher->hash($password));
223
-
224
-		return $password;
225
-	}
226
-
227
-	/**
228
-	 * get password policy
229
-	 *
230
-	 * @return array
231
-	 */
232
-	protected function getPasswordPolicy() {
233
-		$capabilities = $this->capabilitiesManager->getCapabilities();
234
-		if (isset($capabilities['password_policy'])) {
235
-			return $capabilities['password_policy'];
236
-		}
237
-
238
-		return [];
239
-	}
240
-
241
-	/**
242
-	 * create activity if a file/folder was shared by mail
243
-	 *
244
-	 * @param IShare $share
245
-	 */
246
-	protected function createShareActivity(IShare $share) {
247
-
248
-		$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
249
-
250
-		$this->publishActivity(
251
-			Activity::SUBJECT_SHARED_EMAIL_SELF,
252
-			[$userFolder->getRelativePath($share->getNode()->getPath()), $share->getSharedWith()],
253
-			$share->getSharedBy(),
254
-			$share->getNode()->getId(),
255
-			$userFolder->getRelativePath($share->getNode()->getPath())
256
-		);
257
-
258
-		if ($share->getShareOwner() !== $share->getSharedBy()) {
259
-			$ownerFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
260
-			$fileId = $share->getNode()->getId();
261
-			$nodes = $ownerFolder->getById($fileId);
262
-			$ownerPath = $nodes[0]->getPath();
263
-			$this->publishActivity(
264
-				Activity::SUBJECT_SHARED_EMAIL_BY,
265
-				[$ownerFolder->getRelativePath($ownerPath), $share->getSharedWith(), $share->getSharedBy()],
266
-				$share->getShareOwner(),
267
-				$fileId,
268
-				$ownerFolder->getRelativePath($ownerPath)
269
-			);
270
-		}
271
-
272
-	}
273
-
274
-	/**
275
-	 * create activity if a file/folder was shared by mail
276
-	 *
277
-	 * @param IShare $share
278
-	 * @param string $sharedWith
279
-	 * @param bool $sendToSelf
280
-	 */
281
-	protected function createPasswordSendActivity(IShare $share, $sharedWith, $sendToSelf) {
282
-
283
-		$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
284
-
285
-		if ($sendToSelf) {
286
-			$this->publishActivity(
287
-				Activity::SUBJECT_SHARED_EMAIL_PASSWORD_SEND_SELF,
288
-				[$userFolder->getRelativePath($share->getNode()->getPath())],
289
-				$share->getSharedBy(),
290
-				$share->getNode()->getId(),
291
-				$userFolder->getRelativePath($share->getNode()->getPath())
292
-			);
293
-		} else {
294
-			$this->publishActivity(
295
-				Activity::SUBJECT_SHARED_EMAIL_PASSWORD_SEND,
296
-				[$userFolder->getRelativePath($share->getNode()->getPath()), $sharedWith],
297
-				$share->getSharedBy(),
298
-				$share->getNode()->getId(),
299
-				$userFolder->getRelativePath($share->getNode()->getPath())
300
-			);
301
-		}
302
-	}
303
-
304
-
305
-	/**
306
-	 * publish activity if a file/folder was shared by mail
307
-	 *
308
-	 * @param $subject
309
-	 * @param $parameters
310
-	 * @param $affectedUser
311
-	 * @param $fileId
312
-	 * @param $filePath
313
-	 */
314
-	protected function publishActivity($subject, $parameters, $affectedUser, $fileId, $filePath) {
315
-		$event = $this->activityManager->generateEvent();
316
-		$event->setApp('sharebymail')
317
-			->setType('shared')
318
-			->setSubject($subject, $parameters)
319
-			->setAffectedUser($affectedUser)
320
-			->setObject('files', $fileId, $filePath);
321
-		$this->activityManager->publish($event);
322
-
323
-	}
324
-
325
-	/**
326
-	 * @param IShare $share
327
-	 * @return int
328
-	 * @throws \Exception
329
-	 */
330
-	protected function createMailShare(IShare $share) {
331
-		$share->setToken($this->generateToken());
332
-		$shareId = $this->addShareToDB(
333
-			$share->getNodeId(),
334
-			$share->getNodeType(),
335
-			$share->getSharedWith(),
336
-			$share->getSharedBy(),
337
-			$share->getShareOwner(),
338
-			$share->getPermissions(),
339
-			$share->getToken(),
340
-			$share->getPassword()
341
-		);
342
-
343
-		try {
344
-			$link = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare',
345
-				['token' => $share->getToken()]);
346
-			$this->sendMailNotification(
347
-				$share->getNode()->getName(),
348
-				$link,
349
-				$share->getSharedBy(),
350
-				$share->getSharedWith(),
351
-				$share->getExpirationDate()
352
-			);
353
-		} catch (HintException $hintException) {
354
-			$this->logger->error('Failed to send share by mail: ' . $hintException->getMessage());
355
-			$this->removeShareFromTable($shareId);
356
-			throw $hintException;
357
-		} catch (\Exception $e) {
358
-			$this->logger->error('Failed to send share by email: ' . $e->getMessage());
359
-			$this->removeShareFromTable($shareId);
360
-			throw new HintException('Failed to send share by mail',
361
-				$this->l->t('Failed to send share by email'));
362
-		}
363
-
364
-		return $shareId;
365
-
366
-	}
367
-
368
-	/**
369
-	 * @param string $filename
370
-	 * @param string $link
371
-	 * @param string $initiator
372
-	 * @param string $shareWith
373
-	 * @param \DateTime $expiration
374
-	 * @throws \Exception If mail couldn't be sent
375
-	 */
376
-	protected function sendMailNotification($filename,
377
-											$link,
378
-											$initiator,
379
-											$shareWith,
380
-											\DateTime $expiration) {
381
-		$initiatorUser = $this->userManager->get($initiator);
382
-		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
383
-		$subject = (string)$this->l->t('%s shared »%s« with you', array($initiatorDisplayName, $filename));
384
-
385
-		$message = $this->mailer->createMessage();
386
-
387
-		$emailTemplate = $this->mailer->createEMailTemplate();
388
-		$emailTemplate->setMetaData('sharebymail.RecipientNotification', [
389
-			'filename' => $filename,
390
-			'link' => $link,
391
-			'initiator' => $initiatorDisplayName,
392
-			'expiration' => $expiration,
393
-		]);
394
-
395
-		$emailTemplate->addHeader();
396
-		$emailTemplate->addHeading($this->l->t('%s shared »%s« with you', [$initiatorDisplayName, $filename]), false);
397
-		$text = $this->l->t('%s shared »%s« with you.', [$initiatorDisplayName, $filename]);
398
-
399
-		$emailTemplate->addBodyText(
400
-			$text . ' ' . $this->l->t('Click the button below to open it.'),
401
-			$text
402
-		);
403
-		$emailTemplate->addBodyButton(
404
-			$this->l->t('Open »%s«', [$filename]),
405
-			$link
406
-		);
407
-
408
-		$message->setTo([$shareWith]);
409
-
410
-		// The "From" contains the sharers name
411
-		$instanceName = $this->defaults->getName();
412
-		$senderName = $this->l->t(
413
-			'%s via %s',
414
-			[
415
-				$initiatorDisplayName,
416
-				$instanceName
417
-			]
418
-		);
419
-		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
420
-
421
-		// The "Reply-To" is set to the sharer if an mail address is configured
422
-		// also the default footer contains a "Do not reply" which needs to be adjusted.
423
-		$initiatorEmail = $initiatorUser->getEMailAddress();
424
-		if($initiatorEmail !== null) {
425
-			$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
426
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
427
-		} else {
428
-			$emailTemplate->addFooter();
429
-		}
430
-
431
-		$message->setSubject($subject);
432
-		$message->setPlainBody($emailTemplate->renderText());
433
-		$message->setHtmlBody($emailTemplate->renderHtml());
434
-		$this->mailer->send($message);
435
-	}
436
-
437
-	/**
438
-	 * send password to recipient of a mail share
439
-	 *
440
-	 * @param IShare $share
441
-	 * @param string $password
442
-	 * @return bool
443
-	 */
444
-	protected function sendPassword(IShare $share, $password) {
445
-
446
-		$filename = $share->getNode()->getName();
447
-		$initiator = $share->getSharedBy();
448
-		$shareWith = $share->getSharedWith();
449
-
450
-		if ($password === '' || $this->settingsManager->sendPasswordByMail() === false) {
451
-			return false;
452
-		}
453
-
454
-		$initiatorUser = $this->userManager->get($initiator);
455
-		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
456
-		$initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
457
-
458
-		$subject = (string)$this->l->t('Password to access »%s« shared to you by %s', [$filename, $initiatorDisplayName]);
459
-		$plainBodyPart = $this->l->t("%s shared »%s« with you.\nYou should have already received a separate mail with a link to access it.\n", [$initiatorDisplayName, $filename]);
460
-		$htmlBodyPart = $this->l->t('%s shared »%s« with you. You should have already received a separate mail with a link to access it.', [$initiatorDisplayName, $filename]);
461
-
462
-		$message = $this->mailer->createMessage();
463
-
464
-		$emailTemplate = $this->mailer->createEMailTemplate();
465
-		$emailTemplate->addHeader();
466
-		$emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
467
-		$emailTemplate->addBodyText($htmlBodyPart, $plainBodyPart);
468
-		$emailTemplate->addBodyText($this->l->t('It is protected with the following password: %s', [$password]));
469
-
470
-		// The "From" contains the sharers name
471
-		$instanceName = $this->defaults->getName();
472
-		$senderName = $this->l->t(
473
-			'%s via %s',
474
-			[
475
-				$initiatorDisplayName,
476
-				$instanceName
477
-			]
478
-		);
479
-		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
480
-		if ($initiatorEmailAddress !== null) {
481
-			$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
482
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
483
-		} else {
484
-			$emailTemplate->addFooter();
485
-		}
486
-
487
-		$message->setTo([$shareWith]);
488
-		$message->setSubject($subject);
489
-		$message->setBody($emailTemplate->renderText(), 'text/plain');
490
-		$message->setHtmlBody($emailTemplate->renderHtml());
491
-		$this->mailer->send($message);
492
-
493
-		$this->createPasswordSendActivity($share, $shareWith, false);
494
-
495
-		return true;
496
-	}
497
-
498
-	/**
499
-	 * send auto generated password to the owner. This happens if the admin enforces
500
-	 * a password for mail shares and forbid to send the password by mail to the recipient
501
-	 *
502
-	 * @param IShare $share
503
-	 * @param string $password
504
-	 * @return bool
505
-	 * @throws \Exception
506
-	 */
507
-	protected function sendPasswordToOwner(IShare $share, $password) {
508
-
509
-		$filename = $share->getNode()->getName();
510
-		$initiator = $this->userManager->get($share->getSharedBy());
511
-		$initiatorEMailAddress = ($initiator instanceof IUser) ? $initiator->getEMailAddress() : null;
512
-		$initiatorDisplayName = ($initiator instanceof IUser) ? $initiator->getDisplayName() : $share->getSharedBy();
513
-		$shareWith = $share->getSharedWith();
514
-
515
-		if ($initiatorEMailAddress === null) {
516
-			throw new \Exception(
517
-				$this->l->t("We can't send you the auto-generated password. Please set a valid email address in your personal settings and try again.")
518
-			);
519
-		}
520
-
521
-		$subject = (string)$this->l->t('Password to access »%s« shared with %s', [$filename, $shareWith]);
522
-		$bodyPart = $this->l->t("You just shared »%s« with %s. The share was already send to the recipient. Due to the security policies defined by the administrator of %s each share needs to be protected by password and it is not allowed to send the password directly to the recipient. Therefore you need to forward the password manually to the recipient.", [$filename, $shareWith, $this->defaults->getName()]);
523
-
524
-		$message = $this->mailer->createMessage();
525
-		$emailTemplate = $this->mailer->createEMailTemplate();
526
-
527
-		$emailTemplate->addHeader();
528
-		$emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
529
-		$emailTemplate->addBodyText($bodyPart);
530
-		$emailTemplate->addBodyText($this->l->t('This is the password: %s', [$password]));
531
-		$emailTemplate->addBodyText($this->l->t('You can choose a different password at any time in the share dialog.'));
532
-		$emailTemplate->addFooter();
533
-
534
-		if ($initiatorEMailAddress) {
535
-			$message->setFrom([$initiatorEMailAddress => $initiatorDisplayName]);
536
-		}
537
-		$message->setTo([$initiatorEMailAddress => $initiatorDisplayName]);
538
-		$message->setSubject($subject);
539
-		$message->setBody($emailTemplate->renderText(), 'text/plain');
540
-		$message->setHtmlBody($emailTemplate->renderHtml());
541
-		$this->mailer->send($message);
542
-
543
-		$this->createPasswordSendActivity($share, $shareWith, true);
544
-
545
-		return true;
546
-	}
547
-
548
-	/**
549
-	 * generate share token
550
-	 *
551
-	 * @return string
552
-	 */
553
-	protected function generateToken($size = 15) {
554
-		$token = $this->secureRandom->generate($size, ISecureRandom::CHAR_HUMAN_READABLE);
555
-		return $token;
556
-	}
557
-
558
-	/**
559
-	 * Get all children of this share
560
-	 *
561
-	 * @param IShare $parent
562
-	 * @return IShare[]
563
-	 */
564
-	public function getChildren(IShare $parent) {
565
-		$children = [];
566
-
567
-		$qb = $this->dbConnection->getQueryBuilder();
568
-		$qb->select('*')
569
-			->from('share')
570
-			->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
571
-			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
572
-			->orderBy('id');
573
-
574
-		$cursor = $qb->execute();
575
-		while($data = $cursor->fetch()) {
576
-			$children[] = $this->createShareObject($data);
577
-		}
578
-		$cursor->closeCursor();
579
-
580
-		return $children;
581
-	}
582
-
583
-	/**
584
-	 * add share to the database and return the ID
585
-	 *
586
-	 * @param int $itemSource
587
-	 * @param string $itemType
588
-	 * @param string $shareWith
589
-	 * @param string $sharedBy
590
-	 * @param string $uidOwner
591
-	 * @param int $permissions
592
-	 * @param string $token
593
-	 * @return int
594
-	 */
595
-	protected function addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token, $password) {
596
-		$qb = $this->dbConnection->getQueryBuilder();
597
-		$qb->insert('share')
598
-			->setValue('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))
599
-			->setValue('item_type', $qb->createNamedParameter($itemType))
600
-			->setValue('item_source', $qb->createNamedParameter($itemSource))
601
-			->setValue('file_source', $qb->createNamedParameter($itemSource))
602
-			->setValue('share_with', $qb->createNamedParameter($shareWith))
603
-			->setValue('uid_owner', $qb->createNamedParameter($uidOwner))
604
-			->setValue('uid_initiator', $qb->createNamedParameter($sharedBy))
605
-			->setValue('permissions', $qb->createNamedParameter($permissions))
606
-			->setValue('token', $qb->createNamedParameter($token))
607
-			->setValue('password', $qb->createNamedParameter($password))
608
-			->setValue('stime', $qb->createNamedParameter(time()));
609
-
610
-		/*
165
+        $alreadyShared = $this->getSharedWith($shareWith, \OCP\Share::SHARE_TYPE_EMAIL, $share->getNode(), 1, 0);
166
+        if (!empty($alreadyShared)) {
167
+            $message = 'Sharing %s failed, this item is already shared with %s';
168
+            $message_t = $this->l->t('Sharing %s failed, this item is already shared with %s', array($share->getNode()->getName(), $shareWith));
169
+            $this->logger->debug(sprintf($message, $share->getNode()->getName(), $shareWith), ['app' => 'Federated File Sharing']);
170
+            throw new \Exception($message_t);
171
+        }
172
+
173
+        // if the admin enforces a password for all mail shares we create a
174
+        // random password and send it to the recipient
175
+        $password = '';
176
+        $passwordEnforced = $this->settingsManager->enforcePasswordProtection();
177
+        if ($passwordEnforced) {
178
+            $password = $this->autoGeneratePassword($share);
179
+        }
180
+
181
+        $shareId = $this->createMailShare($share);
182
+        $send = $this->sendPassword($share, $password);
183
+        if ($passwordEnforced && $send === false) {
184
+            $this->sendPasswordToOwner($share, $password);
185
+        }
186
+
187
+        $this->createShareActivity($share);
188
+        $data = $this->getRawShare($shareId);
189
+
190
+        return $this->createShareObject($data);
191
+
192
+    }
193
+
194
+    /**
195
+     * auto generate password in case of password enforcement on mail shares
196
+     *
197
+     * @param IShare $share
198
+     * @return string
199
+     * @throws \Exception
200
+     */
201
+    protected function autoGeneratePassword($share) {
202
+        $initiatorUser = $this->userManager->get($share->getSharedBy());
203
+        $initiatorEMailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
204
+        $allowPasswordByMail = $this->settingsManager->sendPasswordByMail();
205
+
206
+        if ($initiatorEMailAddress === null && !$allowPasswordByMail) {
207
+            throw new \Exception(
208
+                $this->l->t("We can't send you the auto-generated password. Please set a valid email address in your personal settings and try again.")
209
+            );
210
+        }
211
+
212
+        $passwordPolicy = $this->getPasswordPolicy();
213
+        $passwordCharset = ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS;
214
+        $passwordLength = 8;
215
+        if (!empty($passwordPolicy)) {
216
+            $passwordLength = (int)$passwordPolicy['minLength'] > 0 ? (int)$passwordPolicy['minLength'] : $passwordLength;
217
+            $passwordCharset .= $passwordPolicy['enforceSpecialCharacters'] ? ISecureRandom::CHAR_SYMBOLS : '';
218
+        }
219
+
220
+        $password = $this->secureRandom->generate($passwordLength, $passwordCharset);
221
+
222
+        $share->setPassword($this->hasher->hash($password));
223
+
224
+        return $password;
225
+    }
226
+
227
+    /**
228
+     * get password policy
229
+     *
230
+     * @return array
231
+     */
232
+    protected function getPasswordPolicy() {
233
+        $capabilities = $this->capabilitiesManager->getCapabilities();
234
+        if (isset($capabilities['password_policy'])) {
235
+            return $capabilities['password_policy'];
236
+        }
237
+
238
+        return [];
239
+    }
240
+
241
+    /**
242
+     * create activity if a file/folder was shared by mail
243
+     *
244
+     * @param IShare $share
245
+     */
246
+    protected function createShareActivity(IShare $share) {
247
+
248
+        $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
249
+
250
+        $this->publishActivity(
251
+            Activity::SUBJECT_SHARED_EMAIL_SELF,
252
+            [$userFolder->getRelativePath($share->getNode()->getPath()), $share->getSharedWith()],
253
+            $share->getSharedBy(),
254
+            $share->getNode()->getId(),
255
+            $userFolder->getRelativePath($share->getNode()->getPath())
256
+        );
257
+
258
+        if ($share->getShareOwner() !== $share->getSharedBy()) {
259
+            $ownerFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
260
+            $fileId = $share->getNode()->getId();
261
+            $nodes = $ownerFolder->getById($fileId);
262
+            $ownerPath = $nodes[0]->getPath();
263
+            $this->publishActivity(
264
+                Activity::SUBJECT_SHARED_EMAIL_BY,
265
+                [$ownerFolder->getRelativePath($ownerPath), $share->getSharedWith(), $share->getSharedBy()],
266
+                $share->getShareOwner(),
267
+                $fileId,
268
+                $ownerFolder->getRelativePath($ownerPath)
269
+            );
270
+        }
271
+
272
+    }
273
+
274
+    /**
275
+     * create activity if a file/folder was shared by mail
276
+     *
277
+     * @param IShare $share
278
+     * @param string $sharedWith
279
+     * @param bool $sendToSelf
280
+     */
281
+    protected function createPasswordSendActivity(IShare $share, $sharedWith, $sendToSelf) {
282
+
283
+        $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
284
+
285
+        if ($sendToSelf) {
286
+            $this->publishActivity(
287
+                Activity::SUBJECT_SHARED_EMAIL_PASSWORD_SEND_SELF,
288
+                [$userFolder->getRelativePath($share->getNode()->getPath())],
289
+                $share->getSharedBy(),
290
+                $share->getNode()->getId(),
291
+                $userFolder->getRelativePath($share->getNode()->getPath())
292
+            );
293
+        } else {
294
+            $this->publishActivity(
295
+                Activity::SUBJECT_SHARED_EMAIL_PASSWORD_SEND,
296
+                [$userFolder->getRelativePath($share->getNode()->getPath()), $sharedWith],
297
+                $share->getSharedBy(),
298
+                $share->getNode()->getId(),
299
+                $userFolder->getRelativePath($share->getNode()->getPath())
300
+            );
301
+        }
302
+    }
303
+
304
+
305
+    /**
306
+     * publish activity if a file/folder was shared by mail
307
+     *
308
+     * @param $subject
309
+     * @param $parameters
310
+     * @param $affectedUser
311
+     * @param $fileId
312
+     * @param $filePath
313
+     */
314
+    protected function publishActivity($subject, $parameters, $affectedUser, $fileId, $filePath) {
315
+        $event = $this->activityManager->generateEvent();
316
+        $event->setApp('sharebymail')
317
+            ->setType('shared')
318
+            ->setSubject($subject, $parameters)
319
+            ->setAffectedUser($affectedUser)
320
+            ->setObject('files', $fileId, $filePath);
321
+        $this->activityManager->publish($event);
322
+
323
+    }
324
+
325
+    /**
326
+     * @param IShare $share
327
+     * @return int
328
+     * @throws \Exception
329
+     */
330
+    protected function createMailShare(IShare $share) {
331
+        $share->setToken($this->generateToken());
332
+        $shareId = $this->addShareToDB(
333
+            $share->getNodeId(),
334
+            $share->getNodeType(),
335
+            $share->getSharedWith(),
336
+            $share->getSharedBy(),
337
+            $share->getShareOwner(),
338
+            $share->getPermissions(),
339
+            $share->getToken(),
340
+            $share->getPassword()
341
+        );
342
+
343
+        try {
344
+            $link = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare',
345
+                ['token' => $share->getToken()]);
346
+            $this->sendMailNotification(
347
+                $share->getNode()->getName(),
348
+                $link,
349
+                $share->getSharedBy(),
350
+                $share->getSharedWith(),
351
+                $share->getExpirationDate()
352
+            );
353
+        } catch (HintException $hintException) {
354
+            $this->logger->error('Failed to send share by mail: ' . $hintException->getMessage());
355
+            $this->removeShareFromTable($shareId);
356
+            throw $hintException;
357
+        } catch (\Exception $e) {
358
+            $this->logger->error('Failed to send share by email: ' . $e->getMessage());
359
+            $this->removeShareFromTable($shareId);
360
+            throw new HintException('Failed to send share by mail',
361
+                $this->l->t('Failed to send share by email'));
362
+        }
363
+
364
+        return $shareId;
365
+
366
+    }
367
+
368
+    /**
369
+     * @param string $filename
370
+     * @param string $link
371
+     * @param string $initiator
372
+     * @param string $shareWith
373
+     * @param \DateTime $expiration
374
+     * @throws \Exception If mail couldn't be sent
375
+     */
376
+    protected function sendMailNotification($filename,
377
+                                            $link,
378
+                                            $initiator,
379
+                                            $shareWith,
380
+                                            \DateTime $expiration) {
381
+        $initiatorUser = $this->userManager->get($initiator);
382
+        $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
383
+        $subject = (string)$this->l->t('%s shared »%s« with you', array($initiatorDisplayName, $filename));
384
+
385
+        $message = $this->mailer->createMessage();
386
+
387
+        $emailTemplate = $this->mailer->createEMailTemplate();
388
+        $emailTemplate->setMetaData('sharebymail.RecipientNotification', [
389
+            'filename' => $filename,
390
+            'link' => $link,
391
+            'initiator' => $initiatorDisplayName,
392
+            'expiration' => $expiration,
393
+        ]);
394
+
395
+        $emailTemplate->addHeader();
396
+        $emailTemplate->addHeading($this->l->t('%s shared »%s« with you', [$initiatorDisplayName, $filename]), false);
397
+        $text = $this->l->t('%s shared »%s« with you.', [$initiatorDisplayName, $filename]);
398
+
399
+        $emailTemplate->addBodyText(
400
+            $text . ' ' . $this->l->t('Click the button below to open it.'),
401
+            $text
402
+        );
403
+        $emailTemplate->addBodyButton(
404
+            $this->l->t('Open »%s«', [$filename]),
405
+            $link
406
+        );
407
+
408
+        $message->setTo([$shareWith]);
409
+
410
+        // The "From" contains the sharers name
411
+        $instanceName = $this->defaults->getName();
412
+        $senderName = $this->l->t(
413
+            '%s via %s',
414
+            [
415
+                $initiatorDisplayName,
416
+                $instanceName
417
+            ]
418
+        );
419
+        $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
420
+
421
+        // The "Reply-To" is set to the sharer if an mail address is configured
422
+        // also the default footer contains a "Do not reply" which needs to be adjusted.
423
+        $initiatorEmail = $initiatorUser->getEMailAddress();
424
+        if($initiatorEmail !== null) {
425
+            $message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
426
+            $emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
427
+        } else {
428
+            $emailTemplate->addFooter();
429
+        }
430
+
431
+        $message->setSubject($subject);
432
+        $message->setPlainBody($emailTemplate->renderText());
433
+        $message->setHtmlBody($emailTemplate->renderHtml());
434
+        $this->mailer->send($message);
435
+    }
436
+
437
+    /**
438
+     * send password to recipient of a mail share
439
+     *
440
+     * @param IShare $share
441
+     * @param string $password
442
+     * @return bool
443
+     */
444
+    protected function sendPassword(IShare $share, $password) {
445
+
446
+        $filename = $share->getNode()->getName();
447
+        $initiator = $share->getSharedBy();
448
+        $shareWith = $share->getSharedWith();
449
+
450
+        if ($password === '' || $this->settingsManager->sendPasswordByMail() === false) {
451
+            return false;
452
+        }
453
+
454
+        $initiatorUser = $this->userManager->get($initiator);
455
+        $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
456
+        $initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
457
+
458
+        $subject = (string)$this->l->t('Password to access »%s« shared to you by %s', [$filename, $initiatorDisplayName]);
459
+        $plainBodyPart = $this->l->t("%s shared »%s« with you.\nYou should have already received a separate mail with a link to access it.\n", [$initiatorDisplayName, $filename]);
460
+        $htmlBodyPart = $this->l->t('%s shared »%s« with you. You should have already received a separate mail with a link to access it.', [$initiatorDisplayName, $filename]);
461
+
462
+        $message = $this->mailer->createMessage();
463
+
464
+        $emailTemplate = $this->mailer->createEMailTemplate();
465
+        $emailTemplate->addHeader();
466
+        $emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
467
+        $emailTemplate->addBodyText($htmlBodyPart, $plainBodyPart);
468
+        $emailTemplate->addBodyText($this->l->t('It is protected with the following password: %s', [$password]));
469
+
470
+        // The "From" contains the sharers name
471
+        $instanceName = $this->defaults->getName();
472
+        $senderName = $this->l->t(
473
+            '%s via %s',
474
+            [
475
+                $initiatorDisplayName,
476
+                $instanceName
477
+            ]
478
+        );
479
+        $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
480
+        if ($initiatorEmailAddress !== null) {
481
+            $message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
482
+            $emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
483
+        } else {
484
+            $emailTemplate->addFooter();
485
+        }
486
+
487
+        $message->setTo([$shareWith]);
488
+        $message->setSubject($subject);
489
+        $message->setBody($emailTemplate->renderText(), 'text/plain');
490
+        $message->setHtmlBody($emailTemplate->renderHtml());
491
+        $this->mailer->send($message);
492
+
493
+        $this->createPasswordSendActivity($share, $shareWith, false);
494
+
495
+        return true;
496
+    }
497
+
498
+    /**
499
+     * send auto generated password to the owner. This happens if the admin enforces
500
+     * a password for mail shares and forbid to send the password by mail to the recipient
501
+     *
502
+     * @param IShare $share
503
+     * @param string $password
504
+     * @return bool
505
+     * @throws \Exception
506
+     */
507
+    protected function sendPasswordToOwner(IShare $share, $password) {
508
+
509
+        $filename = $share->getNode()->getName();
510
+        $initiator = $this->userManager->get($share->getSharedBy());
511
+        $initiatorEMailAddress = ($initiator instanceof IUser) ? $initiator->getEMailAddress() : null;
512
+        $initiatorDisplayName = ($initiator instanceof IUser) ? $initiator->getDisplayName() : $share->getSharedBy();
513
+        $shareWith = $share->getSharedWith();
514
+
515
+        if ($initiatorEMailAddress === null) {
516
+            throw new \Exception(
517
+                $this->l->t("We can't send you the auto-generated password. Please set a valid email address in your personal settings and try again.")
518
+            );
519
+        }
520
+
521
+        $subject = (string)$this->l->t('Password to access »%s« shared with %s', [$filename, $shareWith]);
522
+        $bodyPart = $this->l->t("You just shared »%s« with %s. The share was already send to the recipient. Due to the security policies defined by the administrator of %s each share needs to be protected by password and it is not allowed to send the password directly to the recipient. Therefore you need to forward the password manually to the recipient.", [$filename, $shareWith, $this->defaults->getName()]);
523
+
524
+        $message = $this->mailer->createMessage();
525
+        $emailTemplate = $this->mailer->createEMailTemplate();
526
+
527
+        $emailTemplate->addHeader();
528
+        $emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
529
+        $emailTemplate->addBodyText($bodyPart);
530
+        $emailTemplate->addBodyText($this->l->t('This is the password: %s', [$password]));
531
+        $emailTemplate->addBodyText($this->l->t('You can choose a different password at any time in the share dialog.'));
532
+        $emailTemplate->addFooter();
533
+
534
+        if ($initiatorEMailAddress) {
535
+            $message->setFrom([$initiatorEMailAddress => $initiatorDisplayName]);
536
+        }
537
+        $message->setTo([$initiatorEMailAddress => $initiatorDisplayName]);
538
+        $message->setSubject($subject);
539
+        $message->setBody($emailTemplate->renderText(), 'text/plain');
540
+        $message->setHtmlBody($emailTemplate->renderHtml());
541
+        $this->mailer->send($message);
542
+
543
+        $this->createPasswordSendActivity($share, $shareWith, true);
544
+
545
+        return true;
546
+    }
547
+
548
+    /**
549
+     * generate share token
550
+     *
551
+     * @return string
552
+     */
553
+    protected function generateToken($size = 15) {
554
+        $token = $this->secureRandom->generate($size, ISecureRandom::CHAR_HUMAN_READABLE);
555
+        return $token;
556
+    }
557
+
558
+    /**
559
+     * Get all children of this share
560
+     *
561
+     * @param IShare $parent
562
+     * @return IShare[]
563
+     */
564
+    public function getChildren(IShare $parent) {
565
+        $children = [];
566
+
567
+        $qb = $this->dbConnection->getQueryBuilder();
568
+        $qb->select('*')
569
+            ->from('share')
570
+            ->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
571
+            ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
572
+            ->orderBy('id');
573
+
574
+        $cursor = $qb->execute();
575
+        while($data = $cursor->fetch()) {
576
+            $children[] = $this->createShareObject($data);
577
+        }
578
+        $cursor->closeCursor();
579
+
580
+        return $children;
581
+    }
582
+
583
+    /**
584
+     * add share to the database and return the ID
585
+     *
586
+     * @param int $itemSource
587
+     * @param string $itemType
588
+     * @param string $shareWith
589
+     * @param string $sharedBy
590
+     * @param string $uidOwner
591
+     * @param int $permissions
592
+     * @param string $token
593
+     * @return int
594
+     */
595
+    protected function addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token, $password) {
596
+        $qb = $this->dbConnection->getQueryBuilder();
597
+        $qb->insert('share')
598
+            ->setValue('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))
599
+            ->setValue('item_type', $qb->createNamedParameter($itemType))
600
+            ->setValue('item_source', $qb->createNamedParameter($itemSource))
601
+            ->setValue('file_source', $qb->createNamedParameter($itemSource))
602
+            ->setValue('share_with', $qb->createNamedParameter($shareWith))
603
+            ->setValue('uid_owner', $qb->createNamedParameter($uidOwner))
604
+            ->setValue('uid_initiator', $qb->createNamedParameter($sharedBy))
605
+            ->setValue('permissions', $qb->createNamedParameter($permissions))
606
+            ->setValue('token', $qb->createNamedParameter($token))
607
+            ->setValue('password', $qb->createNamedParameter($password))
608
+            ->setValue('stime', $qb->createNamedParameter(time()));
609
+
610
+        /*
611 611
 		 * Added to fix https://github.com/owncloud/core/issues/22215
612 612
 		 * Can be removed once we get rid of ajax/share.php
613 613
 		 */
614
-		$qb->setValue('file_target', $qb->createNamedParameter(''));
614
+        $qb->setValue('file_target', $qb->createNamedParameter(''));
615 615
 
616
-		$qb->execute();
617
-		$id = $qb->getLastInsertId();
616
+        $qb->execute();
617
+        $id = $qb->getLastInsertId();
618 618
 
619
-		return (int)$id;
620
-	}
619
+        return (int)$id;
620
+    }
621 621
 
622
-	/**
623
-	 * Update a share
624
-	 *
625
-	 * @param IShare $share
626
-	 * @param string|null $plainTextPassword
627
-	 * @return IShare The share object
628
-	 */
629
-	public function update(IShare $share, $plainTextPassword = null) {
622
+    /**
623
+     * Update a share
624
+     *
625
+     * @param IShare $share
626
+     * @param string|null $plainTextPassword
627
+     * @return IShare The share object
628
+     */
629
+    public function update(IShare $share, $plainTextPassword = null) {
630 630
 
631
-		$originalShare = $this->getShareById($share->getId());
631
+        $originalShare = $this->getShareById($share->getId());
632 632
 
633
-		// a real password was given
634
-		$validPassword = $plainTextPassword !== null && $plainTextPassword !== '';
633
+        // a real password was given
634
+        $validPassword = $plainTextPassword !== null && $plainTextPassword !== '';
635 635
 
636
-		if($validPassword && $originalShare->getPassword() !== $share->getPassword()) {
637
-			$this->sendPassword($share, $plainTextPassword);
638
-		}
639
-		/*
636
+        if($validPassword && $originalShare->getPassword() !== $share->getPassword()) {
637
+            $this->sendPassword($share, $plainTextPassword);
638
+        }
639
+        /*
640 640
 		 * We allow updating the permissions and password of mail shares
641 641
 		 */
642
-		$qb = $this->dbConnection->getQueryBuilder();
643
-		$qb->update('share')
644
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
645
-			->set('permissions', $qb->createNamedParameter($share->getPermissions()))
646
-			->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
647
-			->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
648
-			->set('password', $qb->createNamedParameter($share->getPassword()))
649
-			->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
650
-			->execute();
651
-
652
-		return $share;
653
-	}
654
-
655
-	/**
656
-	 * @inheritdoc
657
-	 */
658
-	public function move(IShare $share, $recipient) {
659
-		/**
660
-		 * nothing to do here, mail shares are only outgoing shares
661
-		 */
662
-		return $share;
663
-	}
664
-
665
-	/**
666
-	 * Delete a share (owner unShares the file)
667
-	 *
668
-	 * @param IShare $share
669
-	 */
670
-	public function delete(IShare $share) {
671
-		$this->removeShareFromTable($share->getId());
672
-	}
673
-
674
-	/**
675
-	 * @inheritdoc
676
-	 */
677
-	public function deleteFromSelf(IShare $share, $recipient) {
678
-		// nothing to do here, mail shares are only outgoing shares
679
-		return;
680
-	}
681
-
682
-	/**
683
-	 * @inheritdoc
684
-	 */
685
-	public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
686
-		$qb = $this->dbConnection->getQueryBuilder();
687
-		$qb->select('*')
688
-			->from('share');
689
-
690
-		$qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
691
-
692
-		/**
693
-		 * Reshares for this user are shares where they are the owner.
694
-		 */
695
-		if ($reshares === false) {
696
-			//Special case for old shares created via the web UI
697
-			$or1 = $qb->expr()->andX(
698
-				$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
699
-				$qb->expr()->isNull('uid_initiator')
700
-			);
701
-
702
-			$qb->andWhere(
703
-				$qb->expr()->orX(
704
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)),
705
-					$or1
706
-				)
707
-			);
708
-		} else {
709
-			$qb->andWhere(
710
-				$qb->expr()->orX(
711
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
712
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
713
-				)
714
-			);
715
-		}
716
-
717
-		if ($node !== null) {
718
-			$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
719
-		}
720
-
721
-		if ($limit !== -1) {
722
-			$qb->setMaxResults($limit);
723
-		}
724
-
725
-		$qb->setFirstResult($offset);
726
-		$qb->orderBy('id');
727
-
728
-		$cursor = $qb->execute();
729
-		$shares = [];
730
-		while($data = $cursor->fetch()) {
731
-			$shares[] = $this->createShareObject($data);
732
-		}
733
-		$cursor->closeCursor();
734
-
735
-		return $shares;
736
-	}
737
-
738
-	/**
739
-	 * @inheritdoc
740
-	 */
741
-	public function getShareById($id, $recipientId = null) {
742
-		$qb = $this->dbConnection->getQueryBuilder();
743
-
744
-		$qb->select('*')
745
-			->from('share')
746
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
747
-			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
748
-
749
-		$cursor = $qb->execute();
750
-		$data = $cursor->fetch();
751
-		$cursor->closeCursor();
752
-
753
-		if ($data === false) {
754
-			throw new ShareNotFound();
755
-		}
756
-
757
-		try {
758
-			$share = $this->createShareObject($data);
759
-		} catch (InvalidShare $e) {
760
-			throw new ShareNotFound();
761
-		}
762
-
763
-		return $share;
764
-	}
765
-
766
-	/**
767
-	 * Get shares for a given path
768
-	 *
769
-	 * @param \OCP\Files\Node $path
770
-	 * @return IShare[]
771
-	 */
772
-	public function getSharesByPath(Node $path) {
773
-		$qb = $this->dbConnection->getQueryBuilder();
774
-
775
-		$cursor = $qb->select('*')
776
-			->from('share')
777
-			->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
778
-			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
779
-			->execute();
780
-
781
-		$shares = [];
782
-		while($data = $cursor->fetch()) {
783
-			$shares[] = $this->createShareObject($data);
784
-		}
785
-		$cursor->closeCursor();
786
-
787
-		return $shares;
788
-	}
789
-
790
-	/**
791
-	 * @inheritdoc
792
-	 */
793
-	public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
794
-		/** @var IShare[] $shares */
795
-		$shares = [];
796
-
797
-		//Get shares directly with this user
798
-		$qb = $this->dbConnection->getQueryBuilder();
799
-		$qb->select('*')
800
-			->from('share');
801
-
802
-		// Order by id
803
-		$qb->orderBy('id');
804
-
805
-		// Set limit and offset
806
-		if ($limit !== -1) {
807
-			$qb->setMaxResults($limit);
808
-		}
809
-		$qb->setFirstResult($offset);
810
-
811
-		$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
812
-		$qb->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)));
813
-
814
-		// Filter by node if provided
815
-		if ($node !== null) {
816
-			$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
817
-		}
818
-
819
-		$cursor = $qb->execute();
820
-
821
-		while($data = $cursor->fetch()) {
822
-			$shares[] = $this->createShareObject($data);
823
-		}
824
-		$cursor->closeCursor();
825
-
826
-
827
-		return $shares;
828
-	}
829
-
830
-	/**
831
-	 * Get a share by token
832
-	 *
833
-	 * @param string $token
834
-	 * @return IShare
835
-	 * @throws ShareNotFound
836
-	 */
837
-	public function getShareByToken($token) {
838
-		$qb = $this->dbConnection->getQueryBuilder();
839
-
840
-		$cursor = $qb->select('*')
841
-			->from('share')
842
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
843
-			->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
844
-			->execute();
845
-
846
-		$data = $cursor->fetch();
847
-
848
-		if ($data === false) {
849
-			throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
850
-		}
851
-
852
-		try {
853
-			$share = $this->createShareObject($data);
854
-		} catch (InvalidShare $e) {
855
-			throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
856
-		}
857
-
858
-		return $share;
859
-	}
860
-
861
-	/**
862
-	 * remove share from table
863
-	 *
864
-	 * @param string $shareId
865
-	 */
866
-	protected function removeShareFromTable($shareId) {
867
-		$qb = $this->dbConnection->getQueryBuilder();
868
-		$qb->delete('share')
869
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($shareId)));
870
-		$qb->execute();
871
-	}
872
-
873
-	/**
874
-	 * Create a share object from an database row
875
-	 *
876
-	 * @param array $data
877
-	 * @return IShare
878
-	 * @throws InvalidShare
879
-	 * @throws ShareNotFound
880
-	 */
881
-	protected function createShareObject($data) {
882
-
883
-		$share = new Share($this->rootFolder, $this->userManager);
884
-		$share->setId((int)$data['id'])
885
-			->setShareType((int)$data['share_type'])
886
-			->setPermissions((int)$data['permissions'])
887
-			->setTarget($data['file_target'])
888
-			->setMailSend((bool)$data['mail_send'])
889
-			->setToken($data['token']);
890
-
891
-		$shareTime = new \DateTime();
892
-		$shareTime->setTimestamp((int)$data['stime']);
893
-		$share->setShareTime($shareTime);
894
-		$share->setSharedWith($data['share_with']);
895
-		$share->setPassword($data['password']);
896
-
897
-		if ($data['uid_initiator'] !== null) {
898
-			$share->setShareOwner($data['uid_owner']);
899
-			$share->setSharedBy($data['uid_initiator']);
900
-		} else {
901
-			//OLD SHARE
902
-			$share->setSharedBy($data['uid_owner']);
903
-			$path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
904
-
905
-			$owner = $path->getOwner();
906
-			$share->setShareOwner($owner->getUID());
907
-		}
908
-
909
-		if ($data['expiration'] !== null) {
910
-			$expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']);
911
-			if ($expiration !== false) {
912
-				$share->setExpirationDate($expiration);
913
-			}
914
-		}
915
-
916
-		$share->setNodeId((int)$data['file_source']);
917
-		$share->setNodeType($data['item_type']);
918
-
919
-		$share->setProviderId($this->identifier());
920
-
921
-		return $share;
922
-	}
923
-
924
-	/**
925
-	 * Get the node with file $id for $user
926
-	 *
927
-	 * @param string $userId
928
-	 * @param int $id
929
-	 * @return \OCP\Files\File|\OCP\Files\Folder
930
-	 * @throws InvalidShare
931
-	 */
932
-	private function getNode($userId, $id) {
933
-		try {
934
-			$userFolder = $this->rootFolder->getUserFolder($userId);
935
-		} catch (NoUserException $e) {
936
-			throw new InvalidShare();
937
-		}
938
-
939
-		$nodes = $userFolder->getById($id);
940
-
941
-		if (empty($nodes)) {
942
-			throw new InvalidShare();
943
-		}
944
-
945
-		return $nodes[0];
946
-	}
947
-
948
-	/**
949
-	 * A user is deleted from the system
950
-	 * So clean up the relevant shares.
951
-	 *
952
-	 * @param string $uid
953
-	 * @param int $shareType
954
-	 */
955
-	public function userDeleted($uid, $shareType) {
956
-		$qb = $this->dbConnection->getQueryBuilder();
957
-
958
-		$qb->delete('share')
959
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
960
-			->andWhere($qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)))
961
-			->execute();
962
-	}
963
-
964
-	/**
965
-	 * This provider does not support group shares
966
-	 *
967
-	 * @param string $gid
968
-	 */
969
-	public function groupDeleted($gid) {
970
-		return;
971
-	}
972
-
973
-	/**
974
-	 * This provider does not support group shares
975
-	 *
976
-	 * @param string $uid
977
-	 * @param string $gid
978
-	 */
979
-	public function userDeletedFromGroup($uid, $gid) {
980
-		return;
981
-	}
982
-
983
-	/**
984
-	 * get database row of a give share
985
-	 *
986
-	 * @param $id
987
-	 * @return array
988
-	 * @throws ShareNotFound
989
-	 */
990
-	protected function getRawShare($id) {
991
-
992
-		// Now fetch the inserted share and create a complete share object
993
-		$qb = $this->dbConnection->getQueryBuilder();
994
-		$qb->select('*')
995
-			->from('share')
996
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
997
-
998
-		$cursor = $qb->execute();
999
-		$data = $cursor->fetch();
1000
-		$cursor->closeCursor();
1001
-
1002
-		if ($data === false) {
1003
-			throw new ShareNotFound;
1004
-		}
1005
-
1006
-		return $data;
1007
-	}
1008
-
1009
-	public function getSharesInFolder($userId, Folder $node, $reshares) {
1010
-		$qb = $this->dbConnection->getQueryBuilder();
1011
-		$qb->select('*')
1012
-			->from('share', 's')
1013
-			->andWhere($qb->expr()->orX(
1014
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1015
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1016
-			))
1017
-			->andWhere(
1018
-				$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))
1019
-			);
1020
-
1021
-		/**
1022
-		 * Reshares for this user are shares where they are the owner.
1023
-		 */
1024
-		if ($reshares === false) {
1025
-			$qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
1026
-		} else {
1027
-			$qb->andWhere(
1028
-				$qb->expr()->orX(
1029
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
1030
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
1031
-				)
1032
-			);
1033
-		}
1034
-
1035
-		$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1036
-		$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
1037
-
1038
-		$qb->orderBy('id');
1039
-
1040
-		$cursor = $qb->execute();
1041
-		$shares = [];
1042
-		while ($data = $cursor->fetch()) {
1043
-			$shares[$data['fileid']][] = $this->createShareObject($data);
1044
-		}
1045
-		$cursor->closeCursor();
1046
-
1047
-		return $shares;
1048
-	}
1049
-
1050
-	/**
1051
-	 * @inheritdoc
1052
-	 */
1053
-	public function getAccessList($nodes, $currentAccess) {
1054
-		$ids = [];
1055
-		foreach ($nodes as $node) {
1056
-			$ids[] = $node->getId();
1057
-		}
1058
-
1059
-		$qb = $this->dbConnection->getQueryBuilder();
1060
-		$qb->select('share_with')
1061
-			->from('share')
1062
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
1063
-			->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1064
-			->andWhere($qb->expr()->orX(
1065
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1066
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1067
-			))
1068
-			->setMaxResults(1);
1069
-		$cursor = $qb->execute();
1070
-
1071
-		$mail = $cursor->fetch() !== false;
1072
-		$cursor->closeCursor();
1073
-
1074
-		return ['public' => $mail];
1075
-	}
642
+        $qb = $this->dbConnection->getQueryBuilder();
643
+        $qb->update('share')
644
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
645
+            ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
646
+            ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
647
+            ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
648
+            ->set('password', $qb->createNamedParameter($share->getPassword()))
649
+            ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
650
+            ->execute();
651
+
652
+        return $share;
653
+    }
654
+
655
+    /**
656
+     * @inheritdoc
657
+     */
658
+    public function move(IShare $share, $recipient) {
659
+        /**
660
+         * nothing to do here, mail shares are only outgoing shares
661
+         */
662
+        return $share;
663
+    }
664
+
665
+    /**
666
+     * Delete a share (owner unShares the file)
667
+     *
668
+     * @param IShare $share
669
+     */
670
+    public function delete(IShare $share) {
671
+        $this->removeShareFromTable($share->getId());
672
+    }
673
+
674
+    /**
675
+     * @inheritdoc
676
+     */
677
+    public function deleteFromSelf(IShare $share, $recipient) {
678
+        // nothing to do here, mail shares are only outgoing shares
679
+        return;
680
+    }
681
+
682
+    /**
683
+     * @inheritdoc
684
+     */
685
+    public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
686
+        $qb = $this->dbConnection->getQueryBuilder();
687
+        $qb->select('*')
688
+            ->from('share');
689
+
690
+        $qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
691
+
692
+        /**
693
+         * Reshares for this user are shares where they are the owner.
694
+         */
695
+        if ($reshares === false) {
696
+            //Special case for old shares created via the web UI
697
+            $or1 = $qb->expr()->andX(
698
+                $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
699
+                $qb->expr()->isNull('uid_initiator')
700
+            );
701
+
702
+            $qb->andWhere(
703
+                $qb->expr()->orX(
704
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)),
705
+                    $or1
706
+                )
707
+            );
708
+        } else {
709
+            $qb->andWhere(
710
+                $qb->expr()->orX(
711
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
712
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
713
+                )
714
+            );
715
+        }
716
+
717
+        if ($node !== null) {
718
+            $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
719
+        }
720
+
721
+        if ($limit !== -1) {
722
+            $qb->setMaxResults($limit);
723
+        }
724
+
725
+        $qb->setFirstResult($offset);
726
+        $qb->orderBy('id');
727
+
728
+        $cursor = $qb->execute();
729
+        $shares = [];
730
+        while($data = $cursor->fetch()) {
731
+            $shares[] = $this->createShareObject($data);
732
+        }
733
+        $cursor->closeCursor();
734
+
735
+        return $shares;
736
+    }
737
+
738
+    /**
739
+     * @inheritdoc
740
+     */
741
+    public function getShareById($id, $recipientId = null) {
742
+        $qb = $this->dbConnection->getQueryBuilder();
743
+
744
+        $qb->select('*')
745
+            ->from('share')
746
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
747
+            ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
748
+
749
+        $cursor = $qb->execute();
750
+        $data = $cursor->fetch();
751
+        $cursor->closeCursor();
752
+
753
+        if ($data === false) {
754
+            throw new ShareNotFound();
755
+        }
756
+
757
+        try {
758
+            $share = $this->createShareObject($data);
759
+        } catch (InvalidShare $e) {
760
+            throw new ShareNotFound();
761
+        }
762
+
763
+        return $share;
764
+    }
765
+
766
+    /**
767
+     * Get shares for a given path
768
+     *
769
+     * @param \OCP\Files\Node $path
770
+     * @return IShare[]
771
+     */
772
+    public function getSharesByPath(Node $path) {
773
+        $qb = $this->dbConnection->getQueryBuilder();
774
+
775
+        $cursor = $qb->select('*')
776
+            ->from('share')
777
+            ->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
778
+            ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
779
+            ->execute();
780
+
781
+        $shares = [];
782
+        while($data = $cursor->fetch()) {
783
+            $shares[] = $this->createShareObject($data);
784
+        }
785
+        $cursor->closeCursor();
786
+
787
+        return $shares;
788
+    }
789
+
790
+    /**
791
+     * @inheritdoc
792
+     */
793
+    public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
794
+        /** @var IShare[] $shares */
795
+        $shares = [];
796
+
797
+        //Get shares directly with this user
798
+        $qb = $this->dbConnection->getQueryBuilder();
799
+        $qb->select('*')
800
+            ->from('share');
801
+
802
+        // Order by id
803
+        $qb->orderBy('id');
804
+
805
+        // Set limit and offset
806
+        if ($limit !== -1) {
807
+            $qb->setMaxResults($limit);
808
+        }
809
+        $qb->setFirstResult($offset);
810
+
811
+        $qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
812
+        $qb->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)));
813
+
814
+        // Filter by node if provided
815
+        if ($node !== null) {
816
+            $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
817
+        }
818
+
819
+        $cursor = $qb->execute();
820
+
821
+        while($data = $cursor->fetch()) {
822
+            $shares[] = $this->createShareObject($data);
823
+        }
824
+        $cursor->closeCursor();
825
+
826
+
827
+        return $shares;
828
+    }
829
+
830
+    /**
831
+     * Get a share by token
832
+     *
833
+     * @param string $token
834
+     * @return IShare
835
+     * @throws ShareNotFound
836
+     */
837
+    public function getShareByToken($token) {
838
+        $qb = $this->dbConnection->getQueryBuilder();
839
+
840
+        $cursor = $qb->select('*')
841
+            ->from('share')
842
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
843
+            ->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
844
+            ->execute();
845
+
846
+        $data = $cursor->fetch();
847
+
848
+        if ($data === false) {
849
+            throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
850
+        }
851
+
852
+        try {
853
+            $share = $this->createShareObject($data);
854
+        } catch (InvalidShare $e) {
855
+            throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
856
+        }
857
+
858
+        return $share;
859
+    }
860
+
861
+    /**
862
+     * remove share from table
863
+     *
864
+     * @param string $shareId
865
+     */
866
+    protected function removeShareFromTable($shareId) {
867
+        $qb = $this->dbConnection->getQueryBuilder();
868
+        $qb->delete('share')
869
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($shareId)));
870
+        $qb->execute();
871
+    }
872
+
873
+    /**
874
+     * Create a share object from an database row
875
+     *
876
+     * @param array $data
877
+     * @return IShare
878
+     * @throws InvalidShare
879
+     * @throws ShareNotFound
880
+     */
881
+    protected function createShareObject($data) {
882
+
883
+        $share = new Share($this->rootFolder, $this->userManager);
884
+        $share->setId((int)$data['id'])
885
+            ->setShareType((int)$data['share_type'])
886
+            ->setPermissions((int)$data['permissions'])
887
+            ->setTarget($data['file_target'])
888
+            ->setMailSend((bool)$data['mail_send'])
889
+            ->setToken($data['token']);
890
+
891
+        $shareTime = new \DateTime();
892
+        $shareTime->setTimestamp((int)$data['stime']);
893
+        $share->setShareTime($shareTime);
894
+        $share->setSharedWith($data['share_with']);
895
+        $share->setPassword($data['password']);
896
+
897
+        if ($data['uid_initiator'] !== null) {
898
+            $share->setShareOwner($data['uid_owner']);
899
+            $share->setSharedBy($data['uid_initiator']);
900
+        } else {
901
+            //OLD SHARE
902
+            $share->setSharedBy($data['uid_owner']);
903
+            $path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
904
+
905
+            $owner = $path->getOwner();
906
+            $share->setShareOwner($owner->getUID());
907
+        }
908
+
909
+        if ($data['expiration'] !== null) {
910
+            $expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']);
911
+            if ($expiration !== false) {
912
+                $share->setExpirationDate($expiration);
913
+            }
914
+        }
915
+
916
+        $share->setNodeId((int)$data['file_source']);
917
+        $share->setNodeType($data['item_type']);
918
+
919
+        $share->setProviderId($this->identifier());
920
+
921
+        return $share;
922
+    }
923
+
924
+    /**
925
+     * Get the node with file $id for $user
926
+     *
927
+     * @param string $userId
928
+     * @param int $id
929
+     * @return \OCP\Files\File|\OCP\Files\Folder
930
+     * @throws InvalidShare
931
+     */
932
+    private function getNode($userId, $id) {
933
+        try {
934
+            $userFolder = $this->rootFolder->getUserFolder($userId);
935
+        } catch (NoUserException $e) {
936
+            throw new InvalidShare();
937
+        }
938
+
939
+        $nodes = $userFolder->getById($id);
940
+
941
+        if (empty($nodes)) {
942
+            throw new InvalidShare();
943
+        }
944
+
945
+        return $nodes[0];
946
+    }
947
+
948
+    /**
949
+     * A user is deleted from the system
950
+     * So clean up the relevant shares.
951
+     *
952
+     * @param string $uid
953
+     * @param int $shareType
954
+     */
955
+    public function userDeleted($uid, $shareType) {
956
+        $qb = $this->dbConnection->getQueryBuilder();
957
+
958
+        $qb->delete('share')
959
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
960
+            ->andWhere($qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)))
961
+            ->execute();
962
+    }
963
+
964
+    /**
965
+     * This provider does not support group shares
966
+     *
967
+     * @param string $gid
968
+     */
969
+    public function groupDeleted($gid) {
970
+        return;
971
+    }
972
+
973
+    /**
974
+     * This provider does not support group shares
975
+     *
976
+     * @param string $uid
977
+     * @param string $gid
978
+     */
979
+    public function userDeletedFromGroup($uid, $gid) {
980
+        return;
981
+    }
982
+
983
+    /**
984
+     * get database row of a give share
985
+     *
986
+     * @param $id
987
+     * @return array
988
+     * @throws ShareNotFound
989
+     */
990
+    protected function getRawShare($id) {
991
+
992
+        // Now fetch the inserted share and create a complete share object
993
+        $qb = $this->dbConnection->getQueryBuilder();
994
+        $qb->select('*')
995
+            ->from('share')
996
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
997
+
998
+        $cursor = $qb->execute();
999
+        $data = $cursor->fetch();
1000
+        $cursor->closeCursor();
1001
+
1002
+        if ($data === false) {
1003
+            throw new ShareNotFound;
1004
+        }
1005
+
1006
+        return $data;
1007
+    }
1008
+
1009
+    public function getSharesInFolder($userId, Folder $node, $reshares) {
1010
+        $qb = $this->dbConnection->getQueryBuilder();
1011
+        $qb->select('*')
1012
+            ->from('share', 's')
1013
+            ->andWhere($qb->expr()->orX(
1014
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1015
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1016
+            ))
1017
+            ->andWhere(
1018
+                $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))
1019
+            );
1020
+
1021
+        /**
1022
+         * Reshares for this user are shares where they are the owner.
1023
+         */
1024
+        if ($reshares === false) {
1025
+            $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
1026
+        } else {
1027
+            $qb->andWhere(
1028
+                $qb->expr()->orX(
1029
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
1030
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
1031
+                )
1032
+            );
1033
+        }
1034
+
1035
+        $qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1036
+        $qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
1037
+
1038
+        $qb->orderBy('id');
1039
+
1040
+        $cursor = $qb->execute();
1041
+        $shares = [];
1042
+        while ($data = $cursor->fetch()) {
1043
+            $shares[$data['fileid']][] = $this->createShareObject($data);
1044
+        }
1045
+        $cursor->closeCursor();
1046
+
1047
+        return $shares;
1048
+    }
1049
+
1050
+    /**
1051
+     * @inheritdoc
1052
+     */
1053
+    public function getAccessList($nodes, $currentAccess) {
1054
+        $ids = [];
1055
+        foreach ($nodes as $node) {
1056
+            $ids[] = $node->getId();
1057
+        }
1058
+
1059
+        $qb = $this->dbConnection->getQueryBuilder();
1060
+        $qb->select('share_with')
1061
+            ->from('share')
1062
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
1063
+            ->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1064
+            ->andWhere($qb->expr()->orX(
1065
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1066
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1067
+            ))
1068
+            ->setMaxResults(1);
1069
+        $cursor = $qb->execute();
1070
+
1071
+        $mail = $cursor->fetch() !== false;
1072
+        $cursor->closeCursor();
1073
+
1074
+        return ['public' => $mail];
1075
+    }
1076 1076
 
1077 1077
 }
Please login to merge, or discard this patch.
Spacing   +25 added lines, -25 removed lines patch added patch discarded remove patch
@@ -210,10 +210,10 @@  discard block
 block discarded – undo
210 210
 		}
211 211
 
212 212
 		$passwordPolicy = $this->getPasswordPolicy();
213
-		$passwordCharset = ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS;
213
+		$passwordCharset = ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_UPPER.ISecureRandom::CHAR_DIGITS;
214 214
 		$passwordLength = 8;
215 215
 		if (!empty($passwordPolicy)) {
216
-			$passwordLength = (int)$passwordPolicy['minLength'] > 0 ? (int)$passwordPolicy['minLength'] : $passwordLength;
216
+			$passwordLength = (int) $passwordPolicy['minLength'] > 0 ? (int) $passwordPolicy['minLength'] : $passwordLength;
217 217
 			$passwordCharset .= $passwordPolicy['enforceSpecialCharacters'] ? ISecureRandom::CHAR_SYMBOLS : '';
218 218
 		}
219 219
 
@@ -351,11 +351,11 @@  discard block
 block discarded – undo
351 351
 				$share->getExpirationDate()
352 352
 			);
353 353
 		} catch (HintException $hintException) {
354
-			$this->logger->error('Failed to send share by mail: ' . $hintException->getMessage());
354
+			$this->logger->error('Failed to send share by mail: '.$hintException->getMessage());
355 355
 			$this->removeShareFromTable($shareId);
356 356
 			throw $hintException;
357 357
 		} catch (\Exception $e) {
358
-			$this->logger->error('Failed to send share by email: ' . $e->getMessage());
358
+			$this->logger->error('Failed to send share by email: '.$e->getMessage());
359 359
 			$this->removeShareFromTable($shareId);
360 360
 			throw new HintException('Failed to send share by mail',
361 361
 				$this->l->t('Failed to send share by email'));
@@ -380,7 +380,7 @@  discard block
 block discarded – undo
380 380
 											\DateTime $expiration) {
381 381
 		$initiatorUser = $this->userManager->get($initiator);
382 382
 		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
383
-		$subject = (string)$this->l->t('%s shared »%s« with you', array($initiatorDisplayName, $filename));
383
+		$subject = (string) $this->l->t('%s shared »%s« with you', array($initiatorDisplayName, $filename));
384 384
 
385 385
 		$message = $this->mailer->createMessage();
386 386
 
@@ -397,7 +397,7 @@  discard block
 block discarded – undo
397 397
 		$text = $this->l->t('%s shared »%s« with you.', [$initiatorDisplayName, $filename]);
398 398
 
399 399
 		$emailTemplate->addBodyText(
400
-			$text . ' ' . $this->l->t('Click the button below to open it.'),
400
+			$text.' '.$this->l->t('Click the button below to open it.'),
401 401
 			$text
402 402
 		);
403 403
 		$emailTemplate->addBodyButton(
@@ -421,9 +421,9 @@  discard block
 block discarded – undo
421 421
 		// The "Reply-To" is set to the sharer if an mail address is configured
422 422
 		// also the default footer contains a "Do not reply" which needs to be adjusted.
423 423
 		$initiatorEmail = $initiatorUser->getEMailAddress();
424
-		if($initiatorEmail !== null) {
424
+		if ($initiatorEmail !== null) {
425 425
 			$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
426
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
426
+			$emailTemplate->addFooter($instanceName.' - '.$this->defaults->getSlogan());
427 427
 		} else {
428 428
 			$emailTemplate->addFooter();
429 429
 		}
@@ -455,7 +455,7 @@  discard block
 block discarded – undo
455 455
 		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
456 456
 		$initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
457 457
 
458
-		$subject = (string)$this->l->t('Password to access »%s« shared to you by %s', [$filename, $initiatorDisplayName]);
458
+		$subject = (string) $this->l->t('Password to access »%s« shared to you by %s', [$filename, $initiatorDisplayName]);
459 459
 		$plainBodyPart = $this->l->t("%s shared »%s« with you.\nYou should have already received a separate mail with a link to access it.\n", [$initiatorDisplayName, $filename]);
460 460
 		$htmlBodyPart = $this->l->t('%s shared »%s« with you. You should have already received a separate mail with a link to access it.', [$initiatorDisplayName, $filename]);
461 461
 
@@ -479,7 +479,7 @@  discard block
 block discarded – undo
479 479
 		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
480 480
 		if ($initiatorEmailAddress !== null) {
481 481
 			$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
482
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
482
+			$emailTemplate->addFooter($instanceName.' - '.$this->defaults->getSlogan());
483 483
 		} else {
484 484
 			$emailTemplate->addFooter();
485 485
 		}
@@ -518,7 +518,7 @@  discard block
 block discarded – undo
518 518
 			);
519 519
 		}
520 520
 
521
-		$subject = (string)$this->l->t('Password to access »%s« shared with %s', [$filename, $shareWith]);
521
+		$subject = (string) $this->l->t('Password to access »%s« shared with %s', [$filename, $shareWith]);
522 522
 		$bodyPart = $this->l->t("You just shared »%s« with %s. The share was already send to the recipient. Due to the security policies defined by the administrator of %s each share needs to be protected by password and it is not allowed to send the password directly to the recipient. Therefore you need to forward the password manually to the recipient.", [$filename, $shareWith, $this->defaults->getName()]);
523 523
 
524 524
 		$message = $this->mailer->createMessage();
@@ -572,7 +572,7 @@  discard block
 block discarded – undo
572 572
 			->orderBy('id');
573 573
 
574 574
 		$cursor = $qb->execute();
575
-		while($data = $cursor->fetch()) {
575
+		while ($data = $cursor->fetch()) {
576 576
 			$children[] = $this->createShareObject($data);
577 577
 		}
578 578
 		$cursor->closeCursor();
@@ -616,7 +616,7 @@  discard block
 block discarded – undo
616 616
 		$qb->execute();
617 617
 		$id = $qb->getLastInsertId();
618 618
 
619
-		return (int)$id;
619
+		return (int) $id;
620 620
 	}
621 621
 
622 622
 	/**
@@ -633,7 +633,7 @@  discard block
 block discarded – undo
633 633
 		// a real password was given
634 634
 		$validPassword = $plainTextPassword !== null && $plainTextPassword !== '';
635 635
 
636
-		if($validPassword && $originalShare->getPassword() !== $share->getPassword()) {
636
+		if ($validPassword && $originalShare->getPassword() !== $share->getPassword()) {
637 637
 			$this->sendPassword($share, $plainTextPassword);
638 638
 		}
639 639
 		/*
@@ -727,7 +727,7 @@  discard block
 block discarded – undo
727 727
 
728 728
 		$cursor = $qb->execute();
729 729
 		$shares = [];
730
-		while($data = $cursor->fetch()) {
730
+		while ($data = $cursor->fetch()) {
731 731
 			$shares[] = $this->createShareObject($data);
732 732
 		}
733 733
 		$cursor->closeCursor();
@@ -779,7 +779,7 @@  discard block
 block discarded – undo
779 779
 			->execute();
780 780
 
781 781
 		$shares = [];
782
-		while($data = $cursor->fetch()) {
782
+		while ($data = $cursor->fetch()) {
783 783
 			$shares[] = $this->createShareObject($data);
784 784
 		}
785 785
 		$cursor->closeCursor();
@@ -818,7 +818,7 @@  discard block
 block discarded – undo
818 818
 
819 819
 		$cursor = $qb->execute();
820 820
 
821
-		while($data = $cursor->fetch()) {
821
+		while ($data = $cursor->fetch()) {
822 822
 			$shares[] = $this->createShareObject($data);
823 823
 		}
824 824
 		$cursor->closeCursor();
@@ -881,15 +881,15 @@  discard block
 block discarded – undo
881 881
 	protected function createShareObject($data) {
882 882
 
883 883
 		$share = new Share($this->rootFolder, $this->userManager);
884
-		$share->setId((int)$data['id'])
885
-			->setShareType((int)$data['share_type'])
886
-			->setPermissions((int)$data['permissions'])
884
+		$share->setId((int) $data['id'])
885
+			->setShareType((int) $data['share_type'])
886
+			->setPermissions((int) $data['permissions'])
887 887
 			->setTarget($data['file_target'])
888
-			->setMailSend((bool)$data['mail_send'])
888
+			->setMailSend((bool) $data['mail_send'])
889 889
 			->setToken($data['token']);
890 890
 
891 891
 		$shareTime = new \DateTime();
892
-		$shareTime->setTimestamp((int)$data['stime']);
892
+		$shareTime->setTimestamp((int) $data['stime']);
893 893
 		$share->setShareTime($shareTime);
894 894
 		$share->setSharedWith($data['share_with']);
895 895
 		$share->setPassword($data['password']);
@@ -900,7 +900,7 @@  discard block
 block discarded – undo
900 900
 		} else {
901 901
 			//OLD SHARE
902 902
 			$share->setSharedBy($data['uid_owner']);
903
-			$path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
903
+			$path = $this->getNode($share->getSharedBy(), (int) $data['file_source']);
904 904
 
905 905
 			$owner = $path->getOwner();
906 906
 			$share->setShareOwner($owner->getUID());
@@ -913,7 +913,7 @@  discard block
 block discarded – undo
913 913
 			}
914 914
 		}
915 915
 
916
-		$share->setNodeId((int)$data['file_source']);
916
+		$share->setNodeId((int) $data['file_source']);
917 917
 		$share->setNodeType($data['item_type']);
918 918
 
919 919
 		$share->setProviderId($this->identifier());
@@ -1032,7 +1032,7 @@  discard block
 block discarded – undo
1032 1032
 			);
1033 1033
 		}
1034 1034
 
1035
-		$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1035
+		$qb->innerJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1036 1036
 		$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
1037 1037
 
1038 1038
 		$qb->orderBy('id');
Please login to merge, or discard this patch.
lib/private/Mail/EMailTemplate.php 1 patch
Indentation   +327 added lines, -327 removed lines patch added patch discarded remove patch
@@ -39,31 +39,31 @@  discard block
 block discarded – undo
39 39
  * @package OC\Mail
40 40
  */
41 41
 class EMailTemplate implements IEMailTemplate {
42
-	/** @var Defaults */
43
-	protected $themingDefaults;
44
-	/** @var IURLGenerator */
45
-	protected $urlGenerator;
46
-	/** @var IL10N */
47
-	protected $l10n;
48
-	/** @var string */
49
-	protected $emailId;
50
-	/** @var array */
51
-	protected $data;
52
-
53
-	/** @var string */
54
-	protected $htmlBody = '';
55
-	/** @var string */
56
-	protected $plainBody = '';
57
-	/** @var bool indicated if the footer is added */
58
-	protected $headerAdded = false;
59
-	/** @var bool indicated if the body is already opened */
60
-	protected $bodyOpened = false;
61
-	/** @var bool indicated if there is a list open in the body */
62
-	protected $bodyListOpened = false;
63
-	/** @var bool indicated if the footer is added */
64
-	protected $footerAdded = false;
65
-
66
-	protected $head = <<<EOF
42
+    /** @var Defaults */
43
+    protected $themingDefaults;
44
+    /** @var IURLGenerator */
45
+    protected $urlGenerator;
46
+    /** @var IL10N */
47
+    protected $l10n;
48
+    /** @var string */
49
+    protected $emailId;
50
+    /** @var array */
51
+    protected $data;
52
+
53
+    /** @var string */
54
+    protected $htmlBody = '';
55
+    /** @var string */
56
+    protected $plainBody = '';
57
+    /** @var bool indicated if the footer is added */
58
+    protected $headerAdded = false;
59
+    /** @var bool indicated if the body is already opened */
60
+    protected $bodyOpened = false;
61
+    /** @var bool indicated if there is a list open in the body */
62
+    protected $bodyListOpened = false;
63
+    /** @var bool indicated if the footer is added */
64
+    protected $footerAdded = false;
65
+
66
+    protected $head = <<<EOF
67 67
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
68 68
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en" style="-webkit-font-smoothing:antialiased;background:#f3f3f3!important">
69 69
 <head>
@@ -81,7 +81,7 @@  discard block
 block discarded – undo
81 81
 				<center data-parsed="" style="min-width:580px;width:100%">
82 82
 EOF;
83 83
 
84
-	protected $tail = <<<EOF
84
+    protected $tail = <<<EOF
85 85
 					</center>
86 86
 				</td>
87 87
 			</tr>
@@ -92,7 +92,7 @@  discard block
 block discarded – undo
92 92
 </html>
93 93
 EOF;
94 94
 
95
-	protected $header = <<<EOF
95
+    protected $header = <<<EOF
96 96
 <table align="center" class="wrapper header float-center" style="Margin:0 auto;background:#8a8a8a;background-color:%s;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%%">
97 97
 	<tr style="padding:0;text-align:left;vertical-align:top">
98 98
 		<td class="wrapper-inner" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:20px;text-align:left;vertical-align:top;word-wrap:break-word">
@@ -125,7 +125,7 @@  discard block
 block discarded – undo
125 125
 </table>
126 126
 EOF;
127 127
 
128
-	protected $heading = <<<EOF
128
+    protected $heading = <<<EOF
129 129
 <table align="center" class="container main-heading float-center" style="Margin:0 auto;background:0 0!important;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:580px">
130 130
 	<tbody>
131 131
 	<tr style="padding:0;text-align:left;vertical-align:top">
@@ -144,7 +144,7 @@  discard block
 block discarded – undo
144 144
 </table>
145 145
 EOF;
146 146
 
147
-	protected $bodyBegin = <<<EOF
147
+    protected $bodyBegin = <<<EOF
148 148
 <table align="center" class="wrapper content float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%">
149 149
 	<tr style="padding:0;text-align:left;vertical-align:top">
150 150
 		<td class="wrapper-inner" style="-moz-hyphens:auto;-webkit-hyphens:auto;Margin:0;border-collapse:collapse!important;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;hyphens:auto;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:break-word">
@@ -161,7 +161,7 @@  discard block
 block discarded – undo
161 161
 						</table>
162 162
 EOF;
163 163
 
164
-	protected $bodyText = <<<EOF
164
+    protected $bodyText = <<<EOF
165 165
 <table class="row description" style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%%">
166 166
 	<tbody>
167 167
 	<tr style="padding:0;text-align:left;vertical-align:top">
@@ -180,7 +180,7 @@  discard block
 block discarded – undo
180 180
 </table>
181 181
 EOF;
182 182
 
183
-	protected $listBegin = <<<EOF
183
+    protected $listBegin = <<<EOF
184 184
 <table class="row description" style="border-collapse:collapse;border-spacing:0;display:table;padding:0;position:relative;text-align:left;vertical-align:top;width:100%%">
185 185
 	<tbody>
186 186
 	<tr style="padding:0;text-align:left;vertical-align:top">
@@ -188,7 +188,7 @@  discard block
 block discarded – undo
188 188
 			<table style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%%">
189 189
 EOF;
190 190
 
191
-	protected $listItem = <<<EOF
191
+    protected $listItem = <<<EOF
192 192
 				<tr style="padding:0;text-align:left;vertical-align:top">
193 193
 					<td style="Margin:0;color:#0a0a0a;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;padding:0;text-align:left;width:15px;">
194 194
 						<p class="text-left" style="Margin:0;Margin-bottom:10px;color:#777;font-family:Lucida Grande,Geneva,Verdana,sans-serif;font-size:16px;font-weight:400;line-height:1.3;margin:0;margin-bottom:10px;padding:0;padding-left:10px;text-align:left">%s</p>
@@ -200,7 +200,7 @@  discard block
 block discarded – undo
200 200
 				</tr>
201 201
 EOF;
202 202
 
203
-	protected $listEnd = <<<EOF
203
+    protected $listEnd = <<<EOF
204 204
 			</table>
205 205
 		</th>
206 206
 	</tr>
@@ -208,7 +208,7 @@  discard block
 block discarded – undo
208 208
 </table>
209 209
 EOF;
210 210
 
211
-	protected $buttonGroup = <<<EOF
211
+    protected $buttonGroup = <<<EOF
212 212
 <table class="spacer" style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%%">
213 213
 	<tbody>
214 214
 	<tr style="padding:0;text-align:left;vertical-align:top">
@@ -261,7 +261,7 @@  discard block
 block discarded – undo
261 261
 </table>
262 262
 EOF;
263 263
 
264
-	protected $button = <<<EOF
264
+    protected $button = <<<EOF
265 265
 <table class="spacer" style="border-collapse:collapse;border-spacing:0;padding:0;text-align:left;vertical-align:top;width:100%%">
266 266
 	<tbody>
267 267
 	<tr style="padding:0;text-align:left;vertical-align:top">
@@ -301,7 +301,7 @@  discard block
 block discarded – undo
301 301
 </table>
302 302
 EOF;
303 303
 
304
-	protected $bodyEnd = <<<EOF
304
+    protected $bodyEnd = <<<EOF
305 305
 
306 306
 					</td>
307 307
 				</tr>
@@ -312,7 +312,7 @@  discard block
 block discarded – undo
312 312
 </table>
313 313
 EOF;
314 314
 
315
-	protected $footer = <<<EOF
315
+    protected $footer = <<<EOF
316 316
 <table class="spacer float-center" style="Margin:0 auto;border-collapse:collapse;border-spacing:0;float:none;margin:0 auto;padding:0;text-align:center;vertical-align:top;width:100%%">
317 317
 	<tbody>
318 318
 	<tr style="padding:0;text-align:left;vertical-align:top">
@@ -338,294 +338,294 @@  discard block
 block discarded – undo
338 338
 </table>
339 339
 EOF;
340 340
 
341
-	/**
342
-	 * @param Defaults $themingDefaults
343
-	 * @param IURLGenerator $urlGenerator
344
-	 * @param IL10N $l10n
345
-	 */
346
-	public function __construct(Defaults $themingDefaults,
347
-								IURLGenerator $urlGenerator,
348
-								IL10N $l10n) {
349
-		$this->themingDefaults = $themingDefaults;
350
-		$this->urlGenerator = $urlGenerator;
351
-		$this->l10n = $l10n;
352
-		$this->htmlBody .= $this->head;
353
-	}
354
-
355
-	/**
356
-	 * Set meta data of an email
357
-	 *
358
-	 * @param string $emailId
359
-	 * @param array $data
360
-	 * @since 12.0.3
361
-	 */
362
-	public function setMetaData($emailId, array $data = []) {
363
-		$this->emailId = $emailId;
364
-		$this->data = $data;
365
-	}
366
-
367
-	/**
368
-	 * Adds a header to the email
369
-	 */
370
-	public function addHeader() {
371
-		if ($this->headerAdded) {
372
-			return;
373
-		}
374
-		$this->headerAdded = true;
375
-
376
-		$logoUrl = $this->urlGenerator->getAbsoluteURL($this->themingDefaults->getLogo(false));
377
-		$this->htmlBody .= vsprintf($this->header, [$this->themingDefaults->getColorPrimary(), $logoUrl, $this->themingDefaults->getName()]);
378
-	}
379
-
380
-	/**
381
-	 * Adds a heading to the email
382
-	 *
383
-	 * @param string $title
384
-	 * @param string|bool $plainTitle Title that is used in the plain text email
385
-	 *   if empty the $title is used, if false none will be used
386
-	 */
387
-	public function addHeading($title, $plainTitle = '') {
388
-		if ($this->footerAdded) {
389
-			return;
390
-		}
391
-		if ($plainTitle === '') {
392
-			$plainTitle = $title;
393
-		}
394
-
395
-		$this->htmlBody .= vsprintf($this->heading, [htmlspecialchars($title)]);
396
-		if ($plainTitle !== false) {
397
-			$this->plainBody .= $plainTitle . PHP_EOL . PHP_EOL;
398
-		}
399
-	}
400
-
401
-	/**
402
-	 * Open the HTML body when it is not already
403
-	 */
404
-	protected function ensureBodyIsOpened() {
405
-		if ($this->bodyOpened) {
406
-			return;
407
-		}
408
-
409
-		$this->htmlBody .= $this->bodyBegin;
410
-		$this->bodyOpened = true;
411
-	}
412
-
413
-	/**
414
-	 * Adds a paragraph to the body of the email
415
-	 *
416
-	 * @param string $text
417
-	 * @param string|bool $plainText Text that is used in the plain text email
418
-	 *   if empty the $text is used, if false none will be used
419
-	 */
420
-	public function addBodyText($text, $plainText = '') {
421
-		if ($this->footerAdded) {
422
-			return;
423
-		}
424
-		if ($plainText === '') {
425
-			$plainText = $text;
426
-		}
427
-
428
-		$this->ensureBodyIsOpened();
429
-
430
-		$this->htmlBody .= vsprintf($this->bodyText, [htmlspecialchars($text)]);
431
-		if ($plainText !== false) {
432
-			$this->plainBody .= $plainText . PHP_EOL . PHP_EOL;
433
-		}
434
-	}
435
-
436
-	/**
437
-	 * Adds a list item to the body of the email
438
-	 *
439
-	 * @param string $text
440
-	 * @param string $metaInfo
441
-	 * @param string $icon Absolute path, must be 16*16 pixels
442
-	 * @param string $plainText Text that is used in the plain text email
443
-	 *   if empty the $text is used, if false none will be used
444
-	 * @param string $plainMetaInfo Meta info that is used in the plain text email
445
-	 *   if empty the $metaInfo is used, if false none will be used
446
-	 * @since 12.0.0
447
-	 */
448
-	public function addBodyListItem($text, $metaInfo = '', $icon = '', $plainText = '', $plainMetaInfo = '') {
449
-		$this->ensureBodyListOpened();
450
-
451
-		if ($plainText === '') {
452
-			$plainText = $text;
453
-		}
454
-		if ($plainMetaInfo === '') {
455
-			$plainMetaInfo = $metaInfo;
456
-		}
457
-
458
-		$htmlText = htmlspecialchars($text);
459
-		if ($metaInfo) {
460
-			$htmlText = '<em style="color:#777;">' . htmlspecialchars($metaInfo) . '</em><br>' . $htmlText;
461
-		}
462
-		if ($icon !== '') {
463
-			$icon = '<img src="' . htmlspecialchars($icon) . '" alt="&bull;">';
464
-		} else {
465
-			$icon = '&bull;';
466
-		}
467
-		$this->htmlBody .= vsprintf($this->listItem, [$icon, $htmlText]);
468
-		if ($plainText !== false) {
469
-			$this->plainBody .= '  * ' . $plainText;
470
-			if ($plainMetaInfo !== false) {
471
-				$this->plainBody .= ' (' . $plainMetaInfo . ')';
472
-			}
473
-			$this->plainBody .= PHP_EOL;
474
-		}
475
-	}
476
-
477
-	protected function ensureBodyListOpened() {
478
-		if ($this->bodyListOpened) {
479
-			return;
480
-		}
481
-
482
-		$this->ensureBodyIsOpened();
483
-		$this->bodyListOpened = true;
484
-		$this->htmlBody .= $this->listBegin;
485
-	}
486
-
487
-	protected function ensureBodyListClosed() {
488
-		if (!$this->bodyListOpened) {
489
-			return;
490
-		}
491
-
492
-		$this->bodyListOpened = false;
493
-		$this->htmlBody .= $this->listEnd;
494
-	}
495
-
496
-	/**
497
-	 * Adds a button group of two buttons to the body of the email
498
-	 *
499
-	 * @param string $textLeft Text of left button
500
-	 * @param string $urlLeft URL of left button
501
-	 * @param string $textRight Text of right button
502
-	 * @param string $urlRight URL of right button
503
-	 * @param string $plainTextLeft Text of left button that is used in the plain text version - if unset the $textLeft is used
504
-	 * @param string $plainTextRight Text of right button that is used in the plain text version - if unset the $textRight is used
505
-	 */
506
-	public function addBodyButtonGroup($textLeft,
507
-									   $urlLeft,
508
-									   $textRight,
509
-									   $urlRight,
510
-									   $plainTextLeft = '',
511
-									   $plainTextRight = '') {
512
-		if ($this->footerAdded) {
513
-			return;
514
-		}
515
-		if ($plainTextLeft === '') {
516
-			$plainTextLeft = $textLeft;
517
-		}
518
-
519
-		if ($plainTextRight === '') {
520
-			$plainTextRight = $textRight;
521
-		}
522
-
523
-		$this->ensureBodyIsOpened();
524
-		$this->ensureBodyListClosed();
525
-
526
-		$color = $this->themingDefaults->getColorPrimary();
527
-
528
-		$this->htmlBody .= vsprintf($this->buttonGroup, [$color, $color, $urlLeft, $color, htmlspecialchars($textLeft), $urlRight, htmlspecialchars($textRight)]);
529
-		$this->plainBody .= $plainTextLeft . ': ' . $urlLeft . PHP_EOL;
530
-		$this->plainBody .= $plainTextRight . ': ' . $urlRight . PHP_EOL . PHP_EOL;
531
-
532
-	}
533
-
534
-	/**
535
-	 * Adds a button to the body of the email
536
-	 *
537
-	 * @param string $text Text of button
538
-	 * @param string $url URL of button
539
-	 * @param string $plainText Text of button in plain text version
540
-	 * 		if empty the $text is used, if false none will be used
541
-	 *
542
-	 * @since 12.0.0
543
-	 */
544
-	public function addBodyButton($text, $url, $plainText = '') {
545
-		if ($this->footerAdded) {
546
-			return;
547
-		}
548
-
549
-		$this->ensureBodyIsOpened();
550
-		$this->ensureBodyListClosed();
551
-
552
-		if ($plainText === '') {
553
-			$plainText = $text;
554
-		}
555
-
556
-		$color = $this->themingDefaults->getColorPrimary();
557
-		$this->htmlBody .= vsprintf($this->button, [$color, $color, $url, $color, htmlspecialchars($text)]);
558
-
559
-		if ($plainText !== false) {
560
-			$this->plainBody .= $plainText . ': ';
561
-		}
562
-
563
-		$this->plainBody .=  $url . PHP_EOL;
564
-
565
-	}
566
-
567
-	/**
568
-	 * Close the HTML body when it is open
569
-	 */
570
-	protected function ensureBodyIsClosed() {
571
-		if (!$this->bodyOpened) {
572
-			return;
573
-		}
574
-
575
-		$this->ensureBodyListClosed();
576
-
577
-		$this->htmlBody .= $this->bodyEnd;
578
-		$this->bodyOpened = false;
579
-	}
580
-
581
-	/**
582
-	 * Adds a logo and a text to the footer. <br> in the text will be replaced by new lines in the plain text email
583
-	 *
584
-	 * @param string $text If the text is empty the default "Name - Slogan<br>This is an automatically sent email" will be used
585
-	 */
586
-	public function addFooter($text = '') {
587
-		if($text === '') {
588
-			$text = $this->themingDefaults->getName() . ' - ' . $this->themingDefaults->getSlogan() . '<br>' . $this->l10n->t('This is an automatically sent email, please do not reply.');
589
-		}
590
-
591
-		if ($this->footerAdded) {
592
-			return;
593
-		}
594
-		$this->footerAdded = true;
595
-
596
-		$this->ensureBodyIsClosed();
597
-
598
-		$this->htmlBody .= vsprintf($this->footer, [$text]);
599
-		$this->htmlBody .= $this->tail;
600
-		$this->plainBody .= PHP_EOL . '-- ' . PHP_EOL;
601
-		$this->plainBody .= str_replace('<br>', PHP_EOL, $text);
602
-	}
603
-
604
-	/**
605
-	 * Returns the rendered HTML email as string
606
-	 *
607
-	 * @return string
608
-	 */
609
-	public function renderHtml() {
610
-		if (!$this->footerAdded) {
611
-			$this->footerAdded = true;
612
-			$this->ensureBodyIsClosed();
613
-			$this->htmlBody .= $this->tail;
614
-		}
615
-		return $this->htmlBody;
616
-	}
617
-
618
-	/**
619
-	 * Returns the rendered plain text email as string
620
-	 *
621
-	 * @return string
622
-	 */
623
-	public function renderText() {
624
-		if (!$this->footerAdded) {
625
-			$this->footerAdded = true;
626
-			$this->ensureBodyIsClosed();
627
-			$this->htmlBody .= $this->tail;
628
-		}
629
-		return $this->plainBody;
630
-	}
341
+    /**
342
+     * @param Defaults $themingDefaults
343
+     * @param IURLGenerator $urlGenerator
344
+     * @param IL10N $l10n
345
+     */
346
+    public function __construct(Defaults $themingDefaults,
347
+                                IURLGenerator $urlGenerator,
348
+                                IL10N $l10n) {
349
+        $this->themingDefaults = $themingDefaults;
350
+        $this->urlGenerator = $urlGenerator;
351
+        $this->l10n = $l10n;
352
+        $this->htmlBody .= $this->head;
353
+    }
354
+
355
+    /**
356
+     * Set meta data of an email
357
+     *
358
+     * @param string $emailId
359
+     * @param array $data
360
+     * @since 12.0.3
361
+     */
362
+    public function setMetaData($emailId, array $data = []) {
363
+        $this->emailId = $emailId;
364
+        $this->data = $data;
365
+    }
366
+
367
+    /**
368
+     * Adds a header to the email
369
+     */
370
+    public function addHeader() {
371
+        if ($this->headerAdded) {
372
+            return;
373
+        }
374
+        $this->headerAdded = true;
375
+
376
+        $logoUrl = $this->urlGenerator->getAbsoluteURL($this->themingDefaults->getLogo(false));
377
+        $this->htmlBody .= vsprintf($this->header, [$this->themingDefaults->getColorPrimary(), $logoUrl, $this->themingDefaults->getName()]);
378
+    }
379
+
380
+    /**
381
+     * Adds a heading to the email
382
+     *
383
+     * @param string $title
384
+     * @param string|bool $plainTitle Title that is used in the plain text email
385
+     *   if empty the $title is used, if false none will be used
386
+     */
387
+    public function addHeading($title, $plainTitle = '') {
388
+        if ($this->footerAdded) {
389
+            return;
390
+        }
391
+        if ($plainTitle === '') {
392
+            $plainTitle = $title;
393
+        }
394
+
395
+        $this->htmlBody .= vsprintf($this->heading, [htmlspecialchars($title)]);
396
+        if ($plainTitle !== false) {
397
+            $this->plainBody .= $plainTitle . PHP_EOL . PHP_EOL;
398
+        }
399
+    }
400
+
401
+    /**
402
+     * Open the HTML body when it is not already
403
+     */
404
+    protected function ensureBodyIsOpened() {
405
+        if ($this->bodyOpened) {
406
+            return;
407
+        }
408
+
409
+        $this->htmlBody .= $this->bodyBegin;
410
+        $this->bodyOpened = true;
411
+    }
412
+
413
+    /**
414
+     * Adds a paragraph to the body of the email
415
+     *
416
+     * @param string $text
417
+     * @param string|bool $plainText Text that is used in the plain text email
418
+     *   if empty the $text is used, if false none will be used
419
+     */
420
+    public function addBodyText($text, $plainText = '') {
421
+        if ($this->footerAdded) {
422
+            return;
423
+        }
424
+        if ($plainText === '') {
425
+            $plainText = $text;
426
+        }
427
+
428
+        $this->ensureBodyIsOpened();
429
+
430
+        $this->htmlBody .= vsprintf($this->bodyText, [htmlspecialchars($text)]);
431
+        if ($plainText !== false) {
432
+            $this->plainBody .= $plainText . PHP_EOL . PHP_EOL;
433
+        }
434
+    }
435
+
436
+    /**
437
+     * Adds a list item to the body of the email
438
+     *
439
+     * @param string $text
440
+     * @param string $metaInfo
441
+     * @param string $icon Absolute path, must be 16*16 pixels
442
+     * @param string $plainText Text that is used in the plain text email
443
+     *   if empty the $text is used, if false none will be used
444
+     * @param string $plainMetaInfo Meta info that is used in the plain text email
445
+     *   if empty the $metaInfo is used, if false none will be used
446
+     * @since 12.0.0
447
+     */
448
+    public function addBodyListItem($text, $metaInfo = '', $icon = '', $plainText = '', $plainMetaInfo = '') {
449
+        $this->ensureBodyListOpened();
450
+
451
+        if ($plainText === '') {
452
+            $plainText = $text;
453
+        }
454
+        if ($plainMetaInfo === '') {
455
+            $plainMetaInfo = $metaInfo;
456
+        }
457
+
458
+        $htmlText = htmlspecialchars($text);
459
+        if ($metaInfo) {
460
+            $htmlText = '<em style="color:#777;">' . htmlspecialchars($metaInfo) . '</em><br>' . $htmlText;
461
+        }
462
+        if ($icon !== '') {
463
+            $icon = '<img src="' . htmlspecialchars($icon) . '" alt="&bull;">';
464
+        } else {
465
+            $icon = '&bull;';
466
+        }
467
+        $this->htmlBody .= vsprintf($this->listItem, [$icon, $htmlText]);
468
+        if ($plainText !== false) {
469
+            $this->plainBody .= '  * ' . $plainText;
470
+            if ($plainMetaInfo !== false) {
471
+                $this->plainBody .= ' (' . $plainMetaInfo . ')';
472
+            }
473
+            $this->plainBody .= PHP_EOL;
474
+        }
475
+    }
476
+
477
+    protected function ensureBodyListOpened() {
478
+        if ($this->bodyListOpened) {
479
+            return;
480
+        }
481
+
482
+        $this->ensureBodyIsOpened();
483
+        $this->bodyListOpened = true;
484
+        $this->htmlBody .= $this->listBegin;
485
+    }
486
+
487
+    protected function ensureBodyListClosed() {
488
+        if (!$this->bodyListOpened) {
489
+            return;
490
+        }
491
+
492
+        $this->bodyListOpened = false;
493
+        $this->htmlBody .= $this->listEnd;
494
+    }
495
+
496
+    /**
497
+     * Adds a button group of two buttons to the body of the email
498
+     *
499
+     * @param string $textLeft Text of left button
500
+     * @param string $urlLeft URL of left button
501
+     * @param string $textRight Text of right button
502
+     * @param string $urlRight URL of right button
503
+     * @param string $plainTextLeft Text of left button that is used in the plain text version - if unset the $textLeft is used
504
+     * @param string $plainTextRight Text of right button that is used in the plain text version - if unset the $textRight is used
505
+     */
506
+    public function addBodyButtonGroup($textLeft,
507
+                                        $urlLeft,
508
+                                        $textRight,
509
+                                        $urlRight,
510
+                                        $plainTextLeft = '',
511
+                                        $plainTextRight = '') {
512
+        if ($this->footerAdded) {
513
+            return;
514
+        }
515
+        if ($plainTextLeft === '') {
516
+            $plainTextLeft = $textLeft;
517
+        }
518
+
519
+        if ($plainTextRight === '') {
520
+            $plainTextRight = $textRight;
521
+        }
522
+
523
+        $this->ensureBodyIsOpened();
524
+        $this->ensureBodyListClosed();
525
+
526
+        $color = $this->themingDefaults->getColorPrimary();
527
+
528
+        $this->htmlBody .= vsprintf($this->buttonGroup, [$color, $color, $urlLeft, $color, htmlspecialchars($textLeft), $urlRight, htmlspecialchars($textRight)]);
529
+        $this->plainBody .= $plainTextLeft . ': ' . $urlLeft . PHP_EOL;
530
+        $this->plainBody .= $plainTextRight . ': ' . $urlRight . PHP_EOL . PHP_EOL;
531
+
532
+    }
533
+
534
+    /**
535
+     * Adds a button to the body of the email
536
+     *
537
+     * @param string $text Text of button
538
+     * @param string $url URL of button
539
+     * @param string $plainText Text of button in plain text version
540
+     * 		if empty the $text is used, if false none will be used
541
+     *
542
+     * @since 12.0.0
543
+     */
544
+    public function addBodyButton($text, $url, $plainText = '') {
545
+        if ($this->footerAdded) {
546
+            return;
547
+        }
548
+
549
+        $this->ensureBodyIsOpened();
550
+        $this->ensureBodyListClosed();
551
+
552
+        if ($plainText === '') {
553
+            $plainText = $text;
554
+        }
555
+
556
+        $color = $this->themingDefaults->getColorPrimary();
557
+        $this->htmlBody .= vsprintf($this->button, [$color, $color, $url, $color, htmlspecialchars($text)]);
558
+
559
+        if ($plainText !== false) {
560
+            $this->plainBody .= $plainText . ': ';
561
+        }
562
+
563
+        $this->plainBody .=  $url . PHP_EOL;
564
+
565
+    }
566
+
567
+    /**
568
+     * Close the HTML body when it is open
569
+     */
570
+    protected function ensureBodyIsClosed() {
571
+        if (!$this->bodyOpened) {
572
+            return;
573
+        }
574
+
575
+        $this->ensureBodyListClosed();
576
+
577
+        $this->htmlBody .= $this->bodyEnd;
578
+        $this->bodyOpened = false;
579
+    }
580
+
581
+    /**
582
+     * Adds a logo and a text to the footer. <br> in the text will be replaced by new lines in the plain text email
583
+     *
584
+     * @param string $text If the text is empty the default "Name - Slogan<br>This is an automatically sent email" will be used
585
+     */
586
+    public function addFooter($text = '') {
587
+        if($text === '') {
588
+            $text = $this->themingDefaults->getName() . ' - ' . $this->themingDefaults->getSlogan() . '<br>' . $this->l10n->t('This is an automatically sent email, please do not reply.');
589
+        }
590
+
591
+        if ($this->footerAdded) {
592
+            return;
593
+        }
594
+        $this->footerAdded = true;
595
+
596
+        $this->ensureBodyIsClosed();
597
+
598
+        $this->htmlBody .= vsprintf($this->footer, [$text]);
599
+        $this->htmlBody .= $this->tail;
600
+        $this->plainBody .= PHP_EOL . '-- ' . PHP_EOL;
601
+        $this->plainBody .= str_replace('<br>', PHP_EOL, $text);
602
+    }
603
+
604
+    /**
605
+     * Returns the rendered HTML email as string
606
+     *
607
+     * @return string
608
+     */
609
+    public function renderHtml() {
610
+        if (!$this->footerAdded) {
611
+            $this->footerAdded = true;
612
+            $this->ensureBodyIsClosed();
613
+            $this->htmlBody .= $this->tail;
614
+        }
615
+        return $this->htmlBody;
616
+    }
617
+
618
+    /**
619
+     * Returns the rendered plain text email as string
620
+     *
621
+     * @return string
622
+     */
623
+    public function renderText() {
624
+        if (!$this->footerAdded) {
625
+            $this->footerAdded = true;
626
+            $this->ensureBodyIsClosed();
627
+            $this->htmlBody .= $this->tail;
628
+        }
629
+        return $this->plainBody;
630
+    }
631 631
 }
Please login to merge, or discard this patch.
lib/private/Share20/Manager.php 2 patches
Indentation   +1437 added lines, -1437 removed lines patch added patch discarded remove patch
@@ -60,1465 +60,1465 @@
 block discarded – undo
60 60
  */
61 61
 class Manager implements IManager {
62 62
 
63
-	/** @var IProviderFactory */
64
-	private $factory;
65
-	/** @var ILogger */
66
-	private $logger;
67
-	/** @var IConfig */
68
-	private $config;
69
-	/** @var ISecureRandom */
70
-	private $secureRandom;
71
-	/** @var IHasher */
72
-	private $hasher;
73
-	/** @var IMountManager */
74
-	private $mountManager;
75
-	/** @var IGroupManager */
76
-	private $groupManager;
77
-	/** @var IL10N */
78
-	private $l;
79
-	/** @var IUserManager */
80
-	private $userManager;
81
-	/** @var IRootFolder */
82
-	private $rootFolder;
83
-	/** @var CappedMemoryCache */
84
-	private $sharingDisabledForUsersCache;
85
-	/** @var EventDispatcher */
86
-	private $eventDispatcher;
87
-	/** @var LegacyHooks */
88
-	private $legacyHooks;
89
-	/** @var IMailer */
90
-	private $mailer;
91
-	/** @var IURLGenerator */
92
-	private $urlGenerator;
93
-	/** @var \OC_Defaults */
94
-	private $defaults;
95
-
96
-
97
-	/**
98
-	 * Manager constructor.
99
-	 *
100
-	 * @param ILogger $logger
101
-	 * @param IConfig $config
102
-	 * @param ISecureRandom $secureRandom
103
-	 * @param IHasher $hasher
104
-	 * @param IMountManager $mountManager
105
-	 * @param IGroupManager $groupManager
106
-	 * @param IL10N $l
107
-	 * @param IProviderFactory $factory
108
-	 * @param IUserManager $userManager
109
-	 * @param IRootFolder $rootFolder
110
-	 * @param EventDispatcher $eventDispatcher
111
-	 * @param IMailer $mailer
112
-	 * @param IURLGenerator $urlGenerator
113
-	 * @param \OC_Defaults $defaults
114
-	 */
115
-	public function __construct(
116
-			ILogger $logger,
117
-			IConfig $config,
118
-			ISecureRandom $secureRandom,
119
-			IHasher $hasher,
120
-			IMountManager $mountManager,
121
-			IGroupManager $groupManager,
122
-			IL10N $l,
123
-			IProviderFactory $factory,
124
-			IUserManager $userManager,
125
-			IRootFolder $rootFolder,
126
-			EventDispatcher $eventDispatcher,
127
-			IMailer $mailer,
128
-			IURLGenerator $urlGenerator,
129
-			\OC_Defaults $defaults
130
-	) {
131
-		$this->logger = $logger;
132
-		$this->config = $config;
133
-		$this->secureRandom = $secureRandom;
134
-		$this->hasher = $hasher;
135
-		$this->mountManager = $mountManager;
136
-		$this->groupManager = $groupManager;
137
-		$this->l = $l;
138
-		$this->factory = $factory;
139
-		$this->userManager = $userManager;
140
-		$this->rootFolder = $rootFolder;
141
-		$this->eventDispatcher = $eventDispatcher;
142
-		$this->sharingDisabledForUsersCache = new CappedMemoryCache();
143
-		$this->legacyHooks = new LegacyHooks($this->eventDispatcher);
144
-		$this->mailer = $mailer;
145
-		$this->urlGenerator = $urlGenerator;
146
-		$this->defaults = $defaults;
147
-	}
148
-
149
-	/**
150
-	 * Convert from a full share id to a tuple (providerId, shareId)
151
-	 *
152
-	 * @param string $id
153
-	 * @return string[]
154
-	 */
155
-	private function splitFullId($id) {
156
-		return explode(':', $id, 2);
157
-	}
158
-
159
-	/**
160
-	 * Verify if a password meets all requirements
161
-	 *
162
-	 * @param string $password
163
-	 * @throws \Exception
164
-	 */
165
-	protected function verifyPassword($password) {
166
-		if ($password === null) {
167
-			// No password is set, check if this is allowed.
168
-			if ($this->shareApiLinkEnforcePassword()) {
169
-				throw new \InvalidArgumentException('Passwords are enforced for link shares');
170
-			}
171
-
172
-			return;
173
-		}
174
-
175
-		// Let others verify the password
176
-		try {
177
-			$event = new GenericEvent($password);
178
-			$this->eventDispatcher->dispatch('OCP\PasswordPolicy::validate', $event);
179
-		} catch (HintException $e) {
180
-			throw new \Exception($e->getHint());
181
-		}
182
-	}
183
-
184
-	/**
185
-	 * Check for generic requirements before creating a share
186
-	 *
187
-	 * @param \OCP\Share\IShare $share
188
-	 * @throws \InvalidArgumentException
189
-	 * @throws GenericShareException
190
-	 *
191
-	 * @suppress PhanUndeclaredClassMethod
192
-	 */
193
-	protected function generalCreateChecks(\OCP\Share\IShare $share) {
194
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
195
-			// We expect a valid user as sharedWith for user shares
196
-			if (!$this->userManager->userExists($share->getSharedWith())) {
197
-				throw new \InvalidArgumentException('SharedWith is not a valid user');
198
-			}
199
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
200
-			// We expect a valid group as sharedWith for group shares
201
-			if (!$this->groupManager->groupExists($share->getSharedWith())) {
202
-				throw new \InvalidArgumentException('SharedWith is not a valid group');
203
-			}
204
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
205
-			if ($share->getSharedWith() !== null) {
206
-				throw new \InvalidArgumentException('SharedWith should be empty');
207
-			}
208
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_REMOTE) {
209
-			if ($share->getSharedWith() === null) {
210
-				throw new \InvalidArgumentException('SharedWith should not be empty');
211
-			}
212
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
213
-			if ($share->getSharedWith() === null) {
214
-				throw new \InvalidArgumentException('SharedWith should not be empty');
215
-			}
216
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_CIRCLE) {
217
-			$circle = \OCA\Circles\Api\v1\Circles::detailsCircle($share->getSharedWith());
218
-			if ($circle === null) {
219
-				throw new \InvalidArgumentException('SharedWith is not a valid circle');
220
-			}
221
-		} else {
222
-			// We can't handle other types yet
223
-			throw new \InvalidArgumentException('unknown share type');
224
-		}
225
-
226
-		// Verify the initiator of the share is set
227
-		if ($share->getSharedBy() === null) {
228
-			throw new \InvalidArgumentException('SharedBy should be set');
229
-		}
230
-
231
-		// Cannot share with yourself
232
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
233
-			$share->getSharedWith() === $share->getSharedBy()) {
234
-			throw new \InvalidArgumentException('Can’t share with yourself');
235
-		}
236
-
237
-		// The path should be set
238
-		if ($share->getNode() === null) {
239
-			throw new \InvalidArgumentException('Path should be set');
240
-		}
241
-
242
-		// And it should be a file or a folder
243
-		if (!($share->getNode() instanceof \OCP\Files\File) &&
244
-				!($share->getNode() instanceof \OCP\Files\Folder)) {
245
-			throw new \InvalidArgumentException('Path should be either a file or a folder');
246
-		}
247
-
248
-		// And you can't share your rootfolder
249
-		if ($this->userManager->userExists($share->getSharedBy())) {
250
-			$sharedPath = $this->rootFolder->getUserFolder($share->getSharedBy())->getPath();
251
-		} else {
252
-			$sharedPath = $this->rootFolder->getUserFolder($share->getShareOwner())->getPath();
253
-		}
254
-		if ($sharedPath === $share->getNode()->getPath()) {
255
-			throw new \InvalidArgumentException('You can’t share your root folder');
256
-		}
257
-
258
-		// Check if we actually have share permissions
259
-		if (!$share->getNode()->isShareable()) {
260
-			$message_t = $this->l->t('You are not allowed to share %s', [$share->getNode()->getPath()]);
261
-			throw new GenericShareException($message_t, $message_t, 404);
262
-		}
263
-
264
-		// Permissions should be set
265
-		if ($share->getPermissions() === null) {
266
-			throw new \InvalidArgumentException('A share requires permissions');
267
-		}
268
-
269
-		/*
63
+    /** @var IProviderFactory */
64
+    private $factory;
65
+    /** @var ILogger */
66
+    private $logger;
67
+    /** @var IConfig */
68
+    private $config;
69
+    /** @var ISecureRandom */
70
+    private $secureRandom;
71
+    /** @var IHasher */
72
+    private $hasher;
73
+    /** @var IMountManager */
74
+    private $mountManager;
75
+    /** @var IGroupManager */
76
+    private $groupManager;
77
+    /** @var IL10N */
78
+    private $l;
79
+    /** @var IUserManager */
80
+    private $userManager;
81
+    /** @var IRootFolder */
82
+    private $rootFolder;
83
+    /** @var CappedMemoryCache */
84
+    private $sharingDisabledForUsersCache;
85
+    /** @var EventDispatcher */
86
+    private $eventDispatcher;
87
+    /** @var LegacyHooks */
88
+    private $legacyHooks;
89
+    /** @var IMailer */
90
+    private $mailer;
91
+    /** @var IURLGenerator */
92
+    private $urlGenerator;
93
+    /** @var \OC_Defaults */
94
+    private $defaults;
95
+
96
+
97
+    /**
98
+     * Manager constructor.
99
+     *
100
+     * @param ILogger $logger
101
+     * @param IConfig $config
102
+     * @param ISecureRandom $secureRandom
103
+     * @param IHasher $hasher
104
+     * @param IMountManager $mountManager
105
+     * @param IGroupManager $groupManager
106
+     * @param IL10N $l
107
+     * @param IProviderFactory $factory
108
+     * @param IUserManager $userManager
109
+     * @param IRootFolder $rootFolder
110
+     * @param EventDispatcher $eventDispatcher
111
+     * @param IMailer $mailer
112
+     * @param IURLGenerator $urlGenerator
113
+     * @param \OC_Defaults $defaults
114
+     */
115
+    public function __construct(
116
+            ILogger $logger,
117
+            IConfig $config,
118
+            ISecureRandom $secureRandom,
119
+            IHasher $hasher,
120
+            IMountManager $mountManager,
121
+            IGroupManager $groupManager,
122
+            IL10N $l,
123
+            IProviderFactory $factory,
124
+            IUserManager $userManager,
125
+            IRootFolder $rootFolder,
126
+            EventDispatcher $eventDispatcher,
127
+            IMailer $mailer,
128
+            IURLGenerator $urlGenerator,
129
+            \OC_Defaults $defaults
130
+    ) {
131
+        $this->logger = $logger;
132
+        $this->config = $config;
133
+        $this->secureRandom = $secureRandom;
134
+        $this->hasher = $hasher;
135
+        $this->mountManager = $mountManager;
136
+        $this->groupManager = $groupManager;
137
+        $this->l = $l;
138
+        $this->factory = $factory;
139
+        $this->userManager = $userManager;
140
+        $this->rootFolder = $rootFolder;
141
+        $this->eventDispatcher = $eventDispatcher;
142
+        $this->sharingDisabledForUsersCache = new CappedMemoryCache();
143
+        $this->legacyHooks = new LegacyHooks($this->eventDispatcher);
144
+        $this->mailer = $mailer;
145
+        $this->urlGenerator = $urlGenerator;
146
+        $this->defaults = $defaults;
147
+    }
148
+
149
+    /**
150
+     * Convert from a full share id to a tuple (providerId, shareId)
151
+     *
152
+     * @param string $id
153
+     * @return string[]
154
+     */
155
+    private function splitFullId($id) {
156
+        return explode(':', $id, 2);
157
+    }
158
+
159
+    /**
160
+     * Verify if a password meets all requirements
161
+     *
162
+     * @param string $password
163
+     * @throws \Exception
164
+     */
165
+    protected function verifyPassword($password) {
166
+        if ($password === null) {
167
+            // No password is set, check if this is allowed.
168
+            if ($this->shareApiLinkEnforcePassword()) {
169
+                throw new \InvalidArgumentException('Passwords are enforced for link shares');
170
+            }
171
+
172
+            return;
173
+        }
174
+
175
+        // Let others verify the password
176
+        try {
177
+            $event = new GenericEvent($password);
178
+            $this->eventDispatcher->dispatch('OCP\PasswordPolicy::validate', $event);
179
+        } catch (HintException $e) {
180
+            throw new \Exception($e->getHint());
181
+        }
182
+    }
183
+
184
+    /**
185
+     * Check for generic requirements before creating a share
186
+     *
187
+     * @param \OCP\Share\IShare $share
188
+     * @throws \InvalidArgumentException
189
+     * @throws GenericShareException
190
+     *
191
+     * @suppress PhanUndeclaredClassMethod
192
+     */
193
+    protected function generalCreateChecks(\OCP\Share\IShare $share) {
194
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
195
+            // We expect a valid user as sharedWith for user shares
196
+            if (!$this->userManager->userExists($share->getSharedWith())) {
197
+                throw new \InvalidArgumentException('SharedWith is not a valid user');
198
+            }
199
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
200
+            // We expect a valid group as sharedWith for group shares
201
+            if (!$this->groupManager->groupExists($share->getSharedWith())) {
202
+                throw new \InvalidArgumentException('SharedWith is not a valid group');
203
+            }
204
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
205
+            if ($share->getSharedWith() !== null) {
206
+                throw new \InvalidArgumentException('SharedWith should be empty');
207
+            }
208
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_REMOTE) {
209
+            if ($share->getSharedWith() === null) {
210
+                throw new \InvalidArgumentException('SharedWith should not be empty');
211
+            }
212
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
213
+            if ($share->getSharedWith() === null) {
214
+                throw new \InvalidArgumentException('SharedWith should not be empty');
215
+            }
216
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_CIRCLE) {
217
+            $circle = \OCA\Circles\Api\v1\Circles::detailsCircle($share->getSharedWith());
218
+            if ($circle === null) {
219
+                throw new \InvalidArgumentException('SharedWith is not a valid circle');
220
+            }
221
+        } else {
222
+            // We can't handle other types yet
223
+            throw new \InvalidArgumentException('unknown share type');
224
+        }
225
+
226
+        // Verify the initiator of the share is set
227
+        if ($share->getSharedBy() === null) {
228
+            throw new \InvalidArgumentException('SharedBy should be set');
229
+        }
230
+
231
+        // Cannot share with yourself
232
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
233
+            $share->getSharedWith() === $share->getSharedBy()) {
234
+            throw new \InvalidArgumentException('Can’t share with yourself');
235
+        }
236
+
237
+        // The path should be set
238
+        if ($share->getNode() === null) {
239
+            throw new \InvalidArgumentException('Path should be set');
240
+        }
241
+
242
+        // And it should be a file or a folder
243
+        if (!($share->getNode() instanceof \OCP\Files\File) &&
244
+                !($share->getNode() instanceof \OCP\Files\Folder)) {
245
+            throw new \InvalidArgumentException('Path should be either a file or a folder');
246
+        }
247
+
248
+        // And you can't share your rootfolder
249
+        if ($this->userManager->userExists($share->getSharedBy())) {
250
+            $sharedPath = $this->rootFolder->getUserFolder($share->getSharedBy())->getPath();
251
+        } else {
252
+            $sharedPath = $this->rootFolder->getUserFolder($share->getShareOwner())->getPath();
253
+        }
254
+        if ($sharedPath === $share->getNode()->getPath()) {
255
+            throw new \InvalidArgumentException('You can’t share your root folder');
256
+        }
257
+
258
+        // Check if we actually have share permissions
259
+        if (!$share->getNode()->isShareable()) {
260
+            $message_t = $this->l->t('You are not allowed to share %s', [$share->getNode()->getPath()]);
261
+            throw new GenericShareException($message_t, $message_t, 404);
262
+        }
263
+
264
+        // Permissions should be set
265
+        if ($share->getPermissions() === null) {
266
+            throw new \InvalidArgumentException('A share requires permissions');
267
+        }
268
+
269
+        /*
270 270
 		 * Quick fix for #23536
271 271
 		 * Non moveable mount points do not have update and delete permissions
272 272
 		 * while we 'most likely' do have that on the storage.
273 273
 		 */
274
-		$permissions = $share->getNode()->getPermissions();
275
-		$mount = $share->getNode()->getMountPoint();
276
-		if (!($mount instanceof MoveableMount)) {
277
-			$permissions |= \OCP\Constants::PERMISSION_DELETE | \OCP\Constants::PERMISSION_UPDATE;
278
-		}
279
-
280
-		// Check that we do not share with more permissions than we have
281
-		if ($share->getPermissions() & ~$permissions) {
282
-			$message_t = $this->l->t('Can’t increase permissions of %s', [$share->getNode()->getPath()]);
283
-			throw new GenericShareException($message_t, $message_t, 404);
284
-		}
285
-
286
-
287
-		// Check that read permissions are always set
288
-		// Link shares are allowed to have no read permissions to allow upload to hidden folders
289
-		$noReadPermissionRequired = $share->getShareType() === \OCP\Share::SHARE_TYPE_LINK
290
-			|| $share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL;
291
-		if (!$noReadPermissionRequired &&
292
-			($share->getPermissions() & \OCP\Constants::PERMISSION_READ) === 0) {
293
-			throw new \InvalidArgumentException('Shares need at least read permissions');
294
-		}
295
-
296
-		if ($share->getNode() instanceof \OCP\Files\File) {
297
-			if ($share->getPermissions() & \OCP\Constants::PERMISSION_DELETE) {
298
-				$message_t = $this->l->t('Files can’t be shared with delete permissions');
299
-				throw new GenericShareException($message_t);
300
-			}
301
-			if ($share->getPermissions() & \OCP\Constants::PERMISSION_CREATE) {
302
-				$message_t = $this->l->t('Files can’t be shared with create permissions');
303
-				throw new GenericShareException($message_t);
304
-			}
305
-		}
306
-	}
307
-
308
-	/**
309
-	 * Validate if the expiration date fits the system settings
310
-	 *
311
-	 * @param \OCP\Share\IShare $share The share to validate the expiration date of
312
-	 * @return \OCP\Share\IShare The modified share object
313
-	 * @throws GenericShareException
314
-	 * @throws \InvalidArgumentException
315
-	 * @throws \Exception
316
-	 */
317
-	protected function validateExpirationDate(\OCP\Share\IShare $share) {
318
-
319
-		$expirationDate = $share->getExpirationDate();
320
-
321
-		if ($expirationDate !== null) {
322
-			//Make sure the expiration date is a date
323
-			$expirationDate->setTime(0, 0, 0);
324
-
325
-			$date = new \DateTime();
326
-			$date->setTime(0, 0, 0);
327
-			if ($date >= $expirationDate) {
328
-				$message = $this->l->t('Expiration date is in the past');
329
-				throw new GenericShareException($message, $message, 404);
330
-			}
331
-		}
332
-
333
-		// If expiredate is empty set a default one if there is a default
334
-		$fullId = null;
335
-		try {
336
-			$fullId = $share->getFullId();
337
-		} catch (\UnexpectedValueException $e) {
338
-			// This is a new share
339
-		}
340
-
341
-		if ($fullId === null && $expirationDate === null && $this->shareApiLinkDefaultExpireDate()) {
342
-			$expirationDate = new \DateTime();
343
-			$expirationDate->setTime(0,0,0);
344
-			$expirationDate->add(new \DateInterval('P'.$this->shareApiLinkDefaultExpireDays().'D'));
345
-		}
346
-
347
-		// If we enforce the expiration date check that is does not exceed
348
-		if ($this->shareApiLinkDefaultExpireDateEnforced()) {
349
-			if ($expirationDate === null) {
350
-				throw new \InvalidArgumentException('Expiration date is enforced');
351
-			}
352
-
353
-			$date = new \DateTime();
354
-			$date->setTime(0, 0, 0);
355
-			$date->add(new \DateInterval('P' . $this->shareApiLinkDefaultExpireDays() . 'D'));
356
-			if ($date < $expirationDate) {
357
-				$message = $this->l->t('Can’t set expiration date more than %s days in the future', [$this->shareApiLinkDefaultExpireDays()]);
358
-				throw new GenericShareException($message, $message, 404);
359
-			}
360
-		}
361
-
362
-		$accepted = true;
363
-		$message = '';
364
-		\OCP\Util::emitHook('\OC\Share', 'verifyExpirationDate', [
365
-			'expirationDate' => &$expirationDate,
366
-			'accepted' => &$accepted,
367
-			'message' => &$message,
368
-			'passwordSet' => $share->getPassword() !== null,
369
-		]);
370
-
371
-		if (!$accepted) {
372
-			throw new \Exception($message);
373
-		}
374
-
375
-		$share->setExpirationDate($expirationDate);
376
-
377
-		return $share;
378
-	}
379
-
380
-	/**
381
-	 * Check for pre share requirements for user shares
382
-	 *
383
-	 * @param \OCP\Share\IShare $share
384
-	 * @throws \Exception
385
-	 */
386
-	protected function userCreateChecks(\OCP\Share\IShare $share) {
387
-		// Check if we can share with group members only
388
-		if ($this->shareWithGroupMembersOnly()) {
389
-			$sharedBy = $this->userManager->get($share->getSharedBy());
390
-			$sharedWith = $this->userManager->get($share->getSharedWith());
391
-			// Verify we can share with this user
392
-			$groups = array_intersect(
393
-					$this->groupManager->getUserGroupIds($sharedBy),
394
-					$this->groupManager->getUserGroupIds($sharedWith)
395
-			);
396
-			if (empty($groups)) {
397
-				throw new \Exception('Sharing is only allowed with group members');
398
-			}
399
-		}
400
-
401
-		/*
274
+        $permissions = $share->getNode()->getPermissions();
275
+        $mount = $share->getNode()->getMountPoint();
276
+        if (!($mount instanceof MoveableMount)) {
277
+            $permissions |= \OCP\Constants::PERMISSION_DELETE | \OCP\Constants::PERMISSION_UPDATE;
278
+        }
279
+
280
+        // Check that we do not share with more permissions than we have
281
+        if ($share->getPermissions() & ~$permissions) {
282
+            $message_t = $this->l->t('Can’t increase permissions of %s', [$share->getNode()->getPath()]);
283
+            throw new GenericShareException($message_t, $message_t, 404);
284
+        }
285
+
286
+
287
+        // Check that read permissions are always set
288
+        // Link shares are allowed to have no read permissions to allow upload to hidden folders
289
+        $noReadPermissionRequired = $share->getShareType() === \OCP\Share::SHARE_TYPE_LINK
290
+            || $share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL;
291
+        if (!$noReadPermissionRequired &&
292
+            ($share->getPermissions() & \OCP\Constants::PERMISSION_READ) === 0) {
293
+            throw new \InvalidArgumentException('Shares need at least read permissions');
294
+        }
295
+
296
+        if ($share->getNode() instanceof \OCP\Files\File) {
297
+            if ($share->getPermissions() & \OCP\Constants::PERMISSION_DELETE) {
298
+                $message_t = $this->l->t('Files can’t be shared with delete permissions');
299
+                throw new GenericShareException($message_t);
300
+            }
301
+            if ($share->getPermissions() & \OCP\Constants::PERMISSION_CREATE) {
302
+                $message_t = $this->l->t('Files can’t be shared with create permissions');
303
+                throw new GenericShareException($message_t);
304
+            }
305
+        }
306
+    }
307
+
308
+    /**
309
+     * Validate if the expiration date fits the system settings
310
+     *
311
+     * @param \OCP\Share\IShare $share The share to validate the expiration date of
312
+     * @return \OCP\Share\IShare The modified share object
313
+     * @throws GenericShareException
314
+     * @throws \InvalidArgumentException
315
+     * @throws \Exception
316
+     */
317
+    protected function validateExpirationDate(\OCP\Share\IShare $share) {
318
+
319
+        $expirationDate = $share->getExpirationDate();
320
+
321
+        if ($expirationDate !== null) {
322
+            //Make sure the expiration date is a date
323
+            $expirationDate->setTime(0, 0, 0);
324
+
325
+            $date = new \DateTime();
326
+            $date->setTime(0, 0, 0);
327
+            if ($date >= $expirationDate) {
328
+                $message = $this->l->t('Expiration date is in the past');
329
+                throw new GenericShareException($message, $message, 404);
330
+            }
331
+        }
332
+
333
+        // If expiredate is empty set a default one if there is a default
334
+        $fullId = null;
335
+        try {
336
+            $fullId = $share->getFullId();
337
+        } catch (\UnexpectedValueException $e) {
338
+            // This is a new share
339
+        }
340
+
341
+        if ($fullId === null && $expirationDate === null && $this->shareApiLinkDefaultExpireDate()) {
342
+            $expirationDate = new \DateTime();
343
+            $expirationDate->setTime(0,0,0);
344
+            $expirationDate->add(new \DateInterval('P'.$this->shareApiLinkDefaultExpireDays().'D'));
345
+        }
346
+
347
+        // If we enforce the expiration date check that is does not exceed
348
+        if ($this->shareApiLinkDefaultExpireDateEnforced()) {
349
+            if ($expirationDate === null) {
350
+                throw new \InvalidArgumentException('Expiration date is enforced');
351
+            }
352
+
353
+            $date = new \DateTime();
354
+            $date->setTime(0, 0, 0);
355
+            $date->add(new \DateInterval('P' . $this->shareApiLinkDefaultExpireDays() . 'D'));
356
+            if ($date < $expirationDate) {
357
+                $message = $this->l->t('Can’t set expiration date more than %s days in the future', [$this->shareApiLinkDefaultExpireDays()]);
358
+                throw new GenericShareException($message, $message, 404);
359
+            }
360
+        }
361
+
362
+        $accepted = true;
363
+        $message = '';
364
+        \OCP\Util::emitHook('\OC\Share', 'verifyExpirationDate', [
365
+            'expirationDate' => &$expirationDate,
366
+            'accepted' => &$accepted,
367
+            'message' => &$message,
368
+            'passwordSet' => $share->getPassword() !== null,
369
+        ]);
370
+
371
+        if (!$accepted) {
372
+            throw new \Exception($message);
373
+        }
374
+
375
+        $share->setExpirationDate($expirationDate);
376
+
377
+        return $share;
378
+    }
379
+
380
+    /**
381
+     * Check for pre share requirements for user shares
382
+     *
383
+     * @param \OCP\Share\IShare $share
384
+     * @throws \Exception
385
+     */
386
+    protected function userCreateChecks(\OCP\Share\IShare $share) {
387
+        // Check if we can share with group members only
388
+        if ($this->shareWithGroupMembersOnly()) {
389
+            $sharedBy = $this->userManager->get($share->getSharedBy());
390
+            $sharedWith = $this->userManager->get($share->getSharedWith());
391
+            // Verify we can share with this user
392
+            $groups = array_intersect(
393
+                    $this->groupManager->getUserGroupIds($sharedBy),
394
+                    $this->groupManager->getUserGroupIds($sharedWith)
395
+            );
396
+            if (empty($groups)) {
397
+                throw new \Exception('Sharing is only allowed with group members');
398
+            }
399
+        }
400
+
401
+        /*
402 402
 		 * TODO: Could be costly, fix
403 403
 		 *
404 404
 		 * Also this is not what we want in the future.. then we want to squash identical shares.
405 405
 		 */
406
-		$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_USER);
407
-		$existingShares = $provider->getSharesByPath($share->getNode());
408
-		foreach($existingShares as $existingShare) {
409
-			// Ignore if it is the same share
410
-			try {
411
-				if ($existingShare->getFullId() === $share->getFullId()) {
412
-					continue;
413
-				}
414
-			} catch (\UnexpectedValueException $e) {
415
-				//Shares are not identical
416
-			}
417
-
418
-			// Identical share already existst
419
-			if ($existingShare->getSharedWith() === $share->getSharedWith()) {
420
-				throw new \Exception('Path is already shared with this user');
421
-			}
422
-
423
-			// The share is already shared with this user via a group share
424
-			if ($existingShare->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
425
-				$group = $this->groupManager->get($existingShare->getSharedWith());
426
-				if (!is_null($group)) {
427
-					$user = $this->userManager->get($share->getSharedWith());
428
-
429
-					if ($group->inGroup($user) && $existingShare->getShareOwner() !== $share->getShareOwner()) {
430
-						throw new \Exception('Path is already shared with this user');
431
-					}
432
-				}
433
-			}
434
-		}
435
-	}
436
-
437
-	/**
438
-	 * Check for pre share requirements for group shares
439
-	 *
440
-	 * @param \OCP\Share\IShare $share
441
-	 * @throws \Exception
442
-	 */
443
-	protected function groupCreateChecks(\OCP\Share\IShare $share) {
444
-		// Verify group shares are allowed
445
-		if (!$this->allowGroupSharing()) {
446
-			throw new \Exception('Group sharing is now allowed');
447
-		}
448
-
449
-		// Verify if the user can share with this group
450
-		if ($this->shareWithGroupMembersOnly()) {
451
-			$sharedBy = $this->userManager->get($share->getSharedBy());
452
-			$sharedWith = $this->groupManager->get($share->getSharedWith());
453
-			if (is_null($sharedWith) || !$sharedWith->inGroup($sharedBy)) {
454
-				throw new \Exception('Sharing is only allowed within your own groups');
455
-			}
456
-		}
457
-
458
-		/*
406
+        $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_USER);
407
+        $existingShares = $provider->getSharesByPath($share->getNode());
408
+        foreach($existingShares as $existingShare) {
409
+            // Ignore if it is the same share
410
+            try {
411
+                if ($existingShare->getFullId() === $share->getFullId()) {
412
+                    continue;
413
+                }
414
+            } catch (\UnexpectedValueException $e) {
415
+                //Shares are not identical
416
+            }
417
+
418
+            // Identical share already existst
419
+            if ($existingShare->getSharedWith() === $share->getSharedWith()) {
420
+                throw new \Exception('Path is already shared with this user');
421
+            }
422
+
423
+            // The share is already shared with this user via a group share
424
+            if ($existingShare->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
425
+                $group = $this->groupManager->get($existingShare->getSharedWith());
426
+                if (!is_null($group)) {
427
+                    $user = $this->userManager->get($share->getSharedWith());
428
+
429
+                    if ($group->inGroup($user) && $existingShare->getShareOwner() !== $share->getShareOwner()) {
430
+                        throw new \Exception('Path is already shared with this user');
431
+                    }
432
+                }
433
+            }
434
+        }
435
+    }
436
+
437
+    /**
438
+     * Check for pre share requirements for group shares
439
+     *
440
+     * @param \OCP\Share\IShare $share
441
+     * @throws \Exception
442
+     */
443
+    protected function groupCreateChecks(\OCP\Share\IShare $share) {
444
+        // Verify group shares are allowed
445
+        if (!$this->allowGroupSharing()) {
446
+            throw new \Exception('Group sharing is now allowed');
447
+        }
448
+
449
+        // Verify if the user can share with this group
450
+        if ($this->shareWithGroupMembersOnly()) {
451
+            $sharedBy = $this->userManager->get($share->getSharedBy());
452
+            $sharedWith = $this->groupManager->get($share->getSharedWith());
453
+            if (is_null($sharedWith) || !$sharedWith->inGroup($sharedBy)) {
454
+                throw new \Exception('Sharing is only allowed within your own groups');
455
+            }
456
+        }
457
+
458
+        /*
459 459
 		 * TODO: Could be costly, fix
460 460
 		 *
461 461
 		 * Also this is not what we want in the future.. then we want to squash identical shares.
462 462
 		 */
463
-		$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
464
-		$existingShares = $provider->getSharesByPath($share->getNode());
465
-		foreach($existingShares as $existingShare) {
466
-			try {
467
-				if ($existingShare->getFullId() === $share->getFullId()) {
468
-					continue;
469
-				}
470
-			} catch (\UnexpectedValueException $e) {
471
-				//It is a new share so just continue
472
-			}
473
-
474
-			if ($existingShare->getSharedWith() === $share->getSharedWith()) {
475
-				throw new \Exception('Path is already shared with this group');
476
-			}
477
-		}
478
-	}
479
-
480
-	/**
481
-	 * Check for pre share requirements for link shares
482
-	 *
483
-	 * @param \OCP\Share\IShare $share
484
-	 * @throws \Exception
485
-	 */
486
-	protected function linkCreateChecks(\OCP\Share\IShare $share) {
487
-		// Are link shares allowed?
488
-		if (!$this->shareApiAllowLinks()) {
489
-			throw new \Exception('Link sharing is not allowed');
490
-		}
491
-
492
-		// Link shares by definition can't have share permissions
493
-		if ($share->getPermissions() & \OCP\Constants::PERMISSION_SHARE) {
494
-			throw new \InvalidArgumentException('Link shares can’t have reshare permissions');
495
-		}
496
-
497
-		// Check if public upload is allowed
498
-		if (!$this->shareApiLinkAllowPublicUpload() &&
499
-			($share->getPermissions() & (\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE))) {
500
-			throw new \InvalidArgumentException('Public upload is not allowed');
501
-		}
502
-	}
503
-
504
-	/**
505
-	 * To make sure we don't get invisible link shares we set the parent
506
-	 * of a link if it is a reshare. This is a quick word around
507
-	 * until we can properly display multiple link shares in the UI
508
-	 *
509
-	 * See: https://github.com/owncloud/core/issues/22295
510
-	 *
511
-	 * FIXME: Remove once multiple link shares can be properly displayed
512
-	 *
513
-	 * @param \OCP\Share\IShare $share
514
-	 */
515
-	protected function setLinkParent(\OCP\Share\IShare $share) {
516
-
517
-		// No sense in checking if the method is not there.
518
-		if (method_exists($share, 'setParent')) {
519
-			$storage = $share->getNode()->getStorage();
520
-			if ($storage->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
521
-				/** @var \OCA\Files_Sharing\SharedStorage $storage */
522
-				$share->setParent($storage->getShareId());
523
-			}
524
-		};
525
-	}
526
-
527
-	/**
528
-	 * @param File|Folder $path
529
-	 */
530
-	protected function pathCreateChecks($path) {
531
-		// Make sure that we do not share a path that contains a shared mountpoint
532
-		if ($path instanceof \OCP\Files\Folder) {
533
-			$mounts = $this->mountManager->findIn($path->getPath());
534
-			foreach($mounts as $mount) {
535
-				if ($mount->getStorage()->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
536
-					throw new \InvalidArgumentException('Path contains files shared with you');
537
-				}
538
-			}
539
-		}
540
-	}
541
-
542
-	/**
543
-	 * Check if the user that is sharing can actually share
544
-	 *
545
-	 * @param \OCP\Share\IShare $share
546
-	 * @throws \Exception
547
-	 */
548
-	protected function canShare(\OCP\Share\IShare $share) {
549
-		if (!$this->shareApiEnabled()) {
550
-			throw new \Exception('Sharing is disabled');
551
-		}
552
-
553
-		if ($this->sharingDisabledForUser($share->getSharedBy())) {
554
-			throw new \Exception('Sharing is disabled for you');
555
-		}
556
-	}
557
-
558
-	/**
559
-	 * Share a path
560
-	 *
561
-	 * @param \OCP\Share\IShare $share
562
-	 * @return Share The share object
563
-	 * @throws \Exception
564
-	 *
565
-	 * TODO: handle link share permissions or check them
566
-	 */
567
-	public function createShare(\OCP\Share\IShare $share) {
568
-		$this->canShare($share);
569
-
570
-		$this->generalCreateChecks($share);
571
-
572
-		// Verify if there are any issues with the path
573
-		$this->pathCreateChecks($share->getNode());
574
-
575
-		/*
463
+        $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
464
+        $existingShares = $provider->getSharesByPath($share->getNode());
465
+        foreach($existingShares as $existingShare) {
466
+            try {
467
+                if ($existingShare->getFullId() === $share->getFullId()) {
468
+                    continue;
469
+                }
470
+            } catch (\UnexpectedValueException $e) {
471
+                //It is a new share so just continue
472
+            }
473
+
474
+            if ($existingShare->getSharedWith() === $share->getSharedWith()) {
475
+                throw new \Exception('Path is already shared with this group');
476
+            }
477
+        }
478
+    }
479
+
480
+    /**
481
+     * Check for pre share requirements for link shares
482
+     *
483
+     * @param \OCP\Share\IShare $share
484
+     * @throws \Exception
485
+     */
486
+    protected function linkCreateChecks(\OCP\Share\IShare $share) {
487
+        // Are link shares allowed?
488
+        if (!$this->shareApiAllowLinks()) {
489
+            throw new \Exception('Link sharing is not allowed');
490
+        }
491
+
492
+        // Link shares by definition can't have share permissions
493
+        if ($share->getPermissions() & \OCP\Constants::PERMISSION_SHARE) {
494
+            throw new \InvalidArgumentException('Link shares can’t have reshare permissions');
495
+        }
496
+
497
+        // Check if public upload is allowed
498
+        if (!$this->shareApiLinkAllowPublicUpload() &&
499
+            ($share->getPermissions() & (\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE))) {
500
+            throw new \InvalidArgumentException('Public upload is not allowed');
501
+        }
502
+    }
503
+
504
+    /**
505
+     * To make sure we don't get invisible link shares we set the parent
506
+     * of a link if it is a reshare. This is a quick word around
507
+     * until we can properly display multiple link shares in the UI
508
+     *
509
+     * See: https://github.com/owncloud/core/issues/22295
510
+     *
511
+     * FIXME: Remove once multiple link shares can be properly displayed
512
+     *
513
+     * @param \OCP\Share\IShare $share
514
+     */
515
+    protected function setLinkParent(\OCP\Share\IShare $share) {
516
+
517
+        // No sense in checking if the method is not there.
518
+        if (method_exists($share, 'setParent')) {
519
+            $storage = $share->getNode()->getStorage();
520
+            if ($storage->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
521
+                /** @var \OCA\Files_Sharing\SharedStorage $storage */
522
+                $share->setParent($storage->getShareId());
523
+            }
524
+        };
525
+    }
526
+
527
+    /**
528
+     * @param File|Folder $path
529
+     */
530
+    protected function pathCreateChecks($path) {
531
+        // Make sure that we do not share a path that contains a shared mountpoint
532
+        if ($path instanceof \OCP\Files\Folder) {
533
+            $mounts = $this->mountManager->findIn($path->getPath());
534
+            foreach($mounts as $mount) {
535
+                if ($mount->getStorage()->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
536
+                    throw new \InvalidArgumentException('Path contains files shared with you');
537
+                }
538
+            }
539
+        }
540
+    }
541
+
542
+    /**
543
+     * Check if the user that is sharing can actually share
544
+     *
545
+     * @param \OCP\Share\IShare $share
546
+     * @throws \Exception
547
+     */
548
+    protected function canShare(\OCP\Share\IShare $share) {
549
+        if (!$this->shareApiEnabled()) {
550
+            throw new \Exception('Sharing is disabled');
551
+        }
552
+
553
+        if ($this->sharingDisabledForUser($share->getSharedBy())) {
554
+            throw new \Exception('Sharing is disabled for you');
555
+        }
556
+    }
557
+
558
+    /**
559
+     * Share a path
560
+     *
561
+     * @param \OCP\Share\IShare $share
562
+     * @return Share The share object
563
+     * @throws \Exception
564
+     *
565
+     * TODO: handle link share permissions or check them
566
+     */
567
+    public function createShare(\OCP\Share\IShare $share) {
568
+        $this->canShare($share);
569
+
570
+        $this->generalCreateChecks($share);
571
+
572
+        // Verify if there are any issues with the path
573
+        $this->pathCreateChecks($share->getNode());
574
+
575
+        /*
576 576
 		 * On creation of a share the owner is always the owner of the path
577 577
 		 * Except for mounted federated shares.
578 578
 		 */
579
-		$storage = $share->getNode()->getStorage();
580
-		if ($storage->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
581
-			$parent = $share->getNode()->getParent();
582
-			while($parent->getStorage()->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
583
-				$parent = $parent->getParent();
584
-			}
585
-			$share->setShareOwner($parent->getOwner()->getUID());
586
-		} else {
587
-			$share->setShareOwner($share->getNode()->getOwner()->getUID());
588
-		}
589
-
590
-		//Verify share type
591
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
592
-			$this->userCreateChecks($share);
593
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
594
-			$this->groupCreateChecks($share);
595
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
596
-			$this->linkCreateChecks($share);
597
-			$this->setLinkParent($share);
598
-
599
-			/*
579
+        $storage = $share->getNode()->getStorage();
580
+        if ($storage->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
581
+            $parent = $share->getNode()->getParent();
582
+            while($parent->getStorage()->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
583
+                $parent = $parent->getParent();
584
+            }
585
+            $share->setShareOwner($parent->getOwner()->getUID());
586
+        } else {
587
+            $share->setShareOwner($share->getNode()->getOwner()->getUID());
588
+        }
589
+
590
+        //Verify share type
591
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
592
+            $this->userCreateChecks($share);
593
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
594
+            $this->groupCreateChecks($share);
595
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
596
+            $this->linkCreateChecks($share);
597
+            $this->setLinkParent($share);
598
+
599
+            /*
600 600
 			 * For now ignore a set token.
601 601
 			 */
602
-			$share->setToken(
603
-				$this->secureRandom->generate(
604
-					\OC\Share\Constants::TOKEN_LENGTH,
605
-					\OCP\Security\ISecureRandom::CHAR_HUMAN_READABLE
606
-				)
607
-			);
608
-
609
-			//Verify the expiration date
610
-			$this->validateExpirationDate($share);
611
-
612
-			//Verify the password
613
-			$this->verifyPassword($share->getPassword());
614
-
615
-			// If a password is set. Hash it!
616
-			if ($share->getPassword() !== null) {
617
-				$share->setPassword($this->hasher->hash($share->getPassword()));
618
-			}
619
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
620
-			$share->setToken(
621
-				$this->secureRandom->generate(
622
-					\OC\Share\Constants::TOKEN_LENGTH,
623
-					\OCP\Security\ISecureRandom::CHAR_HUMAN_READABLE
624
-				)
625
-			);
626
-		}
627
-
628
-		// Cannot share with the owner
629
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
630
-			$share->getSharedWith() === $share->getShareOwner()) {
631
-			throw new \InvalidArgumentException('Can’t share with the share owner');
632
-		}
633
-
634
-		// Generate the target
635
-		$target = $this->config->getSystemValue('share_folder', '/') .'/'. $share->getNode()->getName();
636
-		$target = \OC\Files\Filesystem::normalizePath($target);
637
-		$share->setTarget($target);
638
-
639
-		// Pre share event
640
-		$event = new GenericEvent($share);
641
-		$a = $this->eventDispatcher->dispatch('OCP\Share::preShare', $event);
642
-		if ($event->isPropagationStopped() && $event->hasArgument('error')) {
643
-			throw new \Exception($event->getArgument('error'));
644
-		}
645
-
646
-		$oldShare = $share;
647
-		$provider = $this->factory->getProviderForType($share->getShareType());
648
-		$share = $provider->create($share);
649
-		//reuse the node we already have
650
-		$share->setNode($oldShare->getNode());
651
-
652
-		// Post share event
653
-		$event = new GenericEvent($share);
654
-		$this->eventDispatcher->dispatch('OCP\Share::postShare', $event);
655
-
656
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
657
-			$user = $this->userManager->get($share->getSharedWith());
658
-			if ($user !== null) {
659
-				$emailAddress = $user->getEMailAddress();
660
-				if ($emailAddress !== null && $emailAddress !== '') {
661
-					$this->sendMailNotification(
662
-						$share->getNode()->getName(),
663
-						$this->urlGenerator->linkToRouteAbsolute('files.viewcontroller.showFile', [ 'fileid' => $share->getNode()->getId() ]),
664
-						$share->getSharedBy(),
665
-						$emailAddress,
666
-						$share->getExpirationDate()
667
-					);
668
-					$this->logger->debug('Send share notification to ' . $emailAddress . ' for share with ID ' . $share->getId(), ['app' => 'share']);
669
-				} else {
670
-					$this->logger->debug('Share notification not send to ' . $share->getSharedWith() . ' because email address is not set.', ['app' => 'share']);
671
-				}
672
-			} else {
673
-				$this->logger->debug('Share notification not send to ' . $share->getSharedWith() . ' because user could not be found.', ['app' => 'share']);
674
-			}
675
-		}
676
-
677
-		return $share;
678
-	}
679
-
680
-	/**
681
-	 * @param string $filename file/folder name
682
-	 * @param string $link link to the file/folder
683
-	 * @param string $initiator user ID of share sender
684
-	 * @param string $shareWith email address of share receiver
685
-	 * @param \DateTime $expiration
686
-	 * @throws \Exception If mail couldn't be sent
687
-	 */
688
-	protected function sendMailNotification($filename,
689
-											$link,
690
-											$initiator,
691
-											$shareWith,
692
-											\DateTime $expiration) {
693
-		$initiatorUser = $this->userManager->get($initiator);
694
-		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
695
-		$subject = (string)$this->l->t('%s shared »%s« with you', array($initiatorDisplayName, $filename));
696
-
697
-		$message = $this->mailer->createMessage();
698
-
699
-		$emailTemplate = $this->mailer->createEMailTemplate();
700
-		$emailTemplate->setMetaData('files_sharing.RecipientNotification', [
701
-			'filename' => $filename,
702
-			'link' => $link,
703
-			'initiator' => $initiatorDisplayName,
704
-			'expiration' => $expiration,
705
-		]);
706
-
707
-		$emailTemplate->addHeader();
708
-		$emailTemplate->addHeading($this->l->t('%s shared »%s« with you', [$initiatorDisplayName, $filename]), false);
709
-		$text = $this->l->t('%s shared »%s« with you.', [$initiatorDisplayName, $filename]);
710
-
711
-		$emailTemplate->addBodyText(
712
-			$text . ' ' . $this->l->t('Click the button below to open it.'),
713
-			$text
714
-		);
715
-		$emailTemplate->addBodyButton(
716
-			$this->l->t('Open »%s«', [$filename]),
717
-			$link
718
-		);
719
-
720
-		$message->setTo([$shareWith]);
721
-
722
-		// The "From" contains the sharers name
723
-		$instanceName = $this->defaults->getName();
724
-		$senderName = $this->l->t(
725
-			'%s via %s',
726
-			[
727
-				$initiatorDisplayName,
728
-				$instanceName
729
-			]
730
-		);
731
-		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
732
-
733
-		// The "Reply-To" is set to the sharer if an mail address is configured
734
-		// also the default footer contains a "Do not reply" which needs to be adjusted.
735
-		$initiatorEmail = $initiatorUser->getEMailAddress();
736
-		if($initiatorEmail !== null) {
737
-			$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
738
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
739
-		} else {
740
-			$emailTemplate->addFooter();
741
-		}
742
-
743
-		$message->setSubject($subject);
744
-		$message->setPlainBody($emailTemplate->renderText());
745
-		$message->setHtmlBody($emailTemplate->renderHtml());
746
-		$this->mailer->send($message);
747
-	}
748
-
749
-	/**
750
-	 * Update a share
751
-	 *
752
-	 * @param \OCP\Share\IShare $share
753
-	 * @return \OCP\Share\IShare The share object
754
-	 * @throws \InvalidArgumentException
755
-	 */
756
-	public function updateShare(\OCP\Share\IShare $share) {
757
-		$expirationDateUpdated = false;
758
-
759
-		$this->canShare($share);
760
-
761
-		try {
762
-			$originalShare = $this->getShareById($share->getFullId());
763
-		} catch (\UnexpectedValueException $e) {
764
-			throw new \InvalidArgumentException('Share does not have a full id');
765
-		}
766
-
767
-		// We can't change the share type!
768
-		if ($share->getShareType() !== $originalShare->getShareType()) {
769
-			throw new \InvalidArgumentException('Can’t change share type');
770
-		}
771
-
772
-		// We can only change the recipient on user shares
773
-		if ($share->getSharedWith() !== $originalShare->getSharedWith() &&
774
-		    $share->getShareType() !== \OCP\Share::SHARE_TYPE_USER) {
775
-			throw new \InvalidArgumentException('Can only update recipient on user shares');
776
-		}
777
-
778
-		// Cannot share with the owner
779
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
780
-			$share->getSharedWith() === $share->getShareOwner()) {
781
-			throw new \InvalidArgumentException('Can’t share with the share owner');
782
-		}
783
-
784
-		$this->generalCreateChecks($share);
785
-
786
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
787
-			$this->userCreateChecks($share);
788
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
789
-			$this->groupCreateChecks($share);
790
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
791
-			$this->linkCreateChecks($share);
792
-
793
-			$this->updateSharePasswordIfNeeded($share, $originalShare);
794
-
795
-			if ($share->getExpirationDate() != $originalShare->getExpirationDate()) {
796
-				//Verify the expiration date
797
-				$this->validateExpirationDate($share);
798
-				$expirationDateUpdated = true;
799
-			}
800
-		} else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
801
-			$plainTextPassword = $share->getPassword();
802
-			if (!$this->updateSharePasswordIfNeeded($share, $originalShare)) {
803
-				$plainTextPassword = null;
804
-			}
805
-		}
806
-
807
-		$this->pathCreateChecks($share->getNode());
808
-
809
-		// Now update the share!
810
-		$provider = $this->factory->getProviderForType($share->getShareType());
811
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
812
-			$share = $provider->update($share, $plainTextPassword);
813
-		} else {
814
-			$share = $provider->update($share);
815
-		}
816
-
817
-		if ($expirationDateUpdated === true) {
818
-			\OC_Hook::emit('OCP\Share', 'post_set_expiration_date', [
819
-				'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
820
-				'itemSource' => $share->getNode()->getId(),
821
-				'date' => $share->getExpirationDate(),
822
-				'uidOwner' => $share->getSharedBy(),
823
-			]);
824
-		}
825
-
826
-		if ($share->getPassword() !== $originalShare->getPassword()) {
827
-			\OC_Hook::emit('OCP\Share', 'post_update_password', [
828
-				'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
829
-				'itemSource' => $share->getNode()->getId(),
830
-				'uidOwner' => $share->getSharedBy(),
831
-				'token' => $share->getToken(),
832
-				'disabled' => is_null($share->getPassword()),
833
-			]);
834
-		}
835
-
836
-		if ($share->getPermissions() !== $originalShare->getPermissions()) {
837
-			if ($this->userManager->userExists($share->getShareOwner())) {
838
-				$userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
839
-			} else {
840
-				$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
841
-			}
842
-			\OC_Hook::emit('OCP\Share', 'post_update_permissions', array(
843
-				'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
844
-				'itemSource' => $share->getNode()->getId(),
845
-				'shareType' => $share->getShareType(),
846
-				'shareWith' => $share->getSharedWith(),
847
-				'uidOwner' => $share->getSharedBy(),
848
-				'permissions' => $share->getPermissions(),
849
-				'path' => $userFolder->getRelativePath($share->getNode()->getPath()),
850
-			));
851
-		}
852
-
853
-		return $share;
854
-	}
855
-
856
-	/**
857
-	 * Updates the password of the given share if it is not the same as the
858
-	 * password of the original share.
859
-	 *
860
-	 * @param \OCP\Share\IShare $share the share to update its password.
861
-	 * @param \OCP\Share\IShare $originalShare the original share to compare its
862
-	 *        password with.
863
-	 * @return boolean whether the password was updated or not.
864
-	 */
865
-	private function updateSharePasswordIfNeeded(\OCP\Share\IShare $share, \OCP\Share\IShare $originalShare) {
866
-		// Password updated.
867
-		if ($share->getPassword() !== $originalShare->getPassword()) {
868
-			//Verify the password
869
-			$this->verifyPassword($share->getPassword());
870
-
871
-			// If a password is set. Hash it!
872
-			if ($share->getPassword() !== null) {
873
-				$share->setPassword($this->hasher->hash($share->getPassword()));
874
-
875
-				return true;
876
-			}
877
-		}
878
-
879
-		return false;
880
-	}
881
-
882
-	/**
883
-	 * Delete all the children of this share
884
-	 * FIXME: remove once https://github.com/owncloud/core/pull/21660 is in
885
-	 *
886
-	 * @param \OCP\Share\IShare $share
887
-	 * @return \OCP\Share\IShare[] List of deleted shares
888
-	 */
889
-	protected function deleteChildren(\OCP\Share\IShare $share) {
890
-		$deletedShares = [];
891
-
892
-		$provider = $this->factory->getProviderForType($share->getShareType());
893
-
894
-		foreach ($provider->getChildren($share) as $child) {
895
-			$deletedChildren = $this->deleteChildren($child);
896
-			$deletedShares = array_merge($deletedShares, $deletedChildren);
897
-
898
-			$provider->delete($child);
899
-			$deletedShares[] = $child;
900
-		}
901
-
902
-		return $deletedShares;
903
-	}
904
-
905
-	/**
906
-	 * Delete a share
907
-	 *
908
-	 * @param \OCP\Share\IShare $share
909
-	 * @throws ShareNotFound
910
-	 * @throws \InvalidArgumentException
911
-	 */
912
-	public function deleteShare(\OCP\Share\IShare $share) {
913
-
914
-		try {
915
-			$share->getFullId();
916
-		} catch (\UnexpectedValueException $e) {
917
-			throw new \InvalidArgumentException('Share does not have a full id');
918
-		}
919
-
920
-		$event = new GenericEvent($share);
921
-		$this->eventDispatcher->dispatch('OCP\Share::preUnshare', $event);
922
-
923
-		// Get all children and delete them as well
924
-		$deletedShares = $this->deleteChildren($share);
925
-
926
-		// Do the actual delete
927
-		$provider = $this->factory->getProviderForType($share->getShareType());
928
-		$provider->delete($share);
929
-
930
-		// All the deleted shares caused by this delete
931
-		$deletedShares[] = $share;
932
-
933
-		// Emit post hook
934
-		$event->setArgument('deletedShares', $deletedShares);
935
-		$this->eventDispatcher->dispatch('OCP\Share::postUnshare', $event);
936
-	}
937
-
938
-
939
-	/**
940
-	 * Unshare a file as the recipient.
941
-	 * This can be different from a regular delete for example when one of
942
-	 * the users in a groups deletes that share. But the provider should
943
-	 * handle this.
944
-	 *
945
-	 * @param \OCP\Share\IShare $share
946
-	 * @param string $recipientId
947
-	 */
948
-	public function deleteFromSelf(\OCP\Share\IShare $share, $recipientId) {
949
-		list($providerId, ) = $this->splitFullId($share->getFullId());
950
-		$provider = $this->factory->getProvider($providerId);
951
-
952
-		$provider->deleteFromSelf($share, $recipientId);
953
-		$event = new GenericEvent($share);
954
-		$this->eventDispatcher->dispatch('OCP\Share::postUnshareFromSelf', $event);
955
-	}
956
-
957
-	/**
958
-	 * @inheritdoc
959
-	 */
960
-	public function moveShare(\OCP\Share\IShare $share, $recipientId) {
961
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
962
-			throw new \InvalidArgumentException('Can’t change target of link share');
963
-		}
964
-
965
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER && $share->getSharedWith() !== $recipientId) {
966
-			throw new \InvalidArgumentException('Invalid recipient');
967
-		}
968
-
969
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
970
-			$sharedWith = $this->groupManager->get($share->getSharedWith());
971
-			if (is_null($sharedWith)) {
972
-				throw new \InvalidArgumentException('Group "' . $share->getSharedWith() . '" does not exist');
973
-			}
974
-			$recipient = $this->userManager->get($recipientId);
975
-			if (!$sharedWith->inGroup($recipient)) {
976
-				throw new \InvalidArgumentException('Invalid recipient');
977
-			}
978
-		}
979
-
980
-		list($providerId, ) = $this->splitFullId($share->getFullId());
981
-		$provider = $this->factory->getProvider($providerId);
982
-
983
-		$provider->move($share, $recipientId);
984
-	}
985
-
986
-	public function getSharesInFolder($userId, Folder $node, $reshares = false) {
987
-		$providers = $this->factory->getAllProviders();
988
-
989
-		return array_reduce($providers, function($shares, IShareProvider $provider) use ($userId, $node, $reshares) {
990
-			$newShares = $provider->getSharesInFolder($userId, $node, $reshares);
991
-			foreach ($newShares as $fid => $data) {
992
-				if (!isset($shares[$fid])) {
993
-					$shares[$fid] = [];
994
-				}
995
-
996
-				$shares[$fid] = array_merge($shares[$fid], $data);
997
-			}
998
-			return $shares;
999
-		}, []);
1000
-	}
1001
-
1002
-	/**
1003
-	 * @inheritdoc
1004
-	 */
1005
-	public function getSharesBy($userId, $shareType, $path = null, $reshares = false, $limit = 50, $offset = 0) {
1006
-		if ($path !== null &&
1007
-				!($path instanceof \OCP\Files\File) &&
1008
-				!($path instanceof \OCP\Files\Folder)) {
1009
-			throw new \InvalidArgumentException('invalid path');
1010
-		}
1011
-
1012
-		try {
1013
-			$provider = $this->factory->getProviderForType($shareType);
1014
-		} catch (ProviderException $e) {
1015
-			return [];
1016
-		}
1017
-
1018
-		$shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
1019
-
1020
-		/*
602
+            $share->setToken(
603
+                $this->secureRandom->generate(
604
+                    \OC\Share\Constants::TOKEN_LENGTH,
605
+                    \OCP\Security\ISecureRandom::CHAR_HUMAN_READABLE
606
+                )
607
+            );
608
+
609
+            //Verify the expiration date
610
+            $this->validateExpirationDate($share);
611
+
612
+            //Verify the password
613
+            $this->verifyPassword($share->getPassword());
614
+
615
+            // If a password is set. Hash it!
616
+            if ($share->getPassword() !== null) {
617
+                $share->setPassword($this->hasher->hash($share->getPassword()));
618
+            }
619
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
620
+            $share->setToken(
621
+                $this->secureRandom->generate(
622
+                    \OC\Share\Constants::TOKEN_LENGTH,
623
+                    \OCP\Security\ISecureRandom::CHAR_HUMAN_READABLE
624
+                )
625
+            );
626
+        }
627
+
628
+        // Cannot share with the owner
629
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
630
+            $share->getSharedWith() === $share->getShareOwner()) {
631
+            throw new \InvalidArgumentException('Can’t share with the share owner');
632
+        }
633
+
634
+        // Generate the target
635
+        $target = $this->config->getSystemValue('share_folder', '/') .'/'. $share->getNode()->getName();
636
+        $target = \OC\Files\Filesystem::normalizePath($target);
637
+        $share->setTarget($target);
638
+
639
+        // Pre share event
640
+        $event = new GenericEvent($share);
641
+        $a = $this->eventDispatcher->dispatch('OCP\Share::preShare', $event);
642
+        if ($event->isPropagationStopped() && $event->hasArgument('error')) {
643
+            throw new \Exception($event->getArgument('error'));
644
+        }
645
+
646
+        $oldShare = $share;
647
+        $provider = $this->factory->getProviderForType($share->getShareType());
648
+        $share = $provider->create($share);
649
+        //reuse the node we already have
650
+        $share->setNode($oldShare->getNode());
651
+
652
+        // Post share event
653
+        $event = new GenericEvent($share);
654
+        $this->eventDispatcher->dispatch('OCP\Share::postShare', $event);
655
+
656
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
657
+            $user = $this->userManager->get($share->getSharedWith());
658
+            if ($user !== null) {
659
+                $emailAddress = $user->getEMailAddress();
660
+                if ($emailAddress !== null && $emailAddress !== '') {
661
+                    $this->sendMailNotification(
662
+                        $share->getNode()->getName(),
663
+                        $this->urlGenerator->linkToRouteAbsolute('files.viewcontroller.showFile', [ 'fileid' => $share->getNode()->getId() ]),
664
+                        $share->getSharedBy(),
665
+                        $emailAddress,
666
+                        $share->getExpirationDate()
667
+                    );
668
+                    $this->logger->debug('Send share notification to ' . $emailAddress . ' for share with ID ' . $share->getId(), ['app' => 'share']);
669
+                } else {
670
+                    $this->logger->debug('Share notification not send to ' . $share->getSharedWith() . ' because email address is not set.', ['app' => 'share']);
671
+                }
672
+            } else {
673
+                $this->logger->debug('Share notification not send to ' . $share->getSharedWith() . ' because user could not be found.', ['app' => 'share']);
674
+            }
675
+        }
676
+
677
+        return $share;
678
+    }
679
+
680
+    /**
681
+     * @param string $filename file/folder name
682
+     * @param string $link link to the file/folder
683
+     * @param string $initiator user ID of share sender
684
+     * @param string $shareWith email address of share receiver
685
+     * @param \DateTime $expiration
686
+     * @throws \Exception If mail couldn't be sent
687
+     */
688
+    protected function sendMailNotification($filename,
689
+                                            $link,
690
+                                            $initiator,
691
+                                            $shareWith,
692
+                                            \DateTime $expiration) {
693
+        $initiatorUser = $this->userManager->get($initiator);
694
+        $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
695
+        $subject = (string)$this->l->t('%s shared »%s« with you', array($initiatorDisplayName, $filename));
696
+
697
+        $message = $this->mailer->createMessage();
698
+
699
+        $emailTemplate = $this->mailer->createEMailTemplate();
700
+        $emailTemplate->setMetaData('files_sharing.RecipientNotification', [
701
+            'filename' => $filename,
702
+            'link' => $link,
703
+            'initiator' => $initiatorDisplayName,
704
+            'expiration' => $expiration,
705
+        ]);
706
+
707
+        $emailTemplate->addHeader();
708
+        $emailTemplate->addHeading($this->l->t('%s shared »%s« with you', [$initiatorDisplayName, $filename]), false);
709
+        $text = $this->l->t('%s shared »%s« with you.', [$initiatorDisplayName, $filename]);
710
+
711
+        $emailTemplate->addBodyText(
712
+            $text . ' ' . $this->l->t('Click the button below to open it.'),
713
+            $text
714
+        );
715
+        $emailTemplate->addBodyButton(
716
+            $this->l->t('Open »%s«', [$filename]),
717
+            $link
718
+        );
719
+
720
+        $message->setTo([$shareWith]);
721
+
722
+        // The "From" contains the sharers name
723
+        $instanceName = $this->defaults->getName();
724
+        $senderName = $this->l->t(
725
+            '%s via %s',
726
+            [
727
+                $initiatorDisplayName,
728
+                $instanceName
729
+            ]
730
+        );
731
+        $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
732
+
733
+        // The "Reply-To" is set to the sharer if an mail address is configured
734
+        // also the default footer contains a "Do not reply" which needs to be adjusted.
735
+        $initiatorEmail = $initiatorUser->getEMailAddress();
736
+        if($initiatorEmail !== null) {
737
+            $message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
738
+            $emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
739
+        } else {
740
+            $emailTemplate->addFooter();
741
+        }
742
+
743
+        $message->setSubject($subject);
744
+        $message->setPlainBody($emailTemplate->renderText());
745
+        $message->setHtmlBody($emailTemplate->renderHtml());
746
+        $this->mailer->send($message);
747
+    }
748
+
749
+    /**
750
+     * Update a share
751
+     *
752
+     * @param \OCP\Share\IShare $share
753
+     * @return \OCP\Share\IShare The share object
754
+     * @throws \InvalidArgumentException
755
+     */
756
+    public function updateShare(\OCP\Share\IShare $share) {
757
+        $expirationDateUpdated = false;
758
+
759
+        $this->canShare($share);
760
+
761
+        try {
762
+            $originalShare = $this->getShareById($share->getFullId());
763
+        } catch (\UnexpectedValueException $e) {
764
+            throw new \InvalidArgumentException('Share does not have a full id');
765
+        }
766
+
767
+        // We can't change the share type!
768
+        if ($share->getShareType() !== $originalShare->getShareType()) {
769
+            throw new \InvalidArgumentException('Can’t change share type');
770
+        }
771
+
772
+        // We can only change the recipient on user shares
773
+        if ($share->getSharedWith() !== $originalShare->getSharedWith() &&
774
+            $share->getShareType() !== \OCP\Share::SHARE_TYPE_USER) {
775
+            throw new \InvalidArgumentException('Can only update recipient on user shares');
776
+        }
777
+
778
+        // Cannot share with the owner
779
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER &&
780
+            $share->getSharedWith() === $share->getShareOwner()) {
781
+            throw new \InvalidArgumentException('Can’t share with the share owner');
782
+        }
783
+
784
+        $this->generalCreateChecks($share);
785
+
786
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) {
787
+            $this->userCreateChecks($share);
788
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
789
+            $this->groupCreateChecks($share);
790
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
791
+            $this->linkCreateChecks($share);
792
+
793
+            $this->updateSharePasswordIfNeeded($share, $originalShare);
794
+
795
+            if ($share->getExpirationDate() != $originalShare->getExpirationDate()) {
796
+                //Verify the expiration date
797
+                $this->validateExpirationDate($share);
798
+                $expirationDateUpdated = true;
799
+            }
800
+        } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
801
+            $plainTextPassword = $share->getPassword();
802
+            if (!$this->updateSharePasswordIfNeeded($share, $originalShare)) {
803
+                $plainTextPassword = null;
804
+            }
805
+        }
806
+
807
+        $this->pathCreateChecks($share->getNode());
808
+
809
+        // Now update the share!
810
+        $provider = $this->factory->getProviderForType($share->getShareType());
811
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) {
812
+            $share = $provider->update($share, $plainTextPassword);
813
+        } else {
814
+            $share = $provider->update($share);
815
+        }
816
+
817
+        if ($expirationDateUpdated === true) {
818
+            \OC_Hook::emit('OCP\Share', 'post_set_expiration_date', [
819
+                'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
820
+                'itemSource' => $share->getNode()->getId(),
821
+                'date' => $share->getExpirationDate(),
822
+                'uidOwner' => $share->getSharedBy(),
823
+            ]);
824
+        }
825
+
826
+        if ($share->getPassword() !== $originalShare->getPassword()) {
827
+            \OC_Hook::emit('OCP\Share', 'post_update_password', [
828
+                'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
829
+                'itemSource' => $share->getNode()->getId(),
830
+                'uidOwner' => $share->getSharedBy(),
831
+                'token' => $share->getToken(),
832
+                'disabled' => is_null($share->getPassword()),
833
+            ]);
834
+        }
835
+
836
+        if ($share->getPermissions() !== $originalShare->getPermissions()) {
837
+            if ($this->userManager->userExists($share->getShareOwner())) {
838
+                $userFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
839
+            } else {
840
+                $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
841
+            }
842
+            \OC_Hook::emit('OCP\Share', 'post_update_permissions', array(
843
+                'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder',
844
+                'itemSource' => $share->getNode()->getId(),
845
+                'shareType' => $share->getShareType(),
846
+                'shareWith' => $share->getSharedWith(),
847
+                'uidOwner' => $share->getSharedBy(),
848
+                'permissions' => $share->getPermissions(),
849
+                'path' => $userFolder->getRelativePath($share->getNode()->getPath()),
850
+            ));
851
+        }
852
+
853
+        return $share;
854
+    }
855
+
856
+    /**
857
+     * Updates the password of the given share if it is not the same as the
858
+     * password of the original share.
859
+     *
860
+     * @param \OCP\Share\IShare $share the share to update its password.
861
+     * @param \OCP\Share\IShare $originalShare the original share to compare its
862
+     *        password with.
863
+     * @return boolean whether the password was updated or not.
864
+     */
865
+    private function updateSharePasswordIfNeeded(\OCP\Share\IShare $share, \OCP\Share\IShare $originalShare) {
866
+        // Password updated.
867
+        if ($share->getPassword() !== $originalShare->getPassword()) {
868
+            //Verify the password
869
+            $this->verifyPassword($share->getPassword());
870
+
871
+            // If a password is set. Hash it!
872
+            if ($share->getPassword() !== null) {
873
+                $share->setPassword($this->hasher->hash($share->getPassword()));
874
+
875
+                return true;
876
+            }
877
+        }
878
+
879
+        return false;
880
+    }
881
+
882
+    /**
883
+     * Delete all the children of this share
884
+     * FIXME: remove once https://github.com/owncloud/core/pull/21660 is in
885
+     *
886
+     * @param \OCP\Share\IShare $share
887
+     * @return \OCP\Share\IShare[] List of deleted shares
888
+     */
889
+    protected function deleteChildren(\OCP\Share\IShare $share) {
890
+        $deletedShares = [];
891
+
892
+        $provider = $this->factory->getProviderForType($share->getShareType());
893
+
894
+        foreach ($provider->getChildren($share) as $child) {
895
+            $deletedChildren = $this->deleteChildren($child);
896
+            $deletedShares = array_merge($deletedShares, $deletedChildren);
897
+
898
+            $provider->delete($child);
899
+            $deletedShares[] = $child;
900
+        }
901
+
902
+        return $deletedShares;
903
+    }
904
+
905
+    /**
906
+     * Delete a share
907
+     *
908
+     * @param \OCP\Share\IShare $share
909
+     * @throws ShareNotFound
910
+     * @throws \InvalidArgumentException
911
+     */
912
+    public function deleteShare(\OCP\Share\IShare $share) {
913
+
914
+        try {
915
+            $share->getFullId();
916
+        } catch (\UnexpectedValueException $e) {
917
+            throw new \InvalidArgumentException('Share does not have a full id');
918
+        }
919
+
920
+        $event = new GenericEvent($share);
921
+        $this->eventDispatcher->dispatch('OCP\Share::preUnshare', $event);
922
+
923
+        // Get all children and delete them as well
924
+        $deletedShares = $this->deleteChildren($share);
925
+
926
+        // Do the actual delete
927
+        $provider = $this->factory->getProviderForType($share->getShareType());
928
+        $provider->delete($share);
929
+
930
+        // All the deleted shares caused by this delete
931
+        $deletedShares[] = $share;
932
+
933
+        // Emit post hook
934
+        $event->setArgument('deletedShares', $deletedShares);
935
+        $this->eventDispatcher->dispatch('OCP\Share::postUnshare', $event);
936
+    }
937
+
938
+
939
+    /**
940
+     * Unshare a file as the recipient.
941
+     * This can be different from a regular delete for example when one of
942
+     * the users in a groups deletes that share. But the provider should
943
+     * handle this.
944
+     *
945
+     * @param \OCP\Share\IShare $share
946
+     * @param string $recipientId
947
+     */
948
+    public function deleteFromSelf(\OCP\Share\IShare $share, $recipientId) {
949
+        list($providerId, ) = $this->splitFullId($share->getFullId());
950
+        $provider = $this->factory->getProvider($providerId);
951
+
952
+        $provider->deleteFromSelf($share, $recipientId);
953
+        $event = new GenericEvent($share);
954
+        $this->eventDispatcher->dispatch('OCP\Share::postUnshareFromSelf', $event);
955
+    }
956
+
957
+    /**
958
+     * @inheritdoc
959
+     */
960
+    public function moveShare(\OCP\Share\IShare $share, $recipientId) {
961
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) {
962
+            throw new \InvalidArgumentException('Can’t change target of link share');
963
+        }
964
+
965
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER && $share->getSharedWith() !== $recipientId) {
966
+            throw new \InvalidArgumentException('Invalid recipient');
967
+        }
968
+
969
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
970
+            $sharedWith = $this->groupManager->get($share->getSharedWith());
971
+            if (is_null($sharedWith)) {
972
+                throw new \InvalidArgumentException('Group "' . $share->getSharedWith() . '" does not exist');
973
+            }
974
+            $recipient = $this->userManager->get($recipientId);
975
+            if (!$sharedWith->inGroup($recipient)) {
976
+                throw new \InvalidArgumentException('Invalid recipient');
977
+            }
978
+        }
979
+
980
+        list($providerId, ) = $this->splitFullId($share->getFullId());
981
+        $provider = $this->factory->getProvider($providerId);
982
+
983
+        $provider->move($share, $recipientId);
984
+    }
985
+
986
+    public function getSharesInFolder($userId, Folder $node, $reshares = false) {
987
+        $providers = $this->factory->getAllProviders();
988
+
989
+        return array_reduce($providers, function($shares, IShareProvider $provider) use ($userId, $node, $reshares) {
990
+            $newShares = $provider->getSharesInFolder($userId, $node, $reshares);
991
+            foreach ($newShares as $fid => $data) {
992
+                if (!isset($shares[$fid])) {
993
+                    $shares[$fid] = [];
994
+                }
995
+
996
+                $shares[$fid] = array_merge($shares[$fid], $data);
997
+            }
998
+            return $shares;
999
+        }, []);
1000
+    }
1001
+
1002
+    /**
1003
+     * @inheritdoc
1004
+     */
1005
+    public function getSharesBy($userId, $shareType, $path = null, $reshares = false, $limit = 50, $offset = 0) {
1006
+        if ($path !== null &&
1007
+                !($path instanceof \OCP\Files\File) &&
1008
+                !($path instanceof \OCP\Files\Folder)) {
1009
+            throw new \InvalidArgumentException('invalid path');
1010
+        }
1011
+
1012
+        try {
1013
+            $provider = $this->factory->getProviderForType($shareType);
1014
+        } catch (ProviderException $e) {
1015
+            return [];
1016
+        }
1017
+
1018
+        $shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
1019
+
1020
+        /*
1021 1021
 		 * Work around so we don't return expired shares but still follow
1022 1022
 		 * proper pagination.
1023 1023
 		 */
1024 1024
 
1025
-		$shares2 = [];
1026
-
1027
-		while(true) {
1028
-			$added = 0;
1029
-			foreach ($shares as $share) {
1030
-
1031
-				try {
1032
-					$this->checkExpireDate($share);
1033
-				} catch (ShareNotFound $e) {
1034
-					//Ignore since this basically means the share is deleted
1035
-					continue;
1036
-				}
1037
-
1038
-				$added++;
1039
-				$shares2[] = $share;
1040
-
1041
-				if (count($shares2) === $limit) {
1042
-					break;
1043
-				}
1044
-			}
1045
-
1046
-			if (count($shares2) === $limit) {
1047
-				break;
1048
-			}
1049
-
1050
-			// If there was no limit on the select we are done
1051
-			if ($limit === -1) {
1052
-				break;
1053
-			}
1054
-
1055
-			$offset += $added;
1056
-
1057
-			// Fetch again $limit shares
1058
-			$shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
1059
-
1060
-			// No more shares means we are done
1061
-			if (empty($shares)) {
1062
-				break;
1063
-			}
1064
-		}
1065
-
1066
-		$shares = $shares2;
1067
-
1068
-		return $shares;
1069
-	}
1070
-
1071
-	/**
1072
-	 * @inheritdoc
1073
-	 */
1074
-	public function getSharedWith($userId, $shareType, $node = null, $limit = 50, $offset = 0) {
1075
-		try {
1076
-			$provider = $this->factory->getProviderForType($shareType);
1077
-		} catch (ProviderException $e) {
1078
-			return [];
1079
-		}
1080
-
1081
-		$shares = $provider->getSharedWith($userId, $shareType, $node, $limit, $offset);
1082
-
1083
-		// remove all shares which are already expired
1084
-		foreach ($shares as $key => $share) {
1085
-			try {
1086
-				$this->checkExpireDate($share);
1087
-			} catch (ShareNotFound $e) {
1088
-				unset($shares[$key]);
1089
-			}
1090
-		}
1091
-
1092
-		return $shares;
1093
-	}
1094
-
1095
-	/**
1096
-	 * @inheritdoc
1097
-	 */
1098
-	public function getShareById($id, $recipient = null) {
1099
-		if ($id === null) {
1100
-			throw new ShareNotFound();
1101
-		}
1102
-
1103
-		list($providerId, $id) = $this->splitFullId($id);
1104
-
1105
-		try {
1106
-			$provider = $this->factory->getProvider($providerId);
1107
-		} catch (ProviderException $e) {
1108
-			throw new ShareNotFound();
1109
-		}
1110
-
1111
-		$share = $provider->getShareById($id, $recipient);
1112
-
1113
-		$this->checkExpireDate($share);
1114
-
1115
-		return $share;
1116
-	}
1117
-
1118
-	/**
1119
-	 * Get all the shares for a given path
1120
-	 *
1121
-	 * @param \OCP\Files\Node $path
1122
-	 * @param int $page
1123
-	 * @param int $perPage
1124
-	 *
1125
-	 * @return Share[]
1126
-	 */
1127
-	public function getSharesByPath(\OCP\Files\Node $path, $page=0, $perPage=50) {
1128
-		return [];
1129
-	}
1130
-
1131
-	/**
1132
-	 * Get the share by token possible with password
1133
-	 *
1134
-	 * @param string $token
1135
-	 * @return Share
1136
-	 *
1137
-	 * @throws ShareNotFound
1138
-	 */
1139
-	public function getShareByToken($token) {
1140
-		$share = null;
1141
-		try {
1142
-			if($this->shareApiAllowLinks()) {
1143
-				$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_LINK);
1144
-				$share = $provider->getShareByToken($token);
1145
-			}
1146
-		} catch (ProviderException $e) {
1147
-		} catch (ShareNotFound $e) {
1148
-		}
1149
-
1150
-
1151
-		// If it is not a link share try to fetch a federated share by token
1152
-		if ($share === null) {
1153
-			try {
1154
-				$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_REMOTE);
1155
-				$share = $provider->getShareByToken($token);
1156
-			} catch (ProviderException $e) {
1157
-			} catch (ShareNotFound $e) {
1158
-			}
1159
-		}
1160
-
1161
-		// If it is not a link share try to fetch a mail share by token
1162
-		if ($share === null && $this->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
1163
-			try {
1164
-				$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_EMAIL);
1165
-				$share = $provider->getShareByToken($token);
1166
-			} catch (ProviderException $e) {
1167
-			} catch (ShareNotFound $e) {
1168
-			}
1169
-		}
1170
-
1171
-		if ($share === null) {
1172
-			throw new ShareNotFound($this->l->t('The requested share does not exist anymore'));
1173
-		}
1174
-
1175
-		$this->checkExpireDate($share);
1176
-
1177
-		/*
1025
+        $shares2 = [];
1026
+
1027
+        while(true) {
1028
+            $added = 0;
1029
+            foreach ($shares as $share) {
1030
+
1031
+                try {
1032
+                    $this->checkExpireDate($share);
1033
+                } catch (ShareNotFound $e) {
1034
+                    //Ignore since this basically means the share is deleted
1035
+                    continue;
1036
+                }
1037
+
1038
+                $added++;
1039
+                $shares2[] = $share;
1040
+
1041
+                if (count($shares2) === $limit) {
1042
+                    break;
1043
+                }
1044
+            }
1045
+
1046
+            if (count($shares2) === $limit) {
1047
+                break;
1048
+            }
1049
+
1050
+            // If there was no limit on the select we are done
1051
+            if ($limit === -1) {
1052
+                break;
1053
+            }
1054
+
1055
+            $offset += $added;
1056
+
1057
+            // Fetch again $limit shares
1058
+            $shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
1059
+
1060
+            // No more shares means we are done
1061
+            if (empty($shares)) {
1062
+                break;
1063
+            }
1064
+        }
1065
+
1066
+        $shares = $shares2;
1067
+
1068
+        return $shares;
1069
+    }
1070
+
1071
+    /**
1072
+     * @inheritdoc
1073
+     */
1074
+    public function getSharedWith($userId, $shareType, $node = null, $limit = 50, $offset = 0) {
1075
+        try {
1076
+            $provider = $this->factory->getProviderForType($shareType);
1077
+        } catch (ProviderException $e) {
1078
+            return [];
1079
+        }
1080
+
1081
+        $shares = $provider->getSharedWith($userId, $shareType, $node, $limit, $offset);
1082
+
1083
+        // remove all shares which are already expired
1084
+        foreach ($shares as $key => $share) {
1085
+            try {
1086
+                $this->checkExpireDate($share);
1087
+            } catch (ShareNotFound $e) {
1088
+                unset($shares[$key]);
1089
+            }
1090
+        }
1091
+
1092
+        return $shares;
1093
+    }
1094
+
1095
+    /**
1096
+     * @inheritdoc
1097
+     */
1098
+    public function getShareById($id, $recipient = null) {
1099
+        if ($id === null) {
1100
+            throw new ShareNotFound();
1101
+        }
1102
+
1103
+        list($providerId, $id) = $this->splitFullId($id);
1104
+
1105
+        try {
1106
+            $provider = $this->factory->getProvider($providerId);
1107
+        } catch (ProviderException $e) {
1108
+            throw new ShareNotFound();
1109
+        }
1110
+
1111
+        $share = $provider->getShareById($id, $recipient);
1112
+
1113
+        $this->checkExpireDate($share);
1114
+
1115
+        return $share;
1116
+    }
1117
+
1118
+    /**
1119
+     * Get all the shares for a given path
1120
+     *
1121
+     * @param \OCP\Files\Node $path
1122
+     * @param int $page
1123
+     * @param int $perPage
1124
+     *
1125
+     * @return Share[]
1126
+     */
1127
+    public function getSharesByPath(\OCP\Files\Node $path, $page=0, $perPage=50) {
1128
+        return [];
1129
+    }
1130
+
1131
+    /**
1132
+     * Get the share by token possible with password
1133
+     *
1134
+     * @param string $token
1135
+     * @return Share
1136
+     *
1137
+     * @throws ShareNotFound
1138
+     */
1139
+    public function getShareByToken($token) {
1140
+        $share = null;
1141
+        try {
1142
+            if($this->shareApiAllowLinks()) {
1143
+                $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_LINK);
1144
+                $share = $provider->getShareByToken($token);
1145
+            }
1146
+        } catch (ProviderException $e) {
1147
+        } catch (ShareNotFound $e) {
1148
+        }
1149
+
1150
+
1151
+        // If it is not a link share try to fetch a federated share by token
1152
+        if ($share === null) {
1153
+            try {
1154
+                $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_REMOTE);
1155
+                $share = $provider->getShareByToken($token);
1156
+            } catch (ProviderException $e) {
1157
+            } catch (ShareNotFound $e) {
1158
+            }
1159
+        }
1160
+
1161
+        // If it is not a link share try to fetch a mail share by token
1162
+        if ($share === null && $this->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) {
1163
+            try {
1164
+                $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_EMAIL);
1165
+                $share = $provider->getShareByToken($token);
1166
+            } catch (ProviderException $e) {
1167
+            } catch (ShareNotFound $e) {
1168
+            }
1169
+        }
1170
+
1171
+        if ($share === null) {
1172
+            throw new ShareNotFound($this->l->t('The requested share does not exist anymore'));
1173
+        }
1174
+
1175
+        $this->checkExpireDate($share);
1176
+
1177
+        /*
1178 1178
 		 * Reduce the permissions for link shares if public upload is not enabled
1179 1179
 		 */
1180
-		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK &&
1181
-			!$this->shareApiLinkAllowPublicUpload()) {
1182
-			$share->setPermissions($share->getPermissions() & ~(\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE));
1183
-		}
1184
-
1185
-		return $share;
1186
-	}
1187
-
1188
-	protected function checkExpireDate($share) {
1189
-		if ($share->getExpirationDate() !== null &&
1190
-			$share->getExpirationDate() <= new \DateTime()) {
1191
-			$this->deleteShare($share);
1192
-			throw new ShareNotFound($this->l->t('The requested share does not exist anymore'));
1193
-		}
1194
-
1195
-	}
1196
-
1197
-	/**
1198
-	 * Verify the password of a public share
1199
-	 *
1200
-	 * @param \OCP\Share\IShare $share
1201
-	 * @param string $password
1202
-	 * @return bool
1203
-	 */
1204
-	public function checkPassword(\OCP\Share\IShare $share, $password) {
1205
-		$passwordProtected = $share->getShareType() !== \OCP\Share::SHARE_TYPE_LINK
1206
-			|| $share->getShareType() !== \OCP\Share::SHARE_TYPE_EMAIL;
1207
-		if (!$passwordProtected) {
1208
-			//TODO maybe exception?
1209
-			return false;
1210
-		}
1211
-
1212
-		if ($password === null || $share->getPassword() === null) {
1213
-			return false;
1214
-		}
1215
-
1216
-		$newHash = '';
1217
-		if (!$this->hasher->verify($password, $share->getPassword(), $newHash)) {
1218
-			return false;
1219
-		}
1220
-
1221
-		if (!empty($newHash)) {
1222
-			$share->setPassword($newHash);
1223
-			$provider = $this->factory->getProviderForType($share->getShareType());
1224
-			$provider->update($share);
1225
-		}
1226
-
1227
-		return true;
1228
-	}
1229
-
1230
-	/**
1231
-	 * @inheritdoc
1232
-	 */
1233
-	public function userDeleted($uid) {
1234
-		$types = [\OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_GROUP, \OCP\Share::SHARE_TYPE_LINK, \OCP\Share::SHARE_TYPE_REMOTE, \OCP\Share::SHARE_TYPE_EMAIL];
1235
-
1236
-		foreach ($types as $type) {
1237
-			try {
1238
-				$provider = $this->factory->getProviderForType($type);
1239
-			} catch (ProviderException $e) {
1240
-				continue;
1241
-			}
1242
-			$provider->userDeleted($uid, $type);
1243
-		}
1244
-	}
1245
-
1246
-	/**
1247
-	 * @inheritdoc
1248
-	 */
1249
-	public function groupDeleted($gid) {
1250
-		$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
1251
-		$provider->groupDeleted($gid);
1252
-	}
1253
-
1254
-	/**
1255
-	 * @inheritdoc
1256
-	 */
1257
-	public function userDeletedFromGroup($uid, $gid) {
1258
-		$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
1259
-		$provider->userDeletedFromGroup($uid, $gid);
1260
-	}
1261
-
1262
-	/**
1263
-	 * Get access list to a path. This means
1264
-	 * all the users that can access a given path.
1265
-	 *
1266
-	 * Consider:
1267
-	 * -root
1268
-	 * |-folder1 (23)
1269
-	 *  |-folder2 (32)
1270
-	 *   |-fileA (42)
1271
-	 *
1272
-	 * fileA is shared with user1 and user1@server1
1273
-	 * folder2 is shared with group2 (user4 is a member of group2)
1274
-	 * folder1 is shared with user2 (renamed to "folder (1)") and user2@server2
1275
-	 *
1276
-	 * Then the access list to '/folder1/folder2/fileA' with $currentAccess is:
1277
-	 * [
1278
-	 *  users  => [
1279
-	 *      'user1' => ['node_id' => 42, 'node_path' => '/fileA'],
1280
-	 *      'user4' => ['node_id' => 32, 'node_path' => '/folder2'],
1281
-	 *      'user2' => ['node_id' => 23, 'node_path' => '/folder (1)'],
1282
-	 *  ],
1283
-	 *  remote => [
1284
-	 *      'user1@server1' => ['node_id' => 42, 'token' => 'SeCr3t'],
1285
-	 *      'user2@server2' => ['node_id' => 23, 'token' => 'FooBaR'],
1286
-	 *  ],
1287
-	 *  public => bool
1288
-	 *  mail => bool
1289
-	 * ]
1290
-	 *
1291
-	 * The access list to '/folder1/folder2/fileA' **without** $currentAccess is:
1292
-	 * [
1293
-	 *  users  => ['user1', 'user2', 'user4'],
1294
-	 *  remote => bool,
1295
-	 *  public => bool
1296
-	 *  mail => bool
1297
-	 * ]
1298
-	 *
1299
-	 * This is required for encryption/activity
1300
-	 *
1301
-	 * @param \OCP\Files\Node $path
1302
-	 * @param bool $recursive Should we check all parent folders as well
1303
-	 * @param bool $currentAccess Should the user have currently access to the file
1304
-	 * @return array
1305
-	 */
1306
-	public function getAccessList(\OCP\Files\Node $path, $recursive = true, $currentAccess = false) {
1307
-		$owner = $path->getOwner()->getUID();
1308
-
1309
-		if ($currentAccess) {
1310
-			$al = ['users' => [], 'remote' => [], 'public' => false];
1311
-		} else {
1312
-			$al = ['users' => [], 'remote' => false, 'public' => false];
1313
-		}
1314
-		if (!$this->userManager->userExists($owner)) {
1315
-			return $al;
1316
-		}
1317
-
1318
-		//Get node for the owner
1319
-		$userFolder = $this->rootFolder->getUserFolder($owner);
1320
-		if ($path->getId() !== $userFolder->getId() && !$userFolder->isSubNode($path)) {
1321
-			$path = $userFolder->getById($path->getId())[0];
1322
-		}
1323
-
1324
-		$providers = $this->factory->getAllProviders();
1325
-
1326
-		/** @var Node[] $nodes */
1327
-		$nodes = [];
1328
-
1329
-
1330
-		if ($currentAccess) {
1331
-			$ownerPath = $path->getPath();
1332
-			$ownerPath = explode('/', $ownerPath, 4);
1333
-			if (count($ownerPath) < 4) {
1334
-				$ownerPath = '';
1335
-			} else {
1336
-				$ownerPath = $ownerPath[3];
1337
-			}
1338
-			$al['users'][$owner] = [
1339
-				'node_id' => $path->getId(),
1340
-				'node_path' => '/' . $ownerPath,
1341
-			];
1342
-		} else {
1343
-			$al['users'][] = $owner;
1344
-		}
1345
-
1346
-		// Collect all the shares
1347
-		while ($path->getPath() !== $userFolder->getPath()) {
1348
-			$nodes[] = $path;
1349
-			if (!$recursive) {
1350
-				break;
1351
-			}
1352
-			$path = $path->getParent();
1353
-		}
1354
-
1355
-		foreach ($providers as $provider) {
1356
-			$tmp = $provider->getAccessList($nodes, $currentAccess);
1357
-
1358
-			foreach ($tmp as $k => $v) {
1359
-				if (isset($al[$k])) {
1360
-					if (is_array($al[$k])) {
1361
-						$al[$k] = array_merge($al[$k], $v);
1362
-					} else {
1363
-						$al[$k] = $al[$k] || $v;
1364
-					}
1365
-				} else {
1366
-					$al[$k] = $v;
1367
-				}
1368
-			}
1369
-		}
1370
-
1371
-		return $al;
1372
-	}
1373
-
1374
-	/**
1375
-	 * Create a new share
1376
-	 * @return \OCP\Share\IShare;
1377
-	 */
1378
-	public function newShare() {
1379
-		return new \OC\Share20\Share($this->rootFolder, $this->userManager);
1380
-	}
1381
-
1382
-	/**
1383
-	 * Is the share API enabled
1384
-	 *
1385
-	 * @return bool
1386
-	 */
1387
-	public function shareApiEnabled() {
1388
-		return $this->config->getAppValue('core', 'shareapi_enabled', 'yes') === 'yes';
1389
-	}
1390
-
1391
-	/**
1392
-	 * Is public link sharing enabled
1393
-	 *
1394
-	 * @return bool
1395
-	 */
1396
-	public function shareApiAllowLinks() {
1397
-		return $this->config->getAppValue('core', 'shareapi_allow_links', 'yes') === 'yes';
1398
-	}
1399
-
1400
-	/**
1401
-	 * Is password on public link requires
1402
-	 *
1403
-	 * @return bool
1404
-	 */
1405
-	public function shareApiLinkEnforcePassword() {
1406
-		return $this->config->getAppValue('core', 'shareapi_enforce_links_password', 'no') === 'yes';
1407
-	}
1408
-
1409
-	/**
1410
-	 * Is default expire date enabled
1411
-	 *
1412
-	 * @return bool
1413
-	 */
1414
-	public function shareApiLinkDefaultExpireDate() {
1415
-		return $this->config->getAppValue('core', 'shareapi_default_expire_date', 'no') === 'yes';
1416
-	}
1417
-
1418
-	/**
1419
-	 * Is default expire date enforced
1420
-	 *`
1421
-	 * @return bool
1422
-	 */
1423
-	public function shareApiLinkDefaultExpireDateEnforced() {
1424
-		return $this->shareApiLinkDefaultExpireDate() &&
1425
-			$this->config->getAppValue('core', 'shareapi_enforce_expire_date', 'no') === 'yes';
1426
-	}
1427
-
1428
-	/**
1429
-	 * Number of default expire days
1430
-	 *shareApiLinkAllowPublicUpload
1431
-	 * @return int
1432
-	 */
1433
-	public function shareApiLinkDefaultExpireDays() {
1434
-		return (int)$this->config->getAppValue('core', 'shareapi_expire_after_n_days', '7');
1435
-	}
1436
-
1437
-	/**
1438
-	 * Allow public upload on link shares
1439
-	 *
1440
-	 * @return bool
1441
-	 */
1442
-	public function shareApiLinkAllowPublicUpload() {
1443
-		return $this->config->getAppValue('core', 'shareapi_allow_public_upload', 'yes') === 'yes';
1444
-	}
1445
-
1446
-	/**
1447
-	 * check if user can only share with group members
1448
-	 * @return bool
1449
-	 */
1450
-	public function shareWithGroupMembersOnly() {
1451
-		return $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
1452
-	}
1453
-
1454
-	/**
1455
-	 * Check if users can share with groups
1456
-	 * @return bool
1457
-	 */
1458
-	public function allowGroupSharing() {
1459
-		return $this->config->getAppValue('core', 'shareapi_allow_group_sharing', 'yes') === 'yes';
1460
-	}
1461
-
1462
-	/**
1463
-	 * Copied from \OC_Util::isSharingDisabledForUser
1464
-	 *
1465
-	 * TODO: Deprecate fuction from OC_Util
1466
-	 *
1467
-	 * @param string $userId
1468
-	 * @return bool
1469
-	 */
1470
-	public function sharingDisabledForUser($userId) {
1471
-		if ($userId === null) {
1472
-			return false;
1473
-		}
1474
-
1475
-		if (isset($this->sharingDisabledForUsersCache[$userId])) {
1476
-			return $this->sharingDisabledForUsersCache[$userId];
1477
-		}
1478
-
1479
-		if ($this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes') {
1480
-			$groupsList = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
1481
-			$excludedGroups = json_decode($groupsList);
1482
-			if (is_null($excludedGroups)) {
1483
-				$excludedGroups = explode(',', $groupsList);
1484
-				$newValue = json_encode($excludedGroups);
1485
-				$this->config->setAppValue('core', 'shareapi_exclude_groups_list', $newValue);
1486
-			}
1487
-			$user = $this->userManager->get($userId);
1488
-			$usersGroups = $this->groupManager->getUserGroupIds($user);
1489
-			if (!empty($usersGroups)) {
1490
-				$remainingGroups = array_diff($usersGroups, $excludedGroups);
1491
-				// if the user is only in groups which are disabled for sharing then
1492
-				// sharing is also disabled for the user
1493
-				if (empty($remainingGroups)) {
1494
-					$this->sharingDisabledForUsersCache[$userId] = true;
1495
-					return true;
1496
-				}
1497
-			}
1498
-		}
1499
-
1500
-		$this->sharingDisabledForUsersCache[$userId] = false;
1501
-		return false;
1502
-	}
1503
-
1504
-	/**
1505
-	 * @inheritdoc
1506
-	 */
1507
-	public function outgoingServer2ServerSharesAllowed() {
1508
-		return $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') === 'yes';
1509
-	}
1510
-
1511
-	/**
1512
-	 * @inheritdoc
1513
-	 */
1514
-	public function shareProviderExists($shareType) {
1515
-		try {
1516
-			$this->factory->getProviderForType($shareType);
1517
-		} catch (ProviderException $e) {
1518
-			return false;
1519
-		}
1520
-
1521
-		return true;
1522
-	}
1180
+        if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK &&
1181
+            !$this->shareApiLinkAllowPublicUpload()) {
1182
+            $share->setPermissions($share->getPermissions() & ~(\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE));
1183
+        }
1184
+
1185
+        return $share;
1186
+    }
1187
+
1188
+    protected function checkExpireDate($share) {
1189
+        if ($share->getExpirationDate() !== null &&
1190
+            $share->getExpirationDate() <= new \DateTime()) {
1191
+            $this->deleteShare($share);
1192
+            throw new ShareNotFound($this->l->t('The requested share does not exist anymore'));
1193
+        }
1194
+
1195
+    }
1196
+
1197
+    /**
1198
+     * Verify the password of a public share
1199
+     *
1200
+     * @param \OCP\Share\IShare $share
1201
+     * @param string $password
1202
+     * @return bool
1203
+     */
1204
+    public function checkPassword(\OCP\Share\IShare $share, $password) {
1205
+        $passwordProtected = $share->getShareType() !== \OCP\Share::SHARE_TYPE_LINK
1206
+            || $share->getShareType() !== \OCP\Share::SHARE_TYPE_EMAIL;
1207
+        if (!$passwordProtected) {
1208
+            //TODO maybe exception?
1209
+            return false;
1210
+        }
1211
+
1212
+        if ($password === null || $share->getPassword() === null) {
1213
+            return false;
1214
+        }
1215
+
1216
+        $newHash = '';
1217
+        if (!$this->hasher->verify($password, $share->getPassword(), $newHash)) {
1218
+            return false;
1219
+        }
1220
+
1221
+        if (!empty($newHash)) {
1222
+            $share->setPassword($newHash);
1223
+            $provider = $this->factory->getProviderForType($share->getShareType());
1224
+            $provider->update($share);
1225
+        }
1226
+
1227
+        return true;
1228
+    }
1229
+
1230
+    /**
1231
+     * @inheritdoc
1232
+     */
1233
+    public function userDeleted($uid) {
1234
+        $types = [\OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_GROUP, \OCP\Share::SHARE_TYPE_LINK, \OCP\Share::SHARE_TYPE_REMOTE, \OCP\Share::SHARE_TYPE_EMAIL];
1235
+
1236
+        foreach ($types as $type) {
1237
+            try {
1238
+                $provider = $this->factory->getProviderForType($type);
1239
+            } catch (ProviderException $e) {
1240
+                continue;
1241
+            }
1242
+            $provider->userDeleted($uid, $type);
1243
+        }
1244
+    }
1245
+
1246
+    /**
1247
+     * @inheritdoc
1248
+     */
1249
+    public function groupDeleted($gid) {
1250
+        $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
1251
+        $provider->groupDeleted($gid);
1252
+    }
1253
+
1254
+    /**
1255
+     * @inheritdoc
1256
+     */
1257
+    public function userDeletedFromGroup($uid, $gid) {
1258
+        $provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
1259
+        $provider->userDeletedFromGroup($uid, $gid);
1260
+    }
1261
+
1262
+    /**
1263
+     * Get access list to a path. This means
1264
+     * all the users that can access a given path.
1265
+     *
1266
+     * Consider:
1267
+     * -root
1268
+     * |-folder1 (23)
1269
+     *  |-folder2 (32)
1270
+     *   |-fileA (42)
1271
+     *
1272
+     * fileA is shared with user1 and user1@server1
1273
+     * folder2 is shared with group2 (user4 is a member of group2)
1274
+     * folder1 is shared with user2 (renamed to "folder (1)") and user2@server2
1275
+     *
1276
+     * Then the access list to '/folder1/folder2/fileA' with $currentAccess is:
1277
+     * [
1278
+     *  users  => [
1279
+     *      'user1' => ['node_id' => 42, 'node_path' => '/fileA'],
1280
+     *      'user4' => ['node_id' => 32, 'node_path' => '/folder2'],
1281
+     *      'user2' => ['node_id' => 23, 'node_path' => '/folder (1)'],
1282
+     *  ],
1283
+     *  remote => [
1284
+     *      'user1@server1' => ['node_id' => 42, 'token' => 'SeCr3t'],
1285
+     *      'user2@server2' => ['node_id' => 23, 'token' => 'FooBaR'],
1286
+     *  ],
1287
+     *  public => bool
1288
+     *  mail => bool
1289
+     * ]
1290
+     *
1291
+     * The access list to '/folder1/folder2/fileA' **without** $currentAccess is:
1292
+     * [
1293
+     *  users  => ['user1', 'user2', 'user4'],
1294
+     *  remote => bool,
1295
+     *  public => bool
1296
+     *  mail => bool
1297
+     * ]
1298
+     *
1299
+     * This is required for encryption/activity
1300
+     *
1301
+     * @param \OCP\Files\Node $path
1302
+     * @param bool $recursive Should we check all parent folders as well
1303
+     * @param bool $currentAccess Should the user have currently access to the file
1304
+     * @return array
1305
+     */
1306
+    public function getAccessList(\OCP\Files\Node $path, $recursive = true, $currentAccess = false) {
1307
+        $owner = $path->getOwner()->getUID();
1308
+
1309
+        if ($currentAccess) {
1310
+            $al = ['users' => [], 'remote' => [], 'public' => false];
1311
+        } else {
1312
+            $al = ['users' => [], 'remote' => false, 'public' => false];
1313
+        }
1314
+        if (!$this->userManager->userExists($owner)) {
1315
+            return $al;
1316
+        }
1317
+
1318
+        //Get node for the owner
1319
+        $userFolder = $this->rootFolder->getUserFolder($owner);
1320
+        if ($path->getId() !== $userFolder->getId() && !$userFolder->isSubNode($path)) {
1321
+            $path = $userFolder->getById($path->getId())[0];
1322
+        }
1323
+
1324
+        $providers = $this->factory->getAllProviders();
1325
+
1326
+        /** @var Node[] $nodes */
1327
+        $nodes = [];
1328
+
1329
+
1330
+        if ($currentAccess) {
1331
+            $ownerPath = $path->getPath();
1332
+            $ownerPath = explode('/', $ownerPath, 4);
1333
+            if (count($ownerPath) < 4) {
1334
+                $ownerPath = '';
1335
+            } else {
1336
+                $ownerPath = $ownerPath[3];
1337
+            }
1338
+            $al['users'][$owner] = [
1339
+                'node_id' => $path->getId(),
1340
+                'node_path' => '/' . $ownerPath,
1341
+            ];
1342
+        } else {
1343
+            $al['users'][] = $owner;
1344
+        }
1345
+
1346
+        // Collect all the shares
1347
+        while ($path->getPath() !== $userFolder->getPath()) {
1348
+            $nodes[] = $path;
1349
+            if (!$recursive) {
1350
+                break;
1351
+            }
1352
+            $path = $path->getParent();
1353
+        }
1354
+
1355
+        foreach ($providers as $provider) {
1356
+            $tmp = $provider->getAccessList($nodes, $currentAccess);
1357
+
1358
+            foreach ($tmp as $k => $v) {
1359
+                if (isset($al[$k])) {
1360
+                    if (is_array($al[$k])) {
1361
+                        $al[$k] = array_merge($al[$k], $v);
1362
+                    } else {
1363
+                        $al[$k] = $al[$k] || $v;
1364
+                    }
1365
+                } else {
1366
+                    $al[$k] = $v;
1367
+                }
1368
+            }
1369
+        }
1370
+
1371
+        return $al;
1372
+    }
1373
+
1374
+    /**
1375
+     * Create a new share
1376
+     * @return \OCP\Share\IShare;
1377
+     */
1378
+    public function newShare() {
1379
+        return new \OC\Share20\Share($this->rootFolder, $this->userManager);
1380
+    }
1381
+
1382
+    /**
1383
+     * Is the share API enabled
1384
+     *
1385
+     * @return bool
1386
+     */
1387
+    public function shareApiEnabled() {
1388
+        return $this->config->getAppValue('core', 'shareapi_enabled', 'yes') === 'yes';
1389
+    }
1390
+
1391
+    /**
1392
+     * Is public link sharing enabled
1393
+     *
1394
+     * @return bool
1395
+     */
1396
+    public function shareApiAllowLinks() {
1397
+        return $this->config->getAppValue('core', 'shareapi_allow_links', 'yes') === 'yes';
1398
+    }
1399
+
1400
+    /**
1401
+     * Is password on public link requires
1402
+     *
1403
+     * @return bool
1404
+     */
1405
+    public function shareApiLinkEnforcePassword() {
1406
+        return $this->config->getAppValue('core', 'shareapi_enforce_links_password', 'no') === 'yes';
1407
+    }
1408
+
1409
+    /**
1410
+     * Is default expire date enabled
1411
+     *
1412
+     * @return bool
1413
+     */
1414
+    public function shareApiLinkDefaultExpireDate() {
1415
+        return $this->config->getAppValue('core', 'shareapi_default_expire_date', 'no') === 'yes';
1416
+    }
1417
+
1418
+    /**
1419
+     * Is default expire date enforced
1420
+     *`
1421
+     * @return bool
1422
+     */
1423
+    public function shareApiLinkDefaultExpireDateEnforced() {
1424
+        return $this->shareApiLinkDefaultExpireDate() &&
1425
+            $this->config->getAppValue('core', 'shareapi_enforce_expire_date', 'no') === 'yes';
1426
+    }
1427
+
1428
+    /**
1429
+     * Number of default expire days
1430
+     *shareApiLinkAllowPublicUpload
1431
+     * @return int
1432
+     */
1433
+    public function shareApiLinkDefaultExpireDays() {
1434
+        return (int)$this->config->getAppValue('core', 'shareapi_expire_after_n_days', '7');
1435
+    }
1436
+
1437
+    /**
1438
+     * Allow public upload on link shares
1439
+     *
1440
+     * @return bool
1441
+     */
1442
+    public function shareApiLinkAllowPublicUpload() {
1443
+        return $this->config->getAppValue('core', 'shareapi_allow_public_upload', 'yes') === 'yes';
1444
+    }
1445
+
1446
+    /**
1447
+     * check if user can only share with group members
1448
+     * @return bool
1449
+     */
1450
+    public function shareWithGroupMembersOnly() {
1451
+        return $this->config->getAppValue('core', 'shareapi_only_share_with_group_members', 'no') === 'yes';
1452
+    }
1453
+
1454
+    /**
1455
+     * Check if users can share with groups
1456
+     * @return bool
1457
+     */
1458
+    public function allowGroupSharing() {
1459
+        return $this->config->getAppValue('core', 'shareapi_allow_group_sharing', 'yes') === 'yes';
1460
+    }
1461
+
1462
+    /**
1463
+     * Copied from \OC_Util::isSharingDisabledForUser
1464
+     *
1465
+     * TODO: Deprecate fuction from OC_Util
1466
+     *
1467
+     * @param string $userId
1468
+     * @return bool
1469
+     */
1470
+    public function sharingDisabledForUser($userId) {
1471
+        if ($userId === null) {
1472
+            return false;
1473
+        }
1474
+
1475
+        if (isset($this->sharingDisabledForUsersCache[$userId])) {
1476
+            return $this->sharingDisabledForUsersCache[$userId];
1477
+        }
1478
+
1479
+        if ($this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes') {
1480
+            $groupsList = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
1481
+            $excludedGroups = json_decode($groupsList);
1482
+            if (is_null($excludedGroups)) {
1483
+                $excludedGroups = explode(',', $groupsList);
1484
+                $newValue = json_encode($excludedGroups);
1485
+                $this->config->setAppValue('core', 'shareapi_exclude_groups_list', $newValue);
1486
+            }
1487
+            $user = $this->userManager->get($userId);
1488
+            $usersGroups = $this->groupManager->getUserGroupIds($user);
1489
+            if (!empty($usersGroups)) {
1490
+                $remainingGroups = array_diff($usersGroups, $excludedGroups);
1491
+                // if the user is only in groups which are disabled for sharing then
1492
+                // sharing is also disabled for the user
1493
+                if (empty($remainingGroups)) {
1494
+                    $this->sharingDisabledForUsersCache[$userId] = true;
1495
+                    return true;
1496
+                }
1497
+            }
1498
+        }
1499
+
1500
+        $this->sharingDisabledForUsersCache[$userId] = false;
1501
+        return false;
1502
+    }
1503
+
1504
+    /**
1505
+     * @inheritdoc
1506
+     */
1507
+    public function outgoingServer2ServerSharesAllowed() {
1508
+        return $this->config->getAppValue('files_sharing', 'outgoing_server2server_share_enabled', 'yes') === 'yes';
1509
+    }
1510
+
1511
+    /**
1512
+     * @inheritdoc
1513
+     */
1514
+    public function shareProviderExists($shareType) {
1515
+        try {
1516
+            $this->factory->getProviderForType($shareType);
1517
+        } catch (ProviderException $e) {
1518
+            return false;
1519
+        }
1520
+
1521
+        return true;
1522
+    }
1523 1523
 
1524 1524
 }
Please login to merge, or discard this patch.
Spacing   +23 added lines, -23 removed lines patch added patch discarded remove patch
@@ -340,7 +340,7 @@  discard block
 block discarded – undo
340 340
 
341 341
 		if ($fullId === null && $expirationDate === null && $this->shareApiLinkDefaultExpireDate()) {
342 342
 			$expirationDate = new \DateTime();
343
-			$expirationDate->setTime(0,0,0);
343
+			$expirationDate->setTime(0, 0, 0);
344 344
 			$expirationDate->add(new \DateInterval('P'.$this->shareApiLinkDefaultExpireDays().'D'));
345 345
 		}
346 346
 
@@ -352,7 +352,7 @@  discard block
 block discarded – undo
352 352
 
353 353
 			$date = new \DateTime();
354 354
 			$date->setTime(0, 0, 0);
355
-			$date->add(new \DateInterval('P' . $this->shareApiLinkDefaultExpireDays() . 'D'));
355
+			$date->add(new \DateInterval('P'.$this->shareApiLinkDefaultExpireDays().'D'));
356 356
 			if ($date < $expirationDate) {
357 357
 				$message = $this->l->t('Can’t set expiration date more than %s days in the future', [$this->shareApiLinkDefaultExpireDays()]);
358 358
 				throw new GenericShareException($message, $message, 404);
@@ -405,7 +405,7 @@  discard block
 block discarded – undo
405 405
 		 */
406 406
 		$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_USER);
407 407
 		$existingShares = $provider->getSharesByPath($share->getNode());
408
-		foreach($existingShares as $existingShare) {
408
+		foreach ($existingShares as $existingShare) {
409 409
 			// Ignore if it is the same share
410 410
 			try {
411 411
 				if ($existingShare->getFullId() === $share->getFullId()) {
@@ -462,7 +462,7 @@  discard block
 block discarded – undo
462 462
 		 */
463 463
 		$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_GROUP);
464 464
 		$existingShares = $provider->getSharesByPath($share->getNode());
465
-		foreach($existingShares as $existingShare) {
465
+		foreach ($existingShares as $existingShare) {
466 466
 			try {
467 467
 				if ($existingShare->getFullId() === $share->getFullId()) {
468 468
 					continue;
@@ -531,7 +531,7 @@  discard block
 block discarded – undo
531 531
 		// Make sure that we do not share a path that contains a shared mountpoint
532 532
 		if ($path instanceof \OCP\Files\Folder) {
533 533
 			$mounts = $this->mountManager->findIn($path->getPath());
534
-			foreach($mounts as $mount) {
534
+			foreach ($mounts as $mount) {
535 535
 				if ($mount->getStorage()->instanceOfStorage('\OCA\Files_Sharing\ISharedStorage')) {
536 536
 					throw new \InvalidArgumentException('Path contains files shared with you');
537 537
 				}
@@ -579,7 +579,7 @@  discard block
 block discarded – undo
579 579
 		$storage = $share->getNode()->getStorage();
580 580
 		if ($storage->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
581 581
 			$parent = $share->getNode()->getParent();
582
-			while($parent->getStorage()->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
582
+			while ($parent->getStorage()->instanceOfStorage('OCA\Files_Sharing\External\Storage')) {
583 583
 				$parent = $parent->getParent();
584 584
 			}
585 585
 			$share->setShareOwner($parent->getOwner()->getUID());
@@ -632,7 +632,7 @@  discard block
 block discarded – undo
632 632
 		}
633 633
 
634 634
 		// Generate the target
635
-		$target = $this->config->getSystemValue('share_folder', '/') .'/'. $share->getNode()->getName();
635
+		$target = $this->config->getSystemValue('share_folder', '/').'/'.$share->getNode()->getName();
636 636
 		$target = \OC\Files\Filesystem::normalizePath($target);
637 637
 		$share->setTarget($target);
638 638
 
@@ -660,17 +660,17 @@  discard block
 block discarded – undo
660 660
 				if ($emailAddress !== null && $emailAddress !== '') {
661 661
 					$this->sendMailNotification(
662 662
 						$share->getNode()->getName(),
663
-						$this->urlGenerator->linkToRouteAbsolute('files.viewcontroller.showFile', [ 'fileid' => $share->getNode()->getId() ]),
663
+						$this->urlGenerator->linkToRouteAbsolute('files.viewcontroller.showFile', ['fileid' => $share->getNode()->getId()]),
664 664
 						$share->getSharedBy(),
665 665
 						$emailAddress,
666 666
 						$share->getExpirationDate()
667 667
 					);
668
-					$this->logger->debug('Send share notification to ' . $emailAddress . ' for share with ID ' . $share->getId(), ['app' => 'share']);
668
+					$this->logger->debug('Send share notification to '.$emailAddress.' for share with ID '.$share->getId(), ['app' => 'share']);
669 669
 				} else {
670
-					$this->logger->debug('Share notification not send to ' . $share->getSharedWith() . ' because email address is not set.', ['app' => 'share']);
670
+					$this->logger->debug('Share notification not send to '.$share->getSharedWith().' because email address is not set.', ['app' => 'share']);
671 671
 				}
672 672
 			} else {
673
-				$this->logger->debug('Share notification not send to ' . $share->getSharedWith() . ' because user could not be found.', ['app' => 'share']);
673
+				$this->logger->debug('Share notification not send to '.$share->getSharedWith().' because user could not be found.', ['app' => 'share']);
674 674
 			}
675 675
 		}
676 676
 
@@ -692,7 +692,7 @@  discard block
 block discarded – undo
692 692
 											\DateTime $expiration) {
693 693
 		$initiatorUser = $this->userManager->get($initiator);
694 694
 		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
695
-		$subject = (string)$this->l->t('%s shared »%s« with you', array($initiatorDisplayName, $filename));
695
+		$subject = (string) $this->l->t('%s shared »%s« with you', array($initiatorDisplayName, $filename));
696 696
 
697 697
 		$message = $this->mailer->createMessage();
698 698
 
@@ -709,7 +709,7 @@  discard block
 block discarded – undo
709 709
 		$text = $this->l->t('%s shared »%s« with you.', [$initiatorDisplayName, $filename]);
710 710
 
711 711
 		$emailTemplate->addBodyText(
712
-			$text . ' ' . $this->l->t('Click the button below to open it.'),
712
+			$text.' '.$this->l->t('Click the button below to open it.'),
713 713
 			$text
714 714
 		);
715 715
 		$emailTemplate->addBodyButton(
@@ -733,9 +733,9 @@  discard block
 block discarded – undo
733 733
 		// The "Reply-To" is set to the sharer if an mail address is configured
734 734
 		// also the default footer contains a "Do not reply" which needs to be adjusted.
735 735
 		$initiatorEmail = $initiatorUser->getEMailAddress();
736
-		if($initiatorEmail !== null) {
736
+		if ($initiatorEmail !== null) {
737 737
 			$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
738
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
738
+			$emailTemplate->addFooter($instanceName.' - '.$this->defaults->getSlogan());
739 739
 		} else {
740 740
 			$emailTemplate->addFooter();
741 741
 		}
@@ -946,7 +946,7 @@  discard block
 block discarded – undo
946 946
 	 * @param string $recipientId
947 947
 	 */
948 948
 	public function deleteFromSelf(\OCP\Share\IShare $share, $recipientId) {
949
-		list($providerId, ) = $this->splitFullId($share->getFullId());
949
+		list($providerId,) = $this->splitFullId($share->getFullId());
950 950
 		$provider = $this->factory->getProvider($providerId);
951 951
 
952 952
 		$provider->deleteFromSelf($share, $recipientId);
@@ -969,7 +969,7 @@  discard block
 block discarded – undo
969 969
 		if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) {
970 970
 			$sharedWith = $this->groupManager->get($share->getSharedWith());
971 971
 			if (is_null($sharedWith)) {
972
-				throw new \InvalidArgumentException('Group "' . $share->getSharedWith() . '" does not exist');
972
+				throw new \InvalidArgumentException('Group "'.$share->getSharedWith().'" does not exist');
973 973
 			}
974 974
 			$recipient = $this->userManager->get($recipientId);
975 975
 			if (!$sharedWith->inGroup($recipient)) {
@@ -977,7 +977,7 @@  discard block
 block discarded – undo
977 977
 			}
978 978
 		}
979 979
 
980
-		list($providerId, ) = $this->splitFullId($share->getFullId());
980
+		list($providerId,) = $this->splitFullId($share->getFullId());
981 981
 		$provider = $this->factory->getProvider($providerId);
982 982
 
983 983
 		$provider->move($share, $recipientId);
@@ -1024,7 +1024,7 @@  discard block
 block discarded – undo
1024 1024
 
1025 1025
 		$shares2 = [];
1026 1026
 
1027
-		while(true) {
1027
+		while (true) {
1028 1028
 			$added = 0;
1029 1029
 			foreach ($shares as $share) {
1030 1030
 
@@ -1124,7 +1124,7 @@  discard block
 block discarded – undo
1124 1124
 	 *
1125 1125
 	 * @return Share[]
1126 1126
 	 */
1127
-	public function getSharesByPath(\OCP\Files\Node $path, $page=0, $perPage=50) {
1127
+	public function getSharesByPath(\OCP\Files\Node $path, $page = 0, $perPage = 50) {
1128 1128
 		return [];
1129 1129
 	}
1130 1130
 
@@ -1139,7 +1139,7 @@  discard block
 block discarded – undo
1139 1139
 	public function getShareByToken($token) {
1140 1140
 		$share = null;
1141 1141
 		try {
1142
-			if($this->shareApiAllowLinks()) {
1142
+			if ($this->shareApiAllowLinks()) {
1143 1143
 				$provider = $this->factory->getProviderForType(\OCP\Share::SHARE_TYPE_LINK);
1144 1144
 				$share = $provider->getShareByToken($token);
1145 1145
 			}
@@ -1337,7 +1337,7 @@  discard block
 block discarded – undo
1337 1337
 			}
1338 1338
 			$al['users'][$owner] = [
1339 1339
 				'node_id' => $path->getId(),
1340
-				'node_path' => '/' . $ownerPath,
1340
+				'node_path' => '/'.$ownerPath,
1341 1341
 			];
1342 1342
 		} else {
1343 1343
 			$al['users'][] = $owner;
@@ -1431,7 +1431,7 @@  discard block
 block discarded – undo
1431 1431
 	 * @return int
1432 1432
 	 */
1433 1433
 	public function shareApiLinkDefaultExpireDays() {
1434
-		return (int)$this->config->getAppValue('core', 'shareapi_expire_after_n_days', '7');
1434
+		return (int) $this->config->getAppValue('core', 'shareapi_expire_after_n_days', '7');
1435 1435
 	}
1436 1436
 
1437 1437
 	/**
Please login to merge, or discard this patch.
lib/public/Mail/IEMailTemplate.php 1 patch
Indentation   +93 added lines, -93 removed lines patch added patch discarded remove patch
@@ -51,106 +51,106 @@
 block discarded – undo
51 51
  * @since 12.0.0
52 52
  */
53 53
 interface IEMailTemplate {
54
-	/**
55
-	 * Set meta data of an email
56
-	 *
57
-	 * @since 12.0.3
58
-	 */
59
-	public function setMetaData($emailId, array $data = []);
54
+    /**
55
+     * Set meta data of an email
56
+     *
57
+     * @since 12.0.3
58
+     */
59
+    public function setMetaData($emailId, array $data = []);
60 60
 
61
-	/**
62
-	 * Adds a header to the email
63
-	 *
64
-	 * @since 12.0.0
65
-	 */
66
-	public function addHeader();
61
+    /**
62
+     * Adds a header to the email
63
+     *
64
+     * @since 12.0.0
65
+     */
66
+    public function addHeader();
67 67
 
68
-	/**
69
-	 * Adds a heading to the email
70
-	 *
71
-	 * @param string $title
72
-	 * @param string|bool $plainTitle Title that is used in the plain text email
73
-	 *   if empty the $title is used, if false none will be used
74
-	 *
75
-	 * @since 12.0.0
76
-	 */
77
-	public function addHeading($title, $plainTitle = '');
68
+    /**
69
+     * Adds a heading to the email
70
+     *
71
+     * @param string $title
72
+     * @param string|bool $plainTitle Title that is used in the plain text email
73
+     *   if empty the $title is used, if false none will be used
74
+     *
75
+     * @since 12.0.0
76
+     */
77
+    public function addHeading($title, $plainTitle = '');
78 78
 
79
-	/**
80
-	 * Adds a paragraph to the body of the email
81
-	 *
82
-	 * @param string $text
83
-	 * @param string|bool $plainText Text that is used in the plain text email
84
-	 *   if empty the $text is used, if false none will be used
85
-	 *
86
-	 * @since 12.0.0
87
-	 */
88
-	public function addBodyText($text, $plainText = '');
79
+    /**
80
+     * Adds a paragraph to the body of the email
81
+     *
82
+     * @param string $text
83
+     * @param string|bool $plainText Text that is used in the plain text email
84
+     *   if empty the $text is used, if false none will be used
85
+     *
86
+     * @since 12.0.0
87
+     */
88
+    public function addBodyText($text, $plainText = '');
89 89
 
90
-	/**
91
-	 * Adds a list item to the body of the email
92
-	 *
93
-	 * @param string $text
94
-	 * @param string $metaInfo
95
-	 * @param string $icon Absolute path, must be 16*16 pixels
96
-	 * @param string $plainText Text that is used in the plain text email
97
-	 *   if empty the $text is used, if false none will be used
98
-	 * @param string $plainMetaInfo Meta info that is used in the plain text email
99
-	 *   if empty the $metaInfo is used, if false none will be used
100
-	 * @since 12.0.0
101
-	 */
102
-	public function addBodyListItem($text, $metaInfo = '', $icon = '', $plainText = '', $plainMetaInfo = '');
90
+    /**
91
+     * Adds a list item to the body of the email
92
+     *
93
+     * @param string $text
94
+     * @param string $metaInfo
95
+     * @param string $icon Absolute path, must be 16*16 pixels
96
+     * @param string $plainText Text that is used in the plain text email
97
+     *   if empty the $text is used, if false none will be used
98
+     * @param string $plainMetaInfo Meta info that is used in the plain text email
99
+     *   if empty the $metaInfo is used, if false none will be used
100
+     * @since 12.0.0
101
+     */
102
+    public function addBodyListItem($text, $metaInfo = '', $icon = '', $plainText = '', $plainMetaInfo = '');
103 103
 
104
-	/**
105
-	 * Adds a button group of two buttons to the body of the email
106
-	 *
107
-	 * @param string $textLeft Text of left button
108
-	 * @param string $urlLeft URL of left button
109
-	 * @param string $textRight Text of right button
110
-	 * @param string $urlRight URL of right button
111
-	 * @param string $plainTextLeft Text of left button that is used in the plain text version - if empty the $textLeft is used
112
-	 * @param string $plainTextRight Text of right button that is used in the plain text version - if empty the $textRight is used
113
-	 *
114
-	 * @since 12.0.0
115
-	 */
116
-	public function addBodyButtonGroup($textLeft, $urlLeft, $textRight, $urlRight, $plainTextLeft = '', $plainTextRight = '');
104
+    /**
105
+     * Adds a button group of two buttons to the body of the email
106
+     *
107
+     * @param string $textLeft Text of left button
108
+     * @param string $urlLeft URL of left button
109
+     * @param string $textRight Text of right button
110
+     * @param string $urlRight URL of right button
111
+     * @param string $plainTextLeft Text of left button that is used in the plain text version - if empty the $textLeft is used
112
+     * @param string $plainTextRight Text of right button that is used in the plain text version - if empty the $textRight is used
113
+     *
114
+     * @since 12.0.0
115
+     */
116
+    public function addBodyButtonGroup($textLeft, $urlLeft, $textRight, $urlRight, $plainTextLeft = '', $plainTextRight = '');
117 117
 
118
-	/**
119
-	 * Adds a button to the body of the email
120
-	 *
121
-	 * @param string $text Text of button
122
-	 * @param string $url URL of button
123
-	 * @param string $plainText Text of button in plain text version
124
-	 * 		if empty the $text is used, if false none will be used
125
-	 *
126
-	 * @since 12.0.0
127
-	 */
128
-	public function addBodyButton($text, $url, $plainText = '');
118
+    /**
119
+     * Adds a button to the body of the email
120
+     *
121
+     * @param string $text Text of button
122
+     * @param string $url URL of button
123
+     * @param string $plainText Text of button in plain text version
124
+     * 		if empty the $text is used, if false none will be used
125
+     *
126
+     * @since 12.0.0
127
+     */
128
+    public function addBodyButton($text, $url, $plainText = '');
129 129
 
130
-	/**
131
-	 * Adds a logo and a text to the footer. <br> in the text will be replaced by new lines in the plain text email
132
-	 *
133
-	 * @param string $text If the text is empty the default "Name - Slogan<br>This is an automatically sent email" will be used
134
-	 *
135
-	 * @since 12.0.0
136
-	 */
137
-	public function addFooter($text = '');
130
+    /**
131
+     * Adds a logo and a text to the footer. <br> in the text will be replaced by new lines in the plain text email
132
+     *
133
+     * @param string $text If the text is empty the default "Name - Slogan<br>This is an automatically sent email" will be used
134
+     *
135
+     * @since 12.0.0
136
+     */
137
+    public function addFooter($text = '');
138 138
 
139
-	/**
140
-	 * Returns the rendered HTML email as string
141
-	 *
142
-	 * @return string
143
-	 *
144
-	 * @since 12.0.0
145
-	 */
146
-	public function renderHtml();
139
+    /**
140
+     * Returns the rendered HTML email as string
141
+     *
142
+     * @return string
143
+     *
144
+     * @since 12.0.0
145
+     */
146
+    public function renderHtml();
147 147
 
148
-	/**
149
-	 * Returns the rendered plain text email as string
150
-	 *
151
-	 * @return string
152
-	 *
153
-	 * @since 12.0.0
154
-	 */
155
-	public function renderText();
148
+    /**
149
+     * Returns the rendered plain text email as string
150
+     *
151
+     * @return string
152
+     *
153
+     * @since 12.0.0
154
+     */
155
+    public function renderText();
156 156
 }
Please login to merge, or discard this patch.