Completed
Pull Request — master (#362)
by Maxence
03:19
created

FileShare::getInfosFromContact()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
cc 1
nc 1
nop 1
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\BroadcasterIsNotCompatibleException;
40
use OCA\Circles\Exceptions\CircleDoesNotExistException;
41
use OCA\Circles\Exceptions\GSStatusException;
42
use OCA\Circles\Exceptions\TokenDoesNotExistException;
43
use OCA\Circles\IBroadcaster;
44
use OCA\Circles\Model\Circle;
45
use OCA\Circles\Model\GlobalScale\GSEvent;
46
use OCA\Circles\Model\GlobalScale\GSShare;
47
use OCA\Circles\Model\Member;
48
use OCA\Circles\Model\SharesToken;
49
use OCA\Circles\Model\SharingFrame;
50
use OCA\Circles\Service\ConfigService;
51
use OCA\Circles\Service\MiscService;
52
use OCP\AppFramework\QueryException;
53
use OCP\Files\NotFoundException;
54
use OCP\IL10N;
55
use OCP\IUser;
56
use OCP\Mail\IEMailTemplate;
57
use OCP\Share\Exceptions\IllegalIDChangeException;
58
use OCP\Share\Exceptions\ShareNotFound;
59
use OCP\Share\IShare;
60
use OCP\Util;
61
62
63
/**
64
 * Class FileShare
65
 *
66
 * @package OCA\Circles\GlobalScale
67
 */
68
class FileShare extends AGlobalScaleEvent {
69
70
71
	use TArrayTools;
72
73
74
	/** @var IL10N */
75
	private $l10n;
76
77
78
	/**
79
	 * @param GSEvent $event
80
	 * @param bool $localCheck
81
	 * @param bool $mustBeChecked
82
	 *
83
	 * @throws GSStatusException
84
	 */
85
	public function verify(GSEvent $event, bool $localCheck = false, bool $mustBeChecked = false): void {
86
		// TODO: might be a bad idea, all process of the sharing should be managed from here.
87
		// Even if we are not in a GS setup.
88
		// The reason is that if a mail needs to be send, all mail address associated to the circle needs to be retrieved
89
		if (!$this->configService->getGSStatus(ConfigService::GS_ENABLED)) {
90
			return;
91
		}
92
93
		// if event/file is local, we generate a federate share for the same circle on other instances
94
		if ($event->getSource() !== $this->configService->getLocalCloudId()) {
95
			return;
96
		}
97
98
		try {
99
			$share = $this->getShareFromData($event->getData());
100
		} catch (Exception $e) {
101
			return;
102
		}
103
104
		try {
105
			$node = $share->getNode();
106
			$filename = $node->getName();
107
		} catch (NotFoundException $e) {
0 ignored issues
show
Bug introduced by
The class OCP\Files\NotFoundException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file 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.

Loading history...
108
			$this->miscService->log('issue while FileShare: ' . $e->getMessage());
109
110
			return;
111
		}
112
113
		$event->getData()
114
			  ->s('gs_federated', $share->getToken())
115
			  ->s('gs_filename', '/' . $filename);
116
	}
117
118
119
	/**
120
	 * @param GSEvent $event
121
	 *
122
	 * @throws GSStatusException
123
	 */
124
	public function manage(GSEvent $event): void {
125
		// TODO: might be a bad idea, all process of the sharing should be managed from here.
126
		// Even if we are not in a GS setup.
127
		// The reason is that if a mail needs to be send, all mail address associated to the circle needs to be retrieved
128
		if (!$this->configService->getGSStatus(ConfigService::GS_ENABLED)) {
129
			return;
130
		}
131
132
		// TODO - if event is local - generate mails sur be sent to TYPE_MAILS
133
134
		// if event is not local, we create a federated file to the right instance of Nextcloud, using the right token
135
		if ($event->getSource() !== $this->configService->getLocalCloudId()) {
136
			try {
137
				$share = $this->getShareFromData($event->getData());
138
			} catch (Exception $e) {
139
				return;
140
			}
141
142
			$data = $event->getData();
143
			$token = $data->g('gs_federated');
144
			$filename = $data->g('gs_filename');
145
146
			$gsShare = new GSShare($share->getSharedWith(), $token);
147
			$gsShare->setOwner($share->getShareOwner());
148
			$gsShare->setInstance($event->getSource());
149
			$gsShare->setParent(-1);
150
			$gsShare->setMountPoint($filename);
151
152
			$this->gsSharesRequest->create($gsShare);
153
		}
154
155
		$circle = $event->getCircle();
156
		$members = $this->membersRequest->forceGetMembers(
157
			$circle->getUniqueId(), Member::LEVEL_MEMBER, Member::TYPE_CONTACT, true
158
		);
159
160
		$accounts = [];
161
		foreach ($members as $member) {
162
			$accounts[] = $this->getInfosFromContact($member);
163
		}
164
165
		$event->setResult(new SimpleDataStore(['contacts' => $accounts]));
166
	}
167
168
169
	/**
170
	 * @param GSEvent[] $events
171
	 */
172
	public function result(array $events): void {
173
		$event = null;
174
//		$mails = $cloudIds = [];
175
		$contacts = [];
176
		foreach (array_keys($events) as $instance) {
177
			$event = $events[$instance];
178
			$contacts = array_merge(
179
				$contacts, $event->getResult()
180
								 ->gArray('contacts')
181
			);
182
//			$mails = array_merge(
183
//				$mails, $event->getResult()
184
//							  ->gArray('mails')
185
//			);
186
//			$cloudIds = array_merge(
187
//				$cloudIds, $event->getResult()
188
//								 ->gArray('cloudIds')
189
//			);
190
		}
191
192
		if ($event === null || !$event->hasCircle()) {
193
			return;
194
		}
195
196
		$circle = $event->getCircle();
197
198
		// we check mail address that were already filled
199
		$mails = $this->getMailAddressFromCircle($circle->getUniqueId());
0 ignored issues
show
Unused Code introduced by
$mails is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
200
201
202
//		foreach ($members as $member) {
203
//			$mails[] = $member->getUserId();
204
//		}
205
206
207
		foreach ($contacts as $contact) {
208
			$this->sendShareToContact($event, $circle, $contact);
209
		}
210
211
212
		// TODO - making this not needed - should force the async on this EVENT as it should be initiated in manage()
213
//		$contacts = $this->membersRequest->forceGetMembers(
214
//			$circle->getUniqueId(), Member::LEVEL_MEMBER, Member::TYPE_CONTACT
215
//		);
216
//
217
//		foreach ($contacts as $contact) {
218
//			$mails = array_merge($mails, $this->getMailsFromContact($contact->getUserId()));
219
//			$cloudIds = array_merge($cloudIds, $this->getCloudIdsFromContact($contact->getUserId()));
220
//		}
221
//
222
//		$mails = array_values(array_unique($mails));
223
//		$this->sendShareToMails($event, $mails);
224
225
//		$cloudIds = array_values(array_unique($cloudIds));
226
//		$this->sendShareToCloudIds($event, $cloudIds);
227
	}
228
229
230
	/**
231
	 * @param GSEvent $event
232
	 * @param array $contact
233
	 */
234
	private function sendShareToContact(GSEvent $event, Circle $circle, array $contact) {
235
		$password = '';
236
		if ($this->configService->enforcePasswordProtection()) {
237
			$password = $this->miscService->token(15);
238
		}
239
240
		try {
241
			$member = $this->membersRequest->forceGetMemberById($contact['memberId']);
242
			$share = $this->getShareFromData($event->getData());
243
		} catch (Exception $e) {
244
			return;
245
		}
246
247
		try {
248
			$sharesToken =
249
				$this->tokensRequest->generateTokenForMember($member, (int)$share->getId(), $password);
250
		} catch (TokenDoesNotExistException $e) {
251
			return;
252
		}
253
254
		foreach ($contact['emails'] as $mail) {
255
			$this->sharedByMail($circle, $share, $mail, $sharesToken, $password);
256
		}
257
258
//		$mails = [$member->getUserId()];
259
//		if ($member->getType() === Member::TYPE_CONTACT) {
260
//			$mails = $this->getMailsFromContact($member->getUserId());
261
//		}
262
//
263
//		foreach ($mails as $mail) {
264
//			$this->sharedByMail($circle, $share, $mail, $sharesToken, $password);
265
//		}
266
267
	}
268
269
270
	/**
271
	 * @param Circle $circle
272
	 * @param IShare $share
273
	 * @param string $email
274
	 * @param SharesToken $sharesToken
275
	 * @param string $password
276
	 */
277 View Code Duplication
	private function sharedByMail(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
278
		Circle $circle, IShare $share, string $email, SharesToken $sharesToken, string $password
279
	) {
280
		// genelink
281
		$link = $this->urlGenerator->linkToRouteAbsolute(
282
			'files_sharing.sharecontroller.showShare',
283
			['token' => $sharesToken->getToken()]
284
		);
285
286
		$lang = $this->configService->getCoreValueForUser($share->getSharedBy(), 'lang', '');
287
		if ($lang !== '') {
288
			$this->l10n = OC::$server->getL10N(Application::APP_NAME, $lang);
289
		}
290
291
		try {
292
			$this->sendMail(
293
				$share->getNode()
294
					  ->getName(), $link,
295
				MiscService::getDisplay($share->getSharedBy(), Member::TYPE_USER),
296
				$circle->getName(), $email
297
			);
298
			$this->sendPasswordByMail(
299
				$share, MiscService::getDisplay($share->getSharedBy(), Member::TYPE_USER),
300
				$email, $password
301
			);
302
		} catch (Exception $e) {
303
			OC::$server->getLogger()
304
					   ->log(1, 'Circles::sharedByMail - mail were not sent: ' . $e->getMessage());
305
		}
306
	}
307
308
309
	/**
310
	 * @param $fileName
311
	 * @param string $link
312
	 * @param string $author
313
	 * @param $circleName
314
	 * @param string $email
315
	 *
316
	 * @throws Exception
317
	 */
318 View Code Duplication
	protected function sendMail($fileName, $link, $author, $circleName, $email) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
319
		$message = $this->mailer->createMessage();
320
321
		$this->miscService->log(
322
			"Sending mail to circle '" . $circleName . "': " . $email . ' file: ' . $fileName
323
			. ' - link: ' . $link, 0
324
		);
325
326
		$subject = $this->l10n->t('%s shared »%s« with you.', [$author, $fileName]);
327
		$text = $this->l10n->t('%s shared »%s« with \'%s\'.', [$author, $fileName, $circleName]);
328
329
		$emailTemplate =
330
			$this->generateEmailTemplate($subject, $text, $fileName, $link, $author, $circleName);
331
332
		$instanceName = $this->defaults->getName();
333
		$senderName = $this->l10n->t('%s on %s', [$author, $instanceName]);
334
335
		$message->setFrom([Util::getDefaultEmailAddress($instanceName) => $senderName]);
336
		$message->setSubject($subject);
337
		$message->setPlainBody($emailTemplate->renderText());
338
		$message->setHtmlBody($emailTemplate->renderHtml());
339
		$message->setTo([$email]);
340
341
		$this->mailer->send($message);
342
	}
343
344
345
	/**
346
	 * @param IShare $share
347
	 * @param string $circleName
348
	 * @param string $email
349
	 *
350
	 * @param $password
351
	 *
352
	 * @throws NotFoundException
353
	 * @throws Exception
354
	 */
355 View Code Duplication
	protected function sendPasswordByMail(IShare $share, $circleName, $email, $password) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
356
		if (!$this->configService->sendPasswordByMail() || $password === '') {
357
			return;
358
		}
359
360
		$message = $this->mailer->createMessage();
361
362
		$this->miscService->log("Sending password mail to circle '" . $circleName . "': " . $email, 0);
363
364
		$filename = $share->getNode()
365
						  ->getName();
366
		$initiator = $share->getSharedBy();
367
		$shareWith = $share->getSharedWith();
368
369
		$initiatorUser = $this->userManager->get($initiator);
370
		$initiatorDisplayName =
371
			($initiatorUser instanceof IUser) ? $initiatorUser->getDisplayName() : $initiator;
0 ignored issues
show
Bug introduced by
The class OCP\IUser does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
372
		$initiatorEmailAddress =
373
			($initiatorUser instanceof IUser) ? $initiatorUser->getEMailAddress() : null;
0 ignored issues
show
Bug introduced by
The class OCP\IUser does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
374
375
		$plainBodyPart = $this->l10n->t(
376
			"%1\$s shared »%2\$s« with you.\nYou should have already received a separate mail with a link to access it.\n",
377
			[$initiatorDisplayName, $filename]
378
		);
379
		$htmlBodyPart = $this->l10n->t(
380
			'%1$s shared »%2$s« with you. You should have already received a separate mail with a link to access it.',
381
			[$initiatorDisplayName, $filename]
382
		);
383
384
		$emailTemplate = $this->mailer->createEMailTemplate(
385
			'sharebymail.RecipientPasswordNotification', [
386
														   'filename'       => $filename,
387
														   'password'       => $password,
388
														   'initiator'      => $initiatorDisplayName,
389
														   'initiatorEmail' => $initiatorEmailAddress,
390
														   'shareWith'      => $shareWith,
391
													   ]
392
		);
393
394
		$emailTemplate->setSubject(
395
			$this->l10n->t(
396
				'Password to access »%1$s« shared to you by %2$s', [$filename, $initiatorDisplayName]
397
			)
398
		);
399
		$emailTemplate->addHeader();
400
		$emailTemplate->addHeading($this->l10n->t('Password to access »%s«', [$filename]), false);
401
		$emailTemplate->addBodyText(htmlspecialchars($htmlBodyPart), $plainBodyPart);
402
		$emailTemplate->addBodyText($this->l10n->t('It is protected with the following password:'));
403
		$emailTemplate->addBodyText($password);
404
405
		// The "From" contains the sharers name
406
		$instanceName = $this->defaults->getName();
407
		$senderName = $this->l10n->t(
408
			'%1$s via %2$s',
409
			[
410
				$initiatorDisplayName,
411
				$instanceName
412
			]
413
		);
414
		$message->setFrom([\OCP\Util::getDefaultEmailAddress($instanceName) => $senderName]);
415
		if ($initiatorEmailAddress !== null) {
416
			$message->setReplyTo([$initiatorEmailAddress => $initiatorDisplayName]);
417
			$emailTemplate->addFooter($instanceName . ' - ' . $this->defaults->getSlogan());
418
		} else {
419
			$emailTemplate->addFooter();
420
		}
421
422
		$message->setTo([$email]);
423
		$message->useTemplate($emailTemplate);
424
		$this->mailer->send($message);
425
	}
426
427
428
	/**
429
	 * @param $subject
430
	 * @param $text
431
	 * @param $fileName
432
	 * @param $link
433
	 * @param string $author
434
	 * @param string $circleName
435
	 *
436
	 * @return IEMailTemplate
437
	 */
438 View Code Duplication
	private function generateEmailTemplate($subject, $text, $fileName, $link, $author, $circleName
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
439
	) {
440
		$emailTemplate = $this->mailer->createEMailTemplate(
441
			'circles.ShareNotification', [
442
										   'fileName'   => $fileName,
443
										   'fileLink'   => $link,
444
										   'author'     => $author,
445
										   'circleName' => $circleName,
446
									   ]
447
		);
448
449
		$emailTemplate->addHeader();
450
		$emailTemplate->addHeading($subject, false);
451
		$emailTemplate->addBodyText(
452
			htmlspecialchars($text) . '<br>' . htmlspecialchars(
453
				$this->l10n->t('Click the button below to open it.')
454
			), $text
455
		);
456
		$emailTemplate->addBodyButton(
457
			$this->l10n->t('Open »%s«', [htmlspecialchars($fileName)]), $link
458
		);
459
460
		return $emailTemplate;
461
	}
462
463
464
	/**
465
	 * @param Member $member
466
	 *
467
	 * @return array
468
	 */
469
	private function getInfosFromContact(Member $member): array {
470
		$contact = MiscService::getContactData($member->getUserId());
471
472
		return [
473
			'memberId' => $member->getMemberId(),
474
			'emails'   => $this->getArray('EMAIL', $contact),
475
			'cloudIds' => $this->getArray('CLOUD', $contact)
476
		];
477
	}
478
479
480
	/**
481
	 * @param string $circleId
482
	 *
483
	 * @return array
484
	 */
485
	private function getMailAddressFromCircle(string $circleId): array {
486
		$members = $this->membersRequest->forceGetMembers(
487
			$circleId, Member::LEVEL_MEMBER, Member::TYPE_MAIL
488
		);
489
490
		return array_map(
491
			function(Member $member) {
492
				return $member->getUserId();
493
			}, $members
494
		);
495
	}
496
497
498
//
499
//	/**
500
//	 * @param GSEvent $event
501
//	 *
502
//	 * @throws BroadcasterIsNotCompatibleException
503
//	 * `     */
504
//	private function generateFederatedShare(GSEvent $event) {
505
//		$data = $event->getData();
506
//		$frame = SharingFrame::fromJSON(json_encode($data->gAll()));
507
//
508
//		try {
509
//			$broadcaster = \OC::$server->query((string)$frame->getHeader('broadcast'));
510
//			if (!($broadcaster instanceof IBroadcaster)) {
511
//				throw new BroadcasterIsNotCompatibleException();
512
//			}
513
//
514
//			$frameCircle = $frame->getCircle();
515
//			$circle = $this->circlesRequest->forceGetCircle($frameCircle->getUniqueId());
516
//		} catch (QueryException | CircleDoesNotExistException $e) {
517
//			return;
518
//		}
519
//
520
//		$this->feedBroadcaster($broadcaster, $frame, $circle);
521
//	}
522
523
//
524
//	/**
525
//	 * @param IBroadcaster $broadcaster
526
//	 * @param SharingFrame $frame
527
//	 * @param Circle $circle
528
//	 */
529
//	private function feedBroadcaster(IBroadcaster $broadcaster, SharingFrame $frame, Circle $circle) {
530
//		$broadcaster->init();
531
//
532
//		if ($circle->getType() !== Circle::CIRCLES_PERSONAL) {
533
//			$broadcaster->createShareToCircle($frame, $circle);
534
//		}
535
//
536
//		$members =
537
//			$this->membersRequest->forceGetMembers($circle->getUniqueId(), Member::LEVEL_MEMBER, 0, true);
538
//		foreach ($members as $member) {
539
//			$this->parseMember($member);
540
//
541
//			if ($member->isBroadcasting()) {
542
//				$broadcaster->createShareToMember($frame, $member);
543
//			}
544
//
545
//			if ($member->getInstance() !== '') {
546
//				$this->miscService->log('#### GENERATE FEDERATED CIRCLES SHARE ' . $member->getInstance());
547
//			}
548
//		}
549
//	}
550
551
//
552
//	/**
553
//	 * @param Member $member
554
//	 */
555
//	private function parseMember(Member &$member) {
556
//		$this->parseMemberFromContact($member);
557
//	}
558
559
560
//	/**
561
//	 * on Type Contact, we convert the type to MAIL and retrieve the first mail of the list.
562
//	 * If no email, we set the member as not broadcasting.
563
//	 *
564
//	 * @param Member $member
565
//	 */
566
//	private function parseMemberFromContact(Member &$member) {
567
//		if ($member->getType() !== Member::TYPE_CONTACT) {
568
//			return;
569
//		}
570
//
571
//		$contact = MiscService::getContactData($member->getUserId());
572
//		if (!key_exists('EMAIL', $contact)) {
573
//			$member->broadcasting(false);
574
//
575
//			return;
576
//		}
577
//
578
//		$member->setType(Member::TYPE_MAIL);
579
//		$member->setUserId(array_shift($contact['EMAIL']));
580
//	}
581
582
583
	/**
584
	 * @param SimpleDataStore $data
585
	 *
586
	 * @return IShare
587
	 * @throws ShareNotFound
588
	 * @throws IllegalIDChangeException
589
	 */
590
	private function getShareFromData(SimpleDataStore $data) {
591
		$frame = SharingFrame::fromArray($data->gArray('frame'));
592
		$payload = $frame->getPayload();
593
		if (!key_exists('share', $payload)) {
594
			throw new ShareNotFound();
595
		}
596
597
		return $this->generateShare($payload['share']);
598
	}
599
600
601
	/**
602
	 * recreate the share from the JSON payload.
603
	 *
604
	 * @param array $data
605
	 *
606
	 * @return IShare
607
	 * @throws IllegalIDChangeException
608
	 */
609
	private function generateShare($data): IShare {
610
		$share = new Share($this->rootFolder, $this->userManager);
611
		$share->setId($data['id']);
612
		$share->setSharedBy($data['sharedBy']);
613
		$share->setSharedWith($data['sharedWith']);
614
		$share->setNodeId($data['nodeId']);
615
		$share->setShareOwner($data['shareOwner']);
616
		$share->setPermissions($data['permissions']);
617
		$share->setToken($data['token']);
618
		$share->setPassword($data['password']);
619
620
		return $share;
621
	}
622
623
624
}
625