Passed
Push — master ( 23df99...f86f59 )
by Joas
16:43 queued 15s
created
apps/oauth2/lib/Controller/OauthApiController.php 1 patch
Indentation   +133 added lines, -133 removed lines patch added patch discarded remove patch
@@ -44,137 +44,137 @@
 block discarded – undo
44 44
 use OCP\Security\ISecureRandom;
45 45
 
46 46
 class OauthApiController extends Controller {
47
-	/** @var AccessTokenMapper */
48
-	private $accessTokenMapper;
49
-	/** @var ClientMapper */
50
-	private $clientMapper;
51
-	/** @var ICrypto */
52
-	private $crypto;
53
-	/** @var TokenProvider */
54
-	private $tokenProvider;
55
-	/** @var ISecureRandom */
56
-	private $secureRandom;
57
-	/** @var ITimeFactory */
58
-	private $time;
59
-	/** @var Throttler */
60
-	private $throttler;
61
-
62
-	public function __construct(string $appName,
63
-								IRequest $request,
64
-								ICrypto $crypto,
65
-								AccessTokenMapper $accessTokenMapper,
66
-								ClientMapper $clientMapper,
67
-								TokenProvider $tokenProvider,
68
-								ISecureRandom $secureRandom,
69
-								ITimeFactory $time,
70
-								Throttler $throttler) {
71
-		parent::__construct($appName, $request);
72
-		$this->crypto = $crypto;
73
-		$this->accessTokenMapper = $accessTokenMapper;
74
-		$this->clientMapper = $clientMapper;
75
-		$this->tokenProvider = $tokenProvider;
76
-		$this->secureRandom = $secureRandom;
77
-		$this->time = $time;
78
-		$this->throttler = $throttler;
79
-	}
80
-
81
-	/**
82
-	 * @PublicPage
83
-	 * @NoCSRFRequired
84
-	 *
85
-	 * @param string $grant_type
86
-	 * @param string $code
87
-	 * @param string $refresh_token
88
-	 * @param string $client_id
89
-	 * @param string $client_secret
90
-	 * @return JSONResponse
91
-	 */
92
-	public function getToken($grant_type, $code, $refresh_token, $client_id, $client_secret): JSONResponse {
93
-
94
-		// We only handle two types
95
-		if ($grant_type !== 'authorization_code' && $grant_type !== 'refresh_token') {
96
-			return new JSONResponse([
97
-				'error' => 'invalid_grant',
98
-			], Http::STATUS_BAD_REQUEST);
99
-		}
100
-
101
-		// We handle the initial and refresh tokens the same way
102
-		if ($grant_type === 'refresh_token') {
103
-			$code = $refresh_token;
104
-		}
105
-
106
-		try {
107
-			$accessToken = $this->accessTokenMapper->getByCode($code);
108
-		} catch (AccessTokenNotFoundException $e) {
109
-			return new JSONResponse([
110
-				'error' => 'invalid_request',
111
-			], Http::STATUS_BAD_REQUEST);
112
-		}
113
-
114
-		try {
115
-			$client = $this->clientMapper->getByUid($accessToken->getClientId());
116
-		} catch (ClientNotFoundException $e) {
117
-			return new JSONResponse([
118
-				'error' => 'invalid_request',
119
-			], Http::STATUS_BAD_REQUEST);
120
-		}
121
-
122
-		if (isset($this->request->server['PHP_AUTH_USER'])) {
123
-			$client_id = $this->request->server['PHP_AUTH_USER'];
124
-			$client_secret = $this->request->server['PHP_AUTH_PW'];
125
-		}
126
-
127
-		// The client id and secret must match. Else we don't provide an access token!
128
-		if ($client->getClientIdentifier() !== $client_id || $client->getSecret() !== $client_secret) {
129
-			return new JSONResponse([
130
-				'error' => 'invalid_client',
131
-			], Http::STATUS_BAD_REQUEST);
132
-		}
133
-
134
-		$decryptedToken = $this->crypto->decrypt($accessToken->getEncryptedToken(), $code);
135
-
136
-		// Obtain the appToken assoicated
137
-		try {
138
-			$appToken = $this->tokenProvider->getTokenById($accessToken->getTokenId());
139
-		} catch (ExpiredTokenException $e) {
140
-			$appToken = $e->getToken();
141
-		} catch (InvalidTokenException $e) {
142
-			//We can't do anything...
143
-			$this->accessTokenMapper->delete($accessToken);
144
-			return new JSONResponse([
145
-				'error' => 'invalid_request',
146
-			], Http::STATUS_BAD_REQUEST);
147
-		}
148
-
149
-		// Rotate the apptoken (so the old one becomes invalid basically)
150
-		$newToken = $this->secureRandom->generate(72, ISecureRandom::CHAR_ALPHANUMERIC);
151
-
152
-		$appToken = $this->tokenProvider->rotate(
153
-			$appToken,
154
-			$decryptedToken,
155
-			$newToken
156
-		);
157
-
158
-		// Expiration is in 1 hour again
159
-		$appToken->setExpires($this->time->getTime() + 3600);
160
-		$this->tokenProvider->updateToken($appToken);
161
-
162
-		// Generate a new refresh token and encrypt the new apptoken in the DB
163
-		$newCode = $this->secureRandom->generate(128, ISecureRandom::CHAR_ALPHANUMERIC);
164
-		$accessToken->setHashedCode(hash('sha512', $newCode));
165
-		$accessToken->setEncryptedToken($this->crypto->encrypt($newToken, $newCode));
166
-		$this->accessTokenMapper->update($accessToken);
167
-
168
-		$this->throttler->resetDelay($this->request->getRemoteAddress(), 'login', ['user' => $appToken->getUID()]);
169
-
170
-		return new JSONResponse(
171
-			[
172
-				'access_token' => $newToken,
173
-				'token_type' => 'Bearer',
174
-				'expires_in' => 3600,
175
-				'refresh_token' => $newCode,
176
-				'user_id' => $appToken->getUID(),
177
-			]
178
-		);
179
-	}
47
+    /** @var AccessTokenMapper */
48
+    private $accessTokenMapper;
49
+    /** @var ClientMapper */
50
+    private $clientMapper;
51
+    /** @var ICrypto */
52
+    private $crypto;
53
+    /** @var TokenProvider */
54
+    private $tokenProvider;
55
+    /** @var ISecureRandom */
56
+    private $secureRandom;
57
+    /** @var ITimeFactory */
58
+    private $time;
59
+    /** @var Throttler */
60
+    private $throttler;
61
+
62
+    public function __construct(string $appName,
63
+                                IRequest $request,
64
+                                ICrypto $crypto,
65
+                                AccessTokenMapper $accessTokenMapper,
66
+                                ClientMapper $clientMapper,
67
+                                TokenProvider $tokenProvider,
68
+                                ISecureRandom $secureRandom,
69
+                                ITimeFactory $time,
70
+                                Throttler $throttler) {
71
+        parent::__construct($appName, $request);
72
+        $this->crypto = $crypto;
73
+        $this->accessTokenMapper = $accessTokenMapper;
74
+        $this->clientMapper = $clientMapper;
75
+        $this->tokenProvider = $tokenProvider;
76
+        $this->secureRandom = $secureRandom;
77
+        $this->time = $time;
78
+        $this->throttler = $throttler;
79
+    }
80
+
81
+    /**
82
+     * @PublicPage
83
+     * @NoCSRFRequired
84
+     *
85
+     * @param string $grant_type
86
+     * @param string $code
87
+     * @param string $refresh_token
88
+     * @param string $client_id
89
+     * @param string $client_secret
90
+     * @return JSONResponse
91
+     */
92
+    public function getToken($grant_type, $code, $refresh_token, $client_id, $client_secret): JSONResponse {
93
+
94
+        // We only handle two types
95
+        if ($grant_type !== 'authorization_code' && $grant_type !== 'refresh_token') {
96
+            return new JSONResponse([
97
+                'error' => 'invalid_grant',
98
+            ], Http::STATUS_BAD_REQUEST);
99
+        }
100
+
101
+        // We handle the initial and refresh tokens the same way
102
+        if ($grant_type === 'refresh_token') {
103
+            $code = $refresh_token;
104
+        }
105
+
106
+        try {
107
+            $accessToken = $this->accessTokenMapper->getByCode($code);
108
+        } catch (AccessTokenNotFoundException $e) {
109
+            return new JSONResponse([
110
+                'error' => 'invalid_request',
111
+            ], Http::STATUS_BAD_REQUEST);
112
+        }
113
+
114
+        try {
115
+            $client = $this->clientMapper->getByUid($accessToken->getClientId());
116
+        } catch (ClientNotFoundException $e) {
117
+            return new JSONResponse([
118
+                'error' => 'invalid_request',
119
+            ], Http::STATUS_BAD_REQUEST);
120
+        }
121
+
122
+        if (isset($this->request->server['PHP_AUTH_USER'])) {
123
+            $client_id = $this->request->server['PHP_AUTH_USER'];
124
+            $client_secret = $this->request->server['PHP_AUTH_PW'];
125
+        }
126
+
127
+        // The client id and secret must match. Else we don't provide an access token!
128
+        if ($client->getClientIdentifier() !== $client_id || $client->getSecret() !== $client_secret) {
129
+            return new JSONResponse([
130
+                'error' => 'invalid_client',
131
+            ], Http::STATUS_BAD_REQUEST);
132
+        }
133
+
134
+        $decryptedToken = $this->crypto->decrypt($accessToken->getEncryptedToken(), $code);
135
+
136
+        // Obtain the appToken assoicated
137
+        try {
138
+            $appToken = $this->tokenProvider->getTokenById($accessToken->getTokenId());
139
+        } catch (ExpiredTokenException $e) {
140
+            $appToken = $e->getToken();
141
+        } catch (InvalidTokenException $e) {
142
+            //We can't do anything...
143
+            $this->accessTokenMapper->delete($accessToken);
144
+            return new JSONResponse([
145
+                'error' => 'invalid_request',
146
+            ], Http::STATUS_BAD_REQUEST);
147
+        }
148
+
149
+        // Rotate the apptoken (so the old one becomes invalid basically)
150
+        $newToken = $this->secureRandom->generate(72, ISecureRandom::CHAR_ALPHANUMERIC);
151
+
152
+        $appToken = $this->tokenProvider->rotate(
153
+            $appToken,
154
+            $decryptedToken,
155
+            $newToken
156
+        );
157
+
158
+        // Expiration is in 1 hour again
159
+        $appToken->setExpires($this->time->getTime() + 3600);
160
+        $this->tokenProvider->updateToken($appToken);
161
+
162
+        // Generate a new refresh token and encrypt the new apptoken in the DB
163
+        $newCode = $this->secureRandom->generate(128, ISecureRandom::CHAR_ALPHANUMERIC);
164
+        $accessToken->setHashedCode(hash('sha512', $newCode));
165
+        $accessToken->setEncryptedToken($this->crypto->encrypt($newToken, $newCode));
166
+        $this->accessTokenMapper->update($accessToken);
167
+
168
+        $this->throttler->resetDelay($this->request->getRemoteAddress(), 'login', ['user' => $appToken->getUID()]);
169
+
170
+        return new JSONResponse(
171
+            [
172
+                'access_token' => $newToken,
173
+                'token_type' => 'Bearer',
174
+                'expires_in' => 3600,
175
+                'refresh_token' => $newCode,
176
+                'user_id' => $appToken->getUID(),
177
+            ]
178
+        );
179
+    }
180 180
 }
Please login to merge, or discard this patch.
apps/sharebymail/lib/ShareByMailProvider.php 2 patches
Indentation   +1118 added lines, -1118 removed lines patch added patch discarded remove patch
@@ -75,1129 +75,1129 @@
 block discarded – undo
75 75
  */
76 76
 class ShareByMailProvider implements IShareProvider {
77 77
 
78
-	/** @var  IDBConnection */
79
-	private $dbConnection;
80
-
81
-	/** @var ILogger */
82
-	private $logger;
83
-
84
-	/** @var ISecureRandom */
85
-	private $secureRandom;
86
-
87
-	/** @var IUserManager */
88
-	private $userManager;
89
-
90
-	/** @var IRootFolder */
91
-	private $rootFolder;
92
-
93
-	/** @var IL10N */
94
-	private $l;
95
-
96
-	/** @var IMailer */
97
-	private $mailer;
98
-
99
-	/** @var IURLGenerator */
100
-	private $urlGenerator;
101
-
102
-	/** @var IManager  */
103
-	private $activityManager;
104
-
105
-	/** @var SettingsManager */
106
-	private $settingsManager;
107
-
108
-	/** @var Defaults */
109
-	private $defaults;
110
-
111
-	/** @var IHasher */
112
-	private $hasher;
113
-
114
-	/** @var IEventDispatcher */
115
-	private $eventDispatcher;
116
-
117
-	/** @var IShareManager */
118
-	private $shareManager;
119
-
120
-	/**
121
-	 * Return the identifier of this provider.
122
-	 *
123
-	 * @return string Containing only [a-zA-Z0-9]
124
-	 */
125
-	public function identifier() {
126
-		return 'ocMailShare';
127
-	}
128
-
129
-	public function __construct(IDBConnection $connection,
130
-								ISecureRandom $secureRandom,
131
-								IUserManager $userManager,
132
-								IRootFolder $rootFolder,
133
-								IL10N $l,
134
-								ILogger $logger,
135
-								IMailer $mailer,
136
-								IURLGenerator $urlGenerator,
137
-								IManager $activityManager,
138
-								SettingsManager $settingsManager,
139
-								Defaults $defaults,
140
-								IHasher $hasher,
141
-								IEventDispatcher $eventDispatcher,
142
-								IShareManager $shareManager) {
143
-		$this->dbConnection = $connection;
144
-		$this->secureRandom = $secureRandom;
145
-		$this->userManager = $userManager;
146
-		$this->rootFolder = $rootFolder;
147
-		$this->l = $l;
148
-		$this->logger = $logger;
149
-		$this->mailer = $mailer;
150
-		$this->urlGenerator = $urlGenerator;
151
-		$this->activityManager = $activityManager;
152
-		$this->settingsManager = $settingsManager;
153
-		$this->defaults = $defaults;
154
-		$this->hasher = $hasher;
155
-		$this->eventDispatcher = $eventDispatcher;
156
-		$this->shareManager = $shareManager;
157
-	}
158
-
159
-	/**
160
-	 * Share a path
161
-	 *
162
-	 * @param IShare $share
163
-	 * @return IShare The share object
164
-	 * @throws ShareNotFound
165
-	 * @throws \Exception
166
-	 */
167
-	public function create(IShare $share) {
168
-		$shareWith = $share->getSharedWith();
169
-		/*
78
+    /** @var  IDBConnection */
79
+    private $dbConnection;
80
+
81
+    /** @var ILogger */
82
+    private $logger;
83
+
84
+    /** @var ISecureRandom */
85
+    private $secureRandom;
86
+
87
+    /** @var IUserManager */
88
+    private $userManager;
89
+
90
+    /** @var IRootFolder */
91
+    private $rootFolder;
92
+
93
+    /** @var IL10N */
94
+    private $l;
95
+
96
+    /** @var IMailer */
97
+    private $mailer;
98
+
99
+    /** @var IURLGenerator */
100
+    private $urlGenerator;
101
+
102
+    /** @var IManager  */
103
+    private $activityManager;
104
+
105
+    /** @var SettingsManager */
106
+    private $settingsManager;
107
+
108
+    /** @var Defaults */
109
+    private $defaults;
110
+
111
+    /** @var IHasher */
112
+    private $hasher;
113
+
114
+    /** @var IEventDispatcher */
115
+    private $eventDispatcher;
116
+
117
+    /** @var IShareManager */
118
+    private $shareManager;
119
+
120
+    /**
121
+     * Return the identifier of this provider.
122
+     *
123
+     * @return string Containing only [a-zA-Z0-9]
124
+     */
125
+    public function identifier() {
126
+        return 'ocMailShare';
127
+    }
128
+
129
+    public function __construct(IDBConnection $connection,
130
+                                ISecureRandom $secureRandom,
131
+                                IUserManager $userManager,
132
+                                IRootFolder $rootFolder,
133
+                                IL10N $l,
134
+                                ILogger $logger,
135
+                                IMailer $mailer,
136
+                                IURLGenerator $urlGenerator,
137
+                                IManager $activityManager,
138
+                                SettingsManager $settingsManager,
139
+                                Defaults $defaults,
140
+                                IHasher $hasher,
141
+                                IEventDispatcher $eventDispatcher,
142
+                                IShareManager $shareManager) {
143
+        $this->dbConnection = $connection;
144
+        $this->secureRandom = $secureRandom;
145
+        $this->userManager = $userManager;
146
+        $this->rootFolder = $rootFolder;
147
+        $this->l = $l;
148
+        $this->logger = $logger;
149
+        $this->mailer = $mailer;
150
+        $this->urlGenerator = $urlGenerator;
151
+        $this->activityManager = $activityManager;
152
+        $this->settingsManager = $settingsManager;
153
+        $this->defaults = $defaults;
154
+        $this->hasher = $hasher;
155
+        $this->eventDispatcher = $eventDispatcher;
156
+        $this->shareManager = $shareManager;
157
+    }
158
+
159
+    /**
160
+     * Share a path
161
+     *
162
+     * @param IShare $share
163
+     * @return IShare The share object
164
+     * @throws ShareNotFound
165
+     * @throws \Exception
166
+     */
167
+    public function create(IShare $share) {
168
+        $shareWith = $share->getSharedWith();
169
+        /*
170 170
 		 * Check if file is not already shared with the remote user
171 171
 		 */
172
-		$alreadyShared = $this->getSharedWith($shareWith, IShare::TYPE_EMAIL, $share->getNode(), 1, 0);
173
-		if (!empty($alreadyShared)) {
174
-			$message = 'Sharing %1$s failed, because this item is already shared with user %2$s';
175
-			$message_t = $this->l->t('Sharing %1$s failed, because this item is already shared with user %2$s', [$share->getNode()->getName(), $shareWith]);
176
-			$this->logger->debug(sprintf($message, $share->getNode()->getName(), $shareWith), ['app' => 'Federated File Sharing']);
177
-			throw new \Exception($message_t);
178
-		}
179
-
180
-		// if the admin enforces a password for all mail shares we create a
181
-		// random password and send it to the recipient
182
-		$password = $share->getPassword() ?: '';
183
-		$passwordEnforced = $this->shareManager->shareApiLinkEnforcePassword();
184
-		if ($passwordEnforced && empty($password)) {
185
-			$password = $this->autoGeneratePassword($share);
186
-		}
187
-
188
-		if (!empty($password)) {
189
-			$share->setPassword($this->hasher->hash($password));
190
-		}
191
-
192
-		$shareId = $this->createMailShare($share);
193
-		$send = $this->sendPassword($share, $password);
194
-		if ($passwordEnforced && $send === false) {
195
-			$this->sendPasswordToOwner($share, $password);
196
-		}
197
-
198
-		$this->createShareActivity($share);
199
-		$data = $this->getRawShare($shareId);
200
-
201
-		return $this->createShareObject($data);
202
-	}
203
-
204
-	/**
205
-	 * auto generate password in case of password enforcement on mail shares
206
-	 *
207
-	 * @param IShare $share
208
-	 * @return string
209
-	 * @throws \Exception
210
-	 */
211
-	protected function autoGeneratePassword($share) {
212
-		$initiatorUser = $this->userManager->get($share->getSharedBy());
213
-		$initiatorEMailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
214
-		$allowPasswordByMail = $this->settingsManager->sendPasswordByMail();
215
-
216
-		if ($initiatorEMailAddress === null && !$allowPasswordByMail) {
217
-			throw new \Exception(
218
-				$this->l->t("We cannot send you the auto-generated password. Please set a valid email address in your personal settings and try again.")
219
-			);
220
-		}
221
-
222
-		$passwordEvent = new GenerateSecurePasswordEvent();
223
-		$this->eventDispatcher->dispatchTyped($passwordEvent);
224
-
225
-		$password = $passwordEvent->getPassword();
226
-		if ($password === null) {
227
-			$password = $this->secureRandom->generate(8, ISecureRandom::CHAR_HUMAN_READABLE);
228
-		}
229
-
230
-		return $password;
231
-	}
232
-
233
-	/**
234
-	 * create activity if a file/folder was shared by mail
235
-	 *
236
-	 * @param IShare $share
237
-	 * @param string $type
238
-	 */
239
-	protected function createShareActivity(IShare $share, string $type = 'share') {
240
-		$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
241
-
242
-		$this->publishActivity(
243
-			$type === 'share' ? Activity::SUBJECT_SHARED_EMAIL_SELF : Activity::SUBJECT_UNSHARED_EMAIL_SELF,
244
-			[$userFolder->getRelativePath($share->getNode()->getPath()), $share->getSharedWith()],
245
-			$share->getSharedBy(),
246
-			$share->getNode()->getId(),
247
-			(string) $userFolder->getRelativePath($share->getNode()->getPath())
248
-		);
249
-
250
-		if ($share->getShareOwner() !== $share->getSharedBy()) {
251
-			$ownerFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
252
-			$fileId = $share->getNode()->getId();
253
-			$nodes = $ownerFolder->getById($fileId);
254
-			$ownerPath = $nodes[0]->getPath();
255
-			$this->publishActivity(
256
-				$type === 'share' ? Activity::SUBJECT_SHARED_EMAIL_BY : Activity::SUBJECT_UNSHARED_EMAIL_BY,
257
-				[$ownerFolder->getRelativePath($ownerPath), $share->getSharedWith(), $share->getSharedBy()],
258
-				$share->getShareOwner(),
259
-				$fileId,
260
-				(string) $ownerFolder->getRelativePath($ownerPath)
261
-			);
262
-		}
263
-	}
264
-
265
-	/**
266
-	 * create activity if a file/folder was shared by mail
267
-	 *
268
-	 * @param IShare $share
269
-	 * @param string $sharedWith
270
-	 * @param bool $sendToSelf
271
-	 */
272
-	protected function createPasswordSendActivity(IShare $share, $sharedWith, $sendToSelf) {
273
-		$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
274
-
275
-		if ($sendToSelf) {
276
-			$this->publishActivity(
277
-				Activity::SUBJECT_SHARED_EMAIL_PASSWORD_SEND_SELF,
278
-				[$userFolder->getRelativePath($share->getNode()->getPath())],
279
-				$share->getSharedBy(),
280
-				$share->getNode()->getId(),
281
-				(string) $userFolder->getRelativePath($share->getNode()->getPath())
282
-			);
283
-		} else {
284
-			$this->publishActivity(
285
-				Activity::SUBJECT_SHARED_EMAIL_PASSWORD_SEND,
286
-				[$userFolder->getRelativePath($share->getNode()->getPath()), $sharedWith],
287
-				$share->getSharedBy(),
288
-				$share->getNode()->getId(),
289
-				(string) $userFolder->getRelativePath($share->getNode()->getPath())
290
-			);
291
-		}
292
-	}
293
-
294
-
295
-	/**
296
-	 * publish activity if a file/folder was shared by mail
297
-	 *
298
-	 * @param string $subject
299
-	 * @param array $parameters
300
-	 * @param string $affectedUser
301
-	 * @param int $fileId
302
-	 * @param string $filePath
303
-	 */
304
-	protected function publishActivity(string $subject, array $parameters, string $affectedUser, int $fileId, string $filePath) {
305
-		$event = $this->activityManager->generateEvent();
306
-		$event->setApp('sharebymail')
307
-			->setType('shared')
308
-			->setSubject($subject, $parameters)
309
-			->setAffectedUser($affectedUser)
310
-			->setObject('files', $fileId, $filePath);
311
-		$this->activityManager->publish($event);
312
-	}
313
-
314
-	/**
315
-	 * @param IShare $share
316
-	 * @return int
317
-	 * @throws \Exception
318
-	 */
319
-	protected function createMailShare(IShare $share) {
320
-		$share->setToken($this->generateToken());
321
-		$shareId = $this->addShareToDB(
322
-			$share->getNodeId(),
323
-			$share->getNodeType(),
324
-			$share->getSharedWith(),
325
-			$share->getSharedBy(),
326
-			$share->getShareOwner(),
327
-			$share->getPermissions(),
328
-			$share->getToken(),
329
-			$share->getPassword(),
330
-			$share->getSendPasswordByTalk(),
331
-			$share->getHideDownload(),
332
-			$share->getLabel(),
333
-			$share->getExpirationDate()
334
-		);
335
-
336
-		try {
337
-			$link = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare',
338
-				['token' => $share->getToken()]);
339
-			$this->sendMailNotification(
340
-				$share->getNode()->getName(),
341
-				$link,
342
-				$share->getSharedBy(),
343
-				$share->getSharedWith(),
344
-				$share->getExpirationDate()
345
-			);
346
-		} catch (HintException $hintException) {
347
-			$this->logger->logException($hintException, [
348
-				'message' => 'Failed to send share by mail.',
349
-				'level' => ILogger::ERROR,
350
-				'app' => 'sharebymail',
351
-			]);
352
-			$this->removeShareFromTable($shareId);
353
-			throw $hintException;
354
-		} catch (\Exception $e) {
355
-			$this->logger->logException($e, [
356
-				'message' => 'Failed to send share by mail.',
357
-				'level' => ILogger::ERROR,
358
-				'app' => 'sharebymail',
359
-			]);
360
-			$this->removeShareFromTable($shareId);
361
-			throw new HintException('Failed to send share by mail',
362
-				$this->l->t('Failed to send share by email'));
363
-		}
364
-
365
-		return $shareId;
366
-	}
367
-
368
-	/**
369
-	 * @param string $filename
370
-	 * @param string $link
371
-	 * @param string $initiator
372
-	 * @param string $shareWith
373
-	 * @param \DateTime|null $expiration
374
-	 * @throws \Exception If mail couldn't be sent
375
-	 */
376
-	protected function sendMailNotification($filename,
377
-											$link,
378
-											$initiator,
379
-											$shareWith,
380
-											\DateTime $expiration = null) {
381
-		$initiatorUser = $this->userManager->get($initiator);
382
-		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
383
-		$message = $this->mailer->createMessage();
384
-
385
-		$emailTemplate = $this->mailer->createEMailTemplate('sharebymail.RecipientNotification', [
386
-			'filename' => $filename,
387
-			'link' => $link,
388
-			'initiator' => $initiatorDisplayName,
389
-			'expiration' => $expiration,
390
-			'shareWith' => $shareWith,
391
-		]);
392
-
393
-		$emailTemplate->setSubject($this->l->t('%1$s shared »%2$s« with you', [$initiatorDisplayName, $filename]));
394
-		$emailTemplate->addHeader();
395
-		$emailTemplate->addHeading($this->l->t('%1$s shared »%2$s« with you', [$initiatorDisplayName, $filename]), false);
396
-		$text = $this->l->t('%1$s shared »%2$s« with you.', [$initiatorDisplayName, $filename]);
397
-
398
-		$emailTemplate->addBodyText(
399
-			htmlspecialchars($text . ' ' . $this->l->t('Click the button below to open it.')),
400
-			$text
401
-		);
402
-		$emailTemplate->addBodyButton(
403
-			$this->l->t('Open »%s«', [$filename]),
404
-			$link
405
-		);
406
-
407
-		$message->setTo([$shareWith]);
408
-
409
-		// The "From" contains the sharers name
410
-		$instanceName = $this->defaults->getName();
411
-		$senderName = $instanceName;
412
-		if ($this->settingsManager->replyToInitiator()) {
413
-			$senderName = $this->l->t(
414
-				'%1$s via %2$s',
415
-				[
416
-					$initiatorDisplayName,
417
-					$instanceName
418
-				]
419
-			);
420
-		}
421
-		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
422
-
423
-		// The "Reply-To" is set to the sharer if an mail address is configured
424
-		// also the default footer contains a "Do not reply" which needs to be adjusted.
425
-		$initiatorEmail = $initiatorUser->getEMailAddress();
426
-		if ($this->settingsManager->replyToInitiator() && $initiatorEmail !== null) {
427
-			$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
428
-			$emailTemplate->addFooter($instanceName . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : ''));
429
-		} else {
430
-			$emailTemplate->addFooter();
431
-		}
432
-
433
-		$message->useTemplate($emailTemplate);
434
-		$this->mailer->send($message);
435
-	}
436
-
437
-	/**
438
-	 * send password to recipient of a mail share
439
-	 *
440
-	 * @param IShare $share
441
-	 * @param string $password
442
-	 * @return bool
443
-	 */
444
-	protected function sendPassword(IShare $share, $password) {
445
-		$filename = $share->getNode()->getName();
446
-		$initiator = $share->getSharedBy();
447
-		$shareWith = $share->getSharedWith();
448
-
449
-		if ($password === '' || $this->settingsManager->sendPasswordByMail() === false || $share->getSendPasswordByTalk()) {
450
-			return false;
451
-		}
452
-
453
-		$initiatorUser = $this->userManager->get($initiator);
454
-		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
455
-		$initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
456
-
457
-		$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]);
458
-		$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]);
459
-
460
-		$message = $this->mailer->createMessage();
461
-
462
-		$emailTemplate = $this->mailer->createEMailTemplate('sharebymail.RecipientPasswordNotification', [
463
-			'filename' => $filename,
464
-			'password' => $password,
465
-			'initiator' => $initiatorDisplayName,
466
-			'initiatorEmail' => $initiatorEmailAddress,
467
-			'shareWith' => $shareWith,
468
-		]);
469
-
470
-		$emailTemplate->setSubject($this->l->t('Password to access »%1$s« shared to you by %2$s', [$filename, $initiatorDisplayName]));
471
-		$emailTemplate->addHeader();
472
-		$emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
473
-		$emailTemplate->addBodyText(htmlspecialchars($htmlBodyPart), $plainBodyPart);
474
-		$emailTemplate->addBodyText($this->l->t('It is protected with the following password:'));
475
-		$emailTemplate->addBodyText($password);
476
-
477
-		// The "From" contains the sharers name
478
-		$instanceName = $this->defaults->getName();
479
-		$senderName = $instanceName;
480
-		if ($this->settingsManager->replyToInitiator()) {
481
-			$senderName = $this->l->t(
482
-				'%1$s via %2$s',
483
-				[
484
-					$initiatorDisplayName,
485
-					$instanceName
486
-				]
487
-			);
488
-		}
489
-		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
490
-		if ($this->settingsManager->replyToInitiator() && $initiatorEmailAddress !== null) {
491
-			$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
492
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
493
-		} else {
494
-			$emailTemplate->addFooter();
495
-		}
496
-
497
-		$message->setTo([$shareWith]);
498
-		$message->useTemplate($emailTemplate);
499
-		$this->mailer->send($message);
500
-
501
-		$this->createPasswordSendActivity($share, $shareWith, false);
502
-
503
-		return true;
504
-	}
505
-
506
-	protected function sendNote(IShare $share) {
507
-		$recipient = $share->getSharedWith();
508
-
509
-
510
-		$filename = $share->getNode()->getName();
511
-		$initiator = $share->getSharedBy();
512
-		$note = $share->getNote();
513
-
514
-		$initiatorUser = $this->userManager->get($initiator);
515
-		$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
516
-		$initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
517
-
518
-		$plainHeading = $this->l->t('%1$s shared »%2$s« with you and wants to add:', [$initiatorDisplayName, $filename]);
519
-		$htmlHeading = $this->l->t('%1$s shared »%2$s« with you and wants to add', [$initiatorDisplayName, $filename]);
520
-
521
-		$message = $this->mailer->createMessage();
522
-
523
-		$emailTemplate = $this->mailer->createEMailTemplate('shareByMail.sendNote');
524
-
525
-		$emailTemplate->setSubject($this->l->t('»%s« added a note to a file shared with you', [$initiatorDisplayName]));
526
-		$emailTemplate->addHeader();
527
-		$emailTemplate->addHeading(htmlspecialchars($htmlHeading), $plainHeading);
528
-		$emailTemplate->addBodyText(htmlspecialchars($note), $note);
529
-
530
-		$link = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare',
531
-			['token' => $share->getToken()]);
532
-		$emailTemplate->addBodyButton(
533
-			$this->l->t('Open »%s«', [$filename]),
534
-			$link
535
-		);
536
-
537
-		// The "From" contains the sharers name
538
-		$instanceName = $this->defaults->getName();
539
-		$senderName = $instanceName;
540
-		if ($this->settingsManager->replyToInitiator()) {
541
-			$senderName = $this->l->t(
542
-				'%1$s via %2$s',
543
-				[
544
-					$initiatorDisplayName,
545
-					$instanceName
546
-				]
547
-			);
548
-		}
549
-		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
550
-		if ($this->settingsManager->replyToInitiator() && $initiatorEmailAddress !== null) {
551
-			$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
552
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
553
-		} else {
554
-			$emailTemplate->addFooter();
555
-		}
556
-
557
-		$message->setTo([$recipient]);
558
-		$message->useTemplate($emailTemplate);
559
-		$this->mailer->send($message);
560
-	}
561
-
562
-	/**
563
-	 * send auto generated password to the owner. This happens if the admin enforces
564
-	 * a password for mail shares and forbid to send the password by mail to the recipient
565
-	 *
566
-	 * @param IShare $share
567
-	 * @param string $password
568
-	 * @return bool
569
-	 * @throws \Exception
570
-	 */
571
-	protected function sendPasswordToOwner(IShare $share, $password) {
572
-		$filename = $share->getNode()->getName();
573
-		$initiator = $this->userManager->get($share->getSharedBy());
574
-		$initiatorEMailAddress = ($initiator instanceof IUser) ? $initiator->getEMailAddress() : null;
575
-		$initiatorDisplayName = ($initiator instanceof IUser) ? $initiator->getDisplayName() : $share->getSharedBy();
576
-		$shareWith = $share->getSharedWith();
577
-
578
-		if ($initiatorEMailAddress === null) {
579
-			throw new \Exception(
580
-				$this->l->t("We cannot send you the auto-generated password. Please set a valid email address in your personal settings and try again.")
581
-			);
582
-		}
583
-
584
-		$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()]);
585
-
586
-		$message = $this->mailer->createMessage();
587
-		$emailTemplate = $this->mailer->createEMailTemplate('sharebymail.OwnerPasswordNotification', [
588
-			'filename' => $filename,
589
-			'password' => $password,
590
-			'initiator' => $initiatorDisplayName,
591
-			'initiatorEmail' => $initiatorEMailAddress,
592
-			'shareWith' => $shareWith,
593
-		]);
594
-
595
-		$emailTemplate->setSubject($this->l->t('Password to access »%1$s« shared by you with %2$s', [$filename, $shareWith]));
596
-		$emailTemplate->addHeader();
597
-		$emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
598
-		$emailTemplate->addBodyText($bodyPart);
599
-		$emailTemplate->addBodyText($this->l->t('This is the password:'));
600
-		$emailTemplate->addBodyText($password);
601
-		$emailTemplate->addBodyText($this->l->t('You can choose a different password at any time in the share dialog.'));
602
-		$emailTemplate->addFooter();
603
-
604
-		$instanceName = $this->defaults->getName();
605
-		$senderName = $this->l->t(
606
-			'%1$s via %2$s',
607
-			[
608
-				$initiatorDisplayName,
609
-				$instanceName
610
-			]
611
-		);
612
-		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
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(IShare::TYPE_EMAIL)))
646
-			->orderBy('id');
647
-
648
-		$cursor = $qb->executeQuery();
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
-	 * @param bool $hideDownload
670
-	 * @param string $label
671
-	 * @param \DateTime|null $expirationTime
672
-	 * @return int
673
-	 */
674
-	protected function addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token, $password, $sendPasswordByTalk, $hideDownload, $label, $expirationTime) {
675
-		$qb = $this->dbConnection->getQueryBuilder();
676
-		$qb->insert('share')
677
-			->setValue('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL))
678
-			->setValue('item_type', $qb->createNamedParameter($itemType))
679
-			->setValue('item_source', $qb->createNamedParameter($itemSource))
680
-			->setValue('file_source', $qb->createNamedParameter($itemSource))
681
-			->setValue('share_with', $qb->createNamedParameter($shareWith))
682
-			->setValue('uid_owner', $qb->createNamedParameter($uidOwner))
683
-			->setValue('uid_initiator', $qb->createNamedParameter($sharedBy))
684
-			->setValue('permissions', $qb->createNamedParameter($permissions))
685
-			->setValue('token', $qb->createNamedParameter($token))
686
-			->setValue('password', $qb->createNamedParameter($password))
687
-			->setValue('password_by_talk', $qb->createNamedParameter($sendPasswordByTalk, IQueryBuilder::PARAM_BOOL))
688
-			->setValue('stime', $qb->createNamedParameter(time()))
689
-			->setValue('hide_download', $qb->createNamedParameter((int)$hideDownload, IQueryBuilder::PARAM_INT))
690
-			->setValue('label', $qb->createNamedParameter($label));
691
-
692
-		if ($expirationTime !== null) {
693
-			$qb->setValue('expiration', $qb->createNamedParameter($expirationTime, IQueryBuilder::PARAM_DATE));
694
-		}
695
-
696
-		/*
172
+        $alreadyShared = $this->getSharedWith($shareWith, IShare::TYPE_EMAIL, $share->getNode(), 1, 0);
173
+        if (!empty($alreadyShared)) {
174
+            $message = 'Sharing %1$s failed, because this item is already shared with user %2$s';
175
+            $message_t = $this->l->t('Sharing %1$s failed, because this item is already shared with user %2$s', [$share->getNode()->getName(), $shareWith]);
176
+            $this->logger->debug(sprintf($message, $share->getNode()->getName(), $shareWith), ['app' => 'Federated File Sharing']);
177
+            throw new \Exception($message_t);
178
+        }
179
+
180
+        // if the admin enforces a password for all mail shares we create a
181
+        // random password and send it to the recipient
182
+        $password = $share->getPassword() ?: '';
183
+        $passwordEnforced = $this->shareManager->shareApiLinkEnforcePassword();
184
+        if ($passwordEnforced && empty($password)) {
185
+            $password = $this->autoGeneratePassword($share);
186
+        }
187
+
188
+        if (!empty($password)) {
189
+            $share->setPassword($this->hasher->hash($password));
190
+        }
191
+
192
+        $shareId = $this->createMailShare($share);
193
+        $send = $this->sendPassword($share, $password);
194
+        if ($passwordEnforced && $send === false) {
195
+            $this->sendPasswordToOwner($share, $password);
196
+        }
197
+
198
+        $this->createShareActivity($share);
199
+        $data = $this->getRawShare($shareId);
200
+
201
+        return $this->createShareObject($data);
202
+    }
203
+
204
+    /**
205
+     * auto generate password in case of password enforcement on mail shares
206
+     *
207
+     * @param IShare $share
208
+     * @return string
209
+     * @throws \Exception
210
+     */
211
+    protected function autoGeneratePassword($share) {
212
+        $initiatorUser = $this->userManager->get($share->getSharedBy());
213
+        $initiatorEMailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
214
+        $allowPasswordByMail = $this->settingsManager->sendPasswordByMail();
215
+
216
+        if ($initiatorEMailAddress === null && !$allowPasswordByMail) {
217
+            throw new \Exception(
218
+                $this->l->t("We cannot send you the auto-generated password. Please set a valid email address in your personal settings and try again.")
219
+            );
220
+        }
221
+
222
+        $passwordEvent = new GenerateSecurePasswordEvent();
223
+        $this->eventDispatcher->dispatchTyped($passwordEvent);
224
+
225
+        $password = $passwordEvent->getPassword();
226
+        if ($password === null) {
227
+            $password = $this->secureRandom->generate(8, ISecureRandom::CHAR_HUMAN_READABLE);
228
+        }
229
+
230
+        return $password;
231
+    }
232
+
233
+    /**
234
+     * create activity if a file/folder was shared by mail
235
+     *
236
+     * @param IShare $share
237
+     * @param string $type
238
+     */
239
+    protected function createShareActivity(IShare $share, string $type = 'share') {
240
+        $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
241
+
242
+        $this->publishActivity(
243
+            $type === 'share' ? Activity::SUBJECT_SHARED_EMAIL_SELF : Activity::SUBJECT_UNSHARED_EMAIL_SELF,
244
+            [$userFolder->getRelativePath($share->getNode()->getPath()), $share->getSharedWith()],
245
+            $share->getSharedBy(),
246
+            $share->getNode()->getId(),
247
+            (string) $userFolder->getRelativePath($share->getNode()->getPath())
248
+        );
249
+
250
+        if ($share->getShareOwner() !== $share->getSharedBy()) {
251
+            $ownerFolder = $this->rootFolder->getUserFolder($share->getShareOwner());
252
+            $fileId = $share->getNode()->getId();
253
+            $nodes = $ownerFolder->getById($fileId);
254
+            $ownerPath = $nodes[0]->getPath();
255
+            $this->publishActivity(
256
+                $type === 'share' ? Activity::SUBJECT_SHARED_EMAIL_BY : Activity::SUBJECT_UNSHARED_EMAIL_BY,
257
+                [$ownerFolder->getRelativePath($ownerPath), $share->getSharedWith(), $share->getSharedBy()],
258
+                $share->getShareOwner(),
259
+                $fileId,
260
+                (string) $ownerFolder->getRelativePath($ownerPath)
261
+            );
262
+        }
263
+    }
264
+
265
+    /**
266
+     * create activity if a file/folder was shared by mail
267
+     *
268
+     * @param IShare $share
269
+     * @param string $sharedWith
270
+     * @param bool $sendToSelf
271
+     */
272
+    protected function createPasswordSendActivity(IShare $share, $sharedWith, $sendToSelf) {
273
+        $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
274
+
275
+        if ($sendToSelf) {
276
+            $this->publishActivity(
277
+                Activity::SUBJECT_SHARED_EMAIL_PASSWORD_SEND_SELF,
278
+                [$userFolder->getRelativePath($share->getNode()->getPath())],
279
+                $share->getSharedBy(),
280
+                $share->getNode()->getId(),
281
+                (string) $userFolder->getRelativePath($share->getNode()->getPath())
282
+            );
283
+        } else {
284
+            $this->publishActivity(
285
+                Activity::SUBJECT_SHARED_EMAIL_PASSWORD_SEND,
286
+                [$userFolder->getRelativePath($share->getNode()->getPath()), $sharedWith],
287
+                $share->getSharedBy(),
288
+                $share->getNode()->getId(),
289
+                (string) $userFolder->getRelativePath($share->getNode()->getPath())
290
+            );
291
+        }
292
+    }
293
+
294
+
295
+    /**
296
+     * publish activity if a file/folder was shared by mail
297
+     *
298
+     * @param string $subject
299
+     * @param array $parameters
300
+     * @param string $affectedUser
301
+     * @param int $fileId
302
+     * @param string $filePath
303
+     */
304
+    protected function publishActivity(string $subject, array $parameters, string $affectedUser, int $fileId, string $filePath) {
305
+        $event = $this->activityManager->generateEvent();
306
+        $event->setApp('sharebymail')
307
+            ->setType('shared')
308
+            ->setSubject($subject, $parameters)
309
+            ->setAffectedUser($affectedUser)
310
+            ->setObject('files', $fileId, $filePath);
311
+        $this->activityManager->publish($event);
312
+    }
313
+
314
+    /**
315
+     * @param IShare $share
316
+     * @return int
317
+     * @throws \Exception
318
+     */
319
+    protected function createMailShare(IShare $share) {
320
+        $share->setToken($this->generateToken());
321
+        $shareId = $this->addShareToDB(
322
+            $share->getNodeId(),
323
+            $share->getNodeType(),
324
+            $share->getSharedWith(),
325
+            $share->getSharedBy(),
326
+            $share->getShareOwner(),
327
+            $share->getPermissions(),
328
+            $share->getToken(),
329
+            $share->getPassword(),
330
+            $share->getSendPasswordByTalk(),
331
+            $share->getHideDownload(),
332
+            $share->getLabel(),
333
+            $share->getExpirationDate()
334
+        );
335
+
336
+        try {
337
+            $link = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare',
338
+                ['token' => $share->getToken()]);
339
+            $this->sendMailNotification(
340
+                $share->getNode()->getName(),
341
+                $link,
342
+                $share->getSharedBy(),
343
+                $share->getSharedWith(),
344
+                $share->getExpirationDate()
345
+            );
346
+        } catch (HintException $hintException) {
347
+            $this->logger->logException($hintException, [
348
+                'message' => 'Failed to send share by mail.',
349
+                'level' => ILogger::ERROR,
350
+                'app' => 'sharebymail',
351
+            ]);
352
+            $this->removeShareFromTable($shareId);
353
+            throw $hintException;
354
+        } catch (\Exception $e) {
355
+            $this->logger->logException($e, [
356
+                'message' => 'Failed to send share by mail.',
357
+                'level' => ILogger::ERROR,
358
+                'app' => 'sharebymail',
359
+            ]);
360
+            $this->removeShareFromTable($shareId);
361
+            throw new HintException('Failed to send share by mail',
362
+                $this->l->t('Failed to send share by email'));
363
+        }
364
+
365
+        return $shareId;
366
+    }
367
+
368
+    /**
369
+     * @param string $filename
370
+     * @param string $link
371
+     * @param string $initiator
372
+     * @param string $shareWith
373
+     * @param \DateTime|null $expiration
374
+     * @throws \Exception If mail couldn't be sent
375
+     */
376
+    protected function sendMailNotification($filename,
377
+                                            $link,
378
+                                            $initiator,
379
+                                            $shareWith,
380
+                                            \DateTime $expiration = null) {
381
+        $initiatorUser = $this->userManager->get($initiator);
382
+        $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
383
+        $message = $this->mailer->createMessage();
384
+
385
+        $emailTemplate = $this->mailer->createEMailTemplate('sharebymail.RecipientNotification', [
386
+            'filename' => $filename,
387
+            'link' => $link,
388
+            'initiator' => $initiatorDisplayName,
389
+            'expiration' => $expiration,
390
+            'shareWith' => $shareWith,
391
+        ]);
392
+
393
+        $emailTemplate->setSubject($this->l->t('%1$s shared »%2$s« with you', [$initiatorDisplayName, $filename]));
394
+        $emailTemplate->addHeader();
395
+        $emailTemplate->addHeading($this->l->t('%1$s shared »%2$s« with you', [$initiatorDisplayName, $filename]), false);
396
+        $text = $this->l->t('%1$s shared »%2$s« with you.', [$initiatorDisplayName, $filename]);
397
+
398
+        $emailTemplate->addBodyText(
399
+            htmlspecialchars($text . ' ' . $this->l->t('Click the button below to open it.')),
400
+            $text
401
+        );
402
+        $emailTemplate->addBodyButton(
403
+            $this->l->t('Open »%s«', [$filename]),
404
+            $link
405
+        );
406
+
407
+        $message->setTo([$shareWith]);
408
+
409
+        // The "From" contains the sharers name
410
+        $instanceName = $this->defaults->getName();
411
+        $senderName = $instanceName;
412
+        if ($this->settingsManager->replyToInitiator()) {
413
+            $senderName = $this->l->t(
414
+                '%1$s via %2$s',
415
+                [
416
+                    $initiatorDisplayName,
417
+                    $instanceName
418
+                ]
419
+            );
420
+        }
421
+        $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
422
+
423
+        // The "Reply-To" is set to the sharer if an mail address is configured
424
+        // also the default footer contains a "Do not reply" which needs to be adjusted.
425
+        $initiatorEmail = $initiatorUser->getEMailAddress();
426
+        if ($this->settingsManager->replyToInitiator() && $initiatorEmail !== null) {
427
+            $message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
428
+            $emailTemplate->addFooter($instanceName . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : ''));
429
+        } else {
430
+            $emailTemplate->addFooter();
431
+        }
432
+
433
+        $message->useTemplate($emailTemplate);
434
+        $this->mailer->send($message);
435
+    }
436
+
437
+    /**
438
+     * send password to recipient of a mail share
439
+     *
440
+     * @param IShare $share
441
+     * @param string $password
442
+     * @return bool
443
+     */
444
+    protected function sendPassword(IShare $share, $password) {
445
+        $filename = $share->getNode()->getName();
446
+        $initiator = $share->getSharedBy();
447
+        $shareWith = $share->getSharedWith();
448
+
449
+        if ($password === '' || $this->settingsManager->sendPasswordByMail() === false || $share->getSendPasswordByTalk()) {
450
+            return false;
451
+        }
452
+
453
+        $initiatorUser = $this->userManager->get($initiator);
454
+        $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
455
+        $initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
456
+
457
+        $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]);
458
+        $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]);
459
+
460
+        $message = $this->mailer->createMessage();
461
+
462
+        $emailTemplate = $this->mailer->createEMailTemplate('sharebymail.RecipientPasswordNotification', [
463
+            'filename' => $filename,
464
+            'password' => $password,
465
+            'initiator' => $initiatorDisplayName,
466
+            'initiatorEmail' => $initiatorEmailAddress,
467
+            'shareWith' => $shareWith,
468
+        ]);
469
+
470
+        $emailTemplate->setSubject($this->l->t('Password to access »%1$s« shared to you by %2$s', [$filename, $initiatorDisplayName]));
471
+        $emailTemplate->addHeader();
472
+        $emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
473
+        $emailTemplate->addBodyText(htmlspecialchars($htmlBodyPart), $plainBodyPart);
474
+        $emailTemplate->addBodyText($this->l->t('It is protected with the following password:'));
475
+        $emailTemplate->addBodyText($password);
476
+
477
+        // The "From" contains the sharers name
478
+        $instanceName = $this->defaults->getName();
479
+        $senderName = $instanceName;
480
+        if ($this->settingsManager->replyToInitiator()) {
481
+            $senderName = $this->l->t(
482
+                '%1$s via %2$s',
483
+                [
484
+                    $initiatorDisplayName,
485
+                    $instanceName
486
+                ]
487
+            );
488
+        }
489
+        $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
490
+        if ($this->settingsManager->replyToInitiator() && $initiatorEmailAddress !== null) {
491
+            $message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
492
+            $emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
493
+        } else {
494
+            $emailTemplate->addFooter();
495
+        }
496
+
497
+        $message->setTo([$shareWith]);
498
+        $message->useTemplate($emailTemplate);
499
+        $this->mailer->send($message);
500
+
501
+        $this->createPasswordSendActivity($share, $shareWith, false);
502
+
503
+        return true;
504
+    }
505
+
506
+    protected function sendNote(IShare $share) {
507
+        $recipient = $share->getSharedWith();
508
+
509
+
510
+        $filename = $share->getNode()->getName();
511
+        $initiator = $share->getSharedBy();
512
+        $note = $share->getNote();
513
+
514
+        $initiatorUser = $this->userManager->get($initiator);
515
+        $initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
516
+        $initiatorEmailAddress = ($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
517
+
518
+        $plainHeading = $this->l->t('%1$s shared »%2$s« with you and wants to add:', [$initiatorDisplayName, $filename]);
519
+        $htmlHeading = $this->l->t('%1$s shared »%2$s« with you and wants to add', [$initiatorDisplayName, $filename]);
520
+
521
+        $message = $this->mailer->createMessage();
522
+
523
+        $emailTemplate = $this->mailer->createEMailTemplate('shareByMail.sendNote');
524
+
525
+        $emailTemplate->setSubject($this->l->t('»%s« added a note to a file shared with you', [$initiatorDisplayName]));
526
+        $emailTemplate->addHeader();
527
+        $emailTemplate->addHeading(htmlspecialchars($htmlHeading), $plainHeading);
528
+        $emailTemplate->addBodyText(htmlspecialchars($note), $note);
529
+
530
+        $link = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare',
531
+            ['token' => $share->getToken()]);
532
+        $emailTemplate->addBodyButton(
533
+            $this->l->t('Open »%s«', [$filename]),
534
+            $link
535
+        );
536
+
537
+        // The "From" contains the sharers name
538
+        $instanceName = $this->defaults->getName();
539
+        $senderName = $instanceName;
540
+        if ($this->settingsManager->replyToInitiator()) {
541
+            $senderName = $this->l->t(
542
+                '%1$s via %2$s',
543
+                [
544
+                    $initiatorDisplayName,
545
+                    $instanceName
546
+                ]
547
+            );
548
+        }
549
+        $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
550
+        if ($this->settingsManager->replyToInitiator() && $initiatorEmailAddress !== null) {
551
+            $message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
552
+            $emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
553
+        } else {
554
+            $emailTemplate->addFooter();
555
+        }
556
+
557
+        $message->setTo([$recipient]);
558
+        $message->useTemplate($emailTemplate);
559
+        $this->mailer->send($message);
560
+    }
561
+
562
+    /**
563
+     * send auto generated password to the owner. This happens if the admin enforces
564
+     * a password for mail shares and forbid to send the password by mail to the recipient
565
+     *
566
+     * @param IShare $share
567
+     * @param string $password
568
+     * @return bool
569
+     * @throws \Exception
570
+     */
571
+    protected function sendPasswordToOwner(IShare $share, $password) {
572
+        $filename = $share->getNode()->getName();
573
+        $initiator = $this->userManager->get($share->getSharedBy());
574
+        $initiatorEMailAddress = ($initiator instanceof IUser) ? $initiator->getEMailAddress() : null;
575
+        $initiatorDisplayName = ($initiator instanceof IUser) ? $initiator->getDisplayName() : $share->getSharedBy();
576
+        $shareWith = $share->getSharedWith();
577
+
578
+        if ($initiatorEMailAddress === null) {
579
+            throw new \Exception(
580
+                $this->l->t("We cannot send you the auto-generated password. Please set a valid email address in your personal settings and try again.")
581
+            );
582
+        }
583
+
584
+        $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()]);
585
+
586
+        $message = $this->mailer->createMessage();
587
+        $emailTemplate = $this->mailer->createEMailTemplate('sharebymail.OwnerPasswordNotification', [
588
+            'filename' => $filename,
589
+            'password' => $password,
590
+            'initiator' => $initiatorDisplayName,
591
+            'initiatorEmail' => $initiatorEMailAddress,
592
+            'shareWith' => $shareWith,
593
+        ]);
594
+
595
+        $emailTemplate->setSubject($this->l->t('Password to access »%1$s« shared by you with %2$s', [$filename, $shareWith]));
596
+        $emailTemplate->addHeader();
597
+        $emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename]), false);
598
+        $emailTemplate->addBodyText($bodyPart);
599
+        $emailTemplate->addBodyText($this->l->t('This is the password:'));
600
+        $emailTemplate->addBodyText($password);
601
+        $emailTemplate->addBodyText($this->l->t('You can choose a different password at any time in the share dialog.'));
602
+        $emailTemplate->addFooter();
603
+
604
+        $instanceName = $this->defaults->getName();
605
+        $senderName = $this->l->t(
606
+            '%1$s via %2$s',
607
+            [
608
+                $initiatorDisplayName,
609
+                $instanceName
610
+            ]
611
+        );
612
+        $message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
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(IShare::TYPE_EMAIL)))
646
+            ->orderBy('id');
647
+
648
+        $cursor = $qb->executeQuery();
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
+     * @param bool $hideDownload
670
+     * @param string $label
671
+     * @param \DateTime|null $expirationTime
672
+     * @return int
673
+     */
674
+    protected function addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token, $password, $sendPasswordByTalk, $hideDownload, $label, $expirationTime) {
675
+        $qb = $this->dbConnection->getQueryBuilder();
676
+        $qb->insert('share')
677
+            ->setValue('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL))
678
+            ->setValue('item_type', $qb->createNamedParameter($itemType))
679
+            ->setValue('item_source', $qb->createNamedParameter($itemSource))
680
+            ->setValue('file_source', $qb->createNamedParameter($itemSource))
681
+            ->setValue('share_with', $qb->createNamedParameter($shareWith))
682
+            ->setValue('uid_owner', $qb->createNamedParameter($uidOwner))
683
+            ->setValue('uid_initiator', $qb->createNamedParameter($sharedBy))
684
+            ->setValue('permissions', $qb->createNamedParameter($permissions))
685
+            ->setValue('token', $qb->createNamedParameter($token))
686
+            ->setValue('password', $qb->createNamedParameter($password))
687
+            ->setValue('password_by_talk', $qb->createNamedParameter($sendPasswordByTalk, IQueryBuilder::PARAM_BOOL))
688
+            ->setValue('stime', $qb->createNamedParameter(time()))
689
+            ->setValue('hide_download', $qb->createNamedParameter((int)$hideDownload, IQueryBuilder::PARAM_INT))
690
+            ->setValue('label', $qb->createNamedParameter($label));
691
+
692
+        if ($expirationTime !== null) {
693
+            $qb->setValue('expiration', $qb->createNamedParameter($expirationTime, IQueryBuilder::PARAM_DATE));
694
+        }
695
+
696
+        /*
697 697
 		 * Added to fix https://github.com/owncloud/core/issues/22215
698 698
 		 * Can be removed once we get rid of ajax/share.php
699 699
 		 */
700
-		$qb->setValue('file_target', $qb->createNamedParameter(''));
701
-
702
-		$qb->executeStatement();
703
-		return $qb->getLastInsertId();
704
-	}
705
-
706
-	/**
707
-	 * Update a share
708
-	 *
709
-	 * @param IShare $share
710
-	 * @param string|null $plainTextPassword
711
-	 * @return IShare The share object
712
-	 */
713
-	public function update(IShare $share, $plainTextPassword = null) {
714
-		$originalShare = $this->getShareById($share->getId());
715
-
716
-		// a real password was given
717
-		$validPassword = $plainTextPassword !== null && $plainTextPassword !== '';
718
-
719
-		if ($validPassword && ($originalShare->getPassword() !== $share->getPassword() ||
720
-								($originalShare->getSendPasswordByTalk() && !$share->getSendPasswordByTalk()))) {
721
-			$this->sendPassword($share, $plainTextPassword);
722
-		}
723
-		/*
700
+        $qb->setValue('file_target', $qb->createNamedParameter(''));
701
+
702
+        $qb->executeStatement();
703
+        return $qb->getLastInsertId();
704
+    }
705
+
706
+    /**
707
+     * Update a share
708
+     *
709
+     * @param IShare $share
710
+     * @param string|null $plainTextPassword
711
+     * @return IShare The share object
712
+     */
713
+    public function update(IShare $share, $plainTextPassword = null) {
714
+        $originalShare = $this->getShareById($share->getId());
715
+
716
+        // a real password was given
717
+        $validPassword = $plainTextPassword !== null && $plainTextPassword !== '';
718
+
719
+        if ($validPassword && ($originalShare->getPassword() !== $share->getPassword() ||
720
+                                ($originalShare->getSendPasswordByTalk() && !$share->getSendPasswordByTalk()))) {
721
+            $this->sendPassword($share, $plainTextPassword);
722
+        }
723
+        /*
724 724
 		 * We allow updating the permissions and password of mail shares
725 725
 		 */
726
-		$qb = $this->dbConnection->getQueryBuilder();
727
-		$qb->update('share')
728
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
729
-			->set('permissions', $qb->createNamedParameter($share->getPermissions()))
730
-			->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
731
-			->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
732
-			->set('password', $qb->createNamedParameter($share->getPassword()))
733
-			->set('label', $qb->createNamedParameter($share->getLabel()))
734
-			->set('password_by_talk', $qb->createNamedParameter($share->getSendPasswordByTalk(), IQueryBuilder::PARAM_BOOL))
735
-			->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
736
-			->set('note', $qb->createNamedParameter($share->getNote()))
737
-			->set('hide_download', $qb->createNamedParameter((int)$share->getHideDownload(), IQueryBuilder::PARAM_INT))
738
-			->executeStatement();
739
-
740
-		if ($originalShare->getNote() !== $share->getNote() && $share->getNote() !== '') {
741
-			$this->sendNote($share);
742
-		}
743
-
744
-		return $share;
745
-	}
746
-
747
-	/**
748
-	 * @inheritdoc
749
-	 */
750
-	public function move(IShare $share, $recipient) {
751
-		/**
752
-		 * nothing to do here, mail shares are only outgoing shares
753
-		 */
754
-		return $share;
755
-	}
756
-
757
-	/**
758
-	 * Delete a share (owner unShares the file)
759
-	 *
760
-	 * @param IShare $share
761
-	 */
762
-	public function delete(IShare $share) {
763
-		try {
764
-			$this->createShareActivity($share, 'unshare');
765
-		} catch (\Exception $e) {
766
-		}
767
-
768
-		$this->removeShareFromTable($share->getId());
769
-	}
770
-
771
-	/**
772
-	 * @inheritdoc
773
-	 */
774
-	public function deleteFromSelf(IShare $share, $recipient) {
775
-		// nothing to do here, mail shares are only outgoing shares
776
-	}
777
-
778
-	public function restore(IShare $share, string $recipient): IShare {
779
-		throw new GenericShareException('not implemented');
780
-	}
781
-
782
-	/**
783
-	 * @inheritdoc
784
-	 */
785
-	public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
786
-		$qb = $this->dbConnection->getQueryBuilder();
787
-		$qb->select('*')
788
-			->from('share');
789
-
790
-		$qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)));
791
-
792
-		/**
793
-		 * Reshares for this user are shares where they are the owner.
794
-		 */
795
-		if ($reshares === false) {
796
-			//Special case for old shares created via the web UI
797
-			$or1 = $qb->expr()->andX(
798
-				$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
799
-				$qb->expr()->isNull('uid_initiator')
800
-			);
801
-
802
-			$qb->andWhere(
803
-				$qb->expr()->orX(
804
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)),
805
-					$or1
806
-				)
807
-			);
808
-		} else {
809
-			$qb->andWhere(
810
-				$qb->expr()->orX(
811
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
812
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
813
-				)
814
-			);
815
-		}
816
-
817
-		if ($node !== null) {
818
-			$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
819
-		}
820
-
821
-		if ($limit !== -1) {
822
-			$qb->setMaxResults($limit);
823
-		}
824
-
825
-		$qb->setFirstResult($offset);
826
-		$qb->orderBy('id');
827
-
828
-		$cursor = $qb->executeQuery();
829
-		$shares = [];
830
-		while ($data = $cursor->fetch()) {
831
-			$shares[] = $this->createShareObject($data);
832
-		}
833
-		$cursor->closeCursor();
834
-
835
-		return $shares;
836
-	}
837
-
838
-	/**
839
-	 * @inheritdoc
840
-	 */
841
-	public function getShareById($id, $recipientId = null) {
842
-		$qb = $this->dbConnection->getQueryBuilder();
843
-
844
-		$qb->select('*')
845
-			->from('share')
846
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
847
-			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)));
848
-
849
-		$cursor = $qb->executeQuery();
850
-		$data = $cursor->fetch();
851
-		$cursor->closeCursor();
852
-
853
-		if ($data === false) {
854
-			throw new ShareNotFound();
855
-		}
856
-
857
-		try {
858
-			$share = $this->createShareObject($data);
859
-		} catch (InvalidShare $e) {
860
-			throw new ShareNotFound();
861
-		}
862
-
863
-		return $share;
864
-	}
865
-
866
-	/**
867
-	 * Get shares for a given path
868
-	 *
869
-	 * @param \OCP\Files\Node $path
870
-	 * @return IShare[]
871
-	 */
872
-	public function getSharesByPath(Node $path) {
873
-		$qb = $this->dbConnection->getQueryBuilder();
874
-
875
-		$cursor = $qb->select('*')
876
-			->from('share')
877
-			->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
878
-			->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)))
879
-			->executeQuery();
880
-
881
-		$shares = [];
882
-		while ($data = $cursor->fetch()) {
883
-			$shares[] = $this->createShareObject($data);
884
-		}
885
-		$cursor->closeCursor();
886
-
887
-		return $shares;
888
-	}
889
-
890
-	/**
891
-	 * @inheritdoc
892
-	 */
893
-	public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
894
-		/** @var IShare[] $shares */
895
-		$shares = [];
896
-
897
-		//Get shares directly with this user
898
-		$qb = $this->dbConnection->getQueryBuilder();
899
-		$qb->select('*')
900
-			->from('share');
901
-
902
-		// Order by id
903
-		$qb->orderBy('id');
904
-
905
-		// Set limit and offset
906
-		if ($limit !== -1) {
907
-			$qb->setMaxResults($limit);
908
-		}
909
-		$qb->setFirstResult($offset);
910
-
911
-		$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)));
912
-		$qb->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)));
913
-
914
-		// Filter by node if provided
915
-		if ($node !== null) {
916
-			$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
917
-		}
918
-
919
-		$cursor = $qb->executeQuery();
920
-
921
-		while ($data = $cursor->fetch()) {
922
-			$shares[] = $this->createShareObject($data);
923
-		}
924
-		$cursor->closeCursor();
925
-
926
-
927
-		return $shares;
928
-	}
929
-
930
-	/**
931
-	 * Get a share by token
932
-	 *
933
-	 * @param string $token
934
-	 * @return IShare
935
-	 * @throws ShareNotFound
936
-	 */
937
-	public function getShareByToken($token) {
938
-		$qb = $this->dbConnection->getQueryBuilder();
939
-
940
-		$cursor = $qb->select('*')
941
-			->from('share')
942
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)))
943
-			->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
944
-			->executeQuery();
945
-
946
-		$data = $cursor->fetch();
947
-
948
-		if ($data === false) {
949
-			throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
950
-		}
951
-
952
-		try {
953
-			$share = $this->createShareObject($data);
954
-		} catch (InvalidShare $e) {
955
-			throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
956
-		}
957
-
958
-		return $share;
959
-	}
960
-
961
-	/**
962
-	 * remove share from table
963
-	 *
964
-	 * @param string $shareId
965
-	 */
966
-	protected function removeShareFromTable($shareId) {
967
-		$qb = $this->dbConnection->getQueryBuilder();
968
-		$qb->delete('share')
969
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($shareId)));
970
-		$qb->executeStatement();
971
-	}
972
-
973
-	/**
974
-	 * Create a share object from an database row
975
-	 *
976
-	 * @param array $data
977
-	 * @return IShare
978
-	 * @throws InvalidShare
979
-	 * @throws ShareNotFound
980
-	 */
981
-	protected function createShareObject($data) {
982
-		$share = new Share($this->rootFolder, $this->userManager);
983
-		$share->setId((int)$data['id'])
984
-			->setShareType((int)$data['share_type'])
985
-			->setPermissions((int)$data['permissions'])
986
-			->setTarget($data['file_target'])
987
-			->setMailSend((bool)$data['mail_send'])
988
-			->setNote($data['note'])
989
-			->setToken($data['token']);
990
-
991
-		$shareTime = new \DateTime();
992
-		$shareTime->setTimestamp((int)$data['stime']);
993
-		$share->setShareTime($shareTime);
994
-		$share->setSharedWith($data['share_with']);
995
-		$share->setPassword($data['password']);
996
-		$share->setLabel($data['label']);
997
-		$share->setSendPasswordByTalk((bool)$data['password_by_talk']);
998
-		$share->setHideDownload((bool)$data['hide_download']);
999
-
1000
-		if ($data['uid_initiator'] !== null) {
1001
-			$share->setShareOwner($data['uid_owner']);
1002
-			$share->setSharedBy($data['uid_initiator']);
1003
-		} else {
1004
-			//OLD SHARE
1005
-			$share->setSharedBy($data['uid_owner']);
1006
-			$path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
1007
-
1008
-			$owner = $path->getOwner();
1009
-			$share->setShareOwner($owner->getUID());
1010
-		}
1011
-
1012
-		if ($data['expiration'] !== null) {
1013
-			$expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']);
1014
-			if ($expiration !== false) {
1015
-				$share->setExpirationDate($expiration);
1016
-			}
1017
-		}
1018
-
1019
-		$share->setNodeId((int)$data['file_source']);
1020
-		$share->setNodeType($data['item_type']);
1021
-
1022
-		$share->setProviderId($this->identifier());
1023
-
1024
-		return $share;
1025
-	}
1026
-
1027
-	/**
1028
-	 * Get the node with file $id for $user
1029
-	 *
1030
-	 * @param string $userId
1031
-	 * @param int $id
1032
-	 * @return \OCP\Files\File|\OCP\Files\Folder
1033
-	 * @throws InvalidShare
1034
-	 */
1035
-	private function getNode($userId, $id) {
1036
-		try {
1037
-			$userFolder = $this->rootFolder->getUserFolder($userId);
1038
-		} catch (NoUserException $e) {
1039
-			throw new InvalidShare();
1040
-		}
1041
-
1042
-		$nodes = $userFolder->getById($id);
1043
-
1044
-		if (empty($nodes)) {
1045
-			throw new InvalidShare();
1046
-		}
1047
-
1048
-		return $nodes[0];
1049
-	}
1050
-
1051
-	/**
1052
-	 * A user is deleted from the system
1053
-	 * So clean up the relevant shares.
1054
-	 *
1055
-	 * @param string $uid
1056
-	 * @param int $shareType
1057
-	 */
1058
-	public function userDeleted($uid, $shareType) {
1059
-		$qb = $this->dbConnection->getQueryBuilder();
1060
-
1061
-		$qb->delete('share')
1062
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)))
1063
-			->andWhere($qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)))
1064
-			->executeStatement();
1065
-	}
1066
-
1067
-	/**
1068
-	 * This provider does not support group shares
1069
-	 *
1070
-	 * @param string $gid
1071
-	 */
1072
-	public function groupDeleted($gid) {
1073
-	}
1074
-
1075
-	/**
1076
-	 * This provider does not support group shares
1077
-	 *
1078
-	 * @param string $uid
1079
-	 * @param string $gid
1080
-	 */
1081
-	public function userDeletedFromGroup($uid, $gid) {
1082
-	}
1083
-
1084
-	/**
1085
-	 * get database row of a give share
1086
-	 *
1087
-	 * @param $id
1088
-	 * @return array
1089
-	 * @throws ShareNotFound
1090
-	 */
1091
-	protected function getRawShare($id) {
1092
-
1093
-		// Now fetch the inserted share and create a complete share object
1094
-		$qb = $this->dbConnection->getQueryBuilder();
1095
-		$qb->select('*')
1096
-			->from('share')
1097
-			->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
1098
-
1099
-		$cursor = $qb->executeQuery();
1100
-		$data = $cursor->fetch();
1101
-		$cursor->closeCursor();
1102
-
1103
-		if ($data === false) {
1104
-			throw new ShareNotFound;
1105
-		}
1106
-
1107
-		return $data;
1108
-	}
1109
-
1110
-	public function getSharesInFolder($userId, Folder $node, $reshares) {
1111
-		$qb = $this->dbConnection->getQueryBuilder();
1112
-		$qb->select('*')
1113
-			->from('share', 's')
1114
-			->andWhere($qb->expr()->orX(
1115
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1116
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1117
-			))
1118
-			->andWhere(
1119
-				$qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL))
1120
-			);
1121
-
1122
-		/**
1123
-		 * Reshares for this user are shares where they are the owner.
1124
-		 */
1125
-		if ($reshares === false) {
1126
-			$qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
1127
-		} else {
1128
-			$qb->andWhere(
1129
-				$qb->expr()->orX(
1130
-					$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
1131
-					$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
1132
-				)
1133
-			);
1134
-		}
1135
-
1136
-		$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1137
-		$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
1138
-
1139
-		$qb->orderBy('id');
1140
-
1141
-		$cursor = $qb->executeQuery();
1142
-		$shares = [];
1143
-		while ($data = $cursor->fetch()) {
1144
-			$shares[$data['fileid']][] = $this->createShareObject($data);
1145
-		}
1146
-		$cursor->closeCursor();
1147
-
1148
-		return $shares;
1149
-	}
1150
-
1151
-	/**
1152
-	 * @inheritdoc
1153
-	 */
1154
-	public function getAccessList($nodes, $currentAccess) {
1155
-		$ids = [];
1156
-		foreach ($nodes as $node) {
1157
-			$ids[] = $node->getId();
1158
-		}
1159
-
1160
-		$qb = $this->dbConnection->getQueryBuilder();
1161
-		$qb->select('share_with')
1162
-			->from('share')
1163
-			->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)))
1164
-			->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1165
-			->andWhere($qb->expr()->orX(
1166
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1167
-				$qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1168
-			))
1169
-			->setMaxResults(1);
1170
-		$cursor = $qb->executeQuery();
1171
-
1172
-		$mail = $cursor->fetch() !== false;
1173
-		$cursor->closeCursor();
1174
-
1175
-		return ['public' => $mail];
1176
-	}
1177
-
1178
-	public function getAllShares(): iterable {
1179
-		$qb = $this->dbConnection->getQueryBuilder();
1180
-
1181
-		$qb->select('*')
1182
-			->from('share')
1183
-			->where(
1184
-				$qb->expr()->orX(
1185
-					$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_EMAIL))
1186
-				)
1187
-			);
1188
-
1189
-		$cursor = $qb->executeQuery();
1190
-		while ($data = $cursor->fetch()) {
1191
-			try {
1192
-				$share = $this->createShareObject($data);
1193
-			} catch (InvalidShare $e) {
1194
-				continue;
1195
-			} catch (ShareNotFound $e) {
1196
-				continue;
1197
-			}
1198
-
1199
-			yield $share;
1200
-		}
1201
-		$cursor->closeCursor();
1202
-	}
726
+        $qb = $this->dbConnection->getQueryBuilder();
727
+        $qb->update('share')
728
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId())))
729
+            ->set('permissions', $qb->createNamedParameter($share->getPermissions()))
730
+            ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner()))
731
+            ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy()))
732
+            ->set('password', $qb->createNamedParameter($share->getPassword()))
733
+            ->set('label', $qb->createNamedParameter($share->getLabel()))
734
+            ->set('password_by_talk', $qb->createNamedParameter($share->getSendPasswordByTalk(), IQueryBuilder::PARAM_BOOL))
735
+            ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
736
+            ->set('note', $qb->createNamedParameter($share->getNote()))
737
+            ->set('hide_download', $qb->createNamedParameter((int)$share->getHideDownload(), IQueryBuilder::PARAM_INT))
738
+            ->executeStatement();
739
+
740
+        if ($originalShare->getNote() !== $share->getNote() && $share->getNote() !== '') {
741
+            $this->sendNote($share);
742
+        }
743
+
744
+        return $share;
745
+    }
746
+
747
+    /**
748
+     * @inheritdoc
749
+     */
750
+    public function move(IShare $share, $recipient) {
751
+        /**
752
+         * nothing to do here, mail shares are only outgoing shares
753
+         */
754
+        return $share;
755
+    }
756
+
757
+    /**
758
+     * Delete a share (owner unShares the file)
759
+     *
760
+     * @param IShare $share
761
+     */
762
+    public function delete(IShare $share) {
763
+        try {
764
+            $this->createShareActivity($share, 'unshare');
765
+        } catch (\Exception $e) {
766
+        }
767
+
768
+        $this->removeShareFromTable($share->getId());
769
+    }
770
+
771
+    /**
772
+     * @inheritdoc
773
+     */
774
+    public function deleteFromSelf(IShare $share, $recipient) {
775
+        // nothing to do here, mail shares are only outgoing shares
776
+    }
777
+
778
+    public function restore(IShare $share, string $recipient): IShare {
779
+        throw new GenericShareException('not implemented');
780
+    }
781
+
782
+    /**
783
+     * @inheritdoc
784
+     */
785
+    public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) {
786
+        $qb = $this->dbConnection->getQueryBuilder();
787
+        $qb->select('*')
788
+            ->from('share');
789
+
790
+        $qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)));
791
+
792
+        /**
793
+         * Reshares for this user are shares where they are the owner.
794
+         */
795
+        if ($reshares === false) {
796
+            //Special case for old shares created via the web UI
797
+            $or1 = $qb->expr()->andX(
798
+                $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
799
+                $qb->expr()->isNull('uid_initiator')
800
+            );
801
+
802
+            $qb->andWhere(
803
+                $qb->expr()->orX(
804
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)),
805
+                    $or1
806
+                )
807
+            );
808
+        } else {
809
+            $qb->andWhere(
810
+                $qb->expr()->orX(
811
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
812
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
813
+                )
814
+            );
815
+        }
816
+
817
+        if ($node !== null) {
818
+            $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
819
+        }
820
+
821
+        if ($limit !== -1) {
822
+            $qb->setMaxResults($limit);
823
+        }
824
+
825
+        $qb->setFirstResult($offset);
826
+        $qb->orderBy('id');
827
+
828
+        $cursor = $qb->executeQuery();
829
+        $shares = [];
830
+        while ($data = $cursor->fetch()) {
831
+            $shares[] = $this->createShareObject($data);
832
+        }
833
+        $cursor->closeCursor();
834
+
835
+        return $shares;
836
+    }
837
+
838
+    /**
839
+     * @inheritdoc
840
+     */
841
+    public function getShareById($id, $recipientId = null) {
842
+        $qb = $this->dbConnection->getQueryBuilder();
843
+
844
+        $qb->select('*')
845
+            ->from('share')
846
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)))
847
+            ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)));
848
+
849
+        $cursor = $qb->executeQuery();
850
+        $data = $cursor->fetch();
851
+        $cursor->closeCursor();
852
+
853
+        if ($data === false) {
854
+            throw new ShareNotFound();
855
+        }
856
+
857
+        try {
858
+            $share = $this->createShareObject($data);
859
+        } catch (InvalidShare $e) {
860
+            throw new ShareNotFound();
861
+        }
862
+
863
+        return $share;
864
+    }
865
+
866
+    /**
867
+     * Get shares for a given path
868
+     *
869
+     * @param \OCP\Files\Node $path
870
+     * @return IShare[]
871
+     */
872
+    public function getSharesByPath(Node $path) {
873
+        $qb = $this->dbConnection->getQueryBuilder();
874
+
875
+        $cursor = $qb->select('*')
876
+            ->from('share')
877
+            ->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId())))
878
+            ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)))
879
+            ->executeQuery();
880
+
881
+        $shares = [];
882
+        while ($data = $cursor->fetch()) {
883
+            $shares[] = $this->createShareObject($data);
884
+        }
885
+        $cursor->closeCursor();
886
+
887
+        return $shares;
888
+    }
889
+
890
+    /**
891
+     * @inheritdoc
892
+     */
893
+    public function getSharedWith($userId, $shareType, $node, $limit, $offset) {
894
+        /** @var IShare[] $shares */
895
+        $shares = [];
896
+
897
+        //Get shares directly with this user
898
+        $qb = $this->dbConnection->getQueryBuilder();
899
+        $qb->select('*')
900
+            ->from('share');
901
+
902
+        // Order by id
903
+        $qb->orderBy('id');
904
+
905
+        // Set limit and offset
906
+        if ($limit !== -1) {
907
+            $qb->setMaxResults($limit);
908
+        }
909
+        $qb->setFirstResult($offset);
910
+
911
+        $qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)));
912
+        $qb->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId)));
913
+
914
+        // Filter by node if provided
915
+        if ($node !== null) {
916
+            $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId())));
917
+        }
918
+
919
+        $cursor = $qb->executeQuery();
920
+
921
+        while ($data = $cursor->fetch()) {
922
+            $shares[] = $this->createShareObject($data);
923
+        }
924
+        $cursor->closeCursor();
925
+
926
+
927
+        return $shares;
928
+    }
929
+
930
+    /**
931
+     * Get a share by token
932
+     *
933
+     * @param string $token
934
+     * @return IShare
935
+     * @throws ShareNotFound
936
+     */
937
+    public function getShareByToken($token) {
938
+        $qb = $this->dbConnection->getQueryBuilder();
939
+
940
+        $cursor = $qb->select('*')
941
+            ->from('share')
942
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)))
943
+            ->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token)))
944
+            ->executeQuery();
945
+
946
+        $data = $cursor->fetch();
947
+
948
+        if ($data === false) {
949
+            throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
950
+        }
951
+
952
+        try {
953
+            $share = $this->createShareObject($data);
954
+        } catch (InvalidShare $e) {
955
+            throw new ShareNotFound('Share not found', $this->l->t('Could not find share'));
956
+        }
957
+
958
+        return $share;
959
+    }
960
+
961
+    /**
962
+     * remove share from table
963
+     *
964
+     * @param string $shareId
965
+     */
966
+    protected function removeShareFromTable($shareId) {
967
+        $qb = $this->dbConnection->getQueryBuilder();
968
+        $qb->delete('share')
969
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($shareId)));
970
+        $qb->executeStatement();
971
+    }
972
+
973
+    /**
974
+     * Create a share object from an database row
975
+     *
976
+     * @param array $data
977
+     * @return IShare
978
+     * @throws InvalidShare
979
+     * @throws ShareNotFound
980
+     */
981
+    protected function createShareObject($data) {
982
+        $share = new Share($this->rootFolder, $this->userManager);
983
+        $share->setId((int)$data['id'])
984
+            ->setShareType((int)$data['share_type'])
985
+            ->setPermissions((int)$data['permissions'])
986
+            ->setTarget($data['file_target'])
987
+            ->setMailSend((bool)$data['mail_send'])
988
+            ->setNote($data['note'])
989
+            ->setToken($data['token']);
990
+
991
+        $shareTime = new \DateTime();
992
+        $shareTime->setTimestamp((int)$data['stime']);
993
+        $share->setShareTime($shareTime);
994
+        $share->setSharedWith($data['share_with']);
995
+        $share->setPassword($data['password']);
996
+        $share->setLabel($data['label']);
997
+        $share->setSendPasswordByTalk((bool)$data['password_by_talk']);
998
+        $share->setHideDownload((bool)$data['hide_download']);
999
+
1000
+        if ($data['uid_initiator'] !== null) {
1001
+            $share->setShareOwner($data['uid_owner']);
1002
+            $share->setSharedBy($data['uid_initiator']);
1003
+        } else {
1004
+            //OLD SHARE
1005
+            $share->setSharedBy($data['uid_owner']);
1006
+            $path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
1007
+
1008
+            $owner = $path->getOwner();
1009
+            $share->setShareOwner($owner->getUID());
1010
+        }
1011
+
1012
+        if ($data['expiration'] !== null) {
1013
+            $expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']);
1014
+            if ($expiration !== false) {
1015
+                $share->setExpirationDate($expiration);
1016
+            }
1017
+        }
1018
+
1019
+        $share->setNodeId((int)$data['file_source']);
1020
+        $share->setNodeType($data['item_type']);
1021
+
1022
+        $share->setProviderId($this->identifier());
1023
+
1024
+        return $share;
1025
+    }
1026
+
1027
+    /**
1028
+     * Get the node with file $id for $user
1029
+     *
1030
+     * @param string $userId
1031
+     * @param int $id
1032
+     * @return \OCP\Files\File|\OCP\Files\Folder
1033
+     * @throws InvalidShare
1034
+     */
1035
+    private function getNode($userId, $id) {
1036
+        try {
1037
+            $userFolder = $this->rootFolder->getUserFolder($userId);
1038
+        } catch (NoUserException $e) {
1039
+            throw new InvalidShare();
1040
+        }
1041
+
1042
+        $nodes = $userFolder->getById($id);
1043
+
1044
+        if (empty($nodes)) {
1045
+            throw new InvalidShare();
1046
+        }
1047
+
1048
+        return $nodes[0];
1049
+    }
1050
+
1051
+    /**
1052
+     * A user is deleted from the system
1053
+     * So clean up the relevant shares.
1054
+     *
1055
+     * @param string $uid
1056
+     * @param int $shareType
1057
+     */
1058
+    public function userDeleted($uid, $shareType) {
1059
+        $qb = $this->dbConnection->getQueryBuilder();
1060
+
1061
+        $qb->delete('share')
1062
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)))
1063
+            ->andWhere($qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid)))
1064
+            ->executeStatement();
1065
+    }
1066
+
1067
+    /**
1068
+     * This provider does not support group shares
1069
+     *
1070
+     * @param string $gid
1071
+     */
1072
+    public function groupDeleted($gid) {
1073
+    }
1074
+
1075
+    /**
1076
+     * This provider does not support group shares
1077
+     *
1078
+     * @param string $uid
1079
+     * @param string $gid
1080
+     */
1081
+    public function userDeletedFromGroup($uid, $gid) {
1082
+    }
1083
+
1084
+    /**
1085
+     * get database row of a give share
1086
+     *
1087
+     * @param $id
1088
+     * @return array
1089
+     * @throws ShareNotFound
1090
+     */
1091
+    protected function getRawShare($id) {
1092
+
1093
+        // Now fetch the inserted share and create a complete share object
1094
+        $qb = $this->dbConnection->getQueryBuilder();
1095
+        $qb->select('*')
1096
+            ->from('share')
1097
+            ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
1098
+
1099
+        $cursor = $qb->executeQuery();
1100
+        $data = $cursor->fetch();
1101
+        $cursor->closeCursor();
1102
+
1103
+        if ($data === false) {
1104
+            throw new ShareNotFound;
1105
+        }
1106
+
1107
+        return $data;
1108
+    }
1109
+
1110
+    public function getSharesInFolder($userId, Folder $node, $reshares) {
1111
+        $qb = $this->dbConnection->getQueryBuilder();
1112
+        $qb->select('*')
1113
+            ->from('share', 's')
1114
+            ->andWhere($qb->expr()->orX(
1115
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1116
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1117
+            ))
1118
+            ->andWhere(
1119
+                $qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL))
1120
+            );
1121
+
1122
+        /**
1123
+         * Reshares for this user are shares where they are the owner.
1124
+         */
1125
+        if ($reshares === false) {
1126
+            $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)));
1127
+        } else {
1128
+            $qb->andWhere(
1129
+                $qb->expr()->orX(
1130
+                    $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)),
1131
+                    $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))
1132
+                )
1133
+            );
1134
+        }
1135
+
1136
+        $qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1137
+        $qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
1138
+
1139
+        $qb->orderBy('id');
1140
+
1141
+        $cursor = $qb->executeQuery();
1142
+        $shares = [];
1143
+        while ($data = $cursor->fetch()) {
1144
+            $shares[$data['fileid']][] = $this->createShareObject($data);
1145
+        }
1146
+        $cursor->closeCursor();
1147
+
1148
+        return $shares;
1149
+    }
1150
+
1151
+    /**
1152
+     * @inheritdoc
1153
+     */
1154
+    public function getAccessList($nodes, $currentAccess) {
1155
+        $ids = [];
1156
+        foreach ($nodes as $node) {
1157
+            $ids[] = $node->getId();
1158
+        }
1159
+
1160
+        $qb = $this->dbConnection->getQueryBuilder();
1161
+        $qb->select('share_with')
1162
+            ->from('share')
1163
+            ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_EMAIL)))
1164
+            ->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY)))
1165
+            ->andWhere($qb->expr()->orX(
1166
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('file')),
1167
+                $qb->expr()->eq('item_type', $qb->createNamedParameter('folder'))
1168
+            ))
1169
+            ->setMaxResults(1);
1170
+        $cursor = $qb->executeQuery();
1171
+
1172
+        $mail = $cursor->fetch() !== false;
1173
+        $cursor->closeCursor();
1174
+
1175
+        return ['public' => $mail];
1176
+    }
1177
+
1178
+    public function getAllShares(): iterable {
1179
+        $qb = $this->dbConnection->getQueryBuilder();
1180
+
1181
+        $qb->select('*')
1182
+            ->from('share')
1183
+            ->where(
1184
+                $qb->expr()->orX(
1185
+                    $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share\IShare::TYPE_EMAIL))
1186
+                )
1187
+            );
1188
+
1189
+        $cursor = $qb->executeQuery();
1190
+        while ($data = $cursor->fetch()) {
1191
+            try {
1192
+                $share = $this->createShareObject($data);
1193
+            } catch (InvalidShare $e) {
1194
+                continue;
1195
+            } catch (ShareNotFound $e) {
1196
+                continue;
1197
+            }
1198
+
1199
+            yield $share;
1200
+        }
1201
+        $cursor->closeCursor();
1202
+    }
1203 1203
 }
Please login to merge, or discard this patch.
Spacing   +16 added lines, -16 removed lines patch added patch discarded remove patch
@@ -396,7 +396,7 @@  discard block
 block discarded – undo
396 396
 		$text = $this->l->t('%1$s shared »%2$s« with you.', [$initiatorDisplayName, $filename]);
397 397
 
398 398
 		$emailTemplate->addBodyText(
399
-			htmlspecialchars($text . ' ' . $this->l->t('Click the button below to open it.')),
399
+			htmlspecialchars($text.' '.$this->l->t('Click the button below to open it.')),
400 400
 			$text
401 401
 		);
402 402
 		$emailTemplate->addBodyButton(
@@ -425,7 +425,7 @@  discard block
 block discarded – undo
425 425
 		$initiatorEmail = $initiatorUser->getEMailAddress();
426 426
 		if ($this->settingsManager->replyToInitiator() && $initiatorEmail !== null) {
427 427
 			$message->setReplyTo([$initiatorEmail => $initiatorDisplayName]);
428
-			$emailTemplate->addFooter($instanceName . ($this->defaults->getSlogan() !== '' ? ' - ' . $this->defaults->getSlogan() : ''));
428
+			$emailTemplate->addFooter($instanceName.($this->defaults->getSlogan() !== '' ? ' - '.$this->defaults->getSlogan() : ''));
429 429
 		} else {
430 430
 			$emailTemplate->addFooter();
431 431
 		}
@@ -489,7 +489,7 @@  discard block
 block discarded – undo
489 489
 		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
490 490
 		if ($this->settingsManager->replyToInitiator() && $initiatorEmailAddress !== null) {
491 491
 			$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
492
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
492
+			$emailTemplate->addFooter($instanceName.' - '.$this->defaults->getSlogan());
493 493
 		} else {
494 494
 			$emailTemplate->addFooter();
495 495
 		}
@@ -549,7 +549,7 @@  discard block
 block discarded – undo
549 549
 		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
550 550
 		if ($this->settingsManager->replyToInitiator() && $initiatorEmailAddress !== null) {
551 551
 			$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
552
-			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
552
+			$emailTemplate->addFooter($instanceName.' - '.$this->defaults->getSlogan());
553 553
 		} else {
554 554
 			$emailTemplate->addFooter();
555 555
 		}
@@ -686,7 +686,7 @@  discard block
 block discarded – undo
686 686
 			->setValue('password', $qb->createNamedParameter($password))
687 687
 			->setValue('password_by_talk', $qb->createNamedParameter($sendPasswordByTalk, IQueryBuilder::PARAM_BOOL))
688 688
 			->setValue('stime', $qb->createNamedParameter(time()))
689
-			->setValue('hide_download', $qb->createNamedParameter((int)$hideDownload, IQueryBuilder::PARAM_INT))
689
+			->setValue('hide_download', $qb->createNamedParameter((int) $hideDownload, IQueryBuilder::PARAM_INT))
690 690
 			->setValue('label', $qb->createNamedParameter($label));
691 691
 
692 692
 		if ($expirationTime !== null) {
@@ -734,7 +734,7 @@  discard block
 block discarded – undo
734 734
 			->set('password_by_talk', $qb->createNamedParameter($share->getSendPasswordByTalk(), IQueryBuilder::PARAM_BOOL))
735 735
 			->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE))
736 736
 			->set('note', $qb->createNamedParameter($share->getNote()))
737
-			->set('hide_download', $qb->createNamedParameter((int)$share->getHideDownload(), IQueryBuilder::PARAM_INT))
737
+			->set('hide_download', $qb->createNamedParameter((int) $share->getHideDownload(), IQueryBuilder::PARAM_INT))
738 738
 			->executeStatement();
739 739
 
740 740
 		if ($originalShare->getNote() !== $share->getNote() && $share->getNote() !== '') {
@@ -980,22 +980,22 @@  discard block
 block discarded – undo
980 980
 	 */
981 981
 	protected function createShareObject($data) {
982 982
 		$share = new Share($this->rootFolder, $this->userManager);
983
-		$share->setId((int)$data['id'])
984
-			->setShareType((int)$data['share_type'])
985
-			->setPermissions((int)$data['permissions'])
983
+		$share->setId((int) $data['id'])
984
+			->setShareType((int) $data['share_type'])
985
+			->setPermissions((int) $data['permissions'])
986 986
 			->setTarget($data['file_target'])
987
-			->setMailSend((bool)$data['mail_send'])
987
+			->setMailSend((bool) $data['mail_send'])
988 988
 			->setNote($data['note'])
989 989
 			->setToken($data['token']);
990 990
 
991 991
 		$shareTime = new \DateTime();
992
-		$shareTime->setTimestamp((int)$data['stime']);
992
+		$shareTime->setTimestamp((int) $data['stime']);
993 993
 		$share->setShareTime($shareTime);
994 994
 		$share->setSharedWith($data['share_with']);
995 995
 		$share->setPassword($data['password']);
996 996
 		$share->setLabel($data['label']);
997
-		$share->setSendPasswordByTalk((bool)$data['password_by_talk']);
998
-		$share->setHideDownload((bool)$data['hide_download']);
997
+		$share->setSendPasswordByTalk((bool) $data['password_by_talk']);
998
+		$share->setHideDownload((bool) $data['hide_download']);
999 999
 
1000 1000
 		if ($data['uid_initiator'] !== null) {
1001 1001
 			$share->setShareOwner($data['uid_owner']);
@@ -1003,7 +1003,7 @@  discard block
 block discarded – undo
1003 1003
 		} else {
1004 1004
 			//OLD SHARE
1005 1005
 			$share->setSharedBy($data['uid_owner']);
1006
-			$path = $this->getNode($share->getSharedBy(), (int)$data['file_source']);
1006
+			$path = $this->getNode($share->getSharedBy(), (int) $data['file_source']);
1007 1007
 
1008 1008
 			$owner = $path->getOwner();
1009 1009
 			$share->setShareOwner($owner->getUID());
@@ -1016,7 +1016,7 @@  discard block
 block discarded – undo
1016 1016
 			}
1017 1017
 		}
1018 1018
 
1019
-		$share->setNodeId((int)$data['file_source']);
1019
+		$share->setNodeId((int) $data['file_source']);
1020 1020
 		$share->setNodeType($data['item_type']);
1021 1021
 
1022 1022
 		$share->setProviderId($this->identifier());
@@ -1133,7 +1133,7 @@  discard block
 block discarded – undo
1133 1133
 			);
1134 1134
 		}
1135 1135
 
1136
-		$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1136
+		$qb->innerJoin('s', 'filecache', 'f', $qb->expr()->eq('s.file_source', 'f.fileid'));
1137 1137
 		$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId())));
1138 1138
 
1139 1139
 		$qb->orderBy('id');
Please login to merge, or discard this patch.