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