Completed
Pull Request — master (#4692)
by Björn
46:43 queued 33:22
created
apps/sharebymail/lib/ShareByMailProvider.php 2 patches
Indentation   +989 added lines, -989 removed lines patch added patch discarded remove patch
@@ -52,1007 +52,1007 @@
 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->getShareOwner(),
349
-				$share->getSharedBy(),
350
-				$share->getSharedWith()
351
-			);
352
-		} catch (HintException $hintException) {
353
-			$this->logger->error('Failed to send share by mail: ' . $hintException->getMessage());
354
-			$this->removeShareFromTable($shareId);
355
-			throw $hintException;
356
-		} catch (\Exception $e) {
357
-			$this->logger->error('Failed to send share by mail: ' . $e->getMessage());
358
-			$this->removeShareFromTable($shareId);
359
-			throw new HintException('Failed to send share by mail',
360
-				$this->l->t('Failed to send share by E-mail'));
361
-		}
362
-
363
-		return $shareId;
364
-
365
-	}
366
-
367
-	/**
368
-	 * @param string $filename
369
-	 * @param string $link
370
-	 * @param string $owner
371
-	 * @param string $initiator
372
-	 * @param string $shareWith
373
-	 * @throws \Exception If mail couldn't be sent
374
-	 */
375
-	protected function sendMailNotification($filename,
376
-											$link,
377
-											$owner,
378
-											$initiator,
379
-											$shareWith) {
380
-		$initiatorUser = $this->userManager->get($initiator);
381
-		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
382
-		$subject = (string)$this->l->t('%s shared »%s« with you', array($initiatorDisplayName, $filename));
383
-
384
-		$message = $this->mailer->createMessage();
385
-
386
-		$emailTemplate = $this->mailer->createEMailTemplate();
387
-
388
-		$emailTemplate->addHeader();
389
-		$emailTemplate->addHeading($this->l->t('%s shared »%s« with you', [$initiatorDisplayName, $filename]), false);
390
-		$text = $this->l->t('%s shared »%s« with you.', [$initiatorDisplayName, $filename]);
391
-
392
-		$emailTemplate->addBodyText(
393
-			$text . ' ' . $this->l->t('Click the button below to open it.'),
394
-			$text
395
-		);
396
-		$emailTemplate->addBodyButton(
397
-			$this->l->t('Open »%s«', [$filename]),
398
-			$link
399
-		);
400
-
401
-		$message->setTo([$shareWith]);
402
-
403
-		// The "From" contains the sharers name
404
-		$instanceName = $this->defaults->getName();
405
-		$senderName = $this->l->t(
406
-			'%s via %s',
407
-			[
408
-				$initiatorDisplayName,
409
-				$instanceName
410
-			]
411
-		);
412
-		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
413
-
414
-		// The "Reply-To" is set to the sharer if an mail address is configured
415
-		// also the default footer contains a "Do not reply" which needs to be adjusted.
416
-		$initiatorEmail = $initiatorUser->getEMailAddress();
417
-		if($initiatorEmail !== null) {
418
-			$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
419
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
420
-		} else {
421
-			$emailTemplate->addFooter();
422
-		}
423
-
424
-		$message->setSubject($subject);
425
-		$message->setPlainBody($emailTemplate->renderText());
426
-		$message->setHtmlBody($emailTemplate->renderHtml());
427
-		$this->mailer->send($message);
428
-	}
429
-
430
-	/**
431
-	 * send password to recipient of a mail share
432
-	 *
433
-	 * @param IShare $share
434
-	 * @param string $password
435
-	 * @return bool
436
-	 */
437
-	protected function sendPassword(IShare $share, $password) {
438
-
439
-		$filename = $share->getNode()->getName();
440
-		$initiator = $share->getSharedBy();
441
-		$shareWith = $share->getSharedWith();
442
-
443
-		if ($password === '' || $this->settingsManager->sendPasswordByMail() === false) {
444
-			return false;
445
-		}
446
-
447
-		$initiatorUser = $this->userManager->get($initiator);
448
-		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
449
-		$initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
450
-
451
-		$subject = (string)$this->l->t('Password to access »%s« shared to you by %s', [$filename, $initiatorDisplayName]);
452
-		$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]);
453
-		$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]);
454
-
455
-		$message = $this->mailer->createMessage();
456
-
457
-		$emailTemplate = $this->mailer->createEMailTemplate();
458
-		$emailTemplate->addHeader();
459
-		$emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
460
-		$emailTemplate->addBodyText($htmlBodyPart, $plainBodyPart);
461
-		$emailTemplate->addBodyText($this->l->t('It is protected with the following password: %s', [$password]));
462
-		$emailTemplate->addFooter();
463
-
464
-		if ($initiatorEmailAddress !== null) {
465
-			$message->setFrom([$initiatorEmailAddress => $initiatorDisplayName]);
466
-		}
467
-		$message->setTo([$shareWith]);
468
-		$message->setSubject($subject);
469
-		$message->setBody($emailTemplate->renderText(), 'text/plain');
470
-		$message->setHtmlBody($emailTemplate->renderHtml());
471
-		$this->mailer->send($message);
472
-
473
-		$this->createPasswordSendActivity($share, $shareWith, false);
474
-
475
-		return true;
476
-	}
477
-
478
-	/**
479
-	 * send auto generated password to the owner. This happens if the admin enforces
480
-	 * a password for mail shares and forbid to send the password by mail to the recipient
481
-	 *
482
-	 * @param IShare $share
483
-	 * @param string $password
484
-	 * @return bool
485
-	 * @throws \Exception
486
-	 */
487
-	protected function sendPasswordToOwner(IShare $share, $password) {
488
-
489
-		$filename = $share->getNode()->getName();
490
-		$initiator = $this->userManager->get($share->getSharedBy());
491
-		$initiatorEMailAddress = ($initiator instanceof IUser) ? $initiator->getEMailAddress() : null;
492
-		$initiatorDisplayName = ($initiator instanceof IUser) ? $initiator->getDisplayName() : $share->getSharedBy();
493
-		$shareWith = $share->getSharedWith();
494
-
495
-		if ($initiatorEMailAddress === null) {
496
-			throw new \Exception(
497
-				$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.")
498
-			);
499
-		}
500
-
501
-		$subject = (string)$this->l->t('Password to access »%s« shared with %s', [$filename, $shareWith]);
502
-		$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()]);
503
-
504
-		$message = $this->mailer->createMessage();
505
-		$emailTemplate = $this->mailer->createEMailTemplate();
506
-
507
-		$emailTemplate->addHeader();
508
-		$emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
509
-		$emailTemplate->addBodyText($bodyPart);
510
-		$emailTemplate->addBodyText($this->l->t('This is the password: %s', [$password]));
511
-		$emailTemplate->addBodyText($this->l->t('You can choose a different password at any time in the share dialog.'));
512
-		$emailTemplate->addFooter();
513
-
514
-		if ($initiatorEMailAddress) {
515
-			$message->setFrom([$initiatorEMailAddress => $initiatorDisplayName]);
516
-		}
517
-		$message->setTo([$initiatorEMailAddress => $initiatorDisplayName]);
518
-		$message->setSubject($subject);
519
-		$message->setBody($emailTemplate->renderText(), 'text/plain');
520
-		$message->setHtmlBody($emailTemplate->renderHtml());
521
-		$this->mailer->send($message);
522
-
523
-		$this->createPasswordSendActivity($share, $shareWith, true);
524
-
525
-		return true;
526
-	}
527
-
528
-	/**
529
-	 * generate share token
530
-	 *
531
-	 * @return string
532
-	 */
533
-	protected function generateToken($size = 15) {
534
-		$token = $this->secureRandom->generate(
535
-			$size, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS);
536
-		return $token;
537
-	}
538
-
539
-	/**
540
-	 * Get all children of this share
541
-	 *
542
-	 * @param IShare $parent
543
-	 * @return IShare[]
544
-	 */
545
-	public function getChildren(IShare $parent) {
546
-		$children = [];
547
-
548
-		$qb = $this->dbConnection->getQueryBuilder();
549
-		$qb->select('*')
550
-			->from('share')
551
-			->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
552
-			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
553
-			->orderBy('id');
554
-
555
-		$cursor = $qb->execute();
556
-		while($data = $cursor->fetch()) {
557
-			$children[] = $this->createShareObject($data);
558
-		}
559
-		$cursor->closeCursor();
560
-
561
-		return $children;
562
-	}
563
-
564
-	/**
565
-	 * add share to the database and return the ID
566
-	 *
567
-	 * @param int $itemSource
568
-	 * @param string $itemType
569
-	 * @param string $shareWith
570
-	 * @param string $sharedBy
571
-	 * @param string $uidOwner
572
-	 * @param int $permissions
573
-	 * @param string $token
574
-	 * @return int
575
-	 */
576
-	protected function addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token, $password) {
577
-		$qb = $this->dbConnection->getQueryBuilder();
578
-		$qb->insert('share')
579
-			->setValue('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))
580
-			->setValue('item_type', $qb->createNamedParameter($itemType))
581
-			->setValue('item_source', $qb->createNamedParameter($itemSource))
582
-			->setValue('file_source', $qb->createNamedParameter($itemSource))
583
-			->setValue('share_with', $qb->createNamedParameter($shareWith))
584
-			->setValue('uid_owner', $qb->createNamedParameter($uidOwner))
585
-			->setValue('uid_initiator', $qb->createNamedParameter($sharedBy))
586
-			->setValue('permissions', $qb->createNamedParameter($permissions))
587
-			->setValue('token', $qb->createNamedParameter($token))
588
-			->setValue('password', $qb->createNamedParameter($password))
589
-			->setValue('stime', $qb->createNamedParameter(time()));
590
-
591
-		/*
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->getShareOwner(),
349
+                $share->getSharedBy(),
350
+                $share->getSharedWith()
351
+            );
352
+        } catch (HintException $hintException) {
353
+            $this->logger->error('Failed to send share by mail: ' . $hintException->getMessage());
354
+            $this->removeShareFromTable($shareId);
355
+            throw $hintException;
356
+        } catch (\Exception $e) {
357
+            $this->logger->error('Failed to send share by mail: ' . $e->getMessage());
358
+            $this->removeShareFromTable($shareId);
359
+            throw new HintException('Failed to send share by mail',
360
+                $this->l->t('Failed to send share by E-mail'));
361
+        }
362
+
363
+        return $shareId;
364
+
365
+    }
366
+
367
+    /**
368
+     * @param string $filename
369
+     * @param string $link
370
+     * @param string $owner
371
+     * @param string $initiator
372
+     * @param string $shareWith
373
+     * @throws \Exception If mail couldn't be sent
374
+     */
375
+    protected function sendMailNotification($filename,
376
+                                            $link,
377
+                                            $owner,
378
+                                            $initiator,
379
+                                            $shareWith) {
380
+        $initiatorUser = $this->userManager->get($initiator);
381
+        $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
382
+        $subject = (string)$this->l->t('%s shared »%s« with you', array($initiatorDisplayName, $filename));
383
+
384
+        $message = $this->mailer->createMessage();
385
+
386
+        $emailTemplate = $this->mailer->createEMailTemplate();
387
+
388
+        $emailTemplate->addHeader();
389
+        $emailTemplate->addHeading($this->l->t('%s shared »%s« with you', [$initiatorDisplayName, $filename]), false);
390
+        $text = $this->l->t('%s shared »%s« with you.', [$initiatorDisplayName, $filename]);
391
+
392
+        $emailTemplate->addBodyText(
393
+            $text . ' ' . $this->l->t('Click the button below to open it.'),
394
+            $text
395
+        );
396
+        $emailTemplate->addBodyButton(
397
+            $this->l->t('Open »%s«', [$filename]),
398
+            $link
399
+        );
400
+
401
+        $message->setTo([$shareWith]);
402
+
403
+        // The "From" contains the sharers name
404
+        $instanceName = $this->defaults->getName();
405
+        $senderName = $this->l->t(
406
+            '%s via %s',
407
+            [
408
+                $initiatorDisplayName,
409
+                $instanceName
410
+            ]
411
+        );
412
+        $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
413
+
414
+        // The "Reply-To" is set to the sharer if an mail address is configured
415
+        // also the default footer contains a "Do not reply" which needs to be adjusted.
416
+        $initiatorEmail = $initiatorUser->getEMailAddress();
417
+        if($initiatorEmail !== null) {
418
+            $message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
419
+            $emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
420
+        } else {
421
+            $emailTemplate->addFooter();
422
+        }
423
+
424
+        $message->setSubject($subject);
425
+        $message->setPlainBody($emailTemplate->renderText());
426
+        $message->setHtmlBody($emailTemplate->renderHtml());
427
+        $this->mailer->send($message);
428
+    }
429
+
430
+    /**
431
+     * send password to recipient of a mail share
432
+     *
433
+     * @param IShare $share
434
+     * @param string $password
435
+     * @return bool
436
+     */
437
+    protected function sendPassword(IShare $share, $password) {
438
+
439
+        $filename = $share->getNode()->getName();
440
+        $initiator = $share->getSharedBy();
441
+        $shareWith = $share->getSharedWith();
442
+
443
+        if ($password === '' || $this->settingsManager->sendPasswordByMail() === false) {
444
+            return false;
445
+        }
446
+
447
+        $initiatorUser = $this->userManager->get($initiator);
448
+        $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
449
+        $initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
450
+
451
+        $subject = (string)$this->l->t('Password to access »%s« shared to you by %s', [$filename, $initiatorDisplayName]);
452
+        $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]);
453
+        $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]);
454
+
455
+        $message = $this->mailer->createMessage();
456
+
457
+        $emailTemplate = $this->mailer->createEMailTemplate();
458
+        $emailTemplate->addHeader();
459
+        $emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
460
+        $emailTemplate->addBodyText($htmlBodyPart, $plainBodyPart);
461
+        $emailTemplate->addBodyText($this->l->t('It is protected with the following password: %s', [$password]));
462
+        $emailTemplate->addFooter();
463
+
464
+        if ($initiatorEmailAddress !== null) {
465
+            $message->setFrom([$initiatorEmailAddress => $initiatorDisplayName]);
466
+        }
467
+        $message->setTo([$shareWith]);
468
+        $message->setSubject($subject);
469
+        $message->setBody($emailTemplate->renderText(), 'text/plain');
470
+        $message->setHtmlBody($emailTemplate->renderHtml());
471
+        $this->mailer->send($message);
472
+
473
+        $this->createPasswordSendActivity($share, $shareWith, false);
474
+
475
+        return true;
476
+    }
477
+
478
+    /**
479
+     * send auto generated password to the owner. This happens if the admin enforces
480
+     * a password for mail shares and forbid to send the password by mail to the recipient
481
+     *
482
+     * @param IShare $share
483
+     * @param string $password
484
+     * @return bool
485
+     * @throws \Exception
486
+     */
487
+    protected function sendPasswordToOwner(IShare $share, $password) {
488
+
489
+        $filename = $share->getNode()->getName();
490
+        $initiator = $this->userManager->get($share->getSharedBy());
491
+        $initiatorEMailAddress = ($initiator instanceof IUser) ? $initiator->getEMailAddress() : null;
492
+        $initiatorDisplayName = ($initiator instanceof IUser) ? $initiator->getDisplayName() : $share->getSharedBy();
493
+        $shareWith = $share->getSharedWith();
494
+
495
+        if ($initiatorEMailAddress === null) {
496
+            throw new \Exception(
497
+                $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.")
498
+            );
499
+        }
500
+
501
+        $subject = (string)$this->l->t('Password to access »%s« shared with %s', [$filename, $shareWith]);
502
+        $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()]);
503
+
504
+        $message = $this->mailer->createMessage();
505
+        $emailTemplate = $this->mailer->createEMailTemplate();
506
+
507
+        $emailTemplate->addHeader();
508
+        $emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
509
+        $emailTemplate->addBodyText($bodyPart);
510
+        $emailTemplate->addBodyText($this->l->t('This is the password: %s', [$password]));
511
+        $emailTemplate->addBodyText($this->l->t('You can choose a different password at any time in the share dialog.'));
512
+        $emailTemplate->addFooter();
513
+
514
+        if ($initiatorEMailAddress) {
515
+            $message->setFrom([$initiatorEMailAddress => $initiatorDisplayName]);
516
+        }
517
+        $message->setTo([$initiatorEMailAddress => $initiatorDisplayName]);
518
+        $message->setSubject($subject);
519
+        $message->setBody($emailTemplate->renderText(), 'text/plain');
520
+        $message->setHtmlBody($emailTemplate->renderHtml());
521
+        $this->mailer->send($message);
522
+
523
+        $this->createPasswordSendActivity($share, $shareWith, true);
524
+
525
+        return true;
526
+    }
527
+
528
+    /**
529
+     * generate share token
530
+     *
531
+     * @return string
532
+     */
533
+    protected function generateToken($size = 15) {
534
+        $token = $this->secureRandom->generate(
535
+            $size, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS);
536
+        return $token;
537
+    }
538
+
539
+    /**
540
+     * Get all children of this share
541
+     *
542
+     * @param IShare $parent
543
+     * @return IShare[]
544
+     */
545
+    public function getChildren(IShare $parent) {
546
+        $children = [];
547
+
548
+        $qb = $this->dbConnection->getQueryBuilder();
549
+        $qb->select('*')
550
+            ->from('share')
551
+            ->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
552
+            ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
553
+            ->orderBy('id');
554
+
555
+        $cursor = $qb->execute();
556
+        while($data = $cursor->fetch()) {
557
+            $children[] = $this->createShareObject($data);
558
+        }
559
+        $cursor->closeCursor();
560
+
561
+        return $children;
562
+    }
563
+
564
+    /**
565
+     * add share to the database and return the ID
566
+     *
567
+     * @param int $itemSource
568
+     * @param string $itemType
569
+     * @param string $shareWith
570
+     * @param string $sharedBy
571
+     * @param string $uidOwner
572
+     * @param int $permissions
573
+     * @param string $token
574
+     * @return int
575
+     */
576
+    protected function addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token, $password) {
577
+        $qb = $this->dbConnection->getQueryBuilder();
578
+        $qb->insert('share')
579
+            ->setValue('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))
580
+            ->setValue('item_type', $qb->createNamedParameter($itemType))
581
+            ->setValue('item_source', $qb->createNamedParameter($itemSource))
582
+            ->setValue('file_source', $qb->createNamedParameter($itemSource))
583
+            ->setValue('share_with', $qb->createNamedParameter($shareWith))
584
+            ->setValue('uid_owner', $qb->createNamedParameter($uidOwner))
585
+            ->setValue('uid_initiator', $qb->createNamedParameter($sharedBy))
586
+            ->setValue('permissions', $qb->createNamedParameter($permissions))
587
+            ->setValue('token', $qb->createNamedParameter($token))
588
+            ->setValue('password', $qb->createNamedParameter($password))
589
+            ->setValue('stime', $qb->createNamedParameter(time()));
590
+
591
+        /*
592 592
 		 * Added to fix https://github.com/owncloud/core/issues/22215
593 593
 		 * Can be removed once we get rid of ajax/share.php
594 594
 		 */
595
-		$qb->setValue('file_target', $qb->createNamedParameter(''));
595
+        $qb->setValue('file_target', $qb->createNamedParameter(''));
596 596
 
597
-		$qb->execute();
598
-		$id = $qb->getLastInsertId();
597
+        $qb->execute();
598
+        $id = $qb->getLastInsertId();
599 599
 
600
-		return (int)$id;
601
-	}
600
+        return (int)$id;
601
+    }
602 602
 
603
-	/**
604
-	 * Update a share
605
-	 *
606
-	 * @param IShare $share
607
-	 * @param string|null $plainTextPassword
608
-	 * @return IShare The share object
609
-	 */
610
-	public function update(IShare $share, $plainTextPassword = null) {
603
+    /**
604
+     * Update a share
605
+     *
606
+     * @param IShare $share
607
+     * @param string|null $plainTextPassword
608
+     * @return IShare The share object
609
+     */
610
+    public function update(IShare $share, $plainTextPassword = null) {
611 611
 
612
-		$originalShare = $this->getShareById($share->getId());
612
+        $originalShare = $this->getShareById($share->getId());
613 613
 
614
-		// a real password was given
615
-		$validPassword = $plainTextPassword !== null && $plainTextPassword !== '';
614
+        // a real password was given
615
+        $validPassword = $plainTextPassword !== null && $plainTextPassword !== '';
616 616
 
617
-		if($validPassword && $originalShare->getPassword() !== $share->getPassword()) {
618
-			$this->sendPassword($share, $plainTextPassword);
619
-		}
620
-		/*
617
+        if($validPassword && $originalShare->getPassword() !== $share->getPassword()) {
618
+            $this->sendPassword($share, $plainTextPassword);
619
+        }
620
+        /*
621 621
 		 * We allow updating the permissions and password of mail shares
622 622
 		 */
623
-		$qb = $this->dbConnection->getQueryBuilder();
624
-		$qb->update('share')
625
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
626
-			->set('permissions', $qb->createNamedParameter($share->getPermissions()))
627
-			->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
628
-			->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
629
-			->set('password', $qb->createNamedParameter($share->getPassword()))
630
-			->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
631
-			->execute();
632
-
633
-		return $share;
634
-	}
635
-
636
-	/**
637
-	 * @inheritdoc
638
-	 */
639
-	public function move(IShare $share, $recipient) {
640
-		/**
641
-		 * nothing to do here, mail shares are only outgoing shares
642
-		 */
643
-		return $share;
644
-	}
645
-
646
-	/**
647
-	 * Delete a share (owner unShares the file)
648
-	 *
649
-	 * @param IShare $share
650
-	 */
651
-	public function delete(IShare $share) {
652
-		$this->removeShareFromTable($share->getId());
653
-	}
654
-
655
-	/**
656
-	 * @inheritdoc
657
-	 */
658
-	public function deleteFromSelf(IShare $share, $recipient) {
659
-		// nothing to do here, mail shares are only outgoing shares
660
-		return;
661
-	}
662
-
663
-	/**
664
-	 * @inheritdoc
665
-	 */
666
-	public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
667
-		$qb = $this->dbConnection->getQueryBuilder();
668
-		$qb->select('*')
669
-			->from('share');
670
-
671
-		$qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
672
-
673
-		/**
674
-		 * Reshares for this user are shares where they are the owner.
675
-		 */
676
-		if ($reshares === false) {
677
-			//Special case for old shares created via the web UI
678
-			$or1 = $qb->expr()->andX(
679
-				$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
680
-				$qb->expr()->isNull('uid_initiator')
681
-			);
682
-
683
-			$qb->andWhere(
684
-				$qb->expr()->orX(
685
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)),
686
-					$or1
687
-				)
688
-			);
689
-		} else {
690
-			$qb->andWhere(
691
-				$qb->expr()->orX(
692
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
693
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
694
-				)
695
-			);
696
-		}
697
-
698
-		if ($node !== null) {
699
-			$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
700
-		}
701
-
702
-		if ($limit !== -1) {
703
-			$qb->setMaxResults($limit);
704
-		}
705
-
706
-		$qb->setFirstResult($offset);
707
-		$qb->orderBy('id');
708
-
709
-		$cursor = $qb->execute();
710
-		$shares = [];
711
-		while($data = $cursor->fetch()) {
712
-			$shares[] = $this->createShareObject($data);
713
-		}
714
-		$cursor->closeCursor();
715
-
716
-		return $shares;
717
-	}
718
-
719
-	/**
720
-	 * @inheritdoc
721
-	 */
722
-	public function getShareById($id, $recipientId = null) {
723
-		$qb = $this->dbConnection->getQueryBuilder();
724
-
725
-		$qb->select('*')
726
-			->from('share')
727
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
728
-			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
729
-
730
-		$cursor = $qb->execute();
731
-		$data = $cursor->fetch();
732
-		$cursor->closeCursor();
733
-
734
-		if ($data === false) {
735
-			throw new ShareNotFound();
736
-		}
737
-
738
-		try {
739
-			$share = $this->createShareObject($data);
740
-		} catch (InvalidShare $e) {
741
-			throw new ShareNotFound();
742
-		}
743
-
744
-		return $share;
745
-	}
746
-
747
-	/**
748
-	 * Get shares for a given path
749
-	 *
750
-	 * @param \OCP\Files\Node $path
751
-	 * @return IShare[]
752
-	 */
753
-	public function getSharesByPath(Node $path) {
754
-		$qb = $this->dbConnection->getQueryBuilder();
755
-
756
-		$cursor = $qb->select('*')
757
-			->from('share')
758
-			->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
759
-			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
760
-			->execute();
761
-
762
-		$shares = [];
763
-		while($data = $cursor->fetch()) {
764
-			$shares[] = $this->createShareObject($data);
765
-		}
766
-		$cursor->closeCursor();
767
-
768
-		return $shares;
769
-	}
770
-
771
-	/**
772
-	 * @inheritdoc
773
-	 */
774
-	public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
775
-		/** @var IShare[] $shares */
776
-		$shares = [];
777
-
778
-		//Get shares directly with this user
779
-		$qb = $this->dbConnection->getQueryBuilder();
780
-		$qb->select('*')
781
-			->from('share');
782
-
783
-		// Order by id
784
-		$qb->orderBy('id');
785
-
786
-		// Set limit and offset
787
-		if ($limit !== -1) {
788
-			$qb->setMaxResults($limit);
789
-		}
790
-		$qb->setFirstResult($offset);
791
-
792
-		$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
793
-		$qb->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)));
794
-
795
-		// Filter by node if provided
796
-		if ($node !== null) {
797
-			$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
798
-		}
799
-
800
-		$cursor = $qb->execute();
801
-
802
-		while($data = $cursor->fetch()) {
803
-			$shares[] = $this->createShareObject($data);
804
-		}
805
-		$cursor->closeCursor();
806
-
807
-
808
-		return $shares;
809
-	}
810
-
811
-	/**
812
-	 * Get a share by token
813
-	 *
814
-	 * @param string $token
815
-	 * @return IShare
816
-	 * @throws ShareNotFound
817
-	 */
818
-	public function getShareByToken($token) {
819
-		$qb = $this->dbConnection->getQueryBuilder();
820
-
821
-		$cursor = $qb->select('*')
822
-			->from('share')
823
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
824
-			->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
825
-			->execute();
826
-
827
-		$data = $cursor->fetch();
828
-
829
-		if ($data === false) {
830
-			throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
831
-		}
832
-
833
-		try {
834
-			$share = $this->createShareObject($data);
835
-		} catch (InvalidShare $e) {
836
-			throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
837
-		}
838
-
839
-		return $share;
840
-	}
841
-
842
-	/**
843
-	 * remove share from table
844
-	 *
845
-	 * @param string $shareId
846
-	 */
847
-	protected function removeShareFromTable($shareId) {
848
-		$qb = $this->dbConnection->getQueryBuilder();
849
-		$qb->delete('share')
850
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($shareId)));
851
-		$qb->execute();
852
-	}
853
-
854
-	/**
855
-	 * Create a share object from an database row
856
-	 *
857
-	 * @param array $data
858
-	 * @return IShare
859
-	 * @throws InvalidShare
860
-	 * @throws ShareNotFound
861
-	 */
862
-	protected function createShareObject($data) {
863
-
864
-		$share = new Share($this->rootFolder, $this->userManager);
865
-		$share->setId((int)$data['id'])
866
-			->setShareType((int)$data['share_type'])
867
-			->setPermissions((int)$data['permissions'])
868
-			->setTarget($data['file_target'])
869
-			->setMailSend((bool)$data['mail_send'])
870
-			->setToken($data['token']);
871
-
872
-		$shareTime = new \DateTime();
873
-		$shareTime->setTimestamp((int)$data['stime']);
874
-		$share->setShareTime($shareTime);
875
-		$share->setSharedWith($data['share_with']);
876
-		$share->setPassword($data['password']);
877
-
878
-		if ($data['uid_initiator'] !== null) {
879
-			$share->setShareOwner($data['uid_owner']);
880
-			$share->setSharedBy($data['uid_initiator']);
881
-		} else {
882
-			//OLD SHARE
883
-			$share->setSharedBy($data['uid_owner']);
884
-			$path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
885
-
886
-			$owner = $path->getOwner();
887
-			$share->setShareOwner($owner->getUID());
888
-		}
889
-
890
-		if ($data['expiration'] !== null) {
891
-			$expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']);
892
-			if ($expiration !== false) {
893
-				$share->setExpirationDate($expiration);
894
-			}
895
-		}
896
-
897
-		$share->setNodeId((int)$data['file_source']);
898
-		$share->setNodeType($data['item_type']);
899
-
900
-		$share->setProviderId($this->identifier());
901
-
902
-		return $share;
903
-	}
904
-
905
-	/**
906
-	 * Get the node with file $id for $user
907
-	 *
908
-	 * @param string $userId
909
-	 * @param int $id
910
-	 * @return \OCP\Files\File|\OCP\Files\Folder
911
-	 * @throws InvalidShare
912
-	 */
913
-	private function getNode($userId, $id) {
914
-		try {
915
-			$userFolder = $this->rootFolder->getUserFolder($userId);
916
-		} catch (NotFoundException $e) {
917
-			throw new InvalidShare();
918
-		}
919
-
920
-		$nodes = $userFolder->getById($id);
921
-
922
-		if (empty($nodes)) {
923
-			throw new InvalidShare();
924
-		}
925
-
926
-		return $nodes[0];
927
-	}
928
-
929
-	/**
930
-	 * A user is deleted from the system
931
-	 * So clean up the relevant shares.
932
-	 *
933
-	 * @param string $uid
934
-	 * @param int $shareType
935
-	 */
936
-	public function userDeleted($uid, $shareType) {
937
-		$qb = $this->dbConnection->getQueryBuilder();
938
-
939
-		$qb->delete('share')
940
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
941
-			->andWhere($qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)))
942
-			->execute();
943
-	}
944
-
945
-	/**
946
-	 * This provider does not support group shares
947
-	 *
948
-	 * @param string $gid
949
-	 */
950
-	public function groupDeleted($gid) {
951
-		return;
952
-	}
953
-
954
-	/**
955
-	 * This provider does not support group shares
956
-	 *
957
-	 * @param string $uid
958
-	 * @param string $gid
959
-	 */
960
-	public function userDeletedFromGroup($uid, $gid) {
961
-		return;
962
-	}
963
-
964
-	/**
965
-	 * get database row of a give share
966
-	 *
967
-	 * @param $id
968
-	 * @return array
969
-	 * @throws ShareNotFound
970
-	 */
971
-	protected function getRawShare($id) {
972
-
973
-		// Now fetch the inserted share and create a complete share object
974
-		$qb = $this->dbConnection->getQueryBuilder();
975
-		$qb->select('*')
976
-			->from('share')
977
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
978
-
979
-		$cursor = $qb->execute();
980
-		$data = $cursor->fetch();
981
-		$cursor->closeCursor();
982
-
983
-		if ($data === false) {
984
-			throw new ShareNotFound;
985
-		}
986
-
987
-		return $data;
988
-	}
989
-
990
-	public function getSharesInFolder($userId, Folder $node, $reshares) {
991
-		$qb = $this->dbConnection->getQueryBuilder();
992
-		$qb->select('*')
993
-			->from('share', 's')
994
-			->andWhere($qb->expr()->orX(
995
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
996
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
997
-			))
998
-			->andWhere(
999
-				$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))
1000
-			);
1001
-
1002
-		/**
1003
-		 * Reshares for this user are shares where they are the owner.
1004
-		 */
1005
-		if ($reshares === false) {
1006
-			$qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
1007
-		} else {
1008
-			$qb->andWhere(
1009
-				$qb->expr()->orX(
1010
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
1011
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
1012
-				)
1013
-			);
1014
-		}
1015
-
1016
-		$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1017
-		$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
1018
-
1019
-		$qb->orderBy('id');
1020
-
1021
-		$cursor = $qb->execute();
1022
-		$shares = [];
1023
-		while ($data = $cursor->fetch()) {
1024
-			$shares[$data['fileid']][] = $this->createShareObject($data);
1025
-		}
1026
-		$cursor->closeCursor();
1027
-
1028
-		return $shares;
1029
-	}
1030
-
1031
-	/**
1032
-	 * @inheritdoc
1033
-	 */
1034
-	public function getAccessList($nodes, $currentAccess) {
1035
-		$ids = [];
1036
-		foreach ($nodes as $node) {
1037
-			$ids[] = $node->getId();
1038
-		}
1039
-
1040
-		$qb = $this->dbConnection->getQueryBuilder();
1041
-		$qb->select('share_with')
1042
-			->from('share')
1043
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
1044
-			->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1045
-			->andWhere($qb->expr()->orX(
1046
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1047
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1048
-			))
1049
-			->setMaxResults(1);
1050
-		$cursor = $qb->execute();
1051
-
1052
-		$mail = $cursor->fetch() !== false;
1053
-		$cursor->closeCursor();
1054
-
1055
-		return ['public' => $mail];
1056
-	}
623
+        $qb = $this->dbConnection->getQueryBuilder();
624
+        $qb->update('share')
625
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
626
+            ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
627
+            ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
628
+            ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
629
+            ->set('password', $qb->createNamedParameter($share->getPassword()))
630
+            ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
631
+            ->execute();
632
+
633
+        return $share;
634
+    }
635
+
636
+    /**
637
+     * @inheritdoc
638
+     */
639
+    public function move(IShare $share, $recipient) {
640
+        /**
641
+         * nothing to do here, mail shares are only outgoing shares
642
+         */
643
+        return $share;
644
+    }
645
+
646
+    /**
647
+     * Delete a share (owner unShares the file)
648
+     *
649
+     * @param IShare $share
650
+     */
651
+    public function delete(IShare $share) {
652
+        $this->removeShareFromTable($share->getId());
653
+    }
654
+
655
+    /**
656
+     * @inheritdoc
657
+     */
658
+    public function deleteFromSelf(IShare $share, $recipient) {
659
+        // nothing to do here, mail shares are only outgoing shares
660
+        return;
661
+    }
662
+
663
+    /**
664
+     * @inheritdoc
665
+     */
666
+    public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
667
+        $qb = $this->dbConnection->getQueryBuilder();
668
+        $qb->select('*')
669
+            ->from('share');
670
+
671
+        $qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
672
+
673
+        /**
674
+         * Reshares for this user are shares where they are the owner.
675
+         */
676
+        if ($reshares === false) {
677
+            //Special case for old shares created via the web UI
678
+            $or1 = $qb->expr()->andX(
679
+                $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
680
+                $qb->expr()->isNull('uid_initiator')
681
+            );
682
+
683
+            $qb->andWhere(
684
+                $qb->expr()->orX(
685
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)),
686
+                    $or1
687
+                )
688
+            );
689
+        } else {
690
+            $qb->andWhere(
691
+                $qb->expr()->orX(
692
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
693
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
694
+                )
695
+            );
696
+        }
697
+
698
+        if ($node !== null) {
699
+            $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
700
+        }
701
+
702
+        if ($limit !== -1) {
703
+            $qb->setMaxResults($limit);
704
+        }
705
+
706
+        $qb->setFirstResult($offset);
707
+        $qb->orderBy('id');
708
+
709
+        $cursor = $qb->execute();
710
+        $shares = [];
711
+        while($data = $cursor->fetch()) {
712
+            $shares[] = $this->createShareObject($data);
713
+        }
714
+        $cursor->closeCursor();
715
+
716
+        return $shares;
717
+    }
718
+
719
+    /**
720
+     * @inheritdoc
721
+     */
722
+    public function getShareById($id, $recipientId = null) {
723
+        $qb = $this->dbConnection->getQueryBuilder();
724
+
725
+        $qb->select('*')
726
+            ->from('share')
727
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
728
+            ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
729
+
730
+        $cursor = $qb->execute();
731
+        $data = $cursor->fetch();
732
+        $cursor->closeCursor();
733
+
734
+        if ($data === false) {
735
+            throw new ShareNotFound();
736
+        }
737
+
738
+        try {
739
+            $share = $this->createShareObject($data);
740
+        } catch (InvalidShare $e) {
741
+            throw new ShareNotFound();
742
+        }
743
+
744
+        return $share;
745
+    }
746
+
747
+    /**
748
+     * Get shares for a given path
749
+     *
750
+     * @param \OCP\Files\Node $path
751
+     * @return IShare[]
752
+     */
753
+    public function getSharesByPath(Node $path) {
754
+        $qb = $this->dbConnection->getQueryBuilder();
755
+
756
+        $cursor = $qb->select('*')
757
+            ->from('share')
758
+            ->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
759
+            ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
760
+            ->execute();
761
+
762
+        $shares = [];
763
+        while($data = $cursor->fetch()) {
764
+            $shares[] = $this->createShareObject($data);
765
+        }
766
+        $cursor->closeCursor();
767
+
768
+        return $shares;
769
+    }
770
+
771
+    /**
772
+     * @inheritdoc
773
+     */
774
+    public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
775
+        /** @var IShare[] $shares */
776
+        $shares = [];
777
+
778
+        //Get shares directly with this user
779
+        $qb = $this->dbConnection->getQueryBuilder();
780
+        $qb->select('*')
781
+            ->from('share');
782
+
783
+        // Order by id
784
+        $qb->orderBy('id');
785
+
786
+        // Set limit and offset
787
+        if ($limit !== -1) {
788
+            $qb->setMaxResults($limit);
789
+        }
790
+        $qb->setFirstResult($offset);
791
+
792
+        $qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
793
+        $qb->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)));
794
+
795
+        // Filter by node if provided
796
+        if ($node !== null) {
797
+            $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
798
+        }
799
+
800
+        $cursor = $qb->execute();
801
+
802
+        while($data = $cursor->fetch()) {
803
+            $shares[] = $this->createShareObject($data);
804
+        }
805
+        $cursor->closeCursor();
806
+
807
+
808
+        return $shares;
809
+    }
810
+
811
+    /**
812
+     * Get a share by token
813
+     *
814
+     * @param string $token
815
+     * @return IShare
816
+     * @throws ShareNotFound
817
+     */
818
+    public function getShareByToken($token) {
819
+        $qb = $this->dbConnection->getQueryBuilder();
820
+
821
+        $cursor = $qb->select('*')
822
+            ->from('share')
823
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
824
+            ->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
825
+            ->execute();
826
+
827
+        $data = $cursor->fetch();
828
+
829
+        if ($data === false) {
830
+            throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
831
+        }
832
+
833
+        try {
834
+            $share = $this->createShareObject($data);
835
+        } catch (InvalidShare $e) {
836
+            throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
837
+        }
838
+
839
+        return $share;
840
+    }
841
+
842
+    /**
843
+     * remove share from table
844
+     *
845
+     * @param string $shareId
846
+     */
847
+    protected function removeShareFromTable($shareId) {
848
+        $qb = $this->dbConnection->getQueryBuilder();
849
+        $qb->delete('share')
850
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($shareId)));
851
+        $qb->execute();
852
+    }
853
+
854
+    /**
855
+     * Create a share object from an database row
856
+     *
857
+     * @param array $data
858
+     * @return IShare
859
+     * @throws InvalidShare
860
+     * @throws ShareNotFound
861
+     */
862
+    protected function createShareObject($data) {
863
+
864
+        $share = new Share($this->rootFolder, $this->userManager);
865
+        $share->setId((int)$data['id'])
866
+            ->setShareType((int)$data['share_type'])
867
+            ->setPermissions((int)$data['permissions'])
868
+            ->setTarget($data['file_target'])
869
+            ->setMailSend((bool)$data['mail_send'])
870
+            ->setToken($data['token']);
871
+
872
+        $shareTime = new \DateTime();
873
+        $shareTime->setTimestamp((int)$data['stime']);
874
+        $share->setShareTime($shareTime);
875
+        $share->setSharedWith($data['share_with']);
876
+        $share->setPassword($data['password']);
877
+
878
+        if ($data['uid_initiator'] !== null) {
879
+            $share->setShareOwner($data['uid_owner']);
880
+            $share->setSharedBy($data['uid_initiator']);
881
+        } else {
882
+            //OLD SHARE
883
+            $share->setSharedBy($data['uid_owner']);
884
+            $path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
885
+
886
+            $owner = $path->getOwner();
887
+            $share->setShareOwner($owner->getUID());
888
+        }
889
+
890
+        if ($data['expiration'] !== null) {
891
+            $expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']);
892
+            if ($expiration !== false) {
893
+                $share->setExpirationDate($expiration);
894
+            }
895
+        }
896
+
897
+        $share->setNodeId((int)$data['file_source']);
898
+        $share->setNodeType($data['item_type']);
899
+
900
+        $share->setProviderId($this->identifier());
901
+
902
+        return $share;
903
+    }
904
+
905
+    /**
906
+     * Get the node with file $id for $user
907
+     *
908
+     * @param string $userId
909
+     * @param int $id
910
+     * @return \OCP\Files\File|\OCP\Files\Folder
911
+     * @throws InvalidShare
912
+     */
913
+    private function getNode($userId, $id) {
914
+        try {
915
+            $userFolder = $this->rootFolder->getUserFolder($userId);
916
+        } catch (NotFoundException $e) {
917
+            throw new InvalidShare();
918
+        }
919
+
920
+        $nodes = $userFolder->getById($id);
921
+
922
+        if (empty($nodes)) {
923
+            throw new InvalidShare();
924
+        }
925
+
926
+        return $nodes[0];
927
+    }
928
+
929
+    /**
930
+     * A user is deleted from the system
931
+     * So clean up the relevant shares.
932
+     *
933
+     * @param string $uid
934
+     * @param int $shareType
935
+     */
936
+    public function userDeleted($uid, $shareType) {
937
+        $qb = $this->dbConnection->getQueryBuilder();
938
+
939
+        $qb->delete('share')
940
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
941
+            ->andWhere($qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)))
942
+            ->execute();
943
+    }
944
+
945
+    /**
946
+     * This provider does not support group shares
947
+     *
948
+     * @param string $gid
949
+     */
950
+    public function groupDeleted($gid) {
951
+        return;
952
+    }
953
+
954
+    /**
955
+     * This provider does not support group shares
956
+     *
957
+     * @param string $uid
958
+     * @param string $gid
959
+     */
960
+    public function userDeletedFromGroup($uid, $gid) {
961
+        return;
962
+    }
963
+
964
+    /**
965
+     * get database row of a give share
966
+     *
967
+     * @param $id
968
+     * @return array
969
+     * @throws ShareNotFound
970
+     */
971
+    protected function getRawShare($id) {
972
+
973
+        // Now fetch the inserted share and create a complete share object
974
+        $qb = $this->dbConnection->getQueryBuilder();
975
+        $qb->select('*')
976
+            ->from('share')
977
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
978
+
979
+        $cursor = $qb->execute();
980
+        $data = $cursor->fetch();
981
+        $cursor->closeCursor();
982
+
983
+        if ($data === false) {
984
+            throw new ShareNotFound;
985
+        }
986
+
987
+        return $data;
988
+    }
989
+
990
+    public function getSharesInFolder($userId, Folder $node, $reshares) {
991
+        $qb = $this->dbConnection->getQueryBuilder();
992
+        $qb->select('*')
993
+            ->from('share', 's')
994
+            ->andWhere($qb->expr()->orX(
995
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
996
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
997
+            ))
998
+            ->andWhere(
999
+                $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))
1000
+            );
1001
+
1002
+        /**
1003
+         * Reshares for this user are shares where they are the owner.
1004
+         */
1005
+        if ($reshares === false) {
1006
+            $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
1007
+        } else {
1008
+            $qb->andWhere(
1009
+                $qb->expr()->orX(
1010
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
1011
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
1012
+                )
1013
+            );
1014
+        }
1015
+
1016
+        $qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1017
+        $qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
1018
+
1019
+        $qb->orderBy('id');
1020
+
1021
+        $cursor = $qb->execute();
1022
+        $shares = [];
1023
+        while ($data = $cursor->fetch()) {
1024
+            $shares[$data['fileid']][] = $this->createShareObject($data);
1025
+        }
1026
+        $cursor->closeCursor();
1027
+
1028
+        return $shares;
1029
+    }
1030
+
1031
+    /**
1032
+     * @inheritdoc
1033
+     */
1034
+    public function getAccessList($nodes, $currentAccess) {
1035
+        $ids = [];
1036
+        foreach ($nodes as $node) {
1037
+            $ids[] = $node->getId();
1038
+        }
1039
+
1040
+        $qb = $this->dbConnection->getQueryBuilder();
1041
+        $qb->select('share_with')
1042
+            ->from('share')
1043
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
1044
+            ->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1045
+            ->andWhere($qb->expr()->orX(
1046
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1047
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1048
+            ))
1049
+            ->setMaxResults(1);
1050
+        $cursor = $qb->execute();
1051
+
1052
+        $mail = $cursor->fetch() !== false;
1053
+        $cursor->closeCursor();
1054
+
1055
+        return ['public' => $mail];
1056
+    }
1057 1057
 
1058 1058
 }
Please login to merge, or discard this patch.
Spacing   +25 added lines, -25 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
 
@@ -350,11 +350,11 @@  discard block
 block discarded – undo
350 350
 				$share->getSharedWith()
351 351
 			);
352 352
 		} catch (HintException $hintException) {
353
-			$this->logger->error('Failed to send share by mail: ' . $hintException->getMessage());
353
+			$this->logger->error('Failed to send share by mail: '.$hintException->getMessage());
354 354
 			$this->removeShareFromTable($shareId);
355 355
 			throw $hintException;
356 356
 		} catch (\Exception $e) {
357
-			$this->logger->error('Failed to send share by mail: ' . $e->getMessage());
357
+			$this->logger->error('Failed to send share by mail: '.$e->getMessage());
358 358
 			$this->removeShareFromTable($shareId);
359 359
 			throw new HintException('Failed to send share by mail',
360 360
 				$this->l->t('Failed to send share by E-mail'));
@@ -379,7 +379,7 @@  discard block
 block discarded – undo
379 379
 											$shareWith) {
380 380
 		$initiatorUser = $this->userManager->get($initiator);
381 381
 		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
382
-		$subject = (string)$this->l->t('%s shared »%s« with you', array($initiatorDisplayName, $filename));
382
+		$subject = (string) $this->l->t('%s shared »%s« with you', array($initiatorDisplayName, $filename));
383 383
 
384 384
 		$message = $this->mailer->createMessage();
385 385
 
@@ -390,7 +390,7 @@  discard block
 block discarded – undo
390 390
 		$text = $this->l->t('%s shared »%s« with you.', [$initiatorDisplayName, $filename]);
391 391
 
392 392
 		$emailTemplate->addBodyText(
393
-			$text . ' ' . $this->l->t('Click the button below to open it.'),
393
+			$text.' '.$this->l->t('Click the button below to open it.'),
394 394
 			$text
395 395
 		);
396 396
 		$emailTemplate->addBodyButton(
@@ -414,9 +414,9 @@  discard block
 block discarded – undo
414 414
 		// The "Reply-To" is set to the sharer if an mail address is configured
415 415
 		// also the default footer contains a "Do not reply" which needs to be adjusted.
416 416
 		$initiatorEmail = $initiatorUser->getEMailAddress();
417
-		if($initiatorEmail !== null) {
417
+		if ($initiatorEmail !== null) {
418 418
 			$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
419
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
419
+			$emailTemplate->addFooter($instanceName.' - '.$this->defaults->getSlogan());
420 420
 		} else {
421 421
 			$emailTemplate->addFooter();
422 422
 		}
@@ -448,7 +448,7 @@  discard block
 block discarded – undo
448 448
 		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
449 449
 		$initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
450 450
 
451
-		$subject = (string)$this->l->t('Password to access »%s« shared to you by %s', [$filename, $initiatorDisplayName]);
451
+		$subject = (string) $this->l->t('Password to access »%s« shared to you by %s', [$filename, $initiatorDisplayName]);
452 452
 		$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]);
453 453
 		$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]);
454 454
 
@@ -498,7 +498,7 @@  discard block
 block discarded – undo
498 498
 			);
499 499
 		}
500 500
 
501
-		$subject = (string)$this->l->t('Password to access »%s« shared with %s', [$filename, $shareWith]);
501
+		$subject = (string) $this->l->t('Password to access »%s« shared with %s', [$filename, $shareWith]);
502 502
 		$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()]);
503 503
 
504 504
 		$message = $this->mailer->createMessage();
@@ -532,7 +532,7 @@  discard block
 block discarded – undo
532 532
 	 */
533 533
 	protected function generateToken($size = 15) {
534 534
 		$token = $this->secureRandom->generate(
535
-			$size, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS);
535
+			$size, ISecureRandom::CHAR_LOWER.ISecureRandom::CHAR_UPPER.ISecureRandom::CHAR_DIGITS);
536 536
 		return $token;
537 537
 	}
538 538
 
@@ -553,7 +553,7 @@  discard block
 block discarded – undo
553 553
 			->orderBy('id');
554 554
 
555 555
 		$cursor = $qb->execute();
556
-		while($data = $cursor->fetch()) {
556
+		while ($data = $cursor->fetch()) {
557 557
 			$children[] = $this->createShareObject($data);
558 558
 		}
559 559
 		$cursor->closeCursor();
@@ -597,7 +597,7 @@  discard block
 block discarded – undo
597 597
 		$qb->execute();
598 598
 		$id = $qb->getLastInsertId();
599 599
 
600
-		return (int)$id;
600
+		return (int) $id;
601 601
 	}
602 602
 
603 603
 	/**
@@ -614,7 +614,7 @@  discard block
 block discarded – undo
614 614
 		// a real password was given
615 615
 		$validPassword = $plainTextPassword !== null && $plainTextPassword !== '';
616 616
 
617
-		if($validPassword && $originalShare->getPassword() !== $share->getPassword()) {
617
+		if ($validPassword && $originalShare->getPassword() !== $share->getPassword()) {
618 618
 			$this->sendPassword($share, $plainTextPassword);
619 619
 		}
620 620
 		/*
@@ -708,7 +708,7 @@  discard block
 block discarded – undo
708 708
 
709 709
 		$cursor = $qb->execute();
710 710
 		$shares = [];
711
-		while($data = $cursor->fetch()) {
711
+		while ($data = $cursor->fetch()) {
712 712
 			$shares[] = $this->createShareObject($data);
713 713
 		}
714 714
 		$cursor->closeCursor();
@@ -760,7 +760,7 @@  discard block
 block discarded – undo
760 760
 			->execute();
761 761
 
762 762
 		$shares = [];
763
-		while($data = $cursor->fetch()) {
763
+		while ($data = $cursor->fetch()) {
764 764
 			$shares[] = $this->createShareObject($data);
765 765
 		}
766 766
 		$cursor->closeCursor();
@@ -799,7 +799,7 @@  discard block
 block discarded – undo
799 799
 
800 800
 		$cursor = $qb->execute();
801 801
 
802
-		while($data = $cursor->fetch()) {
802
+		while ($data = $cursor->fetch()) {
803 803
 			$shares[] = $this->createShareObject($data);
804 804
 		}
805 805
 		$cursor->closeCursor();
@@ -862,15 +862,15 @@  discard block
 block discarded – undo
862 862
 	protected function createShareObject($data) {
863 863
 
864 864
 		$share = new Share($this->rootFolder, $this->userManager);
865
-		$share->setId((int)$data['id'])
866
-			->setShareType((int)$data['share_type'])
867
-			->setPermissions((int)$data['permissions'])
865
+		$share->setId((int) $data['id'])
866
+			->setShareType((int) $data['share_type'])
867
+			->setPermissions((int) $data['permissions'])
868 868
 			->setTarget($data['file_target'])
869
-			->setMailSend((bool)$data['mail_send'])
869
+			->setMailSend((bool) $data['mail_send'])
870 870
 			->setToken($data['token']);
871 871
 
872 872
 		$shareTime = new \DateTime();
873
-		$shareTime->setTimestamp((int)$data['stime']);
873
+		$shareTime->setTimestamp((int) $data['stime']);
874 874
 		$share->setShareTime($shareTime);
875 875
 		$share->setSharedWith($data['share_with']);
876 876
 		$share->setPassword($data['password']);
@@ -881,7 +881,7 @@  discard block
 block discarded – undo
881 881
 		} else {
882 882
 			//OLD SHARE
883 883
 			$share->setSharedBy($data['uid_owner']);
884
-			$path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
884
+			$path = $this->getNode($share->getSharedBy(), (int) $data['file_source']);
885 885
 
886 886
 			$owner = $path->getOwner();
887 887
 			$share->setShareOwner($owner->getUID());
@@ -894,7 +894,7 @@  discard block
 block discarded – undo
894 894
 			}
895 895
 		}
896 896
 
897
-		$share->setNodeId((int)$data['file_source']);
897
+		$share->setNodeId((int) $data['file_source']);
898 898
 		$share->setNodeType($data['item_type']);
899 899
 
900 900
 		$share->setProviderId($this->identifier());
@@ -1013,7 +1013,7 @@  discard block
 block discarded – undo
1013 1013
 			);
1014 1014
 		}
1015 1015
 
1016
-		$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1016
+		$qb->innerJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1017 1017
 		$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
1018 1018
 
1019 1019
 		$qb->orderBy('id');
Please login to merge, or discard this patch.