Completed
Pull Request — master (#5302)
by Björn
17:26
created
apps/sharebymail/lib/ShareByMailProvider.php 2 patches
Indentation   +999 added lines, -999 removed lines patch added patch discarded remove patch
@@ -52,1017 +52,1017 @@
 block discarded – undo
52 52
  */
53 53
 class ShareByMailProvider implements IShareProvider {
54 54
 
55
-	/** @var  IDBConnection */
56
-	private $dbConnection;
57
-
58
-	/** @var ILogger */
59
-	private $logger;
60
-
61
-	/** @var ISecureRandom */
62
-	private $secureRandom;
63
-
64
-	/** @var IUserManager */
65
-	private $userManager;
66
-
67
-	/** @var IRootFolder */
68
-	private $rootFolder;
69
-
70
-	/** @var IL10N */
71
-	private $l;
72
-
73
-	/** @var IMailer */
74
-	private $mailer;
75
-
76
-	/** @var IURLGenerator */
77
-	private $urlGenerator;
78
-
79
-	/** @var IManager  */
80
-	private $activityManager;
81
-
82
-	/** @var SettingsManager */
83
-	private $settingsManager;
84
-
85
-	/** @var Defaults */
86
-	private $defaults;
87
-
88
-	/** @var IHasher */
89
-	private $hasher;
90
-
91
-	/** @var  CapabilitiesManager */
92
-	private $capabilitiesManager;
93
-
94
-	/**
95
-	 * Return the identifier of this provider.
96
-	 *
97
-	 * @return string Containing only [a-zA-Z0-9]
98
-	 */
99
-	public function identifier() {
100
-		return 'ocMailShare';
101
-	}
102
-
103
-	/**
104
-	 * DefaultShareProvider constructor.
105
-	 *
106
-	 * @param IDBConnection $connection
107
-	 * @param ISecureRandom $secureRandom
108
-	 * @param IUserManager $userManager
109
-	 * @param IRootFolder $rootFolder
110
-	 * @param IL10N $l
111
-	 * @param ILogger $logger
112
-	 * @param IMailer $mailer
113
-	 * @param IURLGenerator $urlGenerator
114
-	 * @param IManager $activityManager
115
-	 * @param SettingsManager $settingsManager
116
-	 * @param Defaults $defaults
117
-	 * @param IHasher $hasher
118
-	 * @param CapabilitiesManager $capabilitiesManager
119
-	 */
120
-	public function __construct(
121
-		IDBConnection $connection,
122
-		ISecureRandom $secureRandom,
123
-		IUserManager $userManager,
124
-		IRootFolder $rootFolder,
125
-		IL10N $l,
126
-		ILogger $logger,
127
-		IMailer $mailer,
128
-		IURLGenerator $urlGenerator,
129
-		IManager $activityManager,
130
-		SettingsManager $settingsManager,
131
-		Defaults $defaults,
132
-		IHasher $hasher,
133
-		CapabilitiesManager $capabilitiesManager
134
-	) {
135
-		$this->dbConnection = $connection;
136
-		$this->secureRandom = $secureRandom;
137
-		$this->userManager = $userManager;
138
-		$this->rootFolder = $rootFolder;
139
-		$this->l = $l;
140
-		$this->logger = $logger;
141
-		$this->mailer = $mailer;
142
-		$this->urlGenerator = $urlGenerator;
143
-		$this->activityManager = $activityManager;
144
-		$this->settingsManager = $settingsManager;
145
-		$this->defaults = $defaults;
146
-		$this->hasher = $hasher;
147
-		$this->capabilitiesManager = $capabilitiesManager;
148
-	}
149
-
150
-	/**
151
-	 * Share a path
152
-	 *
153
-	 * @param IShare $share
154
-	 * @return IShare The share object
155
-	 * @throws ShareNotFound
156
-	 * @throws \Exception
157
-	 */
158
-	public function create(IShare $share) {
159
-
160
-		$shareWith = $share->getSharedWith();
161
-		/*
55
+    /** @var  IDBConnection */
56
+    private $dbConnection;
57
+
58
+    /** @var ILogger */
59
+    private $logger;
60
+
61
+    /** @var ISecureRandom */
62
+    private $secureRandom;
63
+
64
+    /** @var IUserManager */
65
+    private $userManager;
66
+
67
+    /** @var IRootFolder */
68
+    private $rootFolder;
69
+
70
+    /** @var IL10N */
71
+    private $l;
72
+
73
+    /** @var IMailer */
74
+    private $mailer;
75
+
76
+    /** @var IURLGenerator */
77
+    private $urlGenerator;
78
+
79
+    /** @var IManager  */
80
+    private $activityManager;
81
+
82
+    /** @var SettingsManager */
83
+    private $settingsManager;
84
+
85
+    /** @var Defaults */
86
+    private $defaults;
87
+
88
+    /** @var IHasher */
89
+    private $hasher;
90
+
91
+    /** @var  CapabilitiesManager */
92
+    private $capabilitiesManager;
93
+
94
+    /**
95
+     * Return the identifier of this provider.
96
+     *
97
+     * @return string Containing only [a-zA-Z0-9]
98
+     */
99
+    public function identifier() {
100
+        return 'ocMailShare';
101
+    }
102
+
103
+    /**
104
+     * DefaultShareProvider constructor.
105
+     *
106
+     * @param IDBConnection $connection
107
+     * @param ISecureRandom $secureRandom
108
+     * @param IUserManager $userManager
109
+     * @param IRootFolder $rootFolder
110
+     * @param IL10N $l
111
+     * @param ILogger $logger
112
+     * @param IMailer $mailer
113
+     * @param IURLGenerator $urlGenerator
114
+     * @param IManager $activityManager
115
+     * @param SettingsManager $settingsManager
116
+     * @param Defaults $defaults
117
+     * @param IHasher $hasher
118
+     * @param CapabilitiesManager $capabilitiesManager
119
+     */
120
+    public function __construct(
121
+        IDBConnection $connection,
122
+        ISecureRandom $secureRandom,
123
+        IUserManager $userManager,
124
+        IRootFolder $rootFolder,
125
+        IL10N $l,
126
+        ILogger $logger,
127
+        IMailer $mailer,
128
+        IURLGenerator $urlGenerator,
129
+        IManager $activityManager,
130
+        SettingsManager $settingsManager,
131
+        Defaults $defaults,
132
+        IHasher $hasher,
133
+        CapabilitiesManager $capabilitiesManager
134
+    ) {
135
+        $this->dbConnection = $connection;
136
+        $this->secureRandom = $secureRandom;
137
+        $this->userManager = $userManager;
138
+        $this->rootFolder = $rootFolder;
139
+        $this->l = $l;
140
+        $this->logger = $logger;
141
+        $this->mailer = $mailer;
142
+        $this->urlGenerator = $urlGenerator;
143
+        $this->activityManager = $activityManager;
144
+        $this->settingsManager = $settingsManager;
145
+        $this->defaults = $defaults;
146
+        $this->hasher = $hasher;
147
+        $this->capabilitiesManager = $capabilitiesManager;
148
+    }
149
+
150
+    /**
151
+     * Share a path
152
+     *
153
+     * @param IShare $share
154
+     * @return IShare The share object
155
+     * @throws ShareNotFound
156
+     * @throws \Exception
157
+     */
158
+    public function create(IShare $share) {
159
+
160
+        $shareWith = $share->getSharedWith();
161
+        /*
162 162
 		 * Check if file is not already shared with the remote user
163 163
 		 */
164
-		$alreadyShared = $this->getSharedWith($shareWith, \OCP\Share::SHARE_TYPE_EMAIL, $share->getNode(), 1, 0);
165
-		if (!empty($alreadyShared)) {
166
-			$message = 'Sharing %s failed, this item is already shared with %s';
167
-			$message_t = $this->l->t('Sharing %s failed, this item is already shared with %s', array($share->getNode()->getName(), $shareWith));
168
-			$this->logger->debug(sprintf($message, $share->getNode()->getName(), $shareWith), ['app' => 'Federated File Sharing']);
169
-			throw new \Exception($message_t);
170
-		}
171
-
172
-		// if the admin enforces a password for all mail shares we create a
173
-		// random password and send it to the recipient
174
-		$password = '';
175
-		$passwordEnforced = $this->settingsManager->enforcePasswordProtection();
176
-		if ($passwordEnforced) {
177
-			$password = $this->autoGeneratePassword($share);
178
-		}
179
-
180
-		$shareId = $this->createMailShare($share);
181
-		$send = $this->sendPassword($share, $password);
182
-		if ($passwordEnforced && $send === false) {
183
-			$this->sendPasswordToOwner($share, $password);
184
-		}
185
-
186
-		$this->createShareActivity($share);
187
-		$data = $this->getRawShare($shareId);
188
-
189
-		return $this->createShareObject($data);
190
-
191
-	}
192
-
193
-	/**
194
-	 * auto generate password in case of password enforcement on mail shares
195
-	 *
196
-	 * @param IShare $share
197
-	 * @return string
198
-	 * @throws \Exception
199
-	 */
200
-	protected function autoGeneratePassword($share) {
201
-		$initiatorUser = $this->userManager->get($share->getSharedBy());
202
-		$initiatorEMailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
203
-		$allowPasswordByMail = $this->settingsManager->sendPasswordByMail();
204
-
205
-		if ($initiatorEMailAddress === null && !$allowPasswordByMail) {
206
-			throw new \Exception(
207
-				$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.")
208
-			);
209
-		}
210
-
211
-		$passwordPolicy = $this->getPasswordPolicy();
212
-		$passwordCharset = ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS;
213
-		$passwordLength = 8;
214
-		if (!empty($passwordPolicy)) {
215
-			$passwordLength = (int)$passwordPolicy['minLength'] > 0 ? (int)$passwordPolicy['minLength'] : $passwordLength;
216
-			$passwordCharset .= $passwordPolicy['enforceSpecialCharacters'] ? ISecureRandom::CHAR_SYMBOLS : '';
217
-		}
218
-
219
-		$password = $this->secureRandom->generate($passwordLength, $passwordCharset);
220
-
221
-		$share->setPassword($this->hasher->hash($password));
222
-
223
-		return $password;
224
-	}
225
-
226
-	/**
227
-	 * get password policy
228
-	 *
229
-	 * @return array
230
-	 */
231
-	protected function getPasswordPolicy() {
232
-		$capabilities = $this->capabilitiesManager->getCapabilities();
233
-		if (isset($capabilities['password_policy'])) {
234
-			return $capabilities['password_policy'];
235
-		}
236
-
237
-		return [];
238
-	}
239
-
240
-	/**
241
-	 * create activity if a file/folder was shared by mail
242
-	 *
243
-	 * @param IShare $share
244
-	 */
245
-	protected function createShareActivity(IShare $share) {
246
-
247
-		$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
248
-
249
-		$this->publishActivity(
250
-			Activity::SUBJECT_SHARED_EMAIL_SELF,
251
-			[$userFolder->getRelativePath($share->getNode()->getPath()), $share->getSharedWith()],
252
-			$share->getSharedBy(),
253
-			$share->getNode()->getId(),
254
-			$userFolder->getRelativePath($share->getNode()->getPath())
255
-		);
256
-
257
-		if ($share->getShareOwner() !== $share->getSharedBy()) {
258
-			$ownerFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
259
-			$fileId = $share->getNode()->getId();
260
-			$nodes = $ownerFolder->getById($fileId);
261
-			$ownerPath = $nodes[0]->getPath();
262
-			$this->publishActivity(
263
-				Activity::SUBJECT_SHARED_EMAIL_BY,
264
-				[$ownerFolder->getRelativePath($ownerPath), $share->getSharedWith(), $share->getSharedBy()],
265
-				$share->getShareOwner(),
266
-				$fileId,
267
-				$ownerFolder->getRelativePath($ownerPath)
268
-			);
269
-		}
270
-
271
-	}
272
-
273
-	/**
274
-	 * create activity if a file/folder was shared by mail
275
-	 *
276
-	 * @param IShare $share
277
-	 * @param string $sharedWith
278
-	 * @param bool $sendToSelf
279
-	 */
280
-	protected function createPasswordSendActivity(IShare $share, $sharedWith, $sendToSelf) {
281
-
282
-		$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
283
-
284
-		if ($sendToSelf) {
285
-			$this->publishActivity(
286
-				Activity::SUBJECT_SHARED_EMAIL_PASSWORD_SEND_SELF,
287
-				[$userFolder->getRelativePath($share->getNode()->getPath())],
288
-				$share->getSharedBy(),
289
-				$share->getNode()->getId(),
290
-				$userFolder->getRelativePath($share->getNode()->getPath())
291
-			);
292
-		} else {
293
-			$this->publishActivity(
294
-				Activity::SUBJECT_SHARED_EMAIL_PASSWORD_SEND,
295
-				[$userFolder->getRelativePath($share->getNode()->getPath()), $sharedWith],
296
-				$share->getSharedBy(),
297
-				$share->getNode()->getId(),
298
-				$userFolder->getRelativePath($share->getNode()->getPath())
299
-			);
300
-		}
301
-	}
302
-
303
-
304
-	/**
305
-	 * publish activity if a file/folder was shared by mail
306
-	 *
307
-	 * @param $subject
308
-	 * @param $parameters
309
-	 * @param $affectedUser
310
-	 * @param $fileId
311
-	 * @param $filePath
312
-	 */
313
-	protected function publishActivity($subject, $parameters, $affectedUser, $fileId, $filePath) {
314
-		$event = $this->activityManager->generateEvent();
315
-		$event->setApp('sharebymail')
316
-			->setType('shared')
317
-			->setSubject($subject, $parameters)
318
-			->setAffectedUser($affectedUser)
319
-			->setObject('files', $fileId, $filePath);
320
-		$this->activityManager->publish($event);
321
-
322
-	}
323
-
324
-	/**
325
-	 * @param IShare $share
326
-	 * @return int
327
-	 * @throws \Exception
328
-	 */
329
-	protected function createMailShare(IShare $share) {
330
-		$share->setToken($this->generateToken());
331
-		$shareId = $this->addShareToDB(
332
-			$share->getNodeId(),
333
-			$share->getNodeType(),
334
-			$share->getSharedWith(),
335
-			$share->getSharedBy(),
336
-			$share->getShareOwner(),
337
-			$share->getPermissions(),
338
-			$share->getToken(),
339
-			$share->getPassword()
340
-		);
341
-
342
-		try {
343
-			$link = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare',
344
-				['token' => $share->getToken()]);
345
-			$this->sendMailNotification(
346
-				$share->getNode()->getName(),
347
-				$link,
348
-				$share->getSharedBy(),
349
-				$share->getSharedWith()
350
-			);
351
-		} catch (HintException $hintException) {
352
-			$this->logger->error('Failed to send share by mail: ' . $hintException->getMessage());
353
-			$this->removeShareFromTable($shareId);
354
-			throw $hintException;
355
-		} catch (\Exception $e) {
356
-			$this->logger->error('Failed to send share by email: ' . $e->getMessage());
357
-			$this->removeShareFromTable($shareId);
358
-			throw new HintException('Failed to send share by mail',
359
-				$this->l->t('Failed to send share by email'));
360
-		}
361
-
362
-		return $shareId;
363
-
364
-	}
365
-
366
-	/**
367
-	 * @param string $filename
368
-	 * @param string $link
369
-	 * @param string $initiator
370
-	 * @param string $shareWith
371
-	 * @throws \Exception If mail couldn't be sent
372
-	 */
373
-	protected function sendMailNotification($filename,
374
-											$link,
375
-											$initiator,
376
-											$shareWith) {
377
-		$initiatorUser = $this->userManager->get($initiator);
378
-		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
379
-		$subject = (string)$this->l->t('%s shared »%s« with you', array($initiatorDisplayName, $filename));
380
-
381
-		$message = $this->mailer->createMessage();
382
-
383
-		$emailTemplate = $this->mailer->createEMailTemplate();
384
-
385
-		$emailTemplate->addHeader();
386
-		$emailTemplate->addHeading($this->l->t('%s shared »%s« with you', [$initiatorDisplayName, $filename]), false);
387
-		$text = $this->l->t('%s shared »%s« with you.', [$initiatorDisplayName, $filename]);
388
-
389
-		$emailTemplate->addBodyText(
390
-			$text . ' ' . $this->l->t('Click the button below to open it.'),
391
-			$text
392
-		);
393
-		$emailTemplate->addBodyButton(
394
-			$this->l->t('Open »%s«', [$filename]),
395
-			$link
396
-		);
397
-
398
-		$message->setTo([$shareWith]);
399
-
400
-		// The "From" contains the sharers name
401
-		$instanceName = $this->defaults->getName();
402
-		$senderName = $this->l->t(
403
-			'%s via %s',
404
-			[
405
-				$initiatorDisplayName,
406
-				$instanceName
407
-			]
408
-		);
409
-		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
410
-
411
-		// The "Reply-To" is set to the sharer if an mail address is configured
412
-		// also the default footer contains a "Do not reply" which needs to be adjusted.
413
-		$initiatorEmail = $initiatorUser->getEMailAddress();
414
-		if($initiatorEmail !== null) {
415
-			$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
416
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
417
-		} else {
418
-			$emailTemplate->addFooter();
419
-		}
420
-
421
-		$message->setSubject($subject);
422
-		$message->setPlainBody($emailTemplate->renderText());
423
-		$message->setHtmlBody($emailTemplate->renderHtml());
424
-		$this->mailer->send($message);
425
-	}
426
-
427
-	/**
428
-	 * send password to recipient of a mail share
429
-	 *
430
-	 * @param IShare $share
431
-	 * @param string $password
432
-	 * @return bool
433
-	 */
434
-	protected function sendPassword(IShare $share, $password) {
435
-
436
-		$filename = $share->getNode()->getName();
437
-		$initiator = $share->getSharedBy();
438
-		$shareWith = $share->getSharedWith();
439
-
440
-		if ($password === '' || $this->settingsManager->sendPasswordByMail() === false) {
441
-			return false;
442
-		}
443
-
444
-		$initiatorUser = $this->userManager->get($initiator);
445
-		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
446
-		$initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
447
-
448
-		$subject = (string)$this->l->t('Password to access »%s« shared to you by %s', [$filename, $initiatorDisplayName]);
449
-		$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]);
450
-		$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]);
451
-
452
-		$message = $this->mailer->createMessage();
453
-
454
-		$emailTemplate = $this->mailer->createEMailTemplate();
455
-		$emailTemplate->addHeader();
456
-		$emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
457
-		$emailTemplate->addBodyText($htmlBodyPart, $plainBodyPart);
458
-		$emailTemplate->addBodyText($this->l->t('It is protected with the following password: %s', [$password]));
459
-
460
-		// The "From" contains the sharers name
461
-		$instanceName = $this->defaults->getName();
462
-		$senderName = $this->l->t(
463
-			'%s via %s',
464
-			[
465
-				$initiatorDisplayName,
466
-				$instanceName
467
-			]
468
-		);
469
-		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
470
-		if ($initiatorEmailAddress !== null) {
471
-			$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
472
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
473
-		} else {
474
-			$emailTemplate->addFooter();
475
-		}
476
-
477
-		$message->setTo([$shareWith]);
478
-		$message->setSubject($subject);
479
-		$message->setBody($emailTemplate->renderText(), 'text/plain');
480
-		$message->setHtmlBody($emailTemplate->renderHtml());
481
-		$this->mailer->send($message);
482
-
483
-		$this->createPasswordSendActivity($share, $shareWith, false);
484
-
485
-		return true;
486
-	}
487
-
488
-	/**
489
-	 * send auto generated password to the owner. This happens if the admin enforces
490
-	 * a password for mail shares and forbid to send the password by mail to the recipient
491
-	 *
492
-	 * @param IShare $share
493
-	 * @param string $password
494
-	 * @return bool
495
-	 * @throws \Exception
496
-	 */
497
-	protected function sendPasswordToOwner(IShare $share, $password) {
498
-
499
-		$filename = $share->getNode()->getName();
500
-		$initiator = $this->userManager->get($share->getSharedBy());
501
-		$initiatorEMailAddress = ($initiator instanceof IUser) ? $initiator->getEMailAddress() : null;
502
-		$initiatorDisplayName = ($initiator instanceof IUser) ? $initiator->getDisplayName() : $share->getSharedBy();
503
-		$shareWith = $share->getSharedWith();
504
-
505
-		if ($initiatorEMailAddress === null) {
506
-			throw new \Exception(
507
-				$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.")
508
-			);
509
-		}
510
-
511
-		$subject = (string)$this->l->t('Password to access »%s« shared with %s', [$filename, $shareWith]);
512
-		$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()]);
513
-
514
-		$message = $this->mailer->createMessage();
515
-		$emailTemplate = $this->mailer->createEMailTemplate();
516
-
517
-		$emailTemplate->addHeader();
518
-		$emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
519
-		$emailTemplate->addBodyText($bodyPart);
520
-		$emailTemplate->addBodyText($this->l->t('This is the password: %s', [$password]));
521
-		$emailTemplate->addBodyText($this->l->t('You can choose a different password at any time in the share dialog.'));
522
-		$emailTemplate->addFooter();
523
-
524
-		if ($initiatorEMailAddress) {
525
-			$message->setFrom([$initiatorEMailAddress => $initiatorDisplayName]);
526
-		}
527
-		$message->setTo([$initiatorEMailAddress => $initiatorDisplayName]);
528
-		$message->setSubject($subject);
529
-		$message->setBody($emailTemplate->renderText(), 'text/plain');
530
-		$message->setHtmlBody($emailTemplate->renderHtml());
531
-		$this->mailer->send($message);
532
-
533
-		$this->createPasswordSendActivity($share, $shareWith, true);
534
-
535
-		return true;
536
-	}
537
-
538
-	/**
539
-	 * generate share token
540
-	 *
541
-	 * @return string
542
-	 */
543
-	protected function generateToken($size = 15) {
544
-		$token = $this->secureRandom->generate(
545
-			$size, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS);
546
-		return $token;
547
-	}
548
-
549
-	/**
550
-	 * Get all children of this share
551
-	 *
552
-	 * @param IShare $parent
553
-	 * @return IShare[]
554
-	 */
555
-	public function getChildren(IShare $parent) {
556
-		$children = [];
557
-
558
-		$qb = $this->dbConnection->getQueryBuilder();
559
-		$qb->select('*')
560
-			->from('share')
561
-			->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
562
-			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
563
-			->orderBy('id');
564
-
565
-		$cursor = $qb->execute();
566
-		while($data = $cursor->fetch()) {
567
-			$children[] = $this->createShareObject($data);
568
-		}
569
-		$cursor->closeCursor();
570
-
571
-		return $children;
572
-	}
573
-
574
-	/**
575
-	 * add share to the database and return the ID
576
-	 *
577
-	 * @param int $itemSource
578
-	 * @param string $itemType
579
-	 * @param string $shareWith
580
-	 * @param string $sharedBy
581
-	 * @param string $uidOwner
582
-	 * @param int $permissions
583
-	 * @param string $token
584
-	 * @return int
585
-	 */
586
-	protected function addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token, $password) {
587
-		$qb = $this->dbConnection->getQueryBuilder();
588
-		$qb->insert('share')
589
-			->setValue('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))
590
-			->setValue('item_type', $qb->createNamedParameter($itemType))
591
-			->setValue('item_source', $qb->createNamedParameter($itemSource))
592
-			->setValue('file_source', $qb->createNamedParameter($itemSource))
593
-			->setValue('share_with', $qb->createNamedParameter($shareWith))
594
-			->setValue('uid_owner', $qb->createNamedParameter($uidOwner))
595
-			->setValue('uid_initiator', $qb->createNamedParameter($sharedBy))
596
-			->setValue('permissions', $qb->createNamedParameter($permissions))
597
-			->setValue('token', $qb->createNamedParameter($token))
598
-			->setValue('password', $qb->createNamedParameter($password))
599
-			->setValue('stime', $qb->createNamedParameter(time()));
600
-
601
-		/*
164
+        $alreadyShared = $this->getSharedWith($shareWith, \OCP\Share::SHARE_TYPE_EMAIL, $share->getNode(), 1, 0);
165
+        if (!empty($alreadyShared)) {
166
+            $message = 'Sharing %s failed, this item is already shared with %s';
167
+            $message_t = $this->l->t('Sharing %s failed, this item is already shared with %s', array($share->getNode()->getName(), $shareWith));
168
+            $this->logger->debug(sprintf($message, $share->getNode()->getName(), $shareWith), ['app' => 'Federated File Sharing']);
169
+            throw new \Exception($message_t);
170
+        }
171
+
172
+        // if the admin enforces a password for all mail shares we create a
173
+        // random password and send it to the recipient
174
+        $password = '';
175
+        $passwordEnforced = $this->settingsManager->enforcePasswordProtection();
176
+        if ($passwordEnforced) {
177
+            $password = $this->autoGeneratePassword($share);
178
+        }
179
+
180
+        $shareId = $this->createMailShare($share);
181
+        $send = $this->sendPassword($share, $password);
182
+        if ($passwordEnforced && $send === false) {
183
+            $this->sendPasswordToOwner($share, $password);
184
+        }
185
+
186
+        $this->createShareActivity($share);
187
+        $data = $this->getRawShare($shareId);
188
+
189
+        return $this->createShareObject($data);
190
+
191
+    }
192
+
193
+    /**
194
+     * auto generate password in case of password enforcement on mail shares
195
+     *
196
+     * @param IShare $share
197
+     * @return string
198
+     * @throws \Exception
199
+     */
200
+    protected function autoGeneratePassword($share) {
201
+        $initiatorUser = $this->userManager->get($share->getSharedBy());
202
+        $initiatorEMailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
203
+        $allowPasswordByMail = $this->settingsManager->sendPasswordByMail();
204
+
205
+        if ($initiatorEMailAddress === null && !$allowPasswordByMail) {
206
+            throw new \Exception(
207
+                $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.")
208
+            );
209
+        }
210
+
211
+        $passwordPolicy = $this->getPasswordPolicy();
212
+        $passwordCharset = ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS;
213
+        $passwordLength = 8;
214
+        if (!empty($passwordPolicy)) {
215
+            $passwordLength = (int)$passwordPolicy['minLength'] > 0 ? (int)$passwordPolicy['minLength'] : $passwordLength;
216
+            $passwordCharset .= $passwordPolicy['enforceSpecialCharacters'] ? ISecureRandom::CHAR_SYMBOLS : '';
217
+        }
218
+
219
+        $password = $this->secureRandom->generate($passwordLength, $passwordCharset);
220
+
221
+        $share->setPassword($this->hasher->hash($password));
222
+
223
+        return $password;
224
+    }
225
+
226
+    /**
227
+     * get password policy
228
+     *
229
+     * @return array
230
+     */
231
+    protected function getPasswordPolicy() {
232
+        $capabilities = $this->capabilitiesManager->getCapabilities();
233
+        if (isset($capabilities['password_policy'])) {
234
+            return $capabilities['password_policy'];
235
+        }
236
+
237
+        return [];
238
+    }
239
+
240
+    /**
241
+     * create activity if a file/folder was shared by mail
242
+     *
243
+     * @param IShare $share
244
+     */
245
+    protected function createShareActivity(IShare $share) {
246
+
247
+        $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
248
+
249
+        $this->publishActivity(
250
+            Activity::SUBJECT_SHARED_EMAIL_SELF,
251
+            [$userFolder->getRelativePath($share->getNode()->getPath()), $share->getSharedWith()],
252
+            $share->getSharedBy(),
253
+            $share->getNode()->getId(),
254
+            $userFolder->getRelativePath($share->getNode()->getPath())
255
+        );
256
+
257
+        if ($share->getShareOwner() !== $share->getSharedBy()) {
258
+            $ownerFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
259
+            $fileId = $share->getNode()->getId();
260
+            $nodes = $ownerFolder->getById($fileId);
261
+            $ownerPath = $nodes[0]->getPath();
262
+            $this->publishActivity(
263
+                Activity::SUBJECT_SHARED_EMAIL_BY,
264
+                [$ownerFolder->getRelativePath($ownerPath), $share->getSharedWith(), $share->getSharedBy()],
265
+                $share->getShareOwner(),
266
+                $fileId,
267
+                $ownerFolder->getRelativePath($ownerPath)
268
+            );
269
+        }
270
+
271
+    }
272
+
273
+    /**
274
+     * create activity if a file/folder was shared by mail
275
+     *
276
+     * @param IShare $share
277
+     * @param string $sharedWith
278
+     * @param bool $sendToSelf
279
+     */
280
+    protected function createPasswordSendActivity(IShare $share, $sharedWith, $sendToSelf) {
281
+
282
+        $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
283
+
284
+        if ($sendToSelf) {
285
+            $this->publishActivity(
286
+                Activity::SUBJECT_SHARED_EMAIL_PASSWORD_SEND_SELF,
287
+                [$userFolder->getRelativePath($share->getNode()->getPath())],
288
+                $share->getSharedBy(),
289
+                $share->getNode()->getId(),
290
+                $userFolder->getRelativePath($share->getNode()->getPath())
291
+            );
292
+        } else {
293
+            $this->publishActivity(
294
+                Activity::SUBJECT_SHARED_EMAIL_PASSWORD_SEND,
295
+                [$userFolder->getRelativePath($share->getNode()->getPath()), $sharedWith],
296
+                $share->getSharedBy(),
297
+                $share->getNode()->getId(),
298
+                $userFolder->getRelativePath($share->getNode()->getPath())
299
+            );
300
+        }
301
+    }
302
+
303
+
304
+    /**
305
+     * publish activity if a file/folder was shared by mail
306
+     *
307
+     * @param $subject
308
+     * @param $parameters
309
+     * @param $affectedUser
310
+     * @param $fileId
311
+     * @param $filePath
312
+     */
313
+    protected function publishActivity($subject, $parameters, $affectedUser, $fileId, $filePath) {
314
+        $event = $this->activityManager->generateEvent();
315
+        $event->setApp('sharebymail')
316
+            ->setType('shared')
317
+            ->setSubject($subject, $parameters)
318
+            ->setAffectedUser($affectedUser)
319
+            ->setObject('files', $fileId, $filePath);
320
+        $this->activityManager->publish($event);
321
+
322
+    }
323
+
324
+    /**
325
+     * @param IShare $share
326
+     * @return int
327
+     * @throws \Exception
328
+     */
329
+    protected function createMailShare(IShare $share) {
330
+        $share->setToken($this->generateToken());
331
+        $shareId = $this->addShareToDB(
332
+            $share->getNodeId(),
333
+            $share->getNodeType(),
334
+            $share->getSharedWith(),
335
+            $share->getSharedBy(),
336
+            $share->getShareOwner(),
337
+            $share->getPermissions(),
338
+            $share->getToken(),
339
+            $share->getPassword()
340
+        );
341
+
342
+        try {
343
+            $link = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare',
344
+                ['token' => $share->getToken()]);
345
+            $this->sendMailNotification(
346
+                $share->getNode()->getName(),
347
+                $link,
348
+                $share->getSharedBy(),
349
+                $share->getSharedWith()
350
+            );
351
+        } catch (HintException $hintException) {
352
+            $this->logger->error('Failed to send share by mail: ' . $hintException->getMessage());
353
+            $this->removeShareFromTable($shareId);
354
+            throw $hintException;
355
+        } catch (\Exception $e) {
356
+            $this->logger->error('Failed to send share by email: ' . $e->getMessage());
357
+            $this->removeShareFromTable($shareId);
358
+            throw new HintException('Failed to send share by mail',
359
+                $this->l->t('Failed to send share by email'));
360
+        }
361
+
362
+        return $shareId;
363
+
364
+    }
365
+
366
+    /**
367
+     * @param string $filename
368
+     * @param string $link
369
+     * @param string $initiator
370
+     * @param string $shareWith
371
+     * @throws \Exception If mail couldn't be sent
372
+     */
373
+    protected function sendMailNotification($filename,
374
+                                            $link,
375
+                                            $initiator,
376
+                                            $shareWith) {
377
+        $initiatorUser = $this->userManager->get($initiator);
378
+        $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
379
+        $subject = (string)$this->l->t('%s shared »%s« with you', array($initiatorDisplayName, $filename));
380
+
381
+        $message = $this->mailer->createMessage();
382
+
383
+        $emailTemplate = $this->mailer->createEMailTemplate();
384
+
385
+        $emailTemplate->addHeader();
386
+        $emailTemplate->addHeading($this->l->t('%s shared »%s« with you', [$initiatorDisplayName, $filename]), false);
387
+        $text = $this->l->t('%s shared »%s« with you.', [$initiatorDisplayName, $filename]);
388
+
389
+        $emailTemplate->addBodyText(
390
+            $text . ' ' . $this->l->t('Click the button below to open it.'),
391
+            $text
392
+        );
393
+        $emailTemplate->addBodyButton(
394
+            $this->l->t('Open »%s«', [$filename]),
395
+            $link
396
+        );
397
+
398
+        $message->setTo([$shareWith]);
399
+
400
+        // The "From" contains the sharers name
401
+        $instanceName = $this->defaults->getName();
402
+        $senderName = $this->l->t(
403
+            '%s via %s',
404
+            [
405
+                $initiatorDisplayName,
406
+                $instanceName
407
+            ]
408
+        );
409
+        $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
410
+
411
+        // The "Reply-To" is set to the sharer if an mail address is configured
412
+        // also the default footer contains a "Do not reply" which needs to be adjusted.
413
+        $initiatorEmail = $initiatorUser->getEMailAddress();
414
+        if($initiatorEmail !== null) {
415
+            $message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
416
+            $emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
417
+        } else {
418
+            $emailTemplate->addFooter();
419
+        }
420
+
421
+        $message->setSubject($subject);
422
+        $message->setPlainBody($emailTemplate->renderText());
423
+        $message->setHtmlBody($emailTemplate->renderHtml());
424
+        $this->mailer->send($message);
425
+    }
426
+
427
+    /**
428
+     * send password to recipient of a mail share
429
+     *
430
+     * @param IShare $share
431
+     * @param string $password
432
+     * @return bool
433
+     */
434
+    protected function sendPassword(IShare $share, $password) {
435
+
436
+        $filename = $share->getNode()->getName();
437
+        $initiator = $share->getSharedBy();
438
+        $shareWith = $share->getSharedWith();
439
+
440
+        if ($password === '' || $this->settingsManager->sendPasswordByMail() === false) {
441
+            return false;
442
+        }
443
+
444
+        $initiatorUser = $this->userManager->get($initiator);
445
+        $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
446
+        $initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
447
+
448
+        $subject = (string)$this->l->t('Password to access »%s« shared to you by %s', [$filename, $initiatorDisplayName]);
449
+        $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]);
450
+        $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]);
451
+
452
+        $message = $this->mailer->createMessage();
453
+
454
+        $emailTemplate = $this->mailer->createEMailTemplate();
455
+        $emailTemplate->addHeader();
456
+        $emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
457
+        $emailTemplate->addBodyText($htmlBodyPart, $plainBodyPart);
458
+        $emailTemplate->addBodyText($this->l->t('It is protected with the following password: %s', [$password]));
459
+
460
+        // The "From" contains the sharers name
461
+        $instanceName = $this->defaults->getName();
462
+        $senderName = $this->l->t(
463
+            '%s via %s',
464
+            [
465
+                $initiatorDisplayName,
466
+                $instanceName
467
+            ]
468
+        );
469
+        $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
470
+        if ($initiatorEmailAddress !== null) {
471
+            $message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
472
+            $emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
473
+        } else {
474
+            $emailTemplate->addFooter();
475
+        }
476
+
477
+        $message->setTo([$shareWith]);
478
+        $message->setSubject($subject);
479
+        $message->setBody($emailTemplate->renderText(), 'text/plain');
480
+        $message->setHtmlBody($emailTemplate->renderHtml());
481
+        $this->mailer->send($message);
482
+
483
+        $this->createPasswordSendActivity($share, $shareWith, false);
484
+
485
+        return true;
486
+    }
487
+
488
+    /**
489
+     * send auto generated password to the owner. This happens if the admin enforces
490
+     * a password for mail shares and forbid to send the password by mail to the recipient
491
+     *
492
+     * @param IShare $share
493
+     * @param string $password
494
+     * @return bool
495
+     * @throws \Exception
496
+     */
497
+    protected function sendPasswordToOwner(IShare $share, $password) {
498
+
499
+        $filename = $share->getNode()->getName();
500
+        $initiator = $this->userManager->get($share->getSharedBy());
501
+        $initiatorEMailAddress = ($initiator instanceof IUser) ? $initiator->getEMailAddress() : null;
502
+        $initiatorDisplayName = ($initiator instanceof IUser) ? $initiator->getDisplayName() : $share->getSharedBy();
503
+        $shareWith = $share->getSharedWith();
504
+
505
+        if ($initiatorEMailAddress === null) {
506
+            throw new \Exception(
507
+                $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.")
508
+            );
509
+        }
510
+
511
+        $subject = (string)$this->l->t('Password to access »%s« shared with %s', [$filename, $shareWith]);
512
+        $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()]);
513
+
514
+        $message = $this->mailer->createMessage();
515
+        $emailTemplate = $this->mailer->createEMailTemplate();
516
+
517
+        $emailTemplate->addHeader();
518
+        $emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
519
+        $emailTemplate->addBodyText($bodyPart);
520
+        $emailTemplate->addBodyText($this->l->t('This is the password: %s', [$password]));
521
+        $emailTemplate->addBodyText($this->l->t('You can choose a different password at any time in the share dialog.'));
522
+        $emailTemplate->addFooter();
523
+
524
+        if ($initiatorEMailAddress) {
525
+            $message->setFrom([$initiatorEMailAddress => $initiatorDisplayName]);
526
+        }
527
+        $message->setTo([$initiatorEMailAddress => $initiatorDisplayName]);
528
+        $message->setSubject($subject);
529
+        $message->setBody($emailTemplate->renderText(), 'text/plain');
530
+        $message->setHtmlBody($emailTemplate->renderHtml());
531
+        $this->mailer->send($message);
532
+
533
+        $this->createPasswordSendActivity($share, $shareWith, true);
534
+
535
+        return true;
536
+    }
537
+
538
+    /**
539
+     * generate share token
540
+     *
541
+     * @return string
542
+     */
543
+    protected function generateToken($size = 15) {
544
+        $token = $this->secureRandom->generate(
545
+            $size, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS);
546
+        return $token;
547
+    }
548
+
549
+    /**
550
+     * Get all children of this share
551
+     *
552
+     * @param IShare $parent
553
+     * @return IShare[]
554
+     */
555
+    public function getChildren(IShare $parent) {
556
+        $children = [];
557
+
558
+        $qb = $this->dbConnection->getQueryBuilder();
559
+        $qb->select('*')
560
+            ->from('share')
561
+            ->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
562
+            ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
563
+            ->orderBy('id');
564
+
565
+        $cursor = $qb->execute();
566
+        while($data = $cursor->fetch()) {
567
+            $children[] = $this->createShareObject($data);
568
+        }
569
+        $cursor->closeCursor();
570
+
571
+        return $children;
572
+    }
573
+
574
+    /**
575
+     * add share to the database and return the ID
576
+     *
577
+     * @param int $itemSource
578
+     * @param string $itemType
579
+     * @param string $shareWith
580
+     * @param string $sharedBy
581
+     * @param string $uidOwner
582
+     * @param int $permissions
583
+     * @param string $token
584
+     * @return int
585
+     */
586
+    protected function addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token, $password) {
587
+        $qb = $this->dbConnection->getQueryBuilder();
588
+        $qb->insert('share')
589
+            ->setValue('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))
590
+            ->setValue('item_type', $qb->createNamedParameter($itemType))
591
+            ->setValue('item_source', $qb->createNamedParameter($itemSource))
592
+            ->setValue('file_source', $qb->createNamedParameter($itemSource))
593
+            ->setValue('share_with', $qb->createNamedParameter($shareWith))
594
+            ->setValue('uid_owner', $qb->createNamedParameter($uidOwner))
595
+            ->setValue('uid_initiator', $qb->createNamedParameter($sharedBy))
596
+            ->setValue('permissions', $qb->createNamedParameter($permissions))
597
+            ->setValue('token', $qb->createNamedParameter($token))
598
+            ->setValue('password', $qb->createNamedParameter($password))
599
+            ->setValue('stime', $qb->createNamedParameter(time()));
600
+
601
+        /*
602 602
 		 * Added to fix https://github.com/owncloud/core/issues/22215
603 603
 		 * Can be removed once we get rid of ajax/share.php
604 604
 		 */
605
-		$qb->setValue('file_target', $qb->createNamedParameter(''));
605
+        $qb->setValue('file_target', $qb->createNamedParameter(''));
606 606
 
607
-		$qb->execute();
608
-		$id = $qb->getLastInsertId();
607
+        $qb->execute();
608
+        $id = $qb->getLastInsertId();
609 609
 
610
-		return (int)$id;
611
-	}
610
+        return (int)$id;
611
+    }
612 612
 
613
-	/**
614
-	 * Update a share
615
-	 *
616
-	 * @param IShare $share
617
-	 * @param string|null $plainTextPassword
618
-	 * @return IShare The share object
619
-	 */
620
-	public function update(IShare $share, $plainTextPassword = null) {
613
+    /**
614
+     * Update a share
615
+     *
616
+     * @param IShare $share
617
+     * @param string|null $plainTextPassword
618
+     * @return IShare The share object
619
+     */
620
+    public function update(IShare $share, $plainTextPassword = null) {
621 621
 
622
-		$originalShare = $this->getShareById($share->getId());
622
+        $originalShare = $this->getShareById($share->getId());
623 623
 
624
-		// a real password was given
625
-		$validPassword = $plainTextPassword !== null && $plainTextPassword !== '';
624
+        // a real password was given
625
+        $validPassword = $plainTextPassword !== null && $plainTextPassword !== '';
626 626
 
627
-		if($validPassword && $originalShare->getPassword() !== $share->getPassword()) {
628
-			$this->sendPassword($share, $plainTextPassword);
629
-		}
630
-		/*
627
+        if($validPassword && $originalShare->getPassword() !== $share->getPassword()) {
628
+            $this->sendPassword($share, $plainTextPassword);
629
+        }
630
+        /*
631 631
 		 * We allow updating the permissions and password of mail shares
632 632
 		 */
633
-		$qb = $this->dbConnection->getQueryBuilder();
634
-		$qb->update('share')
635
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
636
-			->set('permissions', $qb->createNamedParameter($share->getPermissions()))
637
-			->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
638
-			->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
639
-			->set('password', $qb->createNamedParameter($share->getPassword()))
640
-			->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
641
-			->execute();
642
-
643
-		return $share;
644
-	}
645
-
646
-	/**
647
-	 * @inheritdoc
648
-	 */
649
-	public function move(IShare $share, $recipient) {
650
-		/**
651
-		 * nothing to do here, mail shares are only outgoing shares
652
-		 */
653
-		return $share;
654
-	}
655
-
656
-	/**
657
-	 * Delete a share (owner unShares the file)
658
-	 *
659
-	 * @param IShare $share
660
-	 */
661
-	public function delete(IShare $share) {
662
-		$this->removeShareFromTable($share->getId());
663
-	}
664
-
665
-	/**
666
-	 * @inheritdoc
667
-	 */
668
-	public function deleteFromSelf(IShare $share, $recipient) {
669
-		// nothing to do here, mail shares are only outgoing shares
670
-		return;
671
-	}
672
-
673
-	/**
674
-	 * @inheritdoc
675
-	 */
676
-	public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
677
-		$qb = $this->dbConnection->getQueryBuilder();
678
-		$qb->select('*')
679
-			->from('share');
680
-
681
-		$qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
682
-
683
-		/**
684
-		 * Reshares for this user are shares where they are the owner.
685
-		 */
686
-		if ($reshares === false) {
687
-			//Special case for old shares created via the web UI
688
-			$or1 = $qb->expr()->andX(
689
-				$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
690
-				$qb->expr()->isNull('uid_initiator')
691
-			);
692
-
693
-			$qb->andWhere(
694
-				$qb->expr()->orX(
695
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)),
696
-					$or1
697
-				)
698
-			);
699
-		} else {
700
-			$qb->andWhere(
701
-				$qb->expr()->orX(
702
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
703
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
704
-				)
705
-			);
706
-		}
707
-
708
-		if ($node !== null) {
709
-			$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
710
-		}
711
-
712
-		if ($limit !== -1) {
713
-			$qb->setMaxResults($limit);
714
-		}
715
-
716
-		$qb->setFirstResult($offset);
717
-		$qb->orderBy('id');
718
-
719
-		$cursor = $qb->execute();
720
-		$shares = [];
721
-		while($data = $cursor->fetch()) {
722
-			$shares[] = $this->createShareObject($data);
723
-		}
724
-		$cursor->closeCursor();
725
-
726
-		return $shares;
727
-	}
728
-
729
-	/**
730
-	 * @inheritdoc
731
-	 */
732
-	public function getShareById($id, $recipientId = null) {
733
-		$qb = $this->dbConnection->getQueryBuilder();
734
-
735
-		$qb->select('*')
736
-			->from('share')
737
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
738
-			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
739
-
740
-		$cursor = $qb->execute();
741
-		$data = $cursor->fetch();
742
-		$cursor->closeCursor();
743
-
744
-		if ($data === false) {
745
-			throw new ShareNotFound();
746
-		}
747
-
748
-		try {
749
-			$share = $this->createShareObject($data);
750
-		} catch (InvalidShare $e) {
751
-			throw new ShareNotFound();
752
-		}
753
-
754
-		return $share;
755
-	}
756
-
757
-	/**
758
-	 * Get shares for a given path
759
-	 *
760
-	 * @param \OCP\Files\Node $path
761
-	 * @return IShare[]
762
-	 */
763
-	public function getSharesByPath(Node $path) {
764
-		$qb = $this->dbConnection->getQueryBuilder();
765
-
766
-		$cursor = $qb->select('*')
767
-			->from('share')
768
-			->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
769
-			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
770
-			->execute();
771
-
772
-		$shares = [];
773
-		while($data = $cursor->fetch()) {
774
-			$shares[] = $this->createShareObject($data);
775
-		}
776
-		$cursor->closeCursor();
777
-
778
-		return $shares;
779
-	}
780
-
781
-	/**
782
-	 * @inheritdoc
783
-	 */
784
-	public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
785
-		/** @var IShare[] $shares */
786
-		$shares = [];
787
-
788
-		//Get shares directly with this user
789
-		$qb = $this->dbConnection->getQueryBuilder();
790
-		$qb->select('*')
791
-			->from('share');
792
-
793
-		// Order by id
794
-		$qb->orderBy('id');
795
-
796
-		// Set limit and offset
797
-		if ($limit !== -1) {
798
-			$qb->setMaxResults($limit);
799
-		}
800
-		$qb->setFirstResult($offset);
801
-
802
-		$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
803
-		$qb->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)));
804
-
805
-		// Filter by node if provided
806
-		if ($node !== null) {
807
-			$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
808
-		}
809
-
810
-		$cursor = $qb->execute();
811
-
812
-		while($data = $cursor->fetch()) {
813
-			$shares[] = $this->createShareObject($data);
814
-		}
815
-		$cursor->closeCursor();
816
-
817
-
818
-		return $shares;
819
-	}
820
-
821
-	/**
822
-	 * Get a share by token
823
-	 *
824
-	 * @param string $token
825
-	 * @return IShare
826
-	 * @throws ShareNotFound
827
-	 */
828
-	public function getShareByToken($token) {
829
-		$qb = $this->dbConnection->getQueryBuilder();
830
-
831
-		$cursor = $qb->select('*')
832
-			->from('share')
833
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
834
-			->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
835
-			->execute();
836
-
837
-		$data = $cursor->fetch();
838
-
839
-		if ($data === false) {
840
-			throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
841
-		}
842
-
843
-		try {
844
-			$share = $this->createShareObject($data);
845
-		} catch (InvalidShare $e) {
846
-			throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
847
-		}
848
-
849
-		return $share;
850
-	}
851
-
852
-	/**
853
-	 * remove share from table
854
-	 *
855
-	 * @param string $shareId
856
-	 */
857
-	protected function removeShareFromTable($shareId) {
858
-		$qb = $this->dbConnection->getQueryBuilder();
859
-		$qb->delete('share')
860
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($shareId)));
861
-		$qb->execute();
862
-	}
863
-
864
-	/**
865
-	 * Create a share object from an database row
866
-	 *
867
-	 * @param array $data
868
-	 * @return IShare
869
-	 * @throws InvalidShare
870
-	 * @throws ShareNotFound
871
-	 */
872
-	protected function createShareObject($data) {
873
-
874
-		$share = new Share($this->rootFolder, $this->userManager);
875
-		$share->setId((int)$data['id'])
876
-			->setShareType((int)$data['share_type'])
877
-			->setPermissions((int)$data['permissions'])
878
-			->setTarget($data['file_target'])
879
-			->setMailSend((bool)$data['mail_send'])
880
-			->setToken($data['token']);
881
-
882
-		$shareTime = new \DateTime();
883
-		$shareTime->setTimestamp((int)$data['stime']);
884
-		$share->setShareTime($shareTime);
885
-		$share->setSharedWith($data['share_with']);
886
-		$share->setPassword($data['password']);
887
-
888
-		if ($data['uid_initiator'] !== null) {
889
-			$share->setShareOwner($data['uid_owner']);
890
-			$share->setSharedBy($data['uid_initiator']);
891
-		} else {
892
-			//OLD SHARE
893
-			$share->setSharedBy($data['uid_owner']);
894
-			$path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
895
-
896
-			$owner = $path->getOwner();
897
-			$share->setShareOwner($owner->getUID());
898
-		}
899
-
900
-		if ($data['expiration'] !== null) {
901
-			$expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']);
902
-			if ($expiration !== false) {
903
-				$share->setExpirationDate($expiration);
904
-			}
905
-		}
906
-
907
-		$share->setNodeId((int)$data['file_source']);
908
-		$share->setNodeType($data['item_type']);
909
-
910
-		$share->setProviderId($this->identifier());
911
-
912
-		return $share;
913
-	}
914
-
915
-	/**
916
-	 * Get the node with file $id for $user
917
-	 *
918
-	 * @param string $userId
919
-	 * @param int $id
920
-	 * @return \OCP\Files\File|\OCP\Files\Folder
921
-	 * @throws InvalidShare
922
-	 */
923
-	private function getNode($userId, $id) {
924
-		try {
925
-			$userFolder = $this->rootFolder->getUserFolder($userId);
926
-		} catch (NotFoundException $e) {
927
-			throw new InvalidShare();
928
-		}
929
-
930
-		$nodes = $userFolder->getById($id);
931
-
932
-		if (empty($nodes)) {
933
-			throw new InvalidShare();
934
-		}
935
-
936
-		return $nodes[0];
937
-	}
938
-
939
-	/**
940
-	 * A user is deleted from the system
941
-	 * So clean up the relevant shares.
942
-	 *
943
-	 * @param string $uid
944
-	 * @param int $shareType
945
-	 */
946
-	public function userDeleted($uid, $shareType) {
947
-		$qb = $this->dbConnection->getQueryBuilder();
948
-
949
-		$qb->delete('share')
950
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
951
-			->andWhere($qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)))
952
-			->execute();
953
-	}
954
-
955
-	/**
956
-	 * This provider does not support group shares
957
-	 *
958
-	 * @param string $gid
959
-	 */
960
-	public function groupDeleted($gid) {
961
-		return;
962
-	}
963
-
964
-	/**
965
-	 * This provider does not support group shares
966
-	 *
967
-	 * @param string $uid
968
-	 * @param string $gid
969
-	 */
970
-	public function userDeletedFromGroup($uid, $gid) {
971
-		return;
972
-	}
973
-
974
-	/**
975
-	 * get database row of a give share
976
-	 *
977
-	 * @param $id
978
-	 * @return array
979
-	 * @throws ShareNotFound
980
-	 */
981
-	protected function getRawShare($id) {
982
-
983
-		// Now fetch the inserted share and create a complete share object
984
-		$qb = $this->dbConnection->getQueryBuilder();
985
-		$qb->select('*')
986
-			->from('share')
987
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
988
-
989
-		$cursor = $qb->execute();
990
-		$data = $cursor->fetch();
991
-		$cursor->closeCursor();
992
-
993
-		if ($data === false) {
994
-			throw new ShareNotFound;
995
-		}
996
-
997
-		return $data;
998
-	}
999
-
1000
-	public function getSharesInFolder($userId, Folder $node, $reshares) {
1001
-		$qb = $this->dbConnection->getQueryBuilder();
1002
-		$qb->select('*')
1003
-			->from('share', 's')
1004
-			->andWhere($qb->expr()->orX(
1005
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1006
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1007
-			))
1008
-			->andWhere(
1009
-				$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))
1010
-			);
1011
-
1012
-		/**
1013
-		 * Reshares for this user are shares where they are the owner.
1014
-		 */
1015
-		if ($reshares === false) {
1016
-			$qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
1017
-		} else {
1018
-			$qb->andWhere(
1019
-				$qb->expr()->orX(
1020
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
1021
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
1022
-				)
1023
-			);
1024
-		}
1025
-
1026
-		$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1027
-		$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
1028
-
1029
-		$qb->orderBy('id');
1030
-
1031
-		$cursor = $qb->execute();
1032
-		$shares = [];
1033
-		while ($data = $cursor->fetch()) {
1034
-			$shares[$data['fileid']][] = $this->createShareObject($data);
1035
-		}
1036
-		$cursor->closeCursor();
1037
-
1038
-		return $shares;
1039
-	}
1040
-
1041
-	/**
1042
-	 * @inheritdoc
1043
-	 */
1044
-	public function getAccessList($nodes, $currentAccess) {
1045
-		$ids = [];
1046
-		foreach ($nodes as $node) {
1047
-			$ids[] = $node->getId();
1048
-		}
1049
-
1050
-		$qb = $this->dbConnection->getQueryBuilder();
1051
-		$qb->select('share_with')
1052
-			->from('share')
1053
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
1054
-			->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1055
-			->andWhere($qb->expr()->orX(
1056
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1057
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1058
-			))
1059
-			->setMaxResults(1);
1060
-		$cursor = $qb->execute();
1061
-
1062
-		$mail = $cursor->fetch() !== false;
1063
-		$cursor->closeCursor();
1064
-
1065
-		return ['public' => $mail];
1066
-	}
633
+        $qb = $this->dbConnection->getQueryBuilder();
634
+        $qb->update('share')
635
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
636
+            ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
637
+            ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
638
+            ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
639
+            ->set('password', $qb->createNamedParameter($share->getPassword()))
640
+            ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
641
+            ->execute();
642
+
643
+        return $share;
644
+    }
645
+
646
+    /**
647
+     * @inheritdoc
648
+     */
649
+    public function move(IShare $share, $recipient) {
650
+        /**
651
+         * nothing to do here, mail shares are only outgoing shares
652
+         */
653
+        return $share;
654
+    }
655
+
656
+    /**
657
+     * Delete a share (owner unShares the file)
658
+     *
659
+     * @param IShare $share
660
+     */
661
+    public function delete(IShare $share) {
662
+        $this->removeShareFromTable($share->getId());
663
+    }
664
+
665
+    /**
666
+     * @inheritdoc
667
+     */
668
+    public function deleteFromSelf(IShare $share, $recipient) {
669
+        // nothing to do here, mail shares are only outgoing shares
670
+        return;
671
+    }
672
+
673
+    /**
674
+     * @inheritdoc
675
+     */
676
+    public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
677
+        $qb = $this->dbConnection->getQueryBuilder();
678
+        $qb->select('*')
679
+            ->from('share');
680
+
681
+        $qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
682
+
683
+        /**
684
+         * Reshares for this user are shares where they are the owner.
685
+         */
686
+        if ($reshares === false) {
687
+            //Special case for old shares created via the web UI
688
+            $or1 = $qb->expr()->andX(
689
+                $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
690
+                $qb->expr()->isNull('uid_initiator')
691
+            );
692
+
693
+            $qb->andWhere(
694
+                $qb->expr()->orX(
695
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)),
696
+                    $or1
697
+                )
698
+            );
699
+        } else {
700
+            $qb->andWhere(
701
+                $qb->expr()->orX(
702
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
703
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
704
+                )
705
+            );
706
+        }
707
+
708
+        if ($node !== null) {
709
+            $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
710
+        }
711
+
712
+        if ($limit !== -1) {
713
+            $qb->setMaxResults($limit);
714
+        }
715
+
716
+        $qb->setFirstResult($offset);
717
+        $qb->orderBy('id');
718
+
719
+        $cursor = $qb->execute();
720
+        $shares = [];
721
+        while($data = $cursor->fetch()) {
722
+            $shares[] = $this->createShareObject($data);
723
+        }
724
+        $cursor->closeCursor();
725
+
726
+        return $shares;
727
+    }
728
+
729
+    /**
730
+     * @inheritdoc
731
+     */
732
+    public function getShareById($id, $recipientId = null) {
733
+        $qb = $this->dbConnection->getQueryBuilder();
734
+
735
+        $qb->select('*')
736
+            ->from('share')
737
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
738
+            ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
739
+
740
+        $cursor = $qb->execute();
741
+        $data = $cursor->fetch();
742
+        $cursor->closeCursor();
743
+
744
+        if ($data === false) {
745
+            throw new ShareNotFound();
746
+        }
747
+
748
+        try {
749
+            $share = $this->createShareObject($data);
750
+        } catch (InvalidShare $e) {
751
+            throw new ShareNotFound();
752
+        }
753
+
754
+        return $share;
755
+    }
756
+
757
+    /**
758
+     * Get shares for a given path
759
+     *
760
+     * @param \OCP\Files\Node $path
761
+     * @return IShare[]
762
+     */
763
+    public function getSharesByPath(Node $path) {
764
+        $qb = $this->dbConnection->getQueryBuilder();
765
+
766
+        $cursor = $qb->select('*')
767
+            ->from('share')
768
+            ->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
769
+            ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
770
+            ->execute();
771
+
772
+        $shares = [];
773
+        while($data = $cursor->fetch()) {
774
+            $shares[] = $this->createShareObject($data);
775
+        }
776
+        $cursor->closeCursor();
777
+
778
+        return $shares;
779
+    }
780
+
781
+    /**
782
+     * @inheritdoc
783
+     */
784
+    public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
785
+        /** @var IShare[] $shares */
786
+        $shares = [];
787
+
788
+        //Get shares directly with this user
789
+        $qb = $this->dbConnection->getQueryBuilder();
790
+        $qb->select('*')
791
+            ->from('share');
792
+
793
+        // Order by id
794
+        $qb->orderBy('id');
795
+
796
+        // Set limit and offset
797
+        if ($limit !== -1) {
798
+            $qb->setMaxResults($limit);
799
+        }
800
+        $qb->setFirstResult($offset);
801
+
802
+        $qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
803
+        $qb->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)));
804
+
805
+        // Filter by node if provided
806
+        if ($node !== null) {
807
+            $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
808
+        }
809
+
810
+        $cursor = $qb->execute();
811
+
812
+        while($data = $cursor->fetch()) {
813
+            $shares[] = $this->createShareObject($data);
814
+        }
815
+        $cursor->closeCursor();
816
+
817
+
818
+        return $shares;
819
+    }
820
+
821
+    /**
822
+     * Get a share by token
823
+     *
824
+     * @param string $token
825
+     * @return IShare
826
+     * @throws ShareNotFound
827
+     */
828
+    public function getShareByToken($token) {
829
+        $qb = $this->dbConnection->getQueryBuilder();
830
+
831
+        $cursor = $qb->select('*')
832
+            ->from('share')
833
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
834
+            ->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
835
+            ->execute();
836
+
837
+        $data = $cursor->fetch();
838
+
839
+        if ($data === false) {
840
+            throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
841
+        }
842
+
843
+        try {
844
+            $share = $this->createShareObject($data);
845
+        } catch (InvalidShare $e) {
846
+            throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
847
+        }
848
+
849
+        return $share;
850
+    }
851
+
852
+    /**
853
+     * remove share from table
854
+     *
855
+     * @param string $shareId
856
+     */
857
+    protected function removeShareFromTable($shareId) {
858
+        $qb = $this->dbConnection->getQueryBuilder();
859
+        $qb->delete('share')
860
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($shareId)));
861
+        $qb->execute();
862
+    }
863
+
864
+    /**
865
+     * Create a share object from an database row
866
+     *
867
+     * @param array $data
868
+     * @return IShare
869
+     * @throws InvalidShare
870
+     * @throws ShareNotFound
871
+     */
872
+    protected function createShareObject($data) {
873
+
874
+        $share = new Share($this->rootFolder, $this->userManager);
875
+        $share->setId((int)$data['id'])
876
+            ->setShareType((int)$data['share_type'])
877
+            ->setPermissions((int)$data['permissions'])
878
+            ->setTarget($data['file_target'])
879
+            ->setMailSend((bool)$data['mail_send'])
880
+            ->setToken($data['token']);
881
+
882
+        $shareTime = new \DateTime();
883
+        $shareTime->setTimestamp((int)$data['stime']);
884
+        $share->setShareTime($shareTime);
885
+        $share->setSharedWith($data['share_with']);
886
+        $share->setPassword($data['password']);
887
+
888
+        if ($data['uid_initiator'] !== null) {
889
+            $share->setShareOwner($data['uid_owner']);
890
+            $share->setSharedBy($data['uid_initiator']);
891
+        } else {
892
+            //OLD SHARE
893
+            $share->setSharedBy($data['uid_owner']);
894
+            $path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
895
+
896
+            $owner = $path->getOwner();
897
+            $share->setShareOwner($owner->getUID());
898
+        }
899
+
900
+        if ($data['expiration'] !== null) {
901
+            $expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']);
902
+            if ($expiration !== false) {
903
+                $share->setExpirationDate($expiration);
904
+            }
905
+        }
906
+
907
+        $share->setNodeId((int)$data['file_source']);
908
+        $share->setNodeType($data['item_type']);
909
+
910
+        $share->setProviderId($this->identifier());
911
+
912
+        return $share;
913
+    }
914
+
915
+    /**
916
+     * Get the node with file $id for $user
917
+     *
918
+     * @param string $userId
919
+     * @param int $id
920
+     * @return \OCP\Files\File|\OCP\Files\Folder
921
+     * @throws InvalidShare
922
+     */
923
+    private function getNode($userId, $id) {
924
+        try {
925
+            $userFolder = $this->rootFolder->getUserFolder($userId);
926
+        } catch (NotFoundException $e) {
927
+            throw new InvalidShare();
928
+        }
929
+
930
+        $nodes = $userFolder->getById($id);
931
+
932
+        if (empty($nodes)) {
933
+            throw new InvalidShare();
934
+        }
935
+
936
+        return $nodes[0];
937
+    }
938
+
939
+    /**
940
+     * A user is deleted from the system
941
+     * So clean up the relevant shares.
942
+     *
943
+     * @param string $uid
944
+     * @param int $shareType
945
+     */
946
+    public function userDeleted($uid, $shareType) {
947
+        $qb = $this->dbConnection->getQueryBuilder();
948
+
949
+        $qb->delete('share')
950
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
951
+            ->andWhere($qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)))
952
+            ->execute();
953
+    }
954
+
955
+    /**
956
+     * This provider does not support group shares
957
+     *
958
+     * @param string $gid
959
+     */
960
+    public function groupDeleted($gid) {
961
+        return;
962
+    }
963
+
964
+    /**
965
+     * This provider does not support group shares
966
+     *
967
+     * @param string $uid
968
+     * @param string $gid
969
+     */
970
+    public function userDeletedFromGroup($uid, $gid) {
971
+        return;
972
+    }
973
+
974
+    /**
975
+     * get database row of a give share
976
+     *
977
+     * @param $id
978
+     * @return array
979
+     * @throws ShareNotFound
980
+     */
981
+    protected function getRawShare($id) {
982
+
983
+        // Now fetch the inserted share and create a complete share object
984
+        $qb = $this->dbConnection->getQueryBuilder();
985
+        $qb->select('*')
986
+            ->from('share')
987
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
988
+
989
+        $cursor = $qb->execute();
990
+        $data = $cursor->fetch();
991
+        $cursor->closeCursor();
992
+
993
+        if ($data === false) {
994
+            throw new ShareNotFound;
995
+        }
996
+
997
+        return $data;
998
+    }
999
+
1000
+    public function getSharesInFolder($userId, Folder $node, $reshares) {
1001
+        $qb = $this->dbConnection->getQueryBuilder();
1002
+        $qb->select('*')
1003
+            ->from('share', 's')
1004
+            ->andWhere($qb->expr()->orX(
1005
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1006
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1007
+            ))
1008
+            ->andWhere(
1009
+                $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))
1010
+            );
1011
+
1012
+        /**
1013
+         * Reshares for this user are shares where they are the owner.
1014
+         */
1015
+        if ($reshares === false) {
1016
+            $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
1017
+        } else {
1018
+            $qb->andWhere(
1019
+                $qb->expr()->orX(
1020
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
1021
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
1022
+                )
1023
+            );
1024
+        }
1025
+
1026
+        $qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1027
+        $qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
1028
+
1029
+        $qb->orderBy('id');
1030
+
1031
+        $cursor = $qb->execute();
1032
+        $shares = [];
1033
+        while ($data = $cursor->fetch()) {
1034
+            $shares[$data['fileid']][] = $this->createShareObject($data);
1035
+        }
1036
+        $cursor->closeCursor();
1037
+
1038
+        return $shares;
1039
+    }
1040
+
1041
+    /**
1042
+     * @inheritdoc
1043
+     */
1044
+    public function getAccessList($nodes, $currentAccess) {
1045
+        $ids = [];
1046
+        foreach ($nodes as $node) {
1047
+            $ids[] = $node->getId();
1048
+        }
1049
+
1050
+        $qb = $this->dbConnection->getQueryBuilder();
1051
+        $qb->select('share_with')
1052
+            ->from('share')
1053
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
1054
+            ->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1055
+            ->andWhere($qb->expr()->orX(
1056
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1057
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1058
+            ))
1059
+            ->setMaxResults(1);
1060
+        $cursor = $qb->execute();
1061
+
1062
+        $mail = $cursor->fetch() !== false;
1063
+        $cursor->closeCursor();
1064
+
1065
+        return ['public' => $mail];
1066
+    }
1067 1067
 
1068 1068
 }
Please login to merge, or discard this patch.
Spacing   +26 added lines, -26 removed lines patch added patch discarded remove patch
@@ -209,10 +209,10 @@  discard block
 block discarded – undo
209 209
 		}
210 210
 
211 211
 		$passwordPolicy = $this->getPasswordPolicy();
212
-		$passwordCharset = ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS;
212
+		$passwordCharset = ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_UPPER.ISecureRandom::CHAR_DIGITS;
213 213
 		$passwordLength = 8;
214 214
 		if (!empty($passwordPolicy)) {
215
-			$passwordLength = (int)$passwordPolicy['minLength'] > 0 ? (int)$passwordPolicy['minLength'] : $passwordLength;
215
+			$passwordLength = (int) $passwordPolicy['minLength'] > 0 ? (int) $passwordPolicy['minLength'] : $passwordLength;
216 216
 			$passwordCharset .= $passwordPolicy['enforceSpecialCharacters'] ? ISecureRandom::CHAR_SYMBOLS : '';
217 217
 		}
218 218
 
@@ -349,11 +349,11 @@  discard block
 block discarded – undo
349 349
 				$share->getSharedWith()
350 350
 			);
351 351
 		} catch (HintException $hintException) {
352
-			$this->logger->error('Failed to send share by mail: ' . $hintException->getMessage());
352
+			$this->logger->error('Failed to send share by mail: '.$hintException->getMessage());
353 353
 			$this->removeShareFromTable($shareId);
354 354
 			throw $hintException;
355 355
 		} catch (\Exception $e) {
356
-			$this->logger->error('Failed to send share by email: ' . $e->getMessage());
356
+			$this->logger->error('Failed to send share by email: '.$e->getMessage());
357 357
 			$this->removeShareFromTable($shareId);
358 358
 			throw new HintException('Failed to send share by mail',
359 359
 				$this->l->t('Failed to send share by email'));
@@ -376,7 +376,7 @@  discard block
 block discarded – undo
376 376
 											$shareWith) {
377 377
 		$initiatorUser = $this->userManager->get($initiator);
378 378
 		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
379
-		$subject = (string)$this->l->t('%s shared »%s« with you', array($initiatorDisplayName, $filename));
379
+		$subject = (string) $this->l->t('%s shared »%s« with you', array($initiatorDisplayName, $filename));
380 380
 
381 381
 		$message = $this->mailer->createMessage();
382 382
 
@@ -387,7 +387,7 @@  discard block
 block discarded – undo
387 387
 		$text = $this->l->t('%s shared »%s« with you.', [$initiatorDisplayName, $filename]);
388 388
 
389 389
 		$emailTemplate->addBodyText(
390
-			$text . ' ' . $this->l->t('Click the button below to open it.'),
390
+			$text.' '.$this->l->t('Click the button below to open it.'),
391 391
 			$text
392 392
 		);
393 393
 		$emailTemplate->addBodyButton(
@@ -411,9 +411,9 @@  discard block
 block discarded – undo
411 411
 		// The "Reply-To" is set to the sharer if an mail address is configured
412 412
 		// also the default footer contains a "Do not reply" which needs to be adjusted.
413 413
 		$initiatorEmail = $initiatorUser->getEMailAddress();
414
-		if($initiatorEmail !== null) {
414
+		if ($initiatorEmail !== null) {
415 415
 			$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
416
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
416
+			$emailTemplate->addFooter($instanceName.' - '.$this->defaults->getSlogan());
417 417
 		} else {
418 418
 			$emailTemplate->addFooter();
419 419
 		}
@@ -445,7 +445,7 @@  discard block
 block discarded – undo
445 445
 		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
446 446
 		$initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
447 447
 
448
-		$subject = (string)$this->l->t('Password to access »%s« shared to you by %s', [$filename, $initiatorDisplayName]);
448
+		$subject = (string) $this->l->t('Password to access »%s« shared to you by %s', [$filename, $initiatorDisplayName]);
449 449
 		$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]);
450 450
 		$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]);
451 451
 
@@ -469,7 +469,7 @@  discard block
 block discarded – undo
469 469
 		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
470 470
 		if ($initiatorEmailAddress !== null) {
471 471
 			$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
472
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
472
+			$emailTemplate->addFooter($instanceName.' - '.$this->defaults->getSlogan());
473 473
 		} else {
474 474
 			$emailTemplate->addFooter();
475 475
 		}
@@ -508,7 +508,7 @@  discard block
 block discarded – undo
508 508
 			);
509 509
 		}
510 510
 
511
-		$subject = (string)$this->l->t('Password to access »%s« shared with %s', [$filename, $shareWith]);
511
+		$subject = (string) $this->l->t('Password to access »%s« shared with %s', [$filename, $shareWith]);
512 512
 		$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()]);
513 513
 
514 514
 		$message = $this->mailer->createMessage();
@@ -542,7 +542,7 @@  discard block
 block discarded – undo
542 542
 	 */
543 543
 	protected function generateToken($size = 15) {
544 544
 		$token = $this->secureRandom->generate(
545
-			$size, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS);
545
+			$size, ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_UPPER.ISecureRandom::CHAR_DIGITS);
546 546
 		return $token;
547 547
 	}
548 548
 
@@ -563,7 +563,7 @@  discard block
 block discarded – undo
563 563
 			->orderBy('id');
564 564
 
565 565
 		$cursor = $qb->execute();
566
-		while($data = $cursor->fetch()) {
566
+		while ($data = $cursor->fetch()) {
567 567
 			$children[] = $this->createShareObject($data);
568 568
 		}
569 569
 		$cursor->closeCursor();
@@ -607,7 +607,7 @@  discard block
 block discarded – undo
607 607
 		$qb->execute();
608 608
 		$id = $qb->getLastInsertId();
609 609
 
610
-		return (int)$id;
610
+		return (int) $id;
611 611
 	}
612 612
 
613 613
 	/**
@@ -624,7 +624,7 @@  discard block
 block discarded – undo
624 624
 		// a real password was given
625 625
 		$validPassword = $plainTextPassword !== null && $plainTextPassword !== '';
626 626
 
627
-		if($validPassword && $originalShare->getPassword() !== $share->getPassword()) {
627
+		if ($validPassword && $originalShare->getPassword() !== $share->getPassword()) {
628 628
 			$this->sendPassword($share, $plainTextPassword);
629 629
 		}
630 630
 		/*
@@ -718,7 +718,7 @@  discard block
 block discarded – undo
718 718
 
719 719
 		$cursor = $qb->execute();
720 720
 		$shares = [];
721
-		while($data = $cursor->fetch()) {
721
+		while ($data = $cursor->fetch()) {
722 722
 			$shares[] = $this->createShareObject($data);
723 723
 		}
724 724
 		$cursor->closeCursor();
@@ -770,7 +770,7 @@  discard block
 block discarded – undo
770 770
 			->execute();
771 771
 
772 772
 		$shares = [];
773
-		while($data = $cursor->fetch()) {
773
+		while ($data = $cursor->fetch()) {
774 774
 			$shares[] = $this->createShareObject($data);
775 775
 		}
776 776
 		$cursor->closeCursor();
@@ -809,7 +809,7 @@  discard block
 block discarded – undo
809 809
 
810 810
 		$cursor = $qb->execute();
811 811
 
812
-		while($data = $cursor->fetch()) {
812
+		while ($data = $cursor->fetch()) {
813 813
 			$shares[] = $this->createShareObject($data);
814 814
 		}
815 815
 		$cursor->closeCursor();
@@ -872,15 +872,15 @@  discard block
 block discarded – undo
872 872
 	protected function createShareObject($data) {
873 873
 
874 874
 		$share = new Share($this->rootFolder, $this->userManager);
875
-		$share->setId((int)$data['id'])
876
-			->setShareType((int)$data['share_type'])
877
-			->setPermissions((int)$data['permissions'])
875
+		$share->setId((int) $data['id'])
876
+			->setShareType((int) $data['share_type'])
877
+			->setPermissions((int) $data['permissions'])
878 878
 			->setTarget($data['file_target'])
879
-			->setMailSend((bool)$data['mail_send'])
879
+			->setMailSend((bool) $data['mail_send'])
880 880
 			->setToken($data['token']);
881 881
 
882 882
 		$shareTime = new \DateTime();
883
-		$shareTime->setTimestamp((int)$data['stime']);
883
+		$shareTime->setTimestamp((int) $data['stime']);
884 884
 		$share->setShareTime($shareTime);
885 885
 		$share->setSharedWith($data['share_with']);
886 886
 		$share->setPassword($data['password']);
@@ -891,7 +891,7 @@  discard block
 block discarded – undo
891 891
 		} else {
892 892
 			//OLD SHARE
893 893
 			$share->setSharedBy($data['uid_owner']);
894
-			$path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
894
+			$path = $this->getNode($share->getSharedBy(), (int) $data['file_source']);
895 895
 
896 896
 			$owner = $path->getOwner();
897 897
 			$share->setShareOwner($owner->getUID());
@@ -904,7 +904,7 @@  discard block
 block discarded – undo
904 904
 			}
905 905
 		}
906 906
 
907
-		$share->setNodeId((int)$data['file_source']);
907
+		$share->setNodeId((int) $data['file_source']);
908 908
 		$share->setNodeType($data['item_type']);
909 909
 
910 910
 		$share->setProviderId($this->identifier());
@@ -1023,7 +1023,7 @@  discard block
 block discarded – undo
1023 1023
 			);
1024 1024
 		}
1025 1025
 
1026
-		$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1026
+		$qb->innerJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1027 1027
 		$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
1028 1028
 
1029 1029
 		$qb->orderBy('id');
Please login to merge, or discard this patch.