1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* @copyright Copyright (c) 2016 Bjoern Schiessle <[email protected]> |
4
|
|
|
* |
5
|
|
|
* @license GNU AGPL version 3 or any later version |
6
|
|
|
* |
7
|
|
|
* This program is free software: you can redistribute it and/or modify |
8
|
|
|
* it under the terms of the GNU Affero General Public License as |
9
|
|
|
* published by the Free Software Foundation, either version 3 of the |
10
|
|
|
* License, or (at your option) any later version. |
11
|
|
|
* |
12
|
|
|
* This program is distributed in the hope that it will be useful, |
13
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
14
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15
|
|
|
* GNU Affero General Public License for more details. |
16
|
|
|
* |
17
|
|
|
* You should have received a copy of the GNU Affero General Public License |
18
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
19
|
|
|
* |
20
|
|
|
*/ |
21
|
|
|
|
22
|
|
|
namespace OCA\ShareByMail; |
23
|
|
|
|
24
|
|
|
use OC\HintException; |
25
|
|
|
use OC\Share20\Exception\InvalidShare; |
26
|
|
|
use OCA\ShareByMail\Settings\SettingsManager; |
27
|
|
|
use OCP\Activity\IManager; |
28
|
|
|
use OCP\DB\QueryBuilder\IQueryBuilder; |
29
|
|
|
use OCP\Files\Folder; |
30
|
|
|
use OCP\Files\IRootFolder; |
31
|
|
|
use OCP\Files\Node; |
32
|
|
|
use OCP\IDBConnection; |
33
|
|
|
use OCP\IL10N; |
34
|
|
|
use OCP\ILogger; |
35
|
|
|
use OCP\IURLGenerator; |
36
|
|
|
use OCP\IUser; |
37
|
|
|
use OCP\IUserManager; |
38
|
|
|
use OCP\Mail\IMailer; |
39
|
|
|
use OCP\Security\ISecureRandom; |
40
|
|
|
use OC\Share20\Share; |
41
|
|
|
use OCP\Share\Exceptions\ShareNotFound; |
42
|
|
|
use OCP\Share\IShare; |
43
|
|
|
use OCP\Share\IShareProvider; |
44
|
|
|
use OCP\Template; |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* Class ShareByMail |
48
|
|
|
* |
49
|
|
|
* @package OCA\ShareByMail |
50
|
|
|
*/ |
51
|
|
|
class ShareByMailProvider implements IShareProvider { |
52
|
|
|
|
53
|
|
|
/** @var IDBConnection */ |
54
|
|
|
private $dbConnection; |
55
|
|
|
|
56
|
|
|
/** @var ILogger */ |
57
|
|
|
private $logger; |
58
|
|
|
|
59
|
|
|
/** @var ISecureRandom */ |
60
|
|
|
private $secureRandom; |
61
|
|
|
|
62
|
|
|
/** @var IUserManager */ |
63
|
|
|
private $userManager; |
64
|
|
|
|
65
|
|
|
/** @var IRootFolder */ |
66
|
|
|
private $rootFolder; |
67
|
|
|
|
68
|
|
|
/** @var IL10N */ |
69
|
|
|
private $l; |
70
|
|
|
|
71
|
|
|
/** @var IMailer */ |
72
|
|
|
private $mailer; |
73
|
|
|
|
74
|
|
|
/** @var IURLGenerator */ |
75
|
|
|
private $urlGenerator; |
76
|
|
|
|
77
|
|
|
/** @var IManager */ |
78
|
|
|
private $activityManager; |
79
|
|
|
|
80
|
|
|
/** @var SettingsManager */ |
81
|
|
|
private $settingsManager; |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* Return the identifier of this provider. |
85
|
|
|
* |
86
|
|
|
* @return string Containing only [a-zA-Z0-9] |
87
|
|
|
*/ |
88
|
|
|
public function identifier() { |
89
|
|
|
return 'ocMailShare'; |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
/** |
93
|
|
|
* DefaultShareProvider constructor. |
94
|
|
|
* |
95
|
|
|
* @param IDBConnection $connection |
96
|
|
|
* @param ISecureRandom $secureRandom |
97
|
|
|
* @param IUserManager $userManager |
98
|
|
|
* @param IRootFolder $rootFolder |
99
|
|
|
* @param IL10N $l |
100
|
|
|
* @param ILogger $logger |
101
|
|
|
* @param IMailer $mailer |
102
|
|
|
* @param IURLGenerator $urlGenerator |
103
|
|
|
* @param IManager $activityManager |
104
|
|
|
* @param SettingsManager $settingsManager |
105
|
|
|
*/ |
106
|
|
View Code Duplication |
public function __construct( |
|
|
|
|
107
|
|
|
IDBConnection $connection, |
108
|
|
|
ISecureRandom $secureRandom, |
109
|
|
|
IUserManager $userManager, |
110
|
|
|
IRootFolder $rootFolder, |
111
|
|
|
IL10N $l, |
112
|
|
|
ILogger $logger, |
113
|
|
|
IMailer $mailer, |
114
|
|
|
IURLGenerator $urlGenerator, |
115
|
|
|
IManager $activityManager, |
116
|
|
|
SettingsManager $settingsManager |
117
|
|
|
) { |
118
|
|
|
$this->dbConnection = $connection; |
119
|
|
|
$this->secureRandom = $secureRandom; |
120
|
|
|
$this->userManager = $userManager; |
121
|
|
|
$this->rootFolder = $rootFolder; |
122
|
|
|
$this->l = $l; |
123
|
|
|
$this->logger = $logger; |
124
|
|
|
$this->mailer = $mailer; |
125
|
|
|
$this->urlGenerator = $urlGenerator; |
126
|
|
|
$this->activityManager = $activityManager; |
127
|
|
|
$this->settingsManager = $settingsManager; |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
/** |
131
|
|
|
* Share a path |
132
|
|
|
* |
133
|
|
|
* @param IShare $share |
134
|
|
|
* @return IShare The share object |
135
|
|
|
* @throws ShareNotFound |
136
|
|
|
* @throws \Exception |
137
|
|
|
*/ |
138
|
|
|
public function create(IShare $share) { |
139
|
|
|
|
140
|
|
|
$shareWith = $share->getSharedWith(); |
141
|
|
|
/* |
142
|
|
|
* Check if file is not already shared with the remote user |
143
|
|
|
*/ |
144
|
|
|
$alreadyShared = $this->getSharedWith($shareWith, \OCP\Share::SHARE_TYPE_EMAIL, $share->getNode(), 1, 0); |
145
|
|
View Code Duplication |
if (!empty($alreadyShared)) { |
146
|
|
|
$message = 'Sharing %s failed, this item is already shared with %s'; |
147
|
|
|
$message_t = $this->l->t('Sharing %s failed, this item is already shared with %s', array($share->getNode()->getName(), $shareWith)); |
148
|
|
|
$this->logger->debug(sprintf($message, $share->getNode()->getName(), $shareWith), ['app' => 'Federated File Sharing']); |
149
|
|
|
throw new \Exception($message_t); |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
$shareId = $this->createMailShare($share); |
153
|
|
|
$this->createActivity($share); |
154
|
|
|
$data = $this->getRawShare($shareId); |
155
|
|
|
return $this->createShareObject($data); |
156
|
|
|
|
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
/** |
160
|
|
|
* create activity if a file/folder was shared by mail |
161
|
|
|
* |
162
|
|
|
* @param IShare $share |
163
|
|
|
*/ |
164
|
|
|
protected function createActivity(IShare $share) { |
165
|
|
|
|
166
|
|
|
$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy()); |
167
|
|
|
|
168
|
|
|
$this->publishActivity( |
169
|
|
|
Activity::SUBJECT_SHARED_EMAIL_SELF, |
170
|
|
|
[$userFolder->getRelativePath($share->getNode()->getPath()), $share->getSharedWith()], |
171
|
|
|
$share->getSharedBy(), |
172
|
|
|
$share->getNode()->getId(), |
173
|
|
|
$userFolder->getRelativePath($share->getNode()->getPath()) |
174
|
|
|
); |
175
|
|
|
|
176
|
|
|
if ($share->getShareOwner() !== $share->getSharedBy()) { |
177
|
|
|
$ownerFolder = $this->rootFolder->getUserFolder($share->getShareOwner()); |
178
|
|
|
$fileId = $share->getNode()->getId(); |
179
|
|
|
$nodes = $ownerFolder->getById($fileId); |
180
|
|
|
$ownerPath = $nodes[0]->getPath(); |
181
|
|
|
$this->publishActivity( |
182
|
|
|
Activity::SUBJECT_SHARED_EMAIL_BY, |
183
|
|
|
[$ownerFolder->getRelativePath($ownerPath), $share->getSharedWith(), $share->getSharedBy()], |
184
|
|
|
$share->getShareOwner(), |
185
|
|
|
$fileId, |
186
|
|
|
$ownerFolder->getRelativePath($ownerPath) |
187
|
|
|
); |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
/** |
193
|
|
|
* publish activity if a file/folder was shared by mail |
194
|
|
|
* |
195
|
|
|
* @param $subject |
196
|
|
|
* @param $parameters |
197
|
|
|
* @param $affectedUser |
198
|
|
|
* @param $fileId |
199
|
|
|
* @param $filePath |
200
|
|
|
*/ |
201
|
|
View Code Duplication |
protected function publishActivity($subject, $parameters, $affectedUser, $fileId, $filePath) { |
|
|
|
|
202
|
|
|
$event = $this->activityManager->generateEvent(); |
203
|
|
|
$event->setApp('sharebymail') |
204
|
|
|
->setType('shared') |
205
|
|
|
->setSubject($subject, $parameters) |
206
|
|
|
->setAffectedUser($affectedUser) |
207
|
|
|
->setObject('files', $fileId, $filePath); |
208
|
|
|
$this->activityManager->publish($event); |
209
|
|
|
|
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
/** |
213
|
|
|
* @param IShare $share |
214
|
|
|
* @return int |
215
|
|
|
* @throws \Exception |
216
|
|
|
*/ |
217
|
|
|
protected function createMailShare(IShare $share) { |
218
|
|
|
$share->setToken($this->generateToken()); |
219
|
|
|
$shareId = $this->addShareToDB( |
220
|
|
|
$share->getNodeId(), |
221
|
|
|
$share->getNodeType(), |
222
|
|
|
$share->getSharedWith(), |
223
|
|
|
$share->getSharedBy(), |
224
|
|
|
$share->getShareOwner(), |
225
|
|
|
$share->getPermissions(), |
226
|
|
|
$share->getToken() |
227
|
|
|
); |
228
|
|
|
|
229
|
|
|
try { |
230
|
|
|
$link = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', |
231
|
|
|
['token' => $share->getToken()]); |
232
|
|
|
$this->sendMailNotification($share->getNode()->getName(), |
233
|
|
|
$link, |
234
|
|
|
$share->getShareOwner(), |
235
|
|
|
$share->getSharedBy(), $share->getSharedWith()); |
236
|
|
|
} catch (HintException $hintException) { |
237
|
|
|
$this->logger->error('Failed to send share by mail: ' . $hintException->getMessage()); |
238
|
|
|
$this->removeShareFromTable($shareId); |
239
|
|
|
throw $hintException; |
240
|
|
|
} catch (\Exception $e) { |
241
|
|
|
$this->logger->error('Failed to send share by mail: ' . $e->getMessage()); |
242
|
|
|
$this->removeShareFromTable($shareId); |
243
|
|
|
throw new HintException('Failed to send share by mail', |
244
|
|
|
$this->l->t('Failed to send share by E-mail')); |
245
|
|
|
} |
246
|
|
|
|
247
|
|
|
return $shareId; |
248
|
|
|
|
249
|
|
|
} |
250
|
|
|
|
251
|
|
|
protected function sendMailNotification($filename, $link, $owner, $initiator, $shareWith) { |
252
|
|
|
$ownerUser = $this->userManager->get($owner); |
253
|
|
|
$initiatorUser = $this->userManager->get($initiator); |
254
|
|
|
$ownerDisplayName = ($ownerUser instanceof IUser) ? $ownerUser->getDisplayName() : $owner; |
255
|
|
|
$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator; |
256
|
|
View Code Duplication |
if ($owner === $initiator) { |
257
|
|
|
$subject = (string)$this->l->t('%s shared »%s« with you', array($ownerDisplayName, $filename)); |
258
|
|
|
} else { |
259
|
|
|
$subject = (string)$this->l->t('%s shared »%s« with you on behalf of %s', array($ownerDisplayName, $filename, $initiatorDisplayName)); |
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
$message = $this->mailer->createMessage(); |
263
|
|
|
|
264
|
|
|
$emailTemplate = $this->mailer->createEMailTemplate(); |
265
|
|
|
|
266
|
|
|
$emailTemplate->addHeader(); |
267
|
|
|
$emailTemplate->addHeading($this->l->t('%s shared »%s« with you', [$ownerDisplayName, $filename]), false); |
|
|
|
|
268
|
|
|
|
269
|
|
View Code Duplication |
if ($owner === $initiator) { |
270
|
|
|
$text = $this->l->t('%s shared »%s« with you.', [$ownerDisplayName, $filename]); |
271
|
|
|
} else { |
272
|
|
|
$text= $this->l->t('%s shared »%s« with you on behalf of %s.', [$ownerDisplayName, $filename, $initiator]); |
273
|
|
|
} |
274
|
|
|
|
275
|
|
|
$emailTemplate->addBodyText( |
276
|
|
|
$text . ' ' . $this->l->t('Click the button below to open it.'), |
277
|
|
|
$text |
278
|
|
|
); |
279
|
|
|
|
280
|
|
|
$emailTemplate->addBodyButton( |
281
|
|
|
$this->l->t('Open »%s«', [$filename]), |
282
|
|
|
$link |
283
|
|
|
); |
284
|
|
|
$emailTemplate->addFooter(); |
285
|
|
|
|
286
|
|
|
$message->setTo([$shareWith]); |
287
|
|
|
$message->setSubject($subject); |
288
|
|
|
$message->setBody($emailTemplate->renderText(), 'text/plain'); |
289
|
|
|
$message->setHtmlBody($emailTemplate->renderHTML()); |
290
|
|
|
$this->mailer->send($message); |
291
|
|
|
|
292
|
|
|
} |
293
|
|
|
|
294
|
|
|
/** |
295
|
|
|
* send password to recipient of a mail share |
296
|
|
|
* |
297
|
|
|
* @param string $filename |
298
|
|
|
* @param string $initiator |
299
|
|
|
* @param string $shareWith |
300
|
|
|
*/ |
301
|
|
|
protected function sendPassword($filename, $initiator, $shareWith, $password) { |
302
|
|
|
|
303
|
|
|
if ($this->settingsManager->sendPasswordByMail() === false) { |
304
|
|
|
return; |
305
|
|
|
} |
306
|
|
|
|
307
|
|
|
$initiatorUser = $this->userManager->get($initiator); |
308
|
|
|
$initiatorDisplayName = ($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator; |
309
|
|
|
$subject = (string)$this->l->t('Password to access »%s« shared to you by %s', [$filename, $initiatorDisplayName]); |
310
|
|
|
|
311
|
|
|
$message = $this->mailer->createMessage(); |
312
|
|
|
|
313
|
|
|
$emailTemplate = $this->mailer->createEMailTemplate(); |
314
|
|
|
|
315
|
|
|
$emailTemplate->addHeader(); |
316
|
|
|
$emailTemplate->addHeading($this->l->t('Password to access »%s«', [$filename])); |
317
|
|
|
|
318
|
|
|
$emailTemplate->addBodyText($this->l->t( |
319
|
|
|
'%s shared »%s« with you. You should have already received a separate mail with a link to access it.', |
320
|
|
|
[$initiatorDisplayName, $filename] |
321
|
|
|
)); |
322
|
|
|
$emailTemplate->addBodyText($this->l->t('It is protected with the following password: %s', [$password])); |
323
|
|
|
|
324
|
|
|
$emailTemplate->addFooter(); |
325
|
|
|
|
326
|
|
|
$message->setTo([$shareWith]); |
327
|
|
|
$message->setSubject($subject); |
328
|
|
|
$message->setBody($emailTemplate->renderText(), 'text/plain'); |
329
|
|
|
$message->setHtmlBody($emailTemplate->renderHTML()); |
330
|
|
|
$this->mailer->send($message); |
331
|
|
|
|
332
|
|
|
} |
333
|
|
|
|
334
|
|
|
|
335
|
|
|
/** |
336
|
|
|
* generate share token |
337
|
|
|
* |
338
|
|
|
* @return string |
339
|
|
|
*/ |
340
|
|
|
protected function generateToken() { |
341
|
|
|
$token = $this->secureRandom->generate( |
342
|
|
|
15, ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_DIGITS); |
343
|
|
|
return $token; |
344
|
|
|
} |
345
|
|
|
|
346
|
|
|
/** |
347
|
|
|
* Get all children of this share |
348
|
|
|
* |
349
|
|
|
* @param IShare $parent |
350
|
|
|
* @return IShare[] |
351
|
|
|
*/ |
352
|
|
View Code Duplication |
public function getChildren(IShare $parent) { |
|
|
|
|
353
|
|
|
$children = []; |
354
|
|
|
|
355
|
|
|
$qb = $this->dbConnection->getQueryBuilder(); |
356
|
|
|
$qb->select('*') |
357
|
|
|
->from('share') |
358
|
|
|
->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId()))) |
359
|
|
|
->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))) |
360
|
|
|
->orderBy('id'); |
361
|
|
|
|
362
|
|
|
$cursor = $qb->execute(); |
363
|
|
|
while($data = $cursor->fetch()) { |
364
|
|
|
$children[] = $this->createShareObject($data); |
365
|
|
|
} |
366
|
|
|
$cursor->closeCursor(); |
367
|
|
|
|
368
|
|
|
return $children; |
369
|
|
|
} |
370
|
|
|
|
371
|
|
|
/** |
372
|
|
|
* add share to the database and return the ID |
373
|
|
|
* |
374
|
|
|
* @param int $itemSource |
375
|
|
|
* @param string $itemType |
376
|
|
|
* @param string $shareWith |
377
|
|
|
* @param string $sharedBy |
378
|
|
|
* @param string $uidOwner |
379
|
|
|
* @param int $permissions |
380
|
|
|
* @param string $token |
381
|
|
|
* @return int |
382
|
|
|
*/ |
383
|
|
View Code Duplication |
protected function addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token) { |
|
|
|
|
384
|
|
|
$qb = $this->dbConnection->getQueryBuilder(); |
385
|
|
|
$qb->insert('share') |
386
|
|
|
->setValue('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)) |
387
|
|
|
->setValue('item_type', $qb->createNamedParameter($itemType)) |
388
|
|
|
->setValue('item_source', $qb->createNamedParameter($itemSource)) |
389
|
|
|
->setValue('file_source', $qb->createNamedParameter($itemSource)) |
390
|
|
|
->setValue('share_with', $qb->createNamedParameter($shareWith)) |
391
|
|
|
->setValue('uid_owner', $qb->createNamedParameter($uidOwner)) |
392
|
|
|
->setValue('uid_initiator', $qb->createNamedParameter($sharedBy)) |
393
|
|
|
->setValue('permissions', $qb->createNamedParameter($permissions)) |
394
|
|
|
->setValue('token', $qb->createNamedParameter($token)) |
395
|
|
|
->setValue('stime', $qb->createNamedParameter(time())); |
396
|
|
|
|
397
|
|
|
/* |
398
|
|
|
* Added to fix https://github.com/owncloud/core/issues/22215 |
399
|
|
|
* Can be removed once we get rid of ajax/share.php |
400
|
|
|
*/ |
401
|
|
|
$qb->setValue('file_target', $qb->createNamedParameter('')); |
402
|
|
|
|
403
|
|
|
$qb->execute(); |
404
|
|
|
$id = $qb->getLastInsertId(); |
405
|
|
|
|
406
|
|
|
return (int)$id; |
407
|
|
|
} |
408
|
|
|
|
409
|
|
|
/** |
410
|
|
|
* Update a share |
411
|
|
|
* |
412
|
|
|
* @param IShare $share |
413
|
|
|
* @param string|null $plainTextPassword |
414
|
|
|
* @return IShare The share object |
415
|
|
|
*/ |
416
|
|
|
public function update(IShare $share, $plainTextPassword = null) { |
417
|
|
|
|
418
|
|
|
$originalShare = $this->getShareById($share->getId()); |
419
|
|
|
|
420
|
|
|
// a real password was given |
421
|
|
|
$validPassword = $plainTextPassword !== null && $plainTextPassword !== ''; |
422
|
|
|
|
423
|
|
|
if($validPassword && $originalShare->getPassword() !== $share->getPassword()) { |
424
|
|
|
$this->sendPassword($share->getNode()->getName(), $share->getSharedBy(), $share->getSharedWith(), $plainTextPassword); |
425
|
|
|
} |
426
|
|
|
/* |
427
|
|
|
* We allow updating the permissions and password of mail shares |
428
|
|
|
*/ |
429
|
|
|
$qb = $this->dbConnection->getQueryBuilder(); |
430
|
|
|
$qb->update('share') |
431
|
|
|
->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId()))) |
432
|
|
|
->set('permissions', $qb->createNamedParameter($share->getPermissions())) |
433
|
|
|
->set('uid_owner', $qb->createNamedParameter($share->getShareOwner())) |
434
|
|
|
->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy())) |
435
|
|
|
->set('password', $qb->createNamedParameter($share->getPassword())) |
436
|
|
|
->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE)) |
437
|
|
|
->execute(); |
438
|
|
|
|
439
|
|
|
return $share; |
440
|
|
|
} |
441
|
|
|
|
442
|
|
|
/** |
443
|
|
|
* @inheritdoc |
444
|
|
|
*/ |
445
|
|
|
public function move(IShare $share, $recipient) { |
446
|
|
|
/** |
447
|
|
|
* nothing to do here, mail shares are only outgoing shares |
448
|
|
|
*/ |
449
|
|
|
return $share; |
450
|
|
|
} |
451
|
|
|
|
452
|
|
|
/** |
453
|
|
|
* Delete a share (owner unShares the file) |
454
|
|
|
* |
455
|
|
|
* @param IShare $share |
456
|
|
|
*/ |
457
|
|
|
public function delete(IShare $share) { |
458
|
|
|
$this->removeShareFromTable($share->getId()); |
459
|
|
|
} |
460
|
|
|
|
461
|
|
|
/** |
462
|
|
|
* @inheritdoc |
463
|
|
|
*/ |
464
|
|
|
public function deleteFromSelf(IShare $share, $recipient) { |
465
|
|
|
// nothing to do here, mail shares are only outgoing shares |
466
|
|
|
return; |
467
|
|
|
} |
468
|
|
|
|
469
|
|
|
/** |
470
|
|
|
* @inheritdoc |
471
|
|
|
*/ |
472
|
|
View Code Duplication |
public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) { |
|
|
|
|
473
|
|
|
$qb = $this->dbConnection->getQueryBuilder(); |
474
|
|
|
$qb->select('*') |
475
|
|
|
->from('share'); |
476
|
|
|
|
477
|
|
|
$qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))); |
478
|
|
|
|
479
|
|
|
/** |
480
|
|
|
* Reshares for this user are shares where they are the owner. |
481
|
|
|
*/ |
482
|
|
|
if ($reshares === false) { |
483
|
|
|
//Special case for old shares created via the web UI |
484
|
|
|
$or1 = $qb->expr()->andX( |
485
|
|
|
$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)), |
486
|
|
|
$qb->expr()->isNull('uid_initiator') |
487
|
|
|
); |
488
|
|
|
|
489
|
|
|
$qb->andWhere( |
490
|
|
|
$qb->expr()->orX( |
491
|
|
|
$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)), |
492
|
|
|
$or1 |
493
|
|
|
) |
494
|
|
|
); |
495
|
|
|
} else { |
496
|
|
|
$qb->andWhere( |
497
|
|
|
$qb->expr()->orX( |
498
|
|
|
$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)), |
499
|
|
|
$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)) |
500
|
|
|
) |
501
|
|
|
); |
502
|
|
|
} |
503
|
|
|
|
504
|
|
|
if ($node !== null) { |
505
|
|
|
$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId()))); |
506
|
|
|
} |
507
|
|
|
|
508
|
|
|
if ($limit !== -1) { |
509
|
|
|
$qb->setMaxResults($limit); |
510
|
|
|
} |
511
|
|
|
|
512
|
|
|
$qb->setFirstResult($offset); |
513
|
|
|
$qb->orderBy('id'); |
514
|
|
|
|
515
|
|
|
$cursor = $qb->execute(); |
516
|
|
|
$shares = []; |
517
|
|
|
while($data = $cursor->fetch()) { |
518
|
|
|
$shares[] = $this->createShareObject($data); |
519
|
|
|
} |
520
|
|
|
$cursor->closeCursor(); |
521
|
|
|
|
522
|
|
|
return $shares; |
523
|
|
|
} |
524
|
|
|
|
525
|
|
|
/** |
526
|
|
|
* @inheritdoc |
527
|
|
|
*/ |
528
|
|
View Code Duplication |
public function getShareById($id, $recipientId = null) { |
|
|
|
|
529
|
|
|
$qb = $this->dbConnection->getQueryBuilder(); |
530
|
|
|
|
531
|
|
|
$qb->select('*') |
532
|
|
|
->from('share') |
533
|
|
|
->where($qb->expr()->eq('id', $qb->createNamedParameter($id))) |
534
|
|
|
->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))); |
535
|
|
|
|
536
|
|
|
$cursor = $qb->execute(); |
537
|
|
|
$data = $cursor->fetch(); |
538
|
|
|
$cursor->closeCursor(); |
539
|
|
|
|
540
|
|
|
if ($data === false) { |
541
|
|
|
throw new ShareNotFound(); |
542
|
|
|
} |
543
|
|
|
|
544
|
|
|
try { |
545
|
|
|
$share = $this->createShareObject($data); |
546
|
|
|
} catch (InvalidShare $e) { |
547
|
|
|
throw new ShareNotFound(); |
548
|
|
|
} |
549
|
|
|
|
550
|
|
|
return $share; |
551
|
|
|
} |
552
|
|
|
|
553
|
|
|
/** |
554
|
|
|
* Get shares for a given path |
555
|
|
|
* |
556
|
|
|
* @param \OCP\Files\Node $path |
557
|
|
|
* @return IShare[] |
558
|
|
|
*/ |
559
|
|
View Code Duplication |
public function getSharesByPath(Node $path) { |
|
|
|
|
560
|
|
|
$qb = $this->dbConnection->getQueryBuilder(); |
561
|
|
|
|
562
|
|
|
$cursor = $qb->select('*') |
563
|
|
|
->from('share') |
564
|
|
|
->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId()))) |
565
|
|
|
->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))) |
566
|
|
|
->execute(); |
567
|
|
|
|
568
|
|
|
$shares = []; |
569
|
|
|
while($data = $cursor->fetch()) { |
570
|
|
|
$shares[] = $this->createShareObject($data); |
571
|
|
|
} |
572
|
|
|
$cursor->closeCursor(); |
573
|
|
|
|
574
|
|
|
return $shares; |
575
|
|
|
} |
576
|
|
|
|
577
|
|
|
/** |
578
|
|
|
* @inheritdoc |
579
|
|
|
*/ |
580
|
|
View Code Duplication |
public function getSharedWith($userId, $shareType, $node, $limit, $offset) { |
|
|
|
|
581
|
|
|
/** @var IShare[] $shares */ |
582
|
|
|
$shares = []; |
583
|
|
|
|
584
|
|
|
//Get shares directly with this user |
585
|
|
|
$qb = $this->dbConnection->getQueryBuilder(); |
586
|
|
|
$qb->select('*') |
587
|
|
|
->from('share'); |
588
|
|
|
|
589
|
|
|
// Order by id |
590
|
|
|
$qb->orderBy('id'); |
591
|
|
|
|
592
|
|
|
// Set limit and offset |
593
|
|
|
if ($limit !== -1) { |
594
|
|
|
$qb->setMaxResults($limit); |
595
|
|
|
} |
596
|
|
|
$qb->setFirstResult($offset); |
597
|
|
|
|
598
|
|
|
$qb->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))); |
599
|
|
|
$qb->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId))); |
600
|
|
|
|
601
|
|
|
// Filter by node if provided |
602
|
|
|
if ($node !== null) { |
603
|
|
|
$qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId()))); |
604
|
|
|
} |
605
|
|
|
|
606
|
|
|
$cursor = $qb->execute(); |
607
|
|
|
|
608
|
|
|
while($data = $cursor->fetch()) { |
609
|
|
|
$shares[] = $this->createShareObject($data); |
610
|
|
|
} |
611
|
|
|
$cursor->closeCursor(); |
612
|
|
|
|
613
|
|
|
|
614
|
|
|
return $shares; |
615
|
|
|
} |
616
|
|
|
|
617
|
|
|
/** |
618
|
|
|
* Get a share by token |
619
|
|
|
* |
620
|
|
|
* @param string $token |
621
|
|
|
* @return IShare |
622
|
|
|
* @throws ShareNotFound |
623
|
|
|
*/ |
624
|
|
View Code Duplication |
public function getShareByToken($token) { |
|
|
|
|
625
|
|
|
$qb = $this->dbConnection->getQueryBuilder(); |
626
|
|
|
|
627
|
|
|
$cursor = $qb->select('*') |
628
|
|
|
->from('share') |
629
|
|
|
->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))) |
630
|
|
|
->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token))) |
631
|
|
|
->execute(); |
632
|
|
|
|
633
|
|
|
$data = $cursor->fetch(); |
634
|
|
|
|
635
|
|
|
if ($data === false) { |
636
|
|
|
throw new ShareNotFound('Share not found', $this->l->t('Could not find share')); |
637
|
|
|
} |
638
|
|
|
|
639
|
|
|
try { |
640
|
|
|
$share = $this->createShareObject($data); |
641
|
|
|
} catch (InvalidShare $e) { |
642
|
|
|
throw new ShareNotFound('Share not found', $this->l->t('Could not find share')); |
643
|
|
|
} |
644
|
|
|
|
645
|
|
|
return $share; |
646
|
|
|
} |
647
|
|
|
|
648
|
|
|
/** |
649
|
|
|
* remove share from table |
650
|
|
|
* |
651
|
|
|
* @param string $shareId |
652
|
|
|
*/ |
653
|
|
|
protected function removeShareFromTable($shareId) { |
654
|
|
|
$qb = $this->dbConnection->getQueryBuilder(); |
655
|
|
|
$qb->delete('share') |
656
|
|
|
->where($qb->expr()->eq('id', $qb->createNamedParameter($shareId))); |
657
|
|
|
$qb->execute(); |
658
|
|
|
} |
659
|
|
|
|
660
|
|
|
/** |
661
|
|
|
* Create a share object from an database row |
662
|
|
|
* |
663
|
|
|
* @param array $data |
664
|
|
|
* @return IShare |
665
|
|
|
* @throws InvalidShare |
666
|
|
|
* @throws ShareNotFound |
667
|
|
|
*/ |
668
|
|
|
protected function createShareObject($data) { |
669
|
|
|
|
670
|
|
|
$share = new Share($this->rootFolder, $this->userManager); |
671
|
|
|
$share->setId((int)$data['id']) |
672
|
|
|
->setShareType((int)$data['share_type']) |
673
|
|
|
->setPermissions((int)$data['permissions']) |
674
|
|
|
->setTarget($data['file_target']) |
675
|
|
|
->setMailSend((bool)$data['mail_send']) |
676
|
|
|
->setToken($data['token']); |
677
|
|
|
|
678
|
|
|
$shareTime = new \DateTime(); |
679
|
|
|
$shareTime->setTimestamp((int)$data['stime']); |
680
|
|
|
$share->setShareTime($shareTime); |
681
|
|
|
$share->setSharedWith($data['share_with']); |
682
|
|
|
$share->setPassword($data['password']); |
683
|
|
|
|
684
|
|
|
if ($data['uid_initiator'] !== null) { |
685
|
|
|
$share->setShareOwner($data['uid_owner']); |
686
|
|
|
$share->setSharedBy($data['uid_initiator']); |
687
|
|
|
} else { |
688
|
|
|
//OLD SHARE |
689
|
|
|
$share->setSharedBy($data['uid_owner']); |
690
|
|
|
$path = $this->getNode($share->getSharedBy(), (int)$data['file_source']); |
691
|
|
|
|
692
|
|
|
$owner = $path->getOwner(); |
693
|
|
|
$share->setShareOwner($owner->getUID()); |
694
|
|
|
} |
695
|
|
|
|
696
|
|
View Code Duplication |
if ($data['expiration'] !== null) { |
697
|
|
|
$expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']); |
698
|
|
|
if ($expiration !== false) { |
699
|
|
|
$share->setExpirationDate($expiration); |
700
|
|
|
} |
701
|
|
|
} |
702
|
|
|
|
703
|
|
|
$share->setNodeId((int)$data['file_source']); |
704
|
|
|
$share->setNodeType($data['item_type']); |
705
|
|
|
|
706
|
|
|
$share->setProviderId($this->identifier()); |
707
|
|
|
|
708
|
|
|
return $share; |
709
|
|
|
} |
710
|
|
|
|
711
|
|
|
/** |
712
|
|
|
* Get the node with file $id for $user |
713
|
|
|
* |
714
|
|
|
* @param string $userId |
715
|
|
|
* @param int $id |
716
|
|
|
* @return \OCP\Files\File|\OCP\Files\Folder |
717
|
|
|
* @throws InvalidShare |
718
|
|
|
*/ |
719
|
|
View Code Duplication |
private function getNode($userId, $id) { |
|
|
|
|
720
|
|
|
try { |
721
|
|
|
$userFolder = $this->rootFolder->getUserFolder($userId); |
722
|
|
|
} catch (NotFoundException $e) { |
|
|
|
|
723
|
|
|
throw new InvalidShare(); |
724
|
|
|
} |
725
|
|
|
|
726
|
|
|
$nodes = $userFolder->getById($id); |
727
|
|
|
|
728
|
|
|
if (empty($nodes)) { |
729
|
|
|
throw new InvalidShare(); |
730
|
|
|
} |
731
|
|
|
|
732
|
|
|
return $nodes[0]; |
733
|
|
|
} |
734
|
|
|
|
735
|
|
|
/** |
736
|
|
|
* A user is deleted from the system |
737
|
|
|
* So clean up the relevant shares. |
738
|
|
|
* |
739
|
|
|
* @param string $uid |
740
|
|
|
* @param int $shareType |
741
|
|
|
*/ |
742
|
|
View Code Duplication |
public function userDeleted($uid, $shareType) { |
|
|
|
|
743
|
|
|
$qb = $this->dbConnection->getQueryBuilder(); |
744
|
|
|
|
745
|
|
|
$qb->delete('share') |
746
|
|
|
->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))) |
747
|
|
|
->andWhere($qb->expr()->eq('uid_owner', $qb->createNamedParameter($uid))) |
748
|
|
|
->execute(); |
749
|
|
|
} |
750
|
|
|
|
751
|
|
|
/** |
752
|
|
|
* This provider does not support group shares |
753
|
|
|
* |
754
|
|
|
* @param string $gid |
755
|
|
|
*/ |
756
|
|
|
public function groupDeleted($gid) { |
757
|
|
|
return; |
758
|
|
|
} |
759
|
|
|
|
760
|
|
|
/** |
761
|
|
|
* This provider does not support group shares |
762
|
|
|
* |
763
|
|
|
* @param string $uid |
764
|
|
|
* @param string $gid |
765
|
|
|
*/ |
766
|
|
|
public function userDeletedFromGroup($uid, $gid) { |
767
|
|
|
return; |
768
|
|
|
} |
769
|
|
|
|
770
|
|
|
/** |
771
|
|
|
* get database row of a give share |
772
|
|
|
* |
773
|
|
|
* @param $id |
774
|
|
|
* @return array |
775
|
|
|
* @throws ShareNotFound |
776
|
|
|
*/ |
777
|
|
View Code Duplication |
protected function getRawShare($id) { |
|
|
|
|
778
|
|
|
|
779
|
|
|
// Now fetch the inserted share and create a complete share object |
780
|
|
|
$qb = $this->dbConnection->getQueryBuilder(); |
781
|
|
|
$qb->select('*') |
782
|
|
|
->from('share') |
783
|
|
|
->where($qb->expr()->eq('id', $qb->createNamedParameter($id))); |
784
|
|
|
|
785
|
|
|
$cursor = $qb->execute(); |
786
|
|
|
$data = $cursor->fetch(); |
787
|
|
|
$cursor->closeCursor(); |
788
|
|
|
|
789
|
|
|
if ($data === false) { |
790
|
|
|
throw new ShareNotFound; |
791
|
|
|
} |
792
|
|
|
|
793
|
|
|
return $data; |
794
|
|
|
} |
795
|
|
|
|
796
|
|
View Code Duplication |
public function getSharesInFolder($userId, Folder $node, $reshares) { |
|
|
|
|
797
|
|
|
$qb = $this->dbConnection->getQueryBuilder(); |
798
|
|
|
$qb->select('*') |
799
|
|
|
->from('share', 's') |
800
|
|
|
->andWhere($qb->expr()->orX( |
801
|
|
|
$qb->expr()->eq('item_type', $qb->createNamedParameter('file')), |
802
|
|
|
$qb->expr()->eq('item_type', $qb->createNamedParameter('folder')) |
803
|
|
|
)) |
804
|
|
|
->andWhere( |
805
|
|
|
$qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL)) |
806
|
|
|
); |
807
|
|
|
|
808
|
|
|
/** |
809
|
|
|
* Reshares for this user are shares where they are the owner. |
810
|
|
|
*/ |
811
|
|
|
if ($reshares === false) { |
812
|
|
|
$qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))); |
813
|
|
|
} else { |
814
|
|
|
$qb->andWhere( |
815
|
|
|
$qb->expr()->orX( |
816
|
|
|
$qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)), |
817
|
|
|
$qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)) |
818
|
|
|
) |
819
|
|
|
); |
820
|
|
|
} |
821
|
|
|
|
822
|
|
|
$qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid')); |
823
|
|
|
$qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId()))); |
824
|
|
|
|
825
|
|
|
$qb->orderBy('id'); |
826
|
|
|
|
827
|
|
|
$cursor = $qb->execute(); |
828
|
|
|
$shares = []; |
829
|
|
|
while ($data = $cursor->fetch()) { |
830
|
|
|
$shares[$data['fileid']][] = $this->createShareObject($data); |
831
|
|
|
} |
832
|
|
|
$cursor->closeCursor(); |
833
|
|
|
|
834
|
|
|
return $shares; |
835
|
|
|
} |
836
|
|
|
|
837
|
|
|
/** |
838
|
|
|
* @inheritdoc |
839
|
|
|
*/ |
840
|
|
|
public function getAccessList($nodes, $currentAccess) { |
841
|
|
|
$ids = []; |
842
|
|
|
foreach ($nodes as $node) { |
843
|
|
|
$ids[] = $node->getId(); |
844
|
|
|
} |
845
|
|
|
|
846
|
|
|
$qb = $this->dbConnection->getQueryBuilder(); |
847
|
|
|
$qb->select('share_with') |
848
|
|
|
->from('share') |
849
|
|
|
->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_EMAIL))) |
850
|
|
|
->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY))) |
851
|
|
|
->andWhere($qb->expr()->orX( |
852
|
|
|
$qb->expr()->eq('item_type', $qb->createNamedParameter('file')), |
853
|
|
|
$qb->expr()->eq('item_type', $qb->createNamedParameter('folder')) |
854
|
|
|
)) |
855
|
|
|
->setMaxResults(1); |
856
|
|
|
$cursor = $qb->execute(); |
857
|
|
|
|
858
|
|
|
$mail = $cursor->fetch() !== false; |
859
|
|
|
$cursor->closeCursor(); |
860
|
|
|
|
861
|
|
|
return ['public' => $mail]; |
862
|
|
|
} |
863
|
|
|
|
864
|
|
|
} |
865
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.