|
1
|
|
|
<?php declare(strict_types=1); |
|
2
|
|
|
|
|
3
|
|
|
|
|
4
|
|
|
/** |
|
5
|
|
|
* Circles - Bring cloud-users closer together. |
|
6
|
|
|
* |
|
7
|
|
|
* This file is licensed under the Affero General Public License version 3 or |
|
8
|
|
|
* later. See the COPYING file. |
|
9
|
|
|
* |
|
10
|
|
|
* @author Maxence Lange <[email protected]> |
|
11
|
|
|
* @copyright 2017 |
|
12
|
|
|
* @license GNU AGPL version 3 or any later version |
|
13
|
|
|
* |
|
14
|
|
|
* This program is free software: you can redistribute it and/or modify |
|
15
|
|
|
* it under the terms of the GNU Affero General Public License as |
|
16
|
|
|
* published by the Free Software Foundation, either version 3 of the |
|
17
|
|
|
* License, or (at your option) any later version. |
|
18
|
|
|
* |
|
19
|
|
|
* This program is distributed in the hope that it will be useful, |
|
20
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
21
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
22
|
|
|
* GNU Affero General Public License for more details. |
|
23
|
|
|
* |
|
24
|
|
|
* You should have received a copy of the GNU Affero General Public License |
|
25
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
26
|
|
|
* |
|
27
|
|
|
*/ |
|
28
|
|
|
|
|
29
|
|
|
|
|
30
|
|
|
namespace OCA\Circles\GlobalScale; |
|
31
|
|
|
|
|
32
|
|
|
|
|
33
|
|
|
use daita\MySmallPhpTools\Model\SimpleDataStore; |
|
34
|
|
|
use daita\MySmallPhpTools\Traits\TArrayTools; |
|
35
|
|
|
use Exception; |
|
36
|
|
|
use OC; |
|
37
|
|
|
use OC\Share20\Share; |
|
38
|
|
|
use OCA\Circles\AppInfo\Application; |
|
39
|
|
|
use OCA\Circles\Exceptions\GSStatusException; |
|
40
|
|
|
use OCA\Circles\Exceptions\TokenDoesNotExistException; |
|
41
|
|
|
use OCA\Circles\Model\Circle; |
|
42
|
|
|
use OCA\Circles\Model\GlobalScale\GSEvent; |
|
43
|
|
|
use OCA\Circles\Model\GlobalScale\GSShare; |
|
44
|
|
|
use OCA\Circles\Model\Member; |
|
45
|
|
|
use OCA\Circles\Model\SharesToken; |
|
46
|
|
|
use OCA\Circles\Model\SharingFrame; |
|
47
|
|
|
use OCA\Circles\Service\ConfigService; |
|
48
|
|
|
use OCA\Circles\Service\MiscService; |
|
49
|
|
|
use OCP\Files\NotFoundException; |
|
50
|
|
|
use OCP\IL10N; |
|
51
|
|
|
use OCP\IUser; |
|
52
|
|
|
use OCP\Mail\IEMailTemplate; |
|
53
|
|
|
use OCP\Share\Exceptions\IllegalIDChangeException; |
|
54
|
|
|
use OCP\Share\Exceptions\ShareNotFound; |
|
55
|
|
|
use OCP\Share\IShare; |
|
56
|
|
|
use OCP\Util; |
|
57
|
|
|
|
|
58
|
|
|
|
|
59
|
|
|
/** |
|
60
|
|
|
* Class FileShare |
|
61
|
|
|
* |
|
62
|
|
|
* @package OCA\Circles\GlobalScale |
|
63
|
|
|
*/ |
|
64
|
|
|
class FileShare extends AGlobalScaleEvent { |
|
65
|
|
|
|
|
66
|
|
|
|
|
67
|
|
|
use TArrayTools; |
|
68
|
|
|
|
|
69
|
|
|
|
|
70
|
|
|
/** @var IL10N */ |
|
71
|
|
|
private $l10n; |
|
72
|
|
|
|
|
73
|
|
|
|
|
74
|
|
|
/** |
|
75
|
|
|
* @param GSEvent $event |
|
76
|
|
|
* @param bool $localCheck |
|
77
|
|
|
* @param bool $mustBeChecked |
|
78
|
|
|
* |
|
79
|
|
|
* @throws GSStatusException |
|
80
|
|
|
*/ |
|
81
|
|
|
public function verify(GSEvent $event, bool $localCheck = false, bool $mustBeChecked = false): void { |
|
82
|
|
|
// TODO: might be a bad idea, all process of the sharing should be managed from here. |
|
83
|
|
|
// Even if we are not in a GS setup. |
|
84
|
|
|
// The reason is that if a mail needs to be send, all mail address associated to the circle needs to be retrieved |
|
85
|
|
|
if (!$this->configService->getGSStatus(ConfigService::GS_ENABLED)) { |
|
86
|
|
|
return; |
|
87
|
|
|
} |
|
88
|
|
|
|
|
89
|
|
|
// if event/file is local, we generate a federate share for the same circle on other instances |
|
90
|
|
|
if ($event->getSource() !== $this->configService->getLocalCloudId()) { |
|
91
|
|
|
return; |
|
92
|
|
|
} |
|
93
|
|
|
|
|
94
|
|
|
try { |
|
95
|
|
|
$share = $this->getShareFromData($event->getData()); |
|
96
|
|
|
} catch (Exception $e) { |
|
97
|
|
|
return; |
|
98
|
|
|
} |
|
99
|
|
|
|
|
100
|
|
|
try { |
|
101
|
|
|
$node = $share->getNode(); |
|
102
|
|
|
$filename = $node->getName(); |
|
103
|
|
|
} catch (NotFoundException $e) { |
|
|
|
|
|
|
104
|
|
|
$this->miscService->log('issue while FileShare: ' . $e->getMessage()); |
|
105
|
|
|
|
|
106
|
|
|
return; |
|
107
|
|
|
} |
|
108
|
|
|
|
|
109
|
|
|
$event->getData() |
|
110
|
|
|
->s('gs_federated', $share->getToken()) |
|
111
|
|
|
->s('gs_filename', '/' . $filename); |
|
112
|
|
|
} |
|
113
|
|
|
|
|
114
|
|
|
|
|
115
|
|
|
/** |
|
116
|
|
|
* @param GSEvent $event |
|
117
|
|
|
* |
|
118
|
|
|
* @throws GSStatusException |
|
119
|
|
|
*/ |
|
120
|
|
|
public function manage(GSEvent $event): void { |
|
121
|
|
|
// TODO: might be a bad idea, all process of the sharing should be managed from here. |
|
122
|
|
|
// Even if we are not in a GS setup. |
|
123
|
|
|
// The reason is that if a mail needs to be send, all mail address associated to the circle needs to be retrieved |
|
124
|
|
|
if (!$this->configService->getGSStatus(ConfigService::GS_ENABLED)) { |
|
125
|
|
|
return; |
|
126
|
|
|
} |
|
127
|
|
|
|
|
128
|
|
|
// TODO - if event is local - generate mails sur be sent to TYPE_MAILS |
|
129
|
|
|
|
|
130
|
|
|
// if event is not local, we create a federated file to the right instance of Nextcloud, using the right token |
|
131
|
|
|
if ($event->getSource() !== $this->configService->getLocalCloudId()) { |
|
132
|
|
|
try { |
|
133
|
|
|
$share = $this->getShareFromData($event->getData()); |
|
134
|
|
|
} catch (Exception $e) { |
|
135
|
|
|
return; |
|
136
|
|
|
} |
|
137
|
|
|
|
|
138
|
|
|
$data = $event->getData(); |
|
139
|
|
|
$token = $data->g('gs_federated'); |
|
140
|
|
|
$filename = $data->g('gs_filename'); |
|
141
|
|
|
|
|
142
|
|
|
$gsShare = new GSShare($share->getSharedWith(), $token); |
|
143
|
|
|
$gsShare->setOwner($share->getShareOwner()); |
|
144
|
|
|
$gsShare->setInstance($event->getSource()); |
|
145
|
|
|
$gsShare->setParent(-1); |
|
146
|
|
|
$gsShare->setMountPoint($filename); |
|
147
|
|
|
|
|
148
|
|
|
$this->gsSharesRequest->create($gsShare); |
|
149
|
|
|
} |
|
150
|
|
|
|
|
151
|
|
|
$circle = $event->getCircle(); |
|
152
|
|
|
$members = $this->membersRequest->forceGetMembers( |
|
153
|
|
|
$circle->getUniqueId(), Member::LEVEL_MEMBER, Member::TYPE_CONTACT, true |
|
154
|
|
|
); |
|
155
|
|
|
|
|
156
|
|
|
$accounts = []; |
|
157
|
|
|
foreach ($members as $member) { |
|
158
|
|
|
if ($member->getInstance() === '') { |
|
159
|
|
|
$accounts[] = $this->getInfosFromContact($member); |
|
160
|
|
|
} |
|
161
|
|
|
} |
|
162
|
|
|
|
|
163
|
|
|
$event->setResult(new SimpleDataStore(['contacts' => $accounts])); |
|
164
|
|
|
} |
|
165
|
|
|
|
|
166
|
|
|
|
|
167
|
|
|
/** |
|
168
|
|
|
* @param GSEvent[] $events |
|
169
|
|
|
*/ |
|
170
|
|
|
public function result(array $events): void { |
|
171
|
|
|
$event = null; |
|
172
|
|
|
// $mails = $cloudIds = []; |
|
173
|
|
|
$contacts = []; |
|
174
|
|
|
foreach (array_keys($events) as $instance) { |
|
175
|
|
|
$event = $events[$instance]; |
|
176
|
|
|
$contacts = array_merge( |
|
177
|
|
|
$contacts, $event->getResult() |
|
178
|
|
|
->gArray('contacts') |
|
179
|
|
|
); |
|
180
|
|
|
// $mails = array_merge( |
|
181
|
|
|
// $mails, $event->getResult() |
|
182
|
|
|
// ->gArray('mails') |
|
183
|
|
|
// ); |
|
184
|
|
|
// $cloudIds = array_merge( |
|
185
|
|
|
// $cloudIds, $event->getResult() |
|
186
|
|
|
// ->gArray('cloudIds') |
|
187
|
|
|
// ); |
|
188
|
|
|
} |
|
189
|
|
|
|
|
190
|
|
|
if ($event === null || !$event->hasCircle()) { |
|
191
|
|
|
return; |
|
192
|
|
|
} |
|
193
|
|
|
|
|
194
|
|
|
$circle = $event->getCircle(); |
|
195
|
|
|
|
|
196
|
|
|
// we check mail address that were already filled |
|
197
|
|
|
// $mails = $this->getMailAddressFromCircle($circle->getUniqueId()); |
|
198
|
|
|
|
|
199
|
|
|
|
|
200
|
|
|
// foreach ($members as $member) { |
|
201
|
|
|
// $mails[] = $member->getUserId(); |
|
202
|
|
|
// } |
|
203
|
|
|
|
|
204
|
|
|
|
|
205
|
|
|
foreach ($contacts as $contact) { |
|
206
|
|
|
$this->sendShareToContact($event, $circle, $contact); |
|
207
|
|
|
} |
|
208
|
|
|
|
|
209
|
|
|
|
|
210
|
|
|
// TODO - making this not needed - should force the async on this EVENT as it should be initiated in manage() |
|
211
|
|
|
// $contacts = $this->membersRequest->forceGetMembers( |
|
212
|
|
|
// $circle->getUniqueId(), Member::LEVEL_MEMBER, Member::TYPE_CONTACT |
|
213
|
|
|
// ); |
|
214
|
|
|
// |
|
215
|
|
|
// foreach ($contacts as $contact) { |
|
216
|
|
|
// $mails = array_merge($mails, $this->getMailsFromContact($contact->getUserId())); |
|
217
|
|
|
// $cloudIds = array_merge($cloudIds, $this->getCloudIdsFromContact($contact->getUserId())); |
|
218
|
|
|
// } |
|
219
|
|
|
// |
|
220
|
|
|
// $mails = array_values(array_unique($mails)); |
|
221
|
|
|
// $this->sendShareToMails($event, $mails); |
|
222
|
|
|
|
|
223
|
|
|
// $cloudIds = array_values(array_unique($cloudIds)); |
|
224
|
|
|
// $this->sendShareToCloudIds($event, $cloudIds); |
|
225
|
|
|
} |
|
226
|
|
|
|
|
227
|
|
|
|
|
228
|
|
|
/** |
|
229
|
|
|
* @param GSEvent $event |
|
230
|
|
|
* @param Circle $circle |
|
231
|
|
|
* @param array $contact |
|
232
|
|
|
*/ |
|
233
|
|
|
private function sendShareToContact(GSEvent $event, Circle $circle, array $contact) { |
|
234
|
|
|
$password = ''; |
|
235
|
|
|
if ($this->configService->enforcePasswordProtection()) { |
|
236
|
|
|
$password = $this->miscService->token(15); |
|
237
|
|
|
} |
|
238
|
|
|
|
|
239
|
|
|
try { |
|
240
|
|
|
$member = $this->membersRequest->forceGetMemberById($contact['memberId']); |
|
241
|
|
|
$share = $this->getShareFromData($event->getData()); |
|
242
|
|
|
} catch (Exception $e) { |
|
243
|
|
|
return; |
|
244
|
|
|
} |
|
245
|
|
|
|
|
246
|
|
|
try { |
|
247
|
|
|
$sharesToken = |
|
248
|
|
|
$this->tokensRequest->generateTokenForMember($member, (int)$share->getId(), $password); |
|
249
|
|
|
} catch (TokenDoesNotExistException $e) { |
|
250
|
|
|
return; |
|
251
|
|
|
} |
|
252
|
|
|
|
|
253
|
|
|
foreach ($contact['emails'] as $mail) { |
|
254
|
|
|
$this->sharedByMail($circle, $share, $mail, $sharesToken, $password); |
|
255
|
|
|
} |
|
256
|
|
|
|
|
257
|
|
|
// $mails = [$member->getUserId()]; |
|
258
|
|
|
// if ($member->getType() === Member::TYPE_CONTACT) { |
|
259
|
|
|
// $mails = $this->getMailsFromContact($member->getUserId()); |
|
260
|
|
|
// } |
|
261
|
|
|
// |
|
262
|
|
|
// foreach ($mails as $mail) { |
|
263
|
|
|
// $this->sharedByMail($circle, $share, $mail, $sharesToken, $password); |
|
264
|
|
|
// } |
|
265
|
|
|
|
|
266
|
|
|
} |
|
267
|
|
|
|
|
268
|
|
|
|
|
269
|
|
|
/** |
|
270
|
|
|
* @param Circle $circle |
|
271
|
|
|
* @param IShare $share |
|
272
|
|
|
* @param string $email |
|
273
|
|
|
* @param SharesToken $sharesToken |
|
274
|
|
|
* @param string $password |
|
275
|
|
|
*/ |
|
276
|
|
View Code Duplication |
private function sharedByMail( |
|
|
|
|
|
|
277
|
|
|
Circle $circle, IShare $share, string $email, SharesToken $sharesToken, string $password |
|
278
|
|
|
) { |
|
279
|
|
|
// genelink |
|
280
|
|
|
$link = $this->urlGenerator->linkToRouteAbsolute( |
|
281
|
|
|
'files_sharing.sharecontroller.showShare', |
|
282
|
|
|
['token' => $sharesToken->getToken()] |
|
283
|
|
|
); |
|
284
|
|
|
|
|
285
|
|
|
$lang = $this->configService->getCoreValueForUser($share->getSharedBy(), 'lang', ''); |
|
286
|
|
|
if ($lang !== '') { |
|
287
|
|
|
$this->l10n = OC::$server->getL10N(Application::APP_NAME, $lang); |
|
288
|
|
|
} |
|
289
|
|
|
|
|
290
|
|
|
try { |
|
291
|
|
|
$this->sendMail( |
|
292
|
|
|
$share->getNode() |
|
293
|
|
|
->getName(), $link, |
|
294
|
|
|
MiscService::getDisplay($share->getSharedBy(), Member::TYPE_USER), |
|
295
|
|
|
$circle->getName(), $email |
|
296
|
|
|
); |
|
297
|
|
|
$this->sendPasswordByMail( |
|
298
|
|
|
$share, MiscService::getDisplay($share->getSharedBy(), Member::TYPE_USER), |
|
299
|
|
|
$email, $password |
|
300
|
|
|
); |
|
301
|
|
|
} catch (Exception $e) { |
|
302
|
|
|
OC::$server->getLogger() |
|
303
|
|
|
->log(1, 'Circles::sharedByMail - mail were not sent: ' . $e->getMessage()); |
|
304
|
|
|
} |
|
305
|
|
|
} |
|
306
|
|
|
|
|
307
|
|
|
|
|
308
|
|
|
/** |
|
309
|
|
|
* @param $fileName |
|
310
|
|
|
* @param string $link |
|
311
|
|
|
* @param string $author |
|
312
|
|
|
* @param $circleName |
|
313
|
|
|
* @param string $email |
|
314
|
|
|
* |
|
315
|
|
|
* @throws Exception |
|
316
|
|
|
*/ |
|
317
|
|
View Code Duplication |
protected function sendMail($fileName, $link, $author, $circleName, $email) { |
|
|
|
|
|
|
318
|
|
|
$message = $this->mailer->createMessage(); |
|
319
|
|
|
|
|
320
|
|
|
$this->miscService->log( |
|
321
|
|
|
"Sending mail to circle '" . $circleName . "': " . $email . ' file: ' . $fileName |
|
322
|
|
|
. ' - link: ' . $link, 0 |
|
323
|
|
|
); |
|
324
|
|
|
|
|
325
|
|
|
$subject = $this->l10n->t('%s shared »%s« with you.', [$author, $fileName]); |
|
326
|
|
|
$text = $this->l10n->t('%s shared »%s« with \'%s\'.', [$author, $fileName, $circleName]); |
|
327
|
|
|
|
|
328
|
|
|
$emailTemplate = |
|
329
|
|
|
$this->generateEmailTemplate($subject, $text, $fileName, $link, $author, $circleName); |
|
330
|
|
|
|
|
331
|
|
|
$instanceName = $this->defaults->getName(); |
|
332
|
|
|
$senderName = $this->l10n->t('%s on %s', [$author, $instanceName]); |
|
333
|
|
|
|
|
334
|
|
|
$message->setFrom([Util::getDefaultEmailAddress($instanceName) => $senderName]); |
|
335
|
|
|
$message->setSubject($subject); |
|
336
|
|
|
$message->setPlainBody($emailTemplate->renderText()); |
|
337
|
|
|
$message->setHtmlBody($emailTemplate->renderHtml()); |
|
338
|
|
|
$message->setTo([$email]); |
|
339
|
|
|
|
|
340
|
|
|
$this->mailer->send($message); |
|
341
|
|
|
} |
|
342
|
|
|
|
|
343
|
|
|
|
|
344
|
|
|
/** |
|
345
|
|
|
* @param IShare $share |
|
346
|
|
|
* @param string $circleName |
|
347
|
|
|
* @param string $email |
|
348
|
|
|
* |
|
349
|
|
|
* @param $password |
|
350
|
|
|
* |
|
351
|
|
|
* @throws NotFoundException |
|
352
|
|
|
* @throws Exception |
|
353
|
|
|
*/ |
|
354
|
|
View Code Duplication |
protected function sendPasswordByMail(IShare $share, $circleName, $email, $password) { |
|
|
|
|
|
|
355
|
|
|
if (!$this->configService->sendPasswordByMail() || $password === '') { |
|
356
|
|
|
return; |
|
357
|
|
|
} |
|
358
|
|
|
|
|
359
|
|
|
$message = $this->mailer->createMessage(); |
|
360
|
|
|
|
|
361
|
|
|
$this->miscService->log("Sending password mail to circle '" . $circleName . "': " . $email, 0); |
|
362
|
|
|
|
|
363
|
|
|
$filename = $share->getNode() |
|
364
|
|
|
->getName(); |
|
365
|
|
|
$initiator = $share->getSharedBy(); |
|
366
|
|
|
$shareWith = $share->getSharedWith(); |
|
367
|
|
|
|
|
368
|
|
|
$initiatorUser = $this->userManager->get($initiator); |
|
369
|
|
|
$initiatorDisplayName = |
|
370
|
|
|
($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator; |
|
|
|
|
|
|
371
|
|
|
$initiatorEmailAddress = |
|
372
|
|
|
($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null; |
|
|
|
|
|
|
373
|
|
|
|
|
374
|
|
|
$plainBodyPart = $this->l10n->t( |
|
375
|
|
|
"%1\$s shared »%2\$s« with you.\nYou should have already received a separate mail with a link to access it.\n", |
|
376
|
|
|
[$initiatorDisplayName, $filename] |
|
377
|
|
|
); |
|
378
|
|
|
$htmlBodyPart = $this->l10n->t( |
|
379
|
|
|
'%1$s shared »%2$s« with you. You should have already received a separate mail with a link to access it.', |
|
380
|
|
|
[$initiatorDisplayName, $filename] |
|
381
|
|
|
); |
|
382
|
|
|
|
|
383
|
|
|
$emailTemplate = $this->mailer->createEMailTemplate( |
|
384
|
|
|
'sharebymail.RecipientPasswordNotification', [ |
|
385
|
|
|
'filename' => $filename, |
|
386
|
|
|
'password' => $password, |
|
387
|
|
|
'initiator' => $initiatorDisplayName, |
|
388
|
|
|
'initiatorEmail' => $initiatorEmailAddress, |
|
389
|
|
|
'shareWith' => $shareWith, |
|
390
|
|
|
] |
|
391
|
|
|
); |
|
392
|
|
|
|
|
393
|
|
|
$emailTemplate->setSubject( |
|
394
|
|
|
$this->l10n->t( |
|
395
|
|
|
'Password to access »%1$s« shared to you by %2$s', [$filename, $initiatorDisplayName] |
|
396
|
|
|
) |
|
397
|
|
|
); |
|
398
|
|
|
$emailTemplate->addHeader(); |
|
399
|
|
|
$emailTemplate->addHeading($this->l10n->t('Password to access »%s«', [$filename]), false); |
|
400
|
|
|
$emailTemplate->addBodyText(htmlspecialchars($htmlBodyPart), $plainBodyPart); |
|
401
|
|
|
$emailTemplate->addBodyText($this->l10n->t('It is protected with the following password:')); |
|
402
|
|
|
$emailTemplate->addBodyText($password); |
|
403
|
|
|
|
|
404
|
|
|
// The "From" contains the sharers name |
|
405
|
|
|
$instanceName = $this->defaults->getName(); |
|
406
|
|
|
$senderName = $this->l10n->t( |
|
407
|
|
|
'%1$s via %2$s', |
|
408
|
|
|
[ |
|
409
|
|
|
$initiatorDisplayName, |
|
410
|
|
|
$instanceName |
|
411
|
|
|
] |
|
412
|
|
|
); |
|
413
|
|
|
$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]); |
|
414
|
|
|
if ($initiatorEmailAddress !== null) { |
|
415
|
|
|
$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]); |
|
416
|
|
|
$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan()); |
|
417
|
|
|
} else { |
|
418
|
|
|
$emailTemplate->addFooter(); |
|
419
|
|
|
} |
|
420
|
|
|
|
|
421
|
|
|
$message->setTo([$email]); |
|
422
|
|
|
$message->useTemplate($emailTemplate); |
|
423
|
|
|
$this->mailer->send($message); |
|
424
|
|
|
} |
|
425
|
|
|
|
|
426
|
|
|
|
|
427
|
|
|
/** |
|
428
|
|
|
* @param $subject |
|
429
|
|
|
* @param $text |
|
430
|
|
|
* @param $fileName |
|
431
|
|
|
* @param $link |
|
432
|
|
|
* @param string $author |
|
433
|
|
|
* @param string $circleName |
|
434
|
|
|
* |
|
435
|
|
|
* @return IEMailTemplate |
|
436
|
|
|
*/ |
|
437
|
|
View Code Duplication |
private function generateEmailTemplate($subject, $text, $fileName, $link, $author, $circleName |
|
|
|
|
|
|
438
|
|
|
) { |
|
439
|
|
|
$emailTemplate = $this->mailer->createEMailTemplate( |
|
440
|
|
|
'circles.ShareNotification', [ |
|
441
|
|
|
'fileName' => $fileName, |
|
442
|
|
|
'fileLink' => $link, |
|
443
|
|
|
'author' => $author, |
|
444
|
|
|
'circleName' => $circleName, |
|
445
|
|
|
] |
|
446
|
|
|
); |
|
447
|
|
|
|
|
448
|
|
|
$emailTemplate->addHeader(); |
|
449
|
|
|
$emailTemplate->addHeading($subject, false); |
|
450
|
|
|
$emailTemplate->addBodyText( |
|
451
|
|
|
htmlspecialchars($text) . '<br>' . htmlspecialchars( |
|
452
|
|
|
$this->l10n->t('Click the button below to open it.') |
|
453
|
|
|
), $text |
|
454
|
|
|
); |
|
455
|
|
|
$emailTemplate->addBodyButton( |
|
456
|
|
|
$this->l10n->t('Open »%s«', [htmlspecialchars($fileName)]), $link |
|
457
|
|
|
); |
|
458
|
|
|
|
|
459
|
|
|
return $emailTemplate; |
|
460
|
|
|
} |
|
461
|
|
|
|
|
462
|
|
|
|
|
463
|
|
|
/** |
|
464
|
|
|
* @param Member $member |
|
465
|
|
|
* |
|
466
|
|
|
* @return array |
|
467
|
|
|
*/ |
|
468
|
|
|
private function getInfosFromContact(Member $member): array { |
|
469
|
|
|
$contact = MiscService::getContactData($member->getUserId()); |
|
470
|
|
|
|
|
471
|
|
|
return [ |
|
472
|
|
|
'memberId' => $member->getMemberId(), |
|
473
|
|
|
'emails' => $this->getArray('EMAIL', $contact), |
|
474
|
|
|
'cloudIds' => $this->getArray('CLOUD', $contact) |
|
475
|
|
|
]; |
|
476
|
|
|
} |
|
477
|
|
|
|
|
478
|
|
|
|
|
479
|
|
|
/** |
|
480
|
|
|
* @param string $circleId |
|
481
|
|
|
* |
|
482
|
|
|
* @return array |
|
483
|
|
|
*/ |
|
484
|
|
|
private function getMailAddressFromCircle(string $circleId): array { |
|
485
|
|
|
$members = $this->membersRequest->forceGetMembers( |
|
486
|
|
|
$circleId, Member::LEVEL_MEMBER, Member::TYPE_MAIL |
|
487
|
|
|
); |
|
488
|
|
|
|
|
489
|
|
|
return array_map( |
|
490
|
|
|
function(Member $member) { |
|
491
|
|
|
return $member->getUserId(); |
|
492
|
|
|
}, $members |
|
493
|
|
|
); |
|
494
|
|
|
} |
|
495
|
|
|
|
|
496
|
|
|
|
|
497
|
|
|
// |
|
498
|
|
|
// /** |
|
499
|
|
|
// * @param GSEvent $event |
|
500
|
|
|
// * |
|
501
|
|
|
// * @throws BroadcasterIsNotCompatibleException |
|
502
|
|
|
// * ` */ |
|
503
|
|
|
// private function generateFederatedShare(GSEvent $event) { |
|
504
|
|
|
// $data = $event->getData(); |
|
505
|
|
|
// $frame = SharingFrame::fromJSON(json_encode($data->gAll())); |
|
506
|
|
|
// |
|
507
|
|
|
// try { |
|
508
|
|
|
// $broadcaster = \OC::$server->query((string)$frame->getHeader('broadcast')); |
|
509
|
|
|
// if (!($broadcaster instanceof IBroadcaster)) { |
|
510
|
|
|
// throw new BroadcasterIsNotCompatibleException(); |
|
511
|
|
|
// } |
|
512
|
|
|
// |
|
513
|
|
|
// $frameCircle = $frame->getCircle(); |
|
514
|
|
|
// $circle = $this->circlesRequest->forceGetCircle($frameCircle->getUniqueId()); |
|
515
|
|
|
// } catch (QueryException | CircleDoesNotExistException $e) { |
|
516
|
|
|
// return; |
|
517
|
|
|
// } |
|
518
|
|
|
// |
|
519
|
|
|
// $this->feedBroadcaster($broadcaster, $frame, $circle); |
|
520
|
|
|
// } |
|
521
|
|
|
|
|
522
|
|
|
// |
|
523
|
|
|
// /** |
|
524
|
|
|
// * @param IBroadcaster $broadcaster |
|
525
|
|
|
// * @param SharingFrame $frame |
|
526
|
|
|
// * @param Circle $circle |
|
527
|
|
|
// */ |
|
528
|
|
|
// private function feedBroadcaster(IBroadcaster $broadcaster, SharingFrame $frame, Circle $circle) { |
|
529
|
|
|
// $broadcaster->init(); |
|
530
|
|
|
// |
|
531
|
|
|
// if ($circle->getType() !== Circle::CIRCLES_PERSONAL) { |
|
532
|
|
|
// $broadcaster->createShareToCircle($frame, $circle); |
|
533
|
|
|
// } |
|
534
|
|
|
// |
|
535
|
|
|
// $members = |
|
536
|
|
|
// $this->membersRequest->forceGetMembers($circle->getUniqueId(), Member::LEVEL_MEMBER, 0, true); |
|
537
|
|
|
// foreach ($members as $member) { |
|
538
|
|
|
// $this->parseMember($member); |
|
539
|
|
|
// |
|
540
|
|
|
// if ($member->isBroadcasting()) { |
|
541
|
|
|
// $broadcaster->createShareToMember($frame, $member); |
|
542
|
|
|
// } |
|
543
|
|
|
// |
|
544
|
|
|
// if ($member->getInstance() !== '') { |
|
545
|
|
|
// $this->miscService->log('#### GENERATE FEDERATED CIRCLES SHARE ' . $member->getInstance()); |
|
546
|
|
|
// } |
|
547
|
|
|
// } |
|
548
|
|
|
// } |
|
549
|
|
|
|
|
550
|
|
|
// |
|
551
|
|
|
// /** |
|
552
|
|
|
// * @param Member $member |
|
553
|
|
|
// */ |
|
554
|
|
|
// private function parseMember(Member &$member) { |
|
555
|
|
|
// $this->parseMemberFromContact($member); |
|
556
|
|
|
// } |
|
557
|
|
|
|
|
558
|
|
|
|
|
559
|
|
|
// /** |
|
560
|
|
|
// * on Type Contact, we convert the type to MAIL and retrieve the first mail of the list. |
|
561
|
|
|
// * If no email, we set the member as not broadcasting. |
|
562
|
|
|
// * |
|
563
|
|
|
// * @param Member $member |
|
564
|
|
|
// */ |
|
565
|
|
|
// private function parseMemberFromContact(Member &$member) { |
|
566
|
|
|
// if ($member->getType() !== Member::TYPE_CONTACT) { |
|
567
|
|
|
// return; |
|
568
|
|
|
// } |
|
569
|
|
|
// |
|
570
|
|
|
// $contact = MiscService::getContactData($member->getUserId()); |
|
571
|
|
|
// if (!key_exists('EMAIL', $contact)) { |
|
572
|
|
|
// $member->broadcasting(false); |
|
573
|
|
|
// |
|
574
|
|
|
// return; |
|
575
|
|
|
// } |
|
576
|
|
|
// |
|
577
|
|
|
// $member->setType(Member::TYPE_MAIL); |
|
578
|
|
|
// $member->setUserId(array_shift($contact['EMAIL'])); |
|
579
|
|
|
// } |
|
580
|
|
|
|
|
581
|
|
|
|
|
582
|
|
|
/** |
|
583
|
|
|
* @param SimpleDataStore $data |
|
584
|
|
|
* |
|
585
|
|
|
* @return IShare |
|
586
|
|
|
* @throws ShareNotFound |
|
587
|
|
|
* @throws IllegalIDChangeException |
|
588
|
|
|
*/ |
|
589
|
|
|
private function getShareFromData(SimpleDataStore $data) { |
|
590
|
|
|
$frame = SharingFrame::fromArray($data->gArray('frame')); |
|
591
|
|
|
$payload = $frame->getPayload(); |
|
592
|
|
|
if (!key_exists('share', $payload)) { |
|
593
|
|
|
throw new ShareNotFound(); |
|
594
|
|
|
} |
|
595
|
|
|
|
|
596
|
|
|
return $this->generateShare($payload['share']); |
|
597
|
|
|
} |
|
598
|
|
|
|
|
599
|
|
|
|
|
600
|
|
|
/** |
|
601
|
|
|
* recreate the share from the JSON payload. |
|
602
|
|
|
* |
|
603
|
|
|
* @param array $data |
|
604
|
|
|
* |
|
605
|
|
|
* @return IShare |
|
606
|
|
|
* @throws IllegalIDChangeException |
|
607
|
|
|
*/ |
|
608
|
|
|
private function generateShare($data): IShare { |
|
609
|
|
|
$share = new Share($this->rootFolder, $this->userManager); |
|
610
|
|
|
$share->setId($data['id']); |
|
611
|
|
|
$share->setSharedBy($data['sharedBy']); |
|
612
|
|
|
$share->setSharedWith($data['sharedWith']); |
|
613
|
|
|
$share->setNodeId($data['nodeId']); |
|
614
|
|
|
$share->setShareOwner($data['shareOwner']); |
|
615
|
|
|
$share->setPermissions($data['permissions']); |
|
616
|
|
|
$share->setToken($data['token']); |
|
617
|
|
|
$share->setPassword($data['password']); |
|
618
|
|
|
|
|
619
|
|
|
return $share; |
|
620
|
|
|
} |
|
621
|
|
|
|
|
622
|
|
|
|
|
623
|
|
|
} |
|
624
|
|
|
|
Scrutinizer analyzes your
composer.json/composer.lockfile if available to determine the classes, and functions that are defined by your dependencies.It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.