Passed
Push — master ( ef6806...fd475d )
by Roeland
09:13 queued 10s
created

ShareByMailProvider::identifier()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016 Bjoern Schiessle <[email protected]>
4
 *
5
 * @license GNU AGPL version 3 or any later version
6
 *
7
 * This program is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU Affero General Public License as
9
 * published by the Free Software Foundation, either version 3 of the
10
 * License, or (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU Affero General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Affero General Public License
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
 *
20
 */
21
22
namespace OCA\ShareByMail;
23
24
use OC\CapabilitiesManager;
25
use OC\HintException;
26
use OC\Share20\Exception\InvalidShare;
27
use OC\User\NoUserException;
28
use OCA\ShareByMail\Settings\SettingsManager;
29
use OCP\Activity\IManager;
30
use OCP\DB\QueryBuilder\IQueryBuilder;
31
use OCP\Defaults;
32
use OCP\Files\Folder;
33
use OCP\Files\IRootFolder;
34
use OCP\Files\Node;
35
use OCP\IDBConnection;
36
use OCP\IL10N;
37
use OCP\ILogger;
38
use OCP\IURLGenerator;
39
use OCP\IUser;
40
use OCP\IUserManager;
41
use OCP\Mail\IMailer;
42
use OCP\Security\IHasher;
43
use OCP\Security\ISecureRandom;
44
use OC\Share20\Share;
45
use OCP\Share\Exceptions\GenericShareException;
46
use OCP\Share\Exceptions\ShareNotFound;
47
use OCP\Share\IShare;
48
use OCP\Share\IShareProvider;
49
50
/**
51
 * Class ShareByMail
52
 *
53
 * @package OCA\ShareByMail
54
 */
55
class ShareByMailProvider implements IShareProvider {
56
57
	/** @var  IDBConnection */
58
	private $dbConnection;
59
60
	/** @var ILogger */
61
	private $logger;
62
63
	/** @var ISecureRandom */
64
	private $secureRandom;
65
66
	/** @var IUserManager */
67
	private $userManager;
68
69
	/** @var IRootFolder */
70
	private $rootFolder;
71
72
	/** @var IL10N */
73
	private $l;
74
75
	/** @var IMailer */
76
	private $mailer;
77
78
	/** @var IURLGenerator */
79
	private $urlGenerator;
80
81
	/** @var IManager  */
82
	private $activityManager;
83
84
	/** @var SettingsManager */
85
	private $settingsManager;
86
87
	/** @var Defaults */
88
	private $defaults;
89
90
	/** @var IHasher */
91
	private $hasher;
92
93
	/** @var  CapabilitiesManager */
94
	private $capabilitiesManager;
95
96
	/**
97
	 * Return the identifier of this provider.
98
	 *
99
	 * @return string Containing only [a-zA-Z0-9]
100
	 */
101
	public function identifier() {
102
		return 'ocMailShare';
103
	}
104
105
	/**
106
	 * DefaultShareProvider constructor.
107
	 *
108
	 * @param IDBConnection $connection
109
	 * @param ISecureRandom $secureRandom
110
	 * @param IUserManager $userManager
111
	 * @param IRootFolder $rootFolder
112
	 * @param IL10N $l
113
	 * @param ILogger $logger
114
	 * @param IMailer $mailer
115
	 * @param IURLGenerator $urlGenerator
116
	 * @param IManager $activityManager
117
	 * @param SettingsManager $settingsManager
118
	 * @param Defaults $defaults
119
	 * @param IHasher $hasher
120
	 * @param CapabilitiesManager $capabilitiesManager
121
	 */
122
	public function __construct(
123
		IDBConnection $connection,
124
		ISecureRandom $secureRandom,
125
		IUserManager $userManager,
126
		IRootFolder $rootFolder,
127
		IL10N $l,
128
		ILogger $logger,
129
		IMailer $mailer,
130
		IURLGenerator $urlGenerator,
131
		IManager $activityManager,
132
		SettingsManager $settingsManager,
133
		Defaults $defaults,
134
		IHasher $hasher,
135
		CapabilitiesManager $capabilitiesManager
136
	) {
137
		$this->dbConnection = $connection;
138
		$this->secureRandom = $secureRandom;
139
		$this->userManager = $userManager;
140
		$this->rootFolder = $rootFolder;
141
		$this->l = $l;
142
		$this->logger = $logger;
143
		$this->mailer = $mailer;
144
		$this->urlGenerator = $urlGenerator;
145
		$this->activityManager = $activityManager;
146
		$this->settingsManager = $settingsManager;
147
		$this->defaults = $defaults;
148
		$this->hasher = $hasher;
149
		$this->capabilitiesManager = $capabilitiesManager;
150
	}
151
152
	/**
153
	 * Share a path
154
	 *
155
	 * @param IShare $share
156
	 * @return IShare The share object
157
	 * @throws ShareNotFound
158
	 * @throws \Exception
159
	 */
160
	public function create(IShare $share) {
161
162
		$shareWith = $share->getSharedWith();
163
		/*
164
		 * Check if file is not already shared with the remote user
165
		 */
166
		$alreadyShared = $this->getSharedWith($shareWith, \OCP\Share::SHARE_TYPE_EMAIL, $share->getNode(), 1, 0);
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_EMAIL has been deprecated: 17.0.0 - use IShare::TYPE_EMAIL instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

166
		$alreadyShared = $this->getSharedWith($shareWith, /** @scrutinizer ignore-deprecated */ \OCP\Share::SHARE_TYPE_EMAIL, $share->getNode(), 1, 0);

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
167
		if (!empty($alreadyShared)) {
168
			$message = 'Sharing %1$s failed, this item is already shared with %2$s';
169
			$message_t = $this->l->t('Sharing %1$s failed, this item is already shared with %2$s', array($share->getNode()->getName(), $shareWith));
170
			$this->logger->debug(sprintf($message, $share->getNode()->getName(), $shareWith), ['app' => 'Federated File Sharing']);
171
			throw new \Exception($message_t);
172
		}
173
174
		// if the admin enforces a password for all mail shares we create a
175
		// random password and send it to the recipient
176
		$password = '';
177
		$passwordEnforced = $this->settingsManager->enforcePasswordProtection();
178
		if ($passwordEnforced) {
179
			$password = $this->autoGeneratePassword($share);
180
		}
181
182
		$shareId = $this->createMailShare($share);
183
		$send = $this->sendPassword($share, $password);
184
		if ($passwordEnforced && $send === false) {
185
			$this->sendPasswordToOwner($share, $password);
186
		}
187
188
		$this->createShareActivity($share);
189
		$data = $this->getRawShare($shareId);
190
191
		return $this->createShareObject($data);
192
193
	}
194
195
	/**
196
	 * auto generate password in case of password enforcement on mail shares
197
	 *
198
	 * @param IShare $share
199
	 * @return string
200
	 * @throws \Exception
201
	 */
202
	protected function autoGeneratePassword($share) {
203
		$initiatorUser = $this->userManager->get($share->getSharedBy());
204
		$initiatorEMailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
205
		$allowPasswordByMail = $this->settingsManager->sendPasswordByMail();
206
207
		if ($initiatorEMailAddress === null && !$allowPasswordByMail) {
208
			throw new \Exception(
209
				$this->l->t("We can't send you the auto-generated password. Please set a valid email address in your personal settings and try again.")
210
			);
211
		}
212
213
		$passwordPolicy = $this->getPasswordPolicy();
214
		$passwordCharset = ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS;
215
		$passwordLength = 8;
216
		if (!empty($passwordPolicy)) {
217
			$passwordLength = (int)$passwordPolicy['minLength'] > 0 ? (int)$passwordPolicy['minLength'] : $passwordLength;
218
			$passwordCharset .= $passwordPolicy['enforceSpecialCharacters'] ? ISecureRandom::CHAR_SYMBOLS : '';
219
		}
220
221
		$password = $this->secureRandom->generate($passwordLength, $passwordCharset);
222
223
		$share->setPassword($this->hasher->hash($password));
224
225
		return $password;
226
	}
227
228
	/**
229
	 * get password policy
230
	 *
231
	 * @return array
232
	 */
233
	protected function getPasswordPolicy() {
234
		$capabilities = $this->capabilitiesManager->getCapabilities();
235
		if (isset($capabilities['password_policy'])) {
236
			return $capabilities['password_policy'];
237
		}
238
239
		return [];
240
	}
241
242
	/**
243
	 * create activity if a file/folder was shared by mail
244
	 *
245
	 * @param IShare $share
246
	 * @param string $type
247
	 */
248
	protected function createShareActivity(IShare $share, string $type = 'share') {
249
250
		$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
251
252
		$this->publishActivity(
253
			$type === 'share' ? Activity::SUBJECT_SHARED_EMAIL_SELF : Activity::SUBJECT_UNSHARED_EMAIL_SELF,
254
			[$userFolder->getRelativePath($share->getNode()->getPath()), $share->getSharedWith()],
255
			$share->getSharedBy(),
256
			$share->getNode()->getId(),
257
			(string) $userFolder->getRelativePath($share->getNode()->getPath())
258
		);
259
260
		if ($share->getShareOwner() !== $share->getSharedBy()) {
261
			$ownerFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
262
			$fileId = $share->getNode()->getId();
263
			$nodes = $ownerFolder->getById($fileId);
264
			$ownerPath = $nodes[0]->getPath();
265
			$this->publishActivity(
266
				$type === 'share' ? Activity::SUBJECT_SHARED_EMAIL_BY : Activity::SUBJECT_UNSHARED_EMAIL_BY,
267
				[$ownerFolder->getRelativePath($ownerPath), $share->getSharedWith(), $share->getSharedBy()],
268
				$share->getShareOwner(),
269
				$fileId,
270
				(string) $ownerFolder->getRelativePath($ownerPath)
271
			);
272
		}
273
274
	}
275
276
	/**
277
	 * create activity if a file/folder was shared by mail
278
	 *
279
	 * @param IShare $share
280
	 * @param string $sharedWith
281
	 * @param bool $sendToSelf
282
	 */
283
	protected function createPasswordSendActivity(IShare $share, $sharedWith, $sendToSelf) {
284
285
		$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
286
287
		if ($sendToSelf) {
288
			$this->publishActivity(
289
				Activity::SUBJECT_SHARED_EMAIL_PASSWORD_SEND_SELF,
290
				[$userFolder->getRelativePath($share->getNode()->getPath())],
291
				$share->getSharedBy(),
292
				$share->getNode()->getId(),
293
				(string) $userFolder->getRelativePath($share->getNode()->getPath())
294
			);
295
		} else {
296
			$this->publishActivity(
297
				Activity::SUBJECT_SHARED_EMAIL_PASSWORD_SEND,
298
				[$userFolder->getRelativePath($share->getNode()->getPath()), $sharedWith],
299
				$share->getSharedBy(),
300
				$share->getNode()->getId(),
301
				(string) $userFolder->getRelativePath($share->getNode()->getPath())
302
			);
303
		}
304
	}
305
306
307
	/**
308
	 * publish activity if a file/folder was shared by mail
309
	 *
310
	 * @param string $subject
311
	 * @param array $parameters
312
	 * @param string $affectedUser
313
	 * @param int $fileId
314
	 * @param string $filePath
315
	 */
316
	protected function publishActivity(string $subject, array $parameters, string $affectedUser, int $fileId, string $filePath) {
317
		$event = $this->activityManager->generateEvent();
318
		$event->setApp('sharebymail')
319
			->setType('shared')
320
			->setSubject($subject, $parameters)
321
			->setAffectedUser($affectedUser)
322
			->setObject('files', $fileId, $filePath);
323
		$this->activityManager->publish($event);
324
325
	}
326
327
	/**
328
	 * @param IShare $share
329
	 * @return int
330
	 * @throws \Exception
331
	 */
332
	protected function createMailShare(IShare $share) {
333
		$share->setToken($this->generateToken());
334
		$shareId = $this->addShareToDB(
335
			$share->getNodeId(),
336
			$share->getNodeType(),
337
			$share->getSharedWith(),
338
			$share->getSharedBy(),
339
			$share->getShareOwner(),
340
			$share->getPermissions(),
341
			$share->getToken(),
342
			$share->getPassword(),
343
			$share->getSendPasswordByTalk()
344
		);
345
346
		try {
347
			$link = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare',
348
				['token' => $share->getToken()]);
349
			$this->sendMailNotification(
350
				$share->getNode()->getName(),
351
				$link,
352
				$share->getSharedBy(),
353
				$share->getSharedWith(),
354
				$share->getExpirationDate()
355
			);
356
		} catch (HintException $hintException) {
357
			$this->logger->logException($hintException, [
358
				'message' => 'Failed to send share by mail.',
359
				'level' => ILogger::ERROR,
360
				'app' => 'sharebymail',
361
			]);
362
			$this->removeShareFromTable($shareId);
363
			throw $hintException;
364
		} catch (\Exception $e) {
365
			$this->logger->logException($e, [
366
				'message' => 'Failed to send share by mail.',
367
				'level' => ILogger::ERROR,
368
				'app' => 'sharebymail',
369
			]);
370
			$this->removeShareFromTable($shareId);
371
			throw new HintException('Failed to send share by mail',
372
				$this->l->t('Failed to send share by email'));
373
		}
374
375
		return $shareId;
376
377
	}
378
379
	/**
380
	 * @param string $filename
381
	 * @param string $link
382
	 * @param string $initiator
383
	 * @param string $shareWith
384
	 * @param \DateTime|null $expiration
385
	 * @throws \Exception If mail couldn't be sent
386
	 */
387
	protected function sendMailNotification($filename,
388
											$link,
389
											$initiator,
390
											$shareWith,
391
											\DateTime $expiration = null) {
392
		$initiatorUser = $this->userManager->get($initiator);
393
		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
394
		$message = $this->mailer->createMessage();
395
396
		$emailTemplate = $this->mailer->createEMailTemplate('sharebymail.RecipientNotification', [
397
			'filename' => $filename,
398
			'link' => $link,
399
			'initiator' => $initiatorDisplayName,
400
			'expiration' => $expiration,
401
			'shareWith' => $shareWith,
402
		]);
403
404
		$emailTemplate->setSubject($this->l->t('%1$s shared »%2$s« with you', array($initiatorDisplayName, $filename)));
405
		$emailTemplate->addHeader();
406
		$emailTemplate->addHeading($this->l->t('%1$s shared »%2$s« with you', [$initiatorDisplayName, $filename]), false);
407
		$text = $this->l->t('%1$s shared »%2$s« with you.', [$initiatorDisplayName, $filename]);
408
409
		$emailTemplate->addBodyText(
410
			htmlspecialchars($text . ' ' . $this->l->t('Click the button below to open it.')),
411
			$text
412
		);
413
		$emailTemplate->addBodyButton(
414
			$this->l->t('Open »%s«', [$filename]),
415
			$link
416
		);
417
418
		$message->setTo([$shareWith]);
419
420
		// The "From" contains the sharers name
421
		$instanceName = $this->defaults->getName();
422
		$senderName = $this->l->t(
423
			'%1$s via %2$s',
424
			[
425
				$initiatorDisplayName,
426
				$instanceName
427
			]
428
		);
429
		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
430
431
		// The "Reply-To" is set to the sharer if an mail address is configured
432
		// also the default footer contains a "Do not reply" which needs to be adjusted.
433
		$initiatorEmail = $initiatorUser->getEMailAddress();
434
		if($initiatorEmail !== null) {
435
			$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
436
			$emailTemplate->addFooter($instanceName . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : ''));
437
		} else {
438
			$emailTemplate->addFooter();
439
		}
440
441
		$message->useTemplate($emailTemplate);
442
		$this->mailer->send($message);
443
	}
444
445
	/**
446
	 * send password to recipient of a mail share
447
	 *
448
	 * @param IShare $share
449
	 * @param string $password
450
	 * @return bool
451
	 */
452
	protected function sendPassword(IShare $share, $password) {
453
454
		$filename = $share->getNode()->getName();
455
		$initiator = $share->getSharedBy();
456
		$shareWith = $share->getSharedWith();
457
458
		if ($password === '' || $this->settingsManager->sendPasswordByMail() === false || $share->getSendPasswordByTalk()) {
459
			return false;
460
		}
461
462
		$initiatorUser = $this->userManager->get($initiator);
463
		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
464
		$initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
465
466
		$plainBodyPart = $this->l->t("%1\$s shared »%2\$s« with you.\nYou should have already received a separate mail with a link to access it.\n", [$initiatorDisplayName, $filename]);
467
		$htmlBodyPart = $this->l->t('%1$s shared »%2$s« with you. You should have already received a separate mail with a link to access it.', [$initiatorDisplayName, $filename]);
468
469
		$message = $this->mailer->createMessage();
470
471
		$emailTemplate = $this->mailer->createEMailTemplate('sharebymail.RecipientPasswordNotification', [
472
			'filename' => $filename,
473
			'password' => $password,
474
			'initiator' => $initiatorDisplayName,
475
			'initiatorEmail' => $initiatorEmailAddress,
476
			'shareWith' => $shareWith,
477
		]);
478
479
		$emailTemplate->setSubject($this->l->t('Password to access »%1$s« shared to you by %2$s', [$filename, $initiatorDisplayName]));
480
		$emailTemplate->addHeader();
481
		$emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
482
		$emailTemplate->addBodyText(htmlspecialchars($htmlBodyPart), $plainBodyPart);
483
		$emailTemplate->addBodyText($this->l->t('It is protected with the following password:'));
484
		$emailTemplate->addBodyText($password);
485
486
		// The "From" contains the sharers name
487
		$instanceName = $this->defaults->getName();
488
		$senderName = $this->l->t(
489
			'%1$s via %2$s',
490
			[
491
				$initiatorDisplayName,
492
				$instanceName
493
			]
494
		);
495
		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
496
		if ($initiatorEmailAddress !== null) {
497
			$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
498
			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
499
		} else {
500
			$emailTemplate->addFooter();
501
		}
502
503
		$message->setTo([$shareWith]);
504
		$message->useTemplate($emailTemplate);
505
		$this->mailer->send($message);
506
507
		$this->createPasswordSendActivity($share, $shareWith, false);
508
509
		return true;
510
	}
511
512
	protected function sendNote(IShare $share) {
513
514
		$recipient = $share->getSharedWith();
515
516
517
		$filename = $share->getNode()->getName();
518
		$initiator = $share->getSharedBy();
519
		$note = $share->getNote();
520
521
		$initiatorUser = $this->userManager->get($initiator);
522
		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
523
		$initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
524
525
		$plainHeading = $this->l->t('%1$s shared »%2$s« with you and wants to add:', [$initiatorDisplayName, $filename]);
526
		$htmlHeading = $this->l->t('%1$s shared »%2$s« with you and wants to add', [$initiatorDisplayName, $filename]);
527
528
		$message = $this->mailer->createMessage();
529
530
		$emailTemplate = $this->mailer->createEMailTemplate('shareByMail.sendNote');
531
532
		$emailTemplate->setSubject($this->l->t('»%s« added a note to a file shared with you', [$initiatorDisplayName]));
533
		$emailTemplate->addHeader();
534
		$emailTemplate->addHeading(htmlspecialchars($htmlHeading), $plainHeading);
535
		$emailTemplate->addBodyText(htmlspecialchars($note), $note);
536
537
		$link = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare',
538
			['token' => $share->getToken()]);
539
		$emailTemplate->addBodyButton(
540
			$this->l->t('Open »%s«', [$filename]),
541
			$link
542
		);
543
544
		// The "From" contains the sharers name
545
		$instanceName = $this->defaults->getName();
546
		$senderName = $this->l->t(
547
			'%1$s via %2$s',
548
			[
549
				$initiatorDisplayName,
550
				$instanceName
551
			]
552
		);
553
		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
554
		if ($initiatorEmailAddress !== null) {
555
			$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
556
			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
557
		} else {
558
			$emailTemplate->addFooter();
559
		}
560
561
		$message->setTo([$recipient]);
562
		$message->useTemplate($emailTemplate);
563
		$this->mailer->send($message);
564
565
	}
566
567
	/**
568
	 * send auto generated password to the owner. This happens if the admin enforces
569
	 * a password for mail shares and forbid to send the password by mail to the recipient
570
	 *
571
	 * @param IShare $share
572
	 * @param string $password
573
	 * @return bool
574
	 * @throws \Exception
575
	 */
576
	protected function sendPasswordToOwner(IShare $share, $password) {
577
578
		$filename = $share->getNode()->getName();
579
		$initiator = $this->userManager->get($share->getSharedBy());
580
		$initiatorEMailAddress = ($initiator instanceof IUser) ? $initiator->getEMailAddress() : null;
581
		$initiatorDisplayName = ($initiator instanceof IUser) ? $initiator->getDisplayName() : $share->getSharedBy();
582
		$shareWith = $share->getSharedWith();
583
584
		if ($initiatorEMailAddress === null) {
585
			throw new \Exception(
586
				$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.")
587
			);
588
		}
589
590
		$bodyPart = $this->l->t('You just shared »%1$s« with %2$s. The share was already sent to the recipient. Due to the security policies defined by the administrator of %3$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()]);
591
592
		$message = $this->mailer->createMessage();
593
		$emailTemplate = $this->mailer->createEMailTemplate('sharebymail.OwnerPasswordNotification', [
594
			'filename' => $filename,
595
			'password' => $password,
596
			'initiator' => $initiatorDisplayName,
597
			'initiatorEmail' => $initiatorEMailAddress,
598
			'shareWith' => $shareWith,
599
		]);
600
601
		$emailTemplate->setSubject($this->l->t('Password to access »%1$s« shared by you with %2$s', [$filename, $shareWith]));
602
		$emailTemplate->addHeader();
603
		$emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
604
		$emailTemplate->addBodyText($bodyPart);
605
		$emailTemplate->addBodyText($this->l->t('This is the password:'));
606
		$emailTemplate->addBodyText($password);
607
		$emailTemplate->addBodyText($this->l->t('You can choose a different password at any time in the share dialog.'));
608
		$emailTemplate->addFooter();
609
610
		if ($initiatorEMailAddress) {
611
			$message->setFrom([$initiatorEMailAddress => $initiatorDisplayName]);
612
		}
613
		$message->setTo([$initiatorEMailAddress => $initiatorDisplayName]);
614
		$message->useTemplate($emailTemplate);
615
		$this->mailer->send($message);
616
617
		$this->createPasswordSendActivity($share, $shareWith, true);
618
619
		return true;
620
	}
621
622
	/**
623
	 * generate share token
624
	 *
625
	 * @return string
626
	 */
627
	protected function generateToken($size = 15) {
628
		$token = $this->secureRandom->generate($size, ISecureRandom::CHAR_HUMAN_READABLE);
629
		return $token;
630
	}
631
632
	/**
633
	 * Get all children of this share
634
	 *
635
	 * @param IShare $parent
636
	 * @return IShare[]
637
	 */
638
	public function getChildren(IShare $parent) {
639
		$children = [];
640
641
		$qb = $this->dbConnection->getQueryBuilder();
642
		$qb->select('*')
643
			->from('share')
644
			->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId())))
645
			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_EMAIL has been deprecated: 17.0.0 - use IShare::TYPE_EMAIL instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

645
			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(/** @scrutinizer ignore-deprecated */ \OCP\Share::SHARE_TYPE_EMAIL)))

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
646
			->orderBy('id');
647
648
		$cursor = $qb->execute();
649
		while($data = $cursor->fetch()) {
650
			$children[] = $this->createShareObject($data);
651
		}
652
		$cursor->closeCursor();
653
654
		return $children;
655
	}
656
657
	/**
658
	 * add share to the database and return the ID
659
	 *
660
	 * @param int $itemSource
661
	 * @param string $itemType
662
	 * @param string $shareWith
663
	 * @param string $sharedBy
664
	 * @param string $uidOwner
665
	 * @param int $permissions
666
	 * @param string $token
667
	 * @param string $password
668
	 * @param bool $sendPasswordByTalk
669
	 * @return int
670
	 */
671
	protected function addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token, $password, $sendPasswordByTalk) {
672
		$qb = $this->dbConnection->getQueryBuilder();
673
		$qb->insert('share')
674
			->setValue('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_EMAIL has been deprecated: 17.0.0 - use IShare::TYPE_EMAIL instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

674
			->setValue('share_type', $qb->createNamedParameter(/** @scrutinizer ignore-deprecated */ \OCP\Share::SHARE_TYPE_EMAIL))

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
675
			->setValue('item_type', $qb->createNamedParameter($itemType))
676
			->setValue('item_source', $qb->createNamedParameter($itemSource))
677
			->setValue('file_source', $qb->createNamedParameter($itemSource))
678
			->setValue('share_with', $qb->createNamedParameter($shareWith))
679
			->setValue('uid_owner', $qb->createNamedParameter($uidOwner))
680
			->setValue('uid_initiator', $qb->createNamedParameter($sharedBy))
681
			->setValue('permissions', $qb->createNamedParameter($permissions))
682
			->setValue('token', $qb->createNamedParameter($token))
683
			->setValue('password', $qb->createNamedParameter($password))
684
			->setValue('password_by_talk', $qb->createNamedParameter($sendPasswordByTalk, IQueryBuilder::PARAM_BOOL))
685
			->setValue('stime', $qb->createNamedParameter(time()));
686
687
		/*
688
		 * Added to fix https://github.com/owncloud/core/issues/22215
689
		 * Can be removed once we get rid of ajax/share.php
690
		 */
691
		$qb->setValue('file_target', $qb->createNamedParameter(''));
692
693
		$qb->execute();
694
		$id = $qb->getLastInsertId();
695
696
		return (int)$id;
697
	}
698
699
	/**
700
	 * Update a share
701
	 *
702
	 * @param IShare $share
703
	 * @param string|null $plainTextPassword
704
	 * @return IShare The share object
705
	 */
706
	public function update(IShare $share, $plainTextPassword = null) {
707
708
		$originalShare = $this->getShareById($share->getId());
709
710
		// a real password was given
711
		$validPassword = $plainTextPassword !== null && $plainTextPassword !== '';
712
713
		if($validPassword && ($originalShare->getPassword() !== $share->getPassword() ||
714
								($originalShare->getSendPasswordByTalk() && !$share->getSendPasswordByTalk()))) {
715
			$this->sendPassword($share, $plainTextPassword);
716
		}
717
		/*
718
		 * We allow updating the permissions and password of mail shares
719
		 */
720
		$qb = $this->dbConnection->getQueryBuilder();
721
		$qb->update('share')
722
			->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
723
			->set('permissions', $qb->createNamedParameter($share->getPermissions()))
724
			->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
725
			->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
726
			->set('password', $qb->createNamedParameter($share->getPassword()))
727
			->set('password_by_talk', $qb->createNamedParameter($share->getSendPasswordByTalk(), IQueryBuilder::PARAM_BOOL))
728
			->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
729
			->set('note', $qb->createNamedParameter($share->getNote()))
730
			->execute();
731
732
		if ($originalShare->getNote() !== $share->getNote() && $share->getNote() !== '') {
733
			$this->sendNote($share);
734
		}
735
736
		return $share;
737
	}
738
739
	/**
740
	 * @inheritdoc
741
	 */
742
	public function move(IShare $share, $recipient) {
743
		/**
744
		 * nothing to do here, mail shares are only outgoing shares
745
		 */
746
		return $share;
747
	}
748
749
	/**
750
	 * Delete a share (owner unShares the file)
751
	 *
752
	 * @param IShare $share
753
	 */
754
	public function delete(IShare $share) {
755
		try {
756
			$this->createShareActivity($share, 'unshare');
757
		} catch (\Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
758
		}
759
760
		$this->removeShareFromTable($share->getId());
761
	}
762
763
	/**
764
	 * @inheritdoc
765
	 */
766
	public function deleteFromSelf(IShare $share, $recipient) {
767
		// nothing to do here, mail shares are only outgoing shares
768
	}
769
770
	public function restore(IShare $share, string $recipient): IShare {
771
		throw new GenericShareException('not implemented');
772
	}
773
774
	/**
775
	 * @inheritdoc
776
	 */
777
	public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
778
		$qb = $this->dbConnection->getQueryBuilder();
779
		$qb->select('*')
780
			->from('share');
781
782
		$qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_EMAIL has been deprecated: 17.0.0 - use IShare::TYPE_EMAIL instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

782
		$qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(/** @scrutinizer ignore-deprecated */ \OCP\Share::SHARE_TYPE_EMAIL)));

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
783
784
		/**
785
		 * Reshares for this user are shares where they are the owner.
786
		 */
787
		if ($reshares === false) {
788
			//Special case for old shares created via the web UI
789
			$or1 = $qb->expr()->andX(
790
				$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
791
				$qb->expr()->isNull('uid_initiator')
792
			);
793
794
			$qb->andWhere(
795
				$qb->expr()->orX(
796
					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)),
797
					$or1
798
				)
799
			);
800
		} else {
801
			$qb->andWhere(
802
				$qb->expr()->orX(
803
					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
804
					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
805
				)
806
			);
807
		}
808
809
		if ($node !== null) {
810
			$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
811
		}
812
813
		if ($limit !== -1) {
814
			$qb->setMaxResults($limit);
815
		}
816
817
		$qb->setFirstResult($offset);
818
		$qb->orderBy('id');
819
820
		$cursor = $qb->execute();
821
		$shares = [];
822
		while($data = $cursor->fetch()) {
823
			$shares[] = $this->createShareObject($data);
824
		}
825
		$cursor->closeCursor();
826
827
		return $shares;
828
	}
829
830
	/**
831
	 * @inheritdoc
832
	 */
833
	public function getShareById($id, $recipientId = null) {
834
		$qb = $this->dbConnection->getQueryBuilder();
835
836
		$qb->select('*')
837
			->from('share')
838
			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
839
			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_EMAIL has been deprecated: 17.0.0 - use IShare::TYPE_EMAIL instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

839
			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(/** @scrutinizer ignore-deprecated */ \OCP\Share::SHARE_TYPE_EMAIL)));

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
840
841
		$cursor = $qb->execute();
842
		$data = $cursor->fetch();
843
		$cursor->closeCursor();
844
845
		if ($data === false) {
846
			throw new ShareNotFound();
847
		}
848
849
		try {
850
			$share = $this->createShareObject($data);
851
		} catch (InvalidShare $e) {
852
			throw new ShareNotFound();
853
		}
854
855
		return $share;
856
	}
857
858
	/**
859
	 * Get shares for a given path
860
	 *
861
	 * @param \OCP\Files\Node $path
862
	 * @return IShare[]
863
	 */
864
	public function getSharesByPath(Node $path) {
865
		$qb = $this->dbConnection->getQueryBuilder();
866
867
		$cursor = $qb->select('*')
868
			->from('share')
869
			->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
870
			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_EMAIL has been deprecated: 17.0.0 - use IShare::TYPE_EMAIL instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

870
			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(/** @scrutinizer ignore-deprecated */ \OCP\Share::SHARE_TYPE_EMAIL)))

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
871
			->execute();
872
873
		$shares = [];
874
		while($data = $cursor->fetch()) {
875
			$shares[] = $this->createShareObject($data);
876
		}
877
		$cursor->closeCursor();
878
879
		return $shares;
880
	}
881
882
	/**
883
	 * @inheritdoc
884
	 */
885
	public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
886
		/** @var IShare[] $shares */
887
		$shares = [];
888
889
		//Get shares directly with this user
890
		$qb = $this->dbConnection->getQueryBuilder();
891
		$qb->select('*')
892
			->from('share');
893
894
		// Order by id
895
		$qb->orderBy('id');
896
897
		// Set limit and offset
898
		if ($limit !== -1) {
899
			$qb->setMaxResults($limit);
900
		}
901
		$qb->setFirstResult($offset);
902
903
		$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)));
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_EMAIL has been deprecated: 17.0.0 - use IShare::TYPE_EMAIL instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

903
		$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(/** @scrutinizer ignore-deprecated */ \OCP\Share::SHARE_TYPE_EMAIL)));

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
904
		$qb->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)));
905
906
		// Filter by node if provided
907
		if ($node !== null) {
908
			$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
909
		}
910
911
		$cursor = $qb->execute();
912
913
		while($data = $cursor->fetch()) {
914
			$shares[] = $this->createShareObject($data);
915
		}
916
		$cursor->closeCursor();
917
918
919
		return $shares;
920
	}
921
922
	/**
923
	 * Get a share by token
924
	 *
925
	 * @param string $token
926
	 * @return IShare
927
	 * @throws ShareNotFound
928
	 */
929
	public function getShareByToken($token) {
930
		$qb = $this->dbConnection->getQueryBuilder();
931
932
		$cursor = $qb->select('*')
933
			->from('share')
934
			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_EMAIL has been deprecated: 17.0.0 - use IShare::TYPE_EMAIL instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

934
			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(/** @scrutinizer ignore-deprecated */ \OCP\Share::SHARE_TYPE_EMAIL)))

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
935
			->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
936
			->execute();
937
938
		$data = $cursor->fetch();
939
940
		if ($data === false) {
941
			throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
942
		}
943
944
		try {
945
			$share = $this->createShareObject($data);
946
		} catch (InvalidShare $e) {
947
			throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
948
		}
949
950
		return $share;
951
	}
952
953
	/**
954
	 * remove share from table
955
	 *
956
	 * @param string $shareId
957
	 */
958
	protected function removeShareFromTable($shareId) {
959
		$qb = $this->dbConnection->getQueryBuilder();
960
		$qb->delete('share')
961
			->where($qb->expr()->eq('id', $qb->createNamedParameter($shareId)));
962
		$qb->execute();
963
	}
964
965
	/**
966
	 * Create a share object from an database row
967
	 *
968
	 * @param array $data
969
	 * @return IShare
970
	 * @throws InvalidShare
971
	 * @throws ShareNotFound
972
	 */
973
	protected function createShareObject($data) {
974
975
		$share = new Share($this->rootFolder, $this->userManager);
976
		$share->setId((int)$data['id'])
977
			->setShareType((int)$data['share_type'])
978
			->setPermissions((int)$data['permissions'])
979
			->setTarget($data['file_target'])
980
			->setMailSend((bool)$data['mail_send'])
981
			->setNote($data['note'])
982
			->setToken($data['token']);
983
984
		$shareTime = new \DateTime();
985
		$shareTime->setTimestamp((int)$data['stime']);
986
		$share->setShareTime($shareTime);
987
		$share->setSharedWith($data['share_with']);
988
		$share->setPassword($data['password']);
989
		$share->setSendPasswordByTalk((bool)$data['password_by_talk']);
990
991
		if ($data['uid_initiator'] !== null) {
992
			$share->setShareOwner($data['uid_owner']);
993
			$share->setSharedBy($data['uid_initiator']);
994
		} else {
995
			//OLD SHARE
996
			$share->setSharedBy($data['uid_owner']);
997
			$path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
998
999
			$owner = $path->getOwner();
1000
			$share->setShareOwner($owner->getUID());
1001
		}
1002
1003
		if ($data['expiration'] !== null) {
1004
			$expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']);
1005
			if ($expiration !== false) {
1006
				$share->setExpirationDate($expiration);
1007
			}
1008
		}
1009
1010
		$share->setNodeId((int)$data['file_source']);
1011
		$share->setNodeType($data['item_type']);
1012
1013
		$share->setProviderId($this->identifier());
1014
1015
		return $share;
1016
	}
1017
1018
	/**
1019
	 * Get the node with file $id for $user
1020
	 *
1021
	 * @param string $userId
1022
	 * @param int $id
1023
	 * @return \OCP\Files\File|\OCP\Files\Folder
1024
	 * @throws InvalidShare
1025
	 */
1026
	private function getNode($userId, $id) {
1027
		try {
1028
			$userFolder = $this->rootFolder->getUserFolder($userId);
1029
		} catch (NoUserException $e) {
1030
			throw new InvalidShare();
1031
		}
1032
1033
		$nodes = $userFolder->getById($id);
1034
1035
		if (empty($nodes)) {
1036
			throw new InvalidShare();
1037
		}
1038
1039
		return $nodes[0];
1040
	}
1041
1042
	/**
1043
	 * A user is deleted from the system
1044
	 * So clean up the relevant shares.
1045
	 *
1046
	 * @param string $uid
1047
	 * @param int $shareType
1048
	 */
1049
	public function userDeleted($uid, $shareType) {
1050
		$qb = $this->dbConnection->getQueryBuilder();
1051
1052
		$qb->delete('share')
1053
			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_EMAIL has been deprecated: 17.0.0 - use IShare::TYPE_EMAIL instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1053
			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(/** @scrutinizer ignore-deprecated */ \OCP\Share::SHARE_TYPE_EMAIL)))

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
1054
			->andWhere($qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)))
1055
			->execute();
1056
	}
1057
1058
	/**
1059
	 * This provider does not support group shares
1060
	 *
1061
	 * @param string $gid
1062
	 */
1063
	public function groupDeleted($gid) {
1064
	}
1065
1066
	/**
1067
	 * This provider does not support group shares
1068
	 *
1069
	 * @param string $uid
1070
	 * @param string $gid
1071
	 */
1072
	public function userDeletedFromGroup($uid, $gid) {
1073
	}
1074
1075
	/**
1076
	 * get database row of a give share
1077
	 *
1078
	 * @param $id
1079
	 * @return array
1080
	 * @throws ShareNotFound
1081
	 */
1082
	protected function getRawShare($id) {
1083
1084
		// Now fetch the inserted share and create a complete share object
1085
		$qb = $this->dbConnection->getQueryBuilder();
1086
		$qb->select('*')
1087
			->from('share')
1088
			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
1089
1090
		$cursor = $qb->execute();
1091
		$data = $cursor->fetch();
1092
		$cursor->closeCursor();
1093
1094
		if ($data === false) {
1095
			throw new ShareNotFound;
1096
		}
1097
1098
		return $data;
1099
	}
1100
1101
	public function getSharesInFolder($userId, Folder $node, $reshares) {
1102
		$qb = $this->dbConnection->getQueryBuilder();
1103
		$qb->select('*')
1104
			->from('share', 's')
1105
			->andWhere($qb->expr()->orX(
1106
				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1107
				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1108
			))
1109
			->andWhere(
1110
				$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_EMAIL has been deprecated: 17.0.0 - use IShare::TYPE_EMAIL instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1110
				$qb->expr()->eq('share_type', $qb->createNamedParameter(/** @scrutinizer ignore-deprecated */ \OCP\Share::SHARE_TYPE_EMAIL))

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
1111
			);
1112
1113
		/**
1114
		 * Reshares for this user are shares where they are the owner.
1115
		 */
1116
		if ($reshares === false) {
1117
			$qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
1118
		} else {
1119
			$qb->andWhere(
1120
				$qb->expr()->orX(
1121
					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
1122
					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
1123
				)
1124
			);
1125
		}
1126
1127
		$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1128
		$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
1129
1130
		$qb->orderBy('id');
1131
1132
		$cursor = $qb->execute();
1133
		$shares = [];
1134
		while ($data = $cursor->fetch()) {
1135
			$shares[$data['fileid']][] = $this->createShareObject($data);
1136
		}
1137
		$cursor->closeCursor();
1138
1139
		return $shares;
1140
	}
1141
1142
	/**
1143
	 * @inheritdoc
1144
	 */
1145
	public function getAccessList($nodes, $currentAccess) {
1146
		$ids = [];
1147
		foreach ($nodes as $node) {
1148
			$ids[] = $node->getId();
1149
		}
1150
1151
		$qb = $this->dbConnection->getQueryBuilder();
1152
		$qb->select('share_with')
1153
			->from('share')
1154
			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)))
0 ignored issues
show
Deprecated Code introduced by
The constant OC\Share\Constants::SHARE_TYPE_EMAIL has been deprecated: 17.0.0 - use IShare::TYPE_EMAIL instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

1154
			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(/** @scrutinizer ignore-deprecated */ \OCP\Share::SHARE_TYPE_EMAIL)))

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
1155
			->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1156
			->andWhere($qb->expr()->orX(
1157
				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1158
				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1159
			))
1160
			->setMaxResults(1);
1161
		$cursor = $qb->execute();
1162
1163
		$mail = $cursor->fetch() !== false;
1164
		$cursor->closeCursor();
1165
1166
		return ['public' => $mail];
1167
	}
1168
1169
	public function getAllShares(): iterable {
1170
		$qb = $this->dbConnection->getQueryBuilder();
1171
1172
		$qb->select('*')
1173
			->from('share')
1174
			->where(
1175
				$qb->expr()->orX(
1176
					$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_EMAIL))
1177
				)
1178
			);
1179
1180
		$cursor = $qb->execute();
1181
		while($data = $cursor->fetch()) {
1182
			try {
1183
				$share = $this->createShareObject($data);
1184
			} catch (InvalidShare $e) {
1185
				continue;
1186
			} catch (ShareNotFound $e) {
1187
				continue;
1188
			}
1189
1190
			yield $share;
1191
		}
1192
		$cursor->closeCursor();
1193
	}
1194
}
1195