Passed
Push — master ( ccc0a5...5195be )
by Roeland
10:43 queued 11s
created
apps/federatedfilesharing/lib/ocm/CloudFederationProviderFiles.php 2 patches
Indentation   +785 added lines, -785 removed lines patch added patch discarded remove patch
@@ -52,789 +52,789 @@
 block discarded – undo
52 52
 
53 53
 class CloudFederationProviderFiles implements ICloudFederationProvider {
54 54
 
55
-	/** @var IAppManager */
56
-	private $appManager;
57
-
58
-	/** @var FederatedShareProvider */
59
-	private $federatedShareProvider;
60
-
61
-	/** @var AddressHandler */
62
-	private $addressHandler;
63
-
64
-	/** @var ILogger */
65
-	private $logger;
66
-
67
-	/** @var IUserManager */
68
-	private $userManager;
69
-
70
-	/** @var ICloudIdManager */
71
-	private $cloudIdManager;
72
-
73
-	/** @var IActivityManager */
74
-	private $activityManager;
75
-
76
-	/** @var INotificationManager */
77
-	private $notificationManager;
78
-
79
-	/** @var IURLGenerator */
80
-	private $urlGenerator;
81
-
82
-	/** @var ICloudFederationFactory */
83
-	private $cloudFederationFactory;
84
-
85
-	/** @var ICloudFederationProviderManager */
86
-	private $cloudFederationProviderManager;
87
-
88
-	/** @var IDBConnection */
89
-	private $connection;
90
-
91
-	/** @var IGroupManager */
92
-	private $groupManager;
93
-
94
-	/**
95
-	 * CloudFederationProvider constructor.
96
-	 *
97
-	 * @param IAppManager $appManager
98
-	 * @param FederatedShareProvider $federatedShareProvider
99
-	 * @param AddressHandler $addressHandler
100
-	 * @param ILogger $logger
101
-	 * @param IUserManager $userManager
102
-	 * @param ICloudIdManager $cloudIdManager
103
-	 * @param IActivityManager $activityManager
104
-	 * @param INotificationManager $notificationManager
105
-	 * @param IURLGenerator $urlGenerator
106
-	 * @param ICloudFederationFactory $cloudFederationFactory
107
-	 * @param ICloudFederationProviderManager $cloudFederationProviderManager
108
-	 * @param IDBConnection $connection
109
-	 * @param IGroupManager $groupManager
110
-	 */
111
-	public function __construct(IAppManager $appManager,
112
-								FederatedShareProvider $federatedShareProvider,
113
-								AddressHandler $addressHandler,
114
-								ILogger $logger,
115
-								IUserManager $userManager,
116
-								ICloudIdManager $cloudIdManager,
117
-								IActivityManager $activityManager,
118
-								INotificationManager $notificationManager,
119
-								IURLGenerator $urlGenerator,
120
-								ICloudFederationFactory $cloudFederationFactory,
121
-								ICloudFederationProviderManager $cloudFederationProviderManager,
122
-								IDBConnection $connection,
123
-								IGroupManager $groupManager
124
-	) {
125
-		$this->appManager = $appManager;
126
-		$this->federatedShareProvider = $federatedShareProvider;
127
-		$this->addressHandler = $addressHandler;
128
-		$this->logger = $logger;
129
-		$this->userManager = $userManager;
130
-		$this->cloudIdManager = $cloudIdManager;
131
-		$this->activityManager = $activityManager;
132
-		$this->notificationManager = $notificationManager;
133
-		$this->urlGenerator = $urlGenerator;
134
-		$this->cloudFederationFactory = $cloudFederationFactory;
135
-		$this->cloudFederationProviderManager = $cloudFederationProviderManager;
136
-		$this->connection = $connection;
137
-		$this->groupManager = $groupManager;
138
-	}
139
-
140
-
141
-
142
-	/**
143
-	 * @return string
144
-	 */
145
-	public function getShareType() {
146
-		return 'file';
147
-	}
148
-
149
-	/**
150
-	 * share received from another server
151
-	 *
152
-	 * @param ICloudFederationShare $share
153
-	 * @return string provider specific unique ID of the share
154
-	 *
155
-	 * @throws ProviderCouldNotAddShareException
156
-	 * @throws \OCP\AppFramework\QueryException
157
-	 * @throws \OC\HintException
158
-	 * @since 14.0.0
159
-	 */
160
-	public function shareReceived(ICloudFederationShare $share) {
161
-
162
-		if (!$this->isS2SEnabled(true)) {
163
-			throw new ProviderCouldNotAddShareException('Server does not support federated cloud sharing', '', Http::STATUS_SERVICE_UNAVAILABLE);
164
-		}
165
-
166
-		$protocol = $share->getProtocol();
167
-		if ($protocol['name'] !== 'webdav') {
168
-			throw new ProviderCouldNotAddShareException('Unsupported protocol for data exchange.', '', Http::STATUS_NOT_IMPLEMENTED);
169
-		}
170
-
171
-		list($ownerUid, $remote) = $this->addressHandler->splitUserRemote($share->getOwner());
172
-		// for backward compatibility make sure that the remote url stored in the
173
-		// database ends with a trailing slash
174
-		if (substr($remote, -1) !== '/') {
175
-			$remote = $remote . '/';
176
-		}
177
-
178
-		$token = $share->getShareSecret();
179
-		$name = $share->getResourceName();
180
-		$owner = $share->getOwnerDisplayName();
181
-		$sharedBy = $share->getSharedByDisplayName();
182
-		$shareWith = $share->getShareWith();
183
-		$remoteId = $share->getProviderId();
184
-		$sharedByFederatedId = $share->getSharedBy();
185
-		$ownerFederatedId = $share->getOwner();
186
-		$shareType = $this->mapShareTypeToNextcloud($share->getShareType());
187
-
188
-		// if no explicit information about the person who created the share was send
189
-		// we assume that the share comes from the owner
190
-		if ($sharedByFederatedId === null) {
191
-			$sharedBy = $owner;
192
-			$sharedByFederatedId = $ownerFederatedId;
193
-		}
194
-
195
-		if ($remote && $token && $name && $owner && $remoteId && $shareWith) {
196
-
197
-			if (!Util::isValidFileName($name)) {
198
-				throw new ProviderCouldNotAddShareException('The mountpoint name contains invalid characters.', '', Http::STATUS_BAD_REQUEST);
199
-			}
200
-
201
-			// FIXME this should be a method in the user management instead
202
-			if ($shareType === Share::SHARE_TYPE_USER) {
203
-				$this->logger->debug('shareWith before, ' . $shareWith, ['app' => 'files_sharing']);
204
-				Util::emitHook(
205
-					'\OCA\Files_Sharing\API\Server2Server',
206
-					'preLoginNameUsedAsUserName',
207
-					array('uid' => &$shareWith)
208
-				);
209
-				$this->logger->debug('shareWith after, ' . $shareWith, ['app' => 'files_sharing']);
210
-
211
-				if (!$this->userManager->userExists($shareWith)) {
212
-					throw new ProviderCouldNotAddShareException('User does not exists', '',Http::STATUS_BAD_REQUEST);
213
-				}
214
-
215
-				\OC_Util::setupFS($shareWith);
216
-			}
217
-
218
-			if ($shareType === Share::SHARE_TYPE_GROUP && !$this->groupManager->groupExists($shareWith)) {
219
-				throw new ProviderCouldNotAddShareException('Group does not exists', '',Http::STATUS_BAD_REQUEST);
220
-			}
221
-
222
-			$externalManager = new \OCA\Files_Sharing\External\Manager(
223
-				\OC::$server->getDatabaseConnection(),
224
-				Filesystem::getMountManager(),
225
-				Filesystem::getLoader(),
226
-				\OC::$server->getHTTPClientService(),
227
-				\OC::$server->getNotificationManager(),
228
-				\OC::$server->query(\OCP\OCS\IDiscoveryService::class),
229
-				\OC::$server->getCloudFederationProviderManager(),
230
-				\OC::$server->getCloudFederationFactory(),
231
-				\OC::$server->getGroupManager(),
232
-				\OC::$server->getUserManager(),
233
-				$shareWith
234
-			);
235
-
236
-			try {
237
-				$externalManager->addShare($remote, $token, '', $name, $owner, $shareType,false, $shareWith, $remoteId);
238
-				$shareId = \OC::$server->getDatabaseConnection()->lastInsertId('*PREFIX*share_external');
239
-
240
-				if ($shareType === Share::SHARE_TYPE_USER) {
241
-					$event = $this->activityManager->generateEvent();
242
-					$event->setApp('files_sharing')
243
-						->setType('remote_share')
244
-						->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_RECEIVED, [$ownerFederatedId, trim($name, '/')])
245
-						->setAffectedUser($shareWith)
246
-						->setObject('remote_share', (int)$shareId, $name);
247
-					\OC::$server->getActivityManager()->publish($event);
248
-					$this->notifyAboutNewShare($shareWith, $shareId, $ownerFederatedId, $sharedByFederatedId, $name, $sharedBy, $owner);
249
-				} else {
250
-					$groupMembers = $this->groupManager->get($shareWith)->getUsers();
251
-					foreach ($groupMembers as $user) {
252
-						$event = $this->activityManager->generateEvent();
253
-						$event->setApp('files_sharing')
254
-							->setType('remote_share')
255
-							->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_RECEIVED, [$ownerFederatedId, trim($name, '/')])
256
-							->setAffectedUser($user->getUID())
257
-							->setObject('remote_share', (int)$shareId, $name);
258
-						\OC::$server->getActivityManager()->publish($event);
259
-						$this->notifyAboutNewShare($user->getUID(), $shareId, $ownerFederatedId, $sharedByFederatedId, $name, $sharedBy, $owner);
260
-					}
261
-				}
262
-				return $shareId;
263
-			} catch (\Exception $e) {
264
-				$this->logger->logException($e, [
265
-					'message' => 'Server can not add remote share.',
266
-					'level' => ILogger::ERROR,
267
-					'app' => 'files_sharing'
268
-				]);
269
-				throw new ProviderCouldNotAddShareException('internal server error, was not able to add share from ' . $remote, '', HTTP::STATUS_INTERNAL_SERVER_ERROR);
270
-			}
271
-		}
272
-
273
-		throw new ProviderCouldNotAddShareException('server can not add remote share, missing parameter', '', HTTP::STATUS_BAD_REQUEST);
274
-
275
-	}
276
-
277
-	/**
278
-	 * notification received from another server
279
-	 *
280
-	 * @param string $notificationType (e.g. SHARE_ACCEPTED)
281
-	 * @param string $providerId id of the share
282
-	 * @param array $notification payload of the notification
283
-	 * @return array data send back to the sender
284
-	 *
285
-	 * @throws ActionNotSupportedException
286
-	 * @throws AuthenticationFailedException
287
-	 * @throws BadRequestException
288
-	 * @throws \OC\HintException
289
-	 * @since 14.0.0
290
-	 */
291
-	public function notificationReceived($notificationType, $providerId, array $notification) {
292
-
293
-		switch ($notificationType) {
294
-			case 'SHARE_ACCEPTED':
295
-				return $this->shareAccepted($providerId, $notification);
296
-			case 'SHARE_DECLINED':
297
-				return $this->shareDeclined($providerId, $notification);
298
-			case 'SHARE_UNSHARED':
299
-				return $this->unshare($providerId, $notification);
300
-			case 'REQUEST_RESHARE':
301
-				return $this->reshareRequested($providerId, $notification);
302
-			case 'RESHARE_UNDO':
303
-				return $this->undoReshare($providerId, $notification);
304
-			case 'RESHARE_CHANGE_PERMISSION':
305
-				return $this->updateResharePermissions($providerId, $notification);
306
-		}
307
-
308
-
309
-		throw new BadRequestException([$notificationType]);
310
-	}
311
-
312
-	/**
313
-	 * map OCM share type (strings) to Nextcloud internal share types (integer)
314
-	 *
315
-	 * @param string $shareType
316
-	 * @return int
317
-	 */
318
-	private function mapShareTypeToNextcloud($shareType) {
319
-		$result = Share::SHARE_TYPE_USER;
320
-		if ($shareType === 'group') {
321
-			$result = Share::SHARE_TYPE_GROUP;
322
-		}
323
-
324
-		return $result;
325
-	}
326
-
327
-	/**
328
-	 * notify user about new federated share
329
-	 *
330
-	 * @param $shareWith
331
-	 * @param $shareId
332
-	 * @param $ownerFederatedId
333
-	 * @param $sharedByFederatedId
334
-	 * @param $name
335
-	 */
336
-	private function notifyAboutNewShare($shareWith, $shareId, $ownerFederatedId, $sharedByFederatedId, $name, $sharedBy, $owner) {
337
-		$notification = $this->notificationManager->createNotification();
338
-		$notification->setApp('files_sharing')
339
-			->setUser($shareWith)
340
-			->setDateTime(new \DateTime())
341
-			->setObject('remote_share', $shareId)
342
-			->setSubject('remote_share', [$ownerFederatedId, $sharedByFederatedId, trim($name, '/'), $sharedBy, $owner]);
343
-
344
-		$declineAction = $notification->createAction();
345
-		$declineAction->setLabel('decline')
346
-			->setLink($this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkTo('', 'ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/' . $shareId)), 'DELETE');
347
-		$notification->addAction($declineAction);
348
-
349
-		$acceptAction = $notification->createAction();
350
-		$acceptAction->setLabel('accept')
351
-			->setLink($this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkTo('', 'ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/' . $shareId)), 'POST');
352
-		$notification->addAction($acceptAction);
353
-
354
-		$this->notificationManager->notify($notification);
355
-	}
356
-
357
-	/**
358
-	 * process notification that the recipient accepted a share
359
-	 *
360
-	 * @param string $id
361
-	 * @param array $notification
362
-	 * @return array
363
-	 * @throws ActionNotSupportedException
364
-	 * @throws AuthenticationFailedException
365
-	 * @throws BadRequestException
366
-	 * @throws \OC\HintException
367
-	 */
368
-	private function shareAccepted($id, array $notification) {
369
-
370
-		if (!$this->isS2SEnabled()) {
371
-			throw new ActionNotSupportedException('Server does not support federated cloud sharing');
372
-		}
373
-
374
-		if (!isset($notification['sharedSecret'])) {
375
-			throw new BadRequestException(['sharedSecret']);
376
-		}
377
-
378
-		$token = $notification['sharedSecret'];
379
-
380
-		$share = $this->federatedShareProvider->getShareById($id);
381
-
382
-		$this->verifyShare($share, $token);
383
-		$this->executeAcceptShare($share);
384
-		if ($share->getShareOwner() !== $share->getSharedBy()) {
385
-			list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy());
386
-			$remoteId = $this->federatedShareProvider->getRemoteId($share);
387
-			$notification = $this->cloudFederationFactory->getCloudFederationNotification();
388
-			$notification->setMessage(
389
-				'SHARE_ACCEPTED',
390
-				'file',
391
-				$remoteId,
392
-				[
393
-					'sharedSecret' => $token,
394
-					'message' => 'Recipient accepted the re-share'
395
-				]
396
-
397
-			);
398
-			$this->cloudFederationProviderManager->sendNotification($remote, $notification);
399
-
400
-		}
401
-
402
-		return [];
403
-	}
404
-
405
-	/**
406
-	 * @param IShare $share
407
-	 * @throws ShareNotFound
408
-	 */
409
-	protected function executeAcceptShare(IShare $share) {
410
-		try {
411
-			$fileId = (int)$share->getNode()->getId();
412
-			list($file, $link) = $this->getFile($this->getCorrectUid($share), $fileId);
413
-		} catch (\Exception $e) {
414
-			throw new ShareNotFound();
415
-		}
416
-
417
-		$event = $this->activityManager->generateEvent();
418
-		$event->setApp('files_sharing')
419
-			->setType('remote_share')
420
-			->setAffectedUser($this->getCorrectUid($share))
421
-			->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_ACCEPTED, [$share->getSharedWith(), [$fileId => $file]])
422
-			->setObject('files', $fileId, $file)
423
-			->setLink($link);
424
-		$this->activityManager->publish($event);
425
-	}
426
-
427
-	/**
428
-	 * process notification that the recipient declined a share
429
-	 *
430
-	 * @param string $id
431
-	 * @param array $notification
432
-	 * @return array
433
-	 * @throws ActionNotSupportedException
434
-	 * @throws AuthenticationFailedException
435
-	 * @throws BadRequestException
436
-	 * @throws ShareNotFound
437
-	 * @throws \OC\HintException
438
-	 *
439
-	 */
440
-	protected function shareDeclined($id, array $notification) {
441
-
442
-		if (!$this->isS2SEnabled()) {
443
-			throw new ActionNotSupportedException('Server does not support federated cloud sharing');
444
-		}
445
-
446
-		if (!isset($notification['sharedSecret'])) {
447
-			throw new BadRequestException(['sharedSecret']);
448
-		}
449
-
450
-		$token = $notification['sharedSecret'];
451
-
452
-		$share = $this->federatedShareProvider->getShareById($id);
453
-
454
-		$this->verifyShare($share, $token);
455
-
456
-		if ($share->getShareOwner() !== $share->getSharedBy()) {
457
-			list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy());
458
-			$remoteId = $this->federatedShareProvider->getRemoteId($share);
459
-			$notification = $this->cloudFederationFactory->getCloudFederationNotification();
460
-			$notification->setMessage(
461
-				'SHARE_DECLINED',
462
-				'file',
463
-				$remoteId,
464
-				[
465
-					'sharedSecret' => $token,
466
-					'message' => 'Recipient declined the re-share'
467
-				]
468
-
469
-			);
470
-			$this->cloudFederationProviderManager->sendNotification($remote, $notification);
471
-		}
472
-
473
-		$this->executeDeclineShare($share);
474
-
475
-		return [];
476
-
477
-	}
478
-
479
-	/**
480
-	 * delete declined share and create a activity
481
-	 *
482
-	 * @param IShare $share
483
-	 * @throws ShareNotFound
484
-	 */
485
-	protected function executeDeclineShare(IShare $share) {
486
-		$this->federatedShareProvider->removeShareFromTable($share);
487
-
488
-		try {
489
-			$fileId = (int)$share->getNode()->getId();
490
-			list($file, $link) = $this->getFile($this->getCorrectUid($share), $fileId);
491
-		} catch (\Exception $e) {
492
-			throw new ShareNotFound();
493
-		}
494
-
495
-		$event = $this->activityManager->generateEvent();
496
-		$event->setApp('files_sharing')
497
-			->setType('remote_share')
498
-			->setAffectedUser($this->getCorrectUid($share))
499
-			->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_DECLINED, [$share->getSharedWith(), [$fileId => $file]])
500
-			->setObject('files', $fileId, $file)
501
-			->setLink($link);
502
-		$this->activityManager->publish($event);
503
-
504
-	}
505
-
506
-	/**
507
-	 * received the notification that the owner unshared a file from you
508
-	 *
509
-	 * @param string $id
510
-	 * @param array $notification
511
-	 * @return array
512
-	 * @throws AuthenticationFailedException
513
-	 * @throws BadRequestException
514
-	 */
515
-	private function undoReshare($id, array $notification) {
516
-		if (!isset($notification['sharedSecret'])) {
517
-			throw new BadRequestException(['sharedSecret']);
518
-		}
519
-		$token = $notification['sharedSecret'];
520
-
521
-		$share = $this->federatedShareProvider->getShareById($id);
522
-
523
-		$this->verifyShare($share, $token);
524
-		$this->federatedShareProvider->removeShareFromTable($share);
525
-		return [];
526
-	}
527
-
528
-	/**
529
-	 * unshare file from self
530
-	 *
531
-	 * @param string $id
532
-	 * @param array $notification
533
-	 * @return array
534
-	 * @throws ActionNotSupportedException
535
-	 * @throws BadRequestException
536
-	 */
537
-	private function unshare($id, array $notification) {
538
-
539
-		if (!$this->isS2SEnabled(true)) {
540
-			throw new ActionNotSupportedException("incoming shares disabled!");
541
-		}
542
-
543
-		if (!isset($notification['sharedSecret'])) {
544
-			throw new BadRequestException(['sharedSecret']);
545
-		}
546
-		$token = $notification['sharedSecret'];
547
-
548
-		$qb = $this->connection->getQueryBuilder();
549
-		$qb->select('*')
550
-			->from('share_external')
551
-			->where(
552
-				$qb->expr()->andX(
553
-					$qb->expr()->eq('remote_id', $qb->createNamedParameter($id)),
554
-					$qb->expr()->eq('share_token', $qb->createNamedParameter($token))
555
-				)
556
-			);
557
-
558
-		$result = $qb->execute();
559
-		$share = $result->fetch();
560
-		$result->closeCursor();
561
-
562
-		if ($token && $id && !empty($share)) {
563
-
564
-			$remote = $this->cleanupRemote($share['remote']);
565
-
566
-			$owner = $this->cloudIdManager->getCloudId($share['owner'], $remote);
567
-			$mountpoint = $share['mountpoint'];
568
-			$user = $share['user'];
569
-
570
-			$qb = $this->connection->getQueryBuilder();
571
-			$qb->delete('share_external')
572
-				->where(
573
-					$qb->expr()->andX(
574
-						$qb->expr()->eq('remote_id', $qb->createNamedParameter($id)),
575
-						$qb->expr()->eq('share_token', $qb->createNamedParameter($token))
576
-					)
577
-				);
578
-
579
-			$qb->execute();
580
-
581
-			// delete all child in case of a group share
582
-			$qb = $this->connection->getQueryBuilder();
583
-			$qb->delete('share_external')
584
-				->where($qb->expr()->eq('parent', $qb->createNamedParameter((int)$share['id'])));
585
-			$qb->execute();
586
-
587
-			if ((int)$share['share_type'] === Share::SHARE_TYPE_USER) {
588
-				if ($share['accepted']) {
589
-					$path = trim($mountpoint, '/');
590
-				} else {
591
-					$path = trim($share['name'], '/');
592
-				}
593
-				$notification = $this->notificationManager->createNotification();
594
-				$notification->setApp('files_sharing')
595
-					->setUser($share['user'])
596
-					->setObject('remote_share', (int)$share['id']);
597
-				$this->notificationManager->markProcessed($notification);
598
-
599
-				$event = $this->activityManager->generateEvent();
600
-				$event->setApp('files_sharing')
601
-					->setType('remote_share')
602
-					->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_UNSHARED, [$owner->getId(), $path])
603
-					->setAffectedUser($user)
604
-					->setObject('remote_share', (int)$share['id'], $path);
605
-				\OC::$server->getActivityManager()->publish($event);
606
-			}
607
-		}
608
-
609
-		return [];
610
-	}
611
-
612
-	private function cleanupRemote($remote) {
613
-		$remote = substr($remote, strpos($remote, '://') + 3);
614
-
615
-		return rtrim($remote, '/');
616
-	}
617
-
618
-	/**
619
-	 * recipient of a share request to re-share the file with another user
620
-	 *
621
-	 * @param string $id
622
-	 * @param array $notification
623
-	 * @return array
624
-	 * @throws AuthenticationFailedException
625
-	 * @throws BadRequestException
626
-	 * @throws ProviderCouldNotAddShareException
627
-	 * @throws ShareNotFound
628
-	 */
629
-	protected function reshareRequested($id, array $notification) {
630
-
631
-		if (!isset($notification['sharedSecret'])) {
632
-			throw new BadRequestException(['sharedSecret']);
633
-		}
634
-		$token = $notification['sharedSecret'];
635
-
636
-		if (!isset($notification['shareWith'])) {
637
-			throw new BadRequestException(['shareWith']);
638
-		}
639
-		$shareWith = $notification['shareWith'];
640
-
641
-		if (!isset($notification['senderId'])) {
642
-			throw new BadRequestException(['senderId']);
643
-		}
644
-		$senderId = $notification['senderId'];
645
-
646
-		$share = $this->federatedShareProvider->getShareById($id);
647
-		// don't allow to share a file back to the owner
648
-		try {
649
-			list($user, $remote) = $this->addressHandler->splitUserRemote($shareWith);
650
-			$owner = $share->getShareOwner();
651
-			$currentServer = $this->addressHandler->generateRemoteURL();
652
-			if ($this->addressHandler->compareAddresses($user, $remote, $owner, $currentServer)) {
653
-				throw new ProviderCouldNotAddShareException('Resharing back to the owner is not allowed: ' . $id);
654
-			}
655
-		} catch (\Exception $e) {
656
-			throw new ProviderCouldNotAddShareException($e->getMessage());
657
-		}
658
-
659
-		$this->verifyShare($share, $token);
660
-
661
-		// check if re-sharing is allowed
662
-		if ($share->getPermissions() & Constants::PERMISSION_SHARE) {
663
-			// the recipient of the initial share is now the initiator for the re-share
664
-			$share->setSharedBy($share->getSharedWith());
665
-			$share->setSharedWith($shareWith);
666
-			$result = $this->federatedShareProvider->create($share);
667
-			$this->federatedShareProvider->storeRemoteId((int)$result->getId(), $senderId);
668
-			return ['token' => $result->getToken(), 'providerId' => $result->getId()];
669
-		} else {
670
-			throw new ProviderCouldNotAddShareException('resharing not allowed for share: ' . $id);
671
-		}
672
-
673
-	}
674
-
675
-	/**
676
-	 * update permission of a re-share so that the share dialog shows the right
677
-	 * permission if the owner or the sender changes the permission
678
-	 *
679
-	 * @param string $id
680
-	 * @param array $notification
681
-	 * @return array
682
-	 * @throws AuthenticationFailedException
683
-	 * @throws BadRequestException
684
-	 */
685
-	protected function updateResharePermissions($id, array $notification) {
686
-
687
-		if (!isset($notification['sharedSecret'])) {
688
-			throw new BadRequestException(['sharedSecret']);
689
-		}
690
-		$token = $notification['sharedSecret'];
691
-
692
-		if (!isset($notification['permission'])) {
693
-			throw new BadRequestException(['permission']);
694
-		}
695
-		$ocmPermissions = $notification['permission'];
696
-
697
-		$share = $this->federatedShareProvider->getShareById($id);
698
-
699
-		$ncPermission = $this->ocmPermissions2ncPermissions($ocmPermissions);
700
-
701
-		$this->verifyShare($share, $token);
702
-		$this->updatePermissionsInDatabase($share, $ncPermission);
703
-
704
-		return [];
705
-	}
706
-
707
-	/**
708
-	 * translate OCM Permissions to Nextcloud permissions
709
-	 *
710
-	 * @param array $ocmPermissions
711
-	 * @return int
712
-	 * @throws BadRequestException
713
-	 */
714
-	protected function ocmPermissions2ncPermissions(array $ocmPermissions) {
715
-		$ncPermissions = 0;
716
-		foreach($ocmPermissions as $permission) {
717
-			switch (strtolower($permission)) {
718
-				case 'read':
719
-					$ncPermissions += Constants::PERMISSION_READ;
720
-					break;
721
-				case 'write':
722
-					$ncPermissions += Constants::PERMISSION_CREATE + Constants::PERMISSION_UPDATE;
723
-					break;
724
-				case 'share':
725
-					$ncPermissions += Constants::PERMISSION_SHARE;
726
-					break;
727
-				default:
728
-					throw new BadRequestException(['permission']);
729
-			}
730
-
731
-		}
732
-
733
-		return $ncPermissions;
734
-	}
735
-
736
-	/**
737
-	 * update permissions in database
738
-	 *
739
-	 * @param IShare $share
740
-	 * @param int $permissions
741
-	 */
742
-	protected function updatePermissionsInDatabase(IShare $share, $permissions) {
743
-		$query = $this->connection->getQueryBuilder();
744
-		$query->update('share')
745
-			->where($query->expr()->eq('id', $query->createNamedParameter($share->getId())))
746
-			->set('permissions', $query->createNamedParameter($permissions))
747
-			->execute();
748
-	}
749
-
750
-
751
-	/**
752
-	 * get file
753
-	 *
754
-	 * @param string $user
755
-	 * @param int $fileSource
756
-	 * @return array with internal path of the file and a absolute link to it
757
-	 */
758
-	private function getFile($user, $fileSource) {
759
-		\OC_Util::setupFS($user);
760
-
761
-		try {
762
-			$file = Filesystem::getPath($fileSource);
763
-		} catch (NotFoundException $e) {
764
-			$file = null;
765
-		}
766
-		$args = Filesystem::is_dir($file) ? array('dir' => $file) : array('dir' => dirname($file), 'scrollto' => $file);
767
-		$link = Util::linkToAbsolute('files', 'index.php', $args);
768
-
769
-		return [$file, $link];
770
-
771
-	}
772
-
773
-	/**
774
-	 * check if we are the initiator or the owner of a re-share and return the correct UID
775
-	 *
776
-	 * @param IShare $share
777
-	 * @return string
778
-	 */
779
-	protected function getCorrectUid(IShare $share) {
780
-		if ($this->userManager->userExists($share->getShareOwner())) {
781
-			return $share->getShareOwner();
782
-		}
783
-
784
-		return $share->getSharedBy();
785
-	}
786
-
787
-
788
-
789
-	/**
790
-	 * check if we got the right share
791
-	 *
792
-	 * @param IShare $share
793
-	 * @param string $token
794
-	 * @return bool
795
-	 * @throws AuthenticationFailedException
796
-	 */
797
-	protected function verifyShare(IShare $share, $token) {
798
-		if (
799
-			$share->getShareType() === FederatedShareProvider::SHARE_TYPE_REMOTE &&
800
-			$share->getToken() === $token
801
-		) {
802
-			return true;
803
-		}
804
-
805
-		throw new AuthenticationFailedException();
806
-	}
807
-
808
-
809
-
810
-	/**
811
-	 * check if server-to-server sharing is enabled
812
-	 *
813
-	 * @param bool $incoming
814
-	 * @return bool
815
-	 */
816
-	private function isS2SEnabled($incoming = false) {
817
-
818
-		$result = $this->appManager->isEnabledForUser('files_sharing');
819
-
820
-		if ($incoming) {
821
-			$result = $result && $this->federatedShareProvider->isIncomingServer2serverShareEnabled();
822
-		} else {
823
-			$result = $result && $this->federatedShareProvider->isOutgoingServer2serverShareEnabled();
824
-		}
825
-
826
-		return $result;
827
-	}
828
-
829
-
830
-	/**
831
-	 * get the supported share types, e.g. "user", "group", etc.
832
-	 *
833
-	 * @return array
834
-	 *
835
-	 * @since 14.0.0
836
-	 */
837
-	public function getSupportedShareTypes() {
838
-		return ['user', 'group'];
839
-	}
55
+    /** @var IAppManager */
56
+    private $appManager;
57
+
58
+    /** @var FederatedShareProvider */
59
+    private $federatedShareProvider;
60
+
61
+    /** @var AddressHandler */
62
+    private $addressHandler;
63
+
64
+    /** @var ILogger */
65
+    private $logger;
66
+
67
+    /** @var IUserManager */
68
+    private $userManager;
69
+
70
+    /** @var ICloudIdManager */
71
+    private $cloudIdManager;
72
+
73
+    /** @var IActivityManager */
74
+    private $activityManager;
75
+
76
+    /** @var INotificationManager */
77
+    private $notificationManager;
78
+
79
+    /** @var IURLGenerator */
80
+    private $urlGenerator;
81
+
82
+    /** @var ICloudFederationFactory */
83
+    private $cloudFederationFactory;
84
+
85
+    /** @var ICloudFederationProviderManager */
86
+    private $cloudFederationProviderManager;
87
+
88
+    /** @var IDBConnection */
89
+    private $connection;
90
+
91
+    /** @var IGroupManager */
92
+    private $groupManager;
93
+
94
+    /**
95
+     * CloudFederationProvider constructor.
96
+     *
97
+     * @param IAppManager $appManager
98
+     * @param FederatedShareProvider $federatedShareProvider
99
+     * @param AddressHandler $addressHandler
100
+     * @param ILogger $logger
101
+     * @param IUserManager $userManager
102
+     * @param ICloudIdManager $cloudIdManager
103
+     * @param IActivityManager $activityManager
104
+     * @param INotificationManager $notificationManager
105
+     * @param IURLGenerator $urlGenerator
106
+     * @param ICloudFederationFactory $cloudFederationFactory
107
+     * @param ICloudFederationProviderManager $cloudFederationProviderManager
108
+     * @param IDBConnection $connection
109
+     * @param IGroupManager $groupManager
110
+     */
111
+    public function __construct(IAppManager $appManager,
112
+                                FederatedShareProvider $federatedShareProvider,
113
+                                AddressHandler $addressHandler,
114
+                                ILogger $logger,
115
+                                IUserManager $userManager,
116
+                                ICloudIdManager $cloudIdManager,
117
+                                IActivityManager $activityManager,
118
+                                INotificationManager $notificationManager,
119
+                                IURLGenerator $urlGenerator,
120
+                                ICloudFederationFactory $cloudFederationFactory,
121
+                                ICloudFederationProviderManager $cloudFederationProviderManager,
122
+                                IDBConnection $connection,
123
+                                IGroupManager $groupManager
124
+    ) {
125
+        $this->appManager = $appManager;
126
+        $this->federatedShareProvider = $federatedShareProvider;
127
+        $this->addressHandler = $addressHandler;
128
+        $this->logger = $logger;
129
+        $this->userManager = $userManager;
130
+        $this->cloudIdManager = $cloudIdManager;
131
+        $this->activityManager = $activityManager;
132
+        $this->notificationManager = $notificationManager;
133
+        $this->urlGenerator = $urlGenerator;
134
+        $this->cloudFederationFactory = $cloudFederationFactory;
135
+        $this->cloudFederationProviderManager = $cloudFederationProviderManager;
136
+        $this->connection = $connection;
137
+        $this->groupManager = $groupManager;
138
+    }
139
+
140
+
141
+
142
+    /**
143
+     * @return string
144
+     */
145
+    public function getShareType() {
146
+        return 'file';
147
+    }
148
+
149
+    /**
150
+     * share received from another server
151
+     *
152
+     * @param ICloudFederationShare $share
153
+     * @return string provider specific unique ID of the share
154
+     *
155
+     * @throws ProviderCouldNotAddShareException
156
+     * @throws \OCP\AppFramework\QueryException
157
+     * @throws \OC\HintException
158
+     * @since 14.0.0
159
+     */
160
+    public function shareReceived(ICloudFederationShare $share) {
161
+
162
+        if (!$this->isS2SEnabled(true)) {
163
+            throw new ProviderCouldNotAddShareException('Server does not support federated cloud sharing', '', Http::STATUS_SERVICE_UNAVAILABLE);
164
+        }
165
+
166
+        $protocol = $share->getProtocol();
167
+        if ($protocol['name'] !== 'webdav') {
168
+            throw new ProviderCouldNotAddShareException('Unsupported protocol for data exchange.', '', Http::STATUS_NOT_IMPLEMENTED);
169
+        }
170
+
171
+        list($ownerUid, $remote) = $this->addressHandler->splitUserRemote($share->getOwner());
172
+        // for backward compatibility make sure that the remote url stored in the
173
+        // database ends with a trailing slash
174
+        if (substr($remote, -1) !== '/') {
175
+            $remote = $remote . '/';
176
+        }
177
+
178
+        $token = $share->getShareSecret();
179
+        $name = $share->getResourceName();
180
+        $owner = $share->getOwnerDisplayName();
181
+        $sharedBy = $share->getSharedByDisplayName();
182
+        $shareWith = $share->getShareWith();
183
+        $remoteId = $share->getProviderId();
184
+        $sharedByFederatedId = $share->getSharedBy();
185
+        $ownerFederatedId = $share->getOwner();
186
+        $shareType = $this->mapShareTypeToNextcloud($share->getShareType());
187
+
188
+        // if no explicit information about the person who created the share was send
189
+        // we assume that the share comes from the owner
190
+        if ($sharedByFederatedId === null) {
191
+            $sharedBy = $owner;
192
+            $sharedByFederatedId = $ownerFederatedId;
193
+        }
194
+
195
+        if ($remote && $token && $name && $owner && $remoteId && $shareWith) {
196
+
197
+            if (!Util::isValidFileName($name)) {
198
+                throw new ProviderCouldNotAddShareException('The mountpoint name contains invalid characters.', '', Http::STATUS_BAD_REQUEST);
199
+            }
200
+
201
+            // FIXME this should be a method in the user management instead
202
+            if ($shareType === Share::SHARE_TYPE_USER) {
203
+                $this->logger->debug('shareWith before, ' . $shareWith, ['app' => 'files_sharing']);
204
+                Util::emitHook(
205
+                    '\OCA\Files_Sharing\API\Server2Server',
206
+                    'preLoginNameUsedAsUserName',
207
+                    array('uid' => &$shareWith)
208
+                );
209
+                $this->logger->debug('shareWith after, ' . $shareWith, ['app' => 'files_sharing']);
210
+
211
+                if (!$this->userManager->userExists($shareWith)) {
212
+                    throw new ProviderCouldNotAddShareException('User does not exists', '',Http::STATUS_BAD_REQUEST);
213
+                }
214
+
215
+                \OC_Util::setupFS($shareWith);
216
+            }
217
+
218
+            if ($shareType === Share::SHARE_TYPE_GROUP && !$this->groupManager->groupExists($shareWith)) {
219
+                throw new ProviderCouldNotAddShareException('Group does not exists', '',Http::STATUS_BAD_REQUEST);
220
+            }
221
+
222
+            $externalManager = new \OCA\Files_Sharing\External\Manager(
223
+                \OC::$server->getDatabaseConnection(),
224
+                Filesystem::getMountManager(),
225
+                Filesystem::getLoader(),
226
+                \OC::$server->getHTTPClientService(),
227
+                \OC::$server->getNotificationManager(),
228
+                \OC::$server->query(\OCP\OCS\IDiscoveryService::class),
229
+                \OC::$server->getCloudFederationProviderManager(),
230
+                \OC::$server->getCloudFederationFactory(),
231
+                \OC::$server->getGroupManager(),
232
+                \OC::$server->getUserManager(),
233
+                $shareWith
234
+            );
235
+
236
+            try {
237
+                $externalManager->addShare($remote, $token, '', $name, $owner, $shareType,false, $shareWith, $remoteId);
238
+                $shareId = \OC::$server->getDatabaseConnection()->lastInsertId('*PREFIX*share_external');
239
+
240
+                if ($shareType === Share::SHARE_TYPE_USER) {
241
+                    $event = $this->activityManager->generateEvent();
242
+                    $event->setApp('files_sharing')
243
+                        ->setType('remote_share')
244
+                        ->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_RECEIVED, [$ownerFederatedId, trim($name, '/')])
245
+                        ->setAffectedUser($shareWith)
246
+                        ->setObject('remote_share', (int)$shareId, $name);
247
+                    \OC::$server->getActivityManager()->publish($event);
248
+                    $this->notifyAboutNewShare($shareWith, $shareId, $ownerFederatedId, $sharedByFederatedId, $name, $sharedBy, $owner);
249
+                } else {
250
+                    $groupMembers = $this->groupManager->get($shareWith)->getUsers();
251
+                    foreach ($groupMembers as $user) {
252
+                        $event = $this->activityManager->generateEvent();
253
+                        $event->setApp('files_sharing')
254
+                            ->setType('remote_share')
255
+                            ->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_RECEIVED, [$ownerFederatedId, trim($name, '/')])
256
+                            ->setAffectedUser($user->getUID())
257
+                            ->setObject('remote_share', (int)$shareId, $name);
258
+                        \OC::$server->getActivityManager()->publish($event);
259
+                        $this->notifyAboutNewShare($user->getUID(), $shareId, $ownerFederatedId, $sharedByFederatedId, $name, $sharedBy, $owner);
260
+                    }
261
+                }
262
+                return $shareId;
263
+            } catch (\Exception $e) {
264
+                $this->logger->logException($e, [
265
+                    'message' => 'Server can not add remote share.',
266
+                    'level' => ILogger::ERROR,
267
+                    'app' => 'files_sharing'
268
+                ]);
269
+                throw new ProviderCouldNotAddShareException('internal server error, was not able to add share from ' . $remote, '', HTTP::STATUS_INTERNAL_SERVER_ERROR);
270
+            }
271
+        }
272
+
273
+        throw new ProviderCouldNotAddShareException('server can not add remote share, missing parameter', '', HTTP::STATUS_BAD_REQUEST);
274
+
275
+    }
276
+
277
+    /**
278
+     * notification received from another server
279
+     *
280
+     * @param string $notificationType (e.g. SHARE_ACCEPTED)
281
+     * @param string $providerId id of the share
282
+     * @param array $notification payload of the notification
283
+     * @return array data send back to the sender
284
+     *
285
+     * @throws ActionNotSupportedException
286
+     * @throws AuthenticationFailedException
287
+     * @throws BadRequestException
288
+     * @throws \OC\HintException
289
+     * @since 14.0.0
290
+     */
291
+    public function notificationReceived($notificationType, $providerId, array $notification) {
292
+
293
+        switch ($notificationType) {
294
+            case 'SHARE_ACCEPTED':
295
+                return $this->shareAccepted($providerId, $notification);
296
+            case 'SHARE_DECLINED':
297
+                return $this->shareDeclined($providerId, $notification);
298
+            case 'SHARE_UNSHARED':
299
+                return $this->unshare($providerId, $notification);
300
+            case 'REQUEST_RESHARE':
301
+                return $this->reshareRequested($providerId, $notification);
302
+            case 'RESHARE_UNDO':
303
+                return $this->undoReshare($providerId, $notification);
304
+            case 'RESHARE_CHANGE_PERMISSION':
305
+                return $this->updateResharePermissions($providerId, $notification);
306
+        }
307
+
308
+
309
+        throw new BadRequestException([$notificationType]);
310
+    }
311
+
312
+    /**
313
+     * map OCM share type (strings) to Nextcloud internal share types (integer)
314
+     *
315
+     * @param string $shareType
316
+     * @return int
317
+     */
318
+    private function mapShareTypeToNextcloud($shareType) {
319
+        $result = Share::SHARE_TYPE_USER;
320
+        if ($shareType === 'group') {
321
+            $result = Share::SHARE_TYPE_GROUP;
322
+        }
323
+
324
+        return $result;
325
+    }
326
+
327
+    /**
328
+     * notify user about new federated share
329
+     *
330
+     * @param $shareWith
331
+     * @param $shareId
332
+     * @param $ownerFederatedId
333
+     * @param $sharedByFederatedId
334
+     * @param $name
335
+     */
336
+    private function notifyAboutNewShare($shareWith, $shareId, $ownerFederatedId, $sharedByFederatedId, $name, $sharedBy, $owner) {
337
+        $notification = $this->notificationManager->createNotification();
338
+        $notification->setApp('files_sharing')
339
+            ->setUser($shareWith)
340
+            ->setDateTime(new \DateTime())
341
+            ->setObject('remote_share', $shareId)
342
+            ->setSubject('remote_share', [$ownerFederatedId, $sharedByFederatedId, trim($name, '/'), $sharedBy, $owner]);
343
+
344
+        $declineAction = $notification->createAction();
345
+        $declineAction->setLabel('decline')
346
+            ->setLink($this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkTo('', 'ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/' . $shareId)), 'DELETE');
347
+        $notification->addAction($declineAction);
348
+
349
+        $acceptAction = $notification->createAction();
350
+        $acceptAction->setLabel('accept')
351
+            ->setLink($this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkTo('', 'ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/' . $shareId)), 'POST');
352
+        $notification->addAction($acceptAction);
353
+
354
+        $this->notificationManager->notify($notification);
355
+    }
356
+
357
+    /**
358
+     * process notification that the recipient accepted a share
359
+     *
360
+     * @param string $id
361
+     * @param array $notification
362
+     * @return array
363
+     * @throws ActionNotSupportedException
364
+     * @throws AuthenticationFailedException
365
+     * @throws BadRequestException
366
+     * @throws \OC\HintException
367
+     */
368
+    private function shareAccepted($id, array $notification) {
369
+
370
+        if (!$this->isS2SEnabled()) {
371
+            throw new ActionNotSupportedException('Server does not support federated cloud sharing');
372
+        }
373
+
374
+        if (!isset($notification['sharedSecret'])) {
375
+            throw new BadRequestException(['sharedSecret']);
376
+        }
377
+
378
+        $token = $notification['sharedSecret'];
379
+
380
+        $share = $this->federatedShareProvider->getShareById($id);
381
+
382
+        $this->verifyShare($share, $token);
383
+        $this->executeAcceptShare($share);
384
+        if ($share->getShareOwner() !== $share->getSharedBy()) {
385
+            list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy());
386
+            $remoteId = $this->federatedShareProvider->getRemoteId($share);
387
+            $notification = $this->cloudFederationFactory->getCloudFederationNotification();
388
+            $notification->setMessage(
389
+                'SHARE_ACCEPTED',
390
+                'file',
391
+                $remoteId,
392
+                [
393
+                    'sharedSecret' => $token,
394
+                    'message' => 'Recipient accepted the re-share'
395
+                ]
396
+
397
+            );
398
+            $this->cloudFederationProviderManager->sendNotification($remote, $notification);
399
+
400
+        }
401
+
402
+        return [];
403
+    }
404
+
405
+    /**
406
+     * @param IShare $share
407
+     * @throws ShareNotFound
408
+     */
409
+    protected function executeAcceptShare(IShare $share) {
410
+        try {
411
+            $fileId = (int)$share->getNode()->getId();
412
+            list($file, $link) = $this->getFile($this->getCorrectUid($share), $fileId);
413
+        } catch (\Exception $e) {
414
+            throw new ShareNotFound();
415
+        }
416
+
417
+        $event = $this->activityManager->generateEvent();
418
+        $event->setApp('files_sharing')
419
+            ->setType('remote_share')
420
+            ->setAffectedUser($this->getCorrectUid($share))
421
+            ->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_ACCEPTED, [$share->getSharedWith(), [$fileId => $file]])
422
+            ->setObject('files', $fileId, $file)
423
+            ->setLink($link);
424
+        $this->activityManager->publish($event);
425
+    }
426
+
427
+    /**
428
+     * process notification that the recipient declined a share
429
+     *
430
+     * @param string $id
431
+     * @param array $notification
432
+     * @return array
433
+     * @throws ActionNotSupportedException
434
+     * @throws AuthenticationFailedException
435
+     * @throws BadRequestException
436
+     * @throws ShareNotFound
437
+     * @throws \OC\HintException
438
+     *
439
+     */
440
+    protected function shareDeclined($id, array $notification) {
441
+
442
+        if (!$this->isS2SEnabled()) {
443
+            throw new ActionNotSupportedException('Server does not support federated cloud sharing');
444
+        }
445
+
446
+        if (!isset($notification['sharedSecret'])) {
447
+            throw new BadRequestException(['sharedSecret']);
448
+        }
449
+
450
+        $token = $notification['sharedSecret'];
451
+
452
+        $share = $this->federatedShareProvider->getShareById($id);
453
+
454
+        $this->verifyShare($share, $token);
455
+
456
+        if ($share->getShareOwner() !== $share->getSharedBy()) {
457
+            list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy());
458
+            $remoteId = $this->federatedShareProvider->getRemoteId($share);
459
+            $notification = $this->cloudFederationFactory->getCloudFederationNotification();
460
+            $notification->setMessage(
461
+                'SHARE_DECLINED',
462
+                'file',
463
+                $remoteId,
464
+                [
465
+                    'sharedSecret' => $token,
466
+                    'message' => 'Recipient declined the re-share'
467
+                ]
468
+
469
+            );
470
+            $this->cloudFederationProviderManager->sendNotification($remote, $notification);
471
+        }
472
+
473
+        $this->executeDeclineShare($share);
474
+
475
+        return [];
476
+
477
+    }
478
+
479
+    /**
480
+     * delete declined share and create a activity
481
+     *
482
+     * @param IShare $share
483
+     * @throws ShareNotFound
484
+     */
485
+    protected function executeDeclineShare(IShare $share) {
486
+        $this->federatedShareProvider->removeShareFromTable($share);
487
+
488
+        try {
489
+            $fileId = (int)$share->getNode()->getId();
490
+            list($file, $link) = $this->getFile($this->getCorrectUid($share), $fileId);
491
+        } catch (\Exception $e) {
492
+            throw new ShareNotFound();
493
+        }
494
+
495
+        $event = $this->activityManager->generateEvent();
496
+        $event->setApp('files_sharing')
497
+            ->setType('remote_share')
498
+            ->setAffectedUser($this->getCorrectUid($share))
499
+            ->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_DECLINED, [$share->getSharedWith(), [$fileId => $file]])
500
+            ->setObject('files', $fileId, $file)
501
+            ->setLink($link);
502
+        $this->activityManager->publish($event);
503
+
504
+    }
505
+
506
+    /**
507
+     * received the notification that the owner unshared a file from you
508
+     *
509
+     * @param string $id
510
+     * @param array $notification
511
+     * @return array
512
+     * @throws AuthenticationFailedException
513
+     * @throws BadRequestException
514
+     */
515
+    private function undoReshare($id, array $notification) {
516
+        if (!isset($notification['sharedSecret'])) {
517
+            throw new BadRequestException(['sharedSecret']);
518
+        }
519
+        $token = $notification['sharedSecret'];
520
+
521
+        $share = $this->federatedShareProvider->getShareById($id);
522
+
523
+        $this->verifyShare($share, $token);
524
+        $this->federatedShareProvider->removeShareFromTable($share);
525
+        return [];
526
+    }
527
+
528
+    /**
529
+     * unshare file from self
530
+     *
531
+     * @param string $id
532
+     * @param array $notification
533
+     * @return array
534
+     * @throws ActionNotSupportedException
535
+     * @throws BadRequestException
536
+     */
537
+    private function unshare($id, array $notification) {
538
+
539
+        if (!$this->isS2SEnabled(true)) {
540
+            throw new ActionNotSupportedException("incoming shares disabled!");
541
+        }
542
+
543
+        if (!isset($notification['sharedSecret'])) {
544
+            throw new BadRequestException(['sharedSecret']);
545
+        }
546
+        $token = $notification['sharedSecret'];
547
+
548
+        $qb = $this->connection->getQueryBuilder();
549
+        $qb->select('*')
550
+            ->from('share_external')
551
+            ->where(
552
+                $qb->expr()->andX(
553
+                    $qb->expr()->eq('remote_id', $qb->createNamedParameter($id)),
554
+                    $qb->expr()->eq('share_token', $qb->createNamedParameter($token))
555
+                )
556
+            );
557
+
558
+        $result = $qb->execute();
559
+        $share = $result->fetch();
560
+        $result->closeCursor();
561
+
562
+        if ($token && $id && !empty($share)) {
563
+
564
+            $remote = $this->cleanupRemote($share['remote']);
565
+
566
+            $owner = $this->cloudIdManager->getCloudId($share['owner'], $remote);
567
+            $mountpoint = $share['mountpoint'];
568
+            $user = $share['user'];
569
+
570
+            $qb = $this->connection->getQueryBuilder();
571
+            $qb->delete('share_external')
572
+                ->where(
573
+                    $qb->expr()->andX(
574
+                        $qb->expr()->eq('remote_id', $qb->createNamedParameter($id)),
575
+                        $qb->expr()->eq('share_token', $qb->createNamedParameter($token))
576
+                    )
577
+                );
578
+
579
+            $qb->execute();
580
+
581
+            // delete all child in case of a group share
582
+            $qb = $this->connection->getQueryBuilder();
583
+            $qb->delete('share_external')
584
+                ->where($qb->expr()->eq('parent', $qb->createNamedParameter((int)$share['id'])));
585
+            $qb->execute();
586
+
587
+            if ((int)$share['share_type'] === Share::SHARE_TYPE_USER) {
588
+                if ($share['accepted']) {
589
+                    $path = trim($mountpoint, '/');
590
+                } else {
591
+                    $path = trim($share['name'], '/');
592
+                }
593
+                $notification = $this->notificationManager->createNotification();
594
+                $notification->setApp('files_sharing')
595
+                    ->setUser($share['user'])
596
+                    ->setObject('remote_share', (int)$share['id']);
597
+                $this->notificationManager->markProcessed($notification);
598
+
599
+                $event = $this->activityManager->generateEvent();
600
+                $event->setApp('files_sharing')
601
+                    ->setType('remote_share')
602
+                    ->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_UNSHARED, [$owner->getId(), $path])
603
+                    ->setAffectedUser($user)
604
+                    ->setObject('remote_share', (int)$share['id'], $path);
605
+                \OC::$server->getActivityManager()->publish($event);
606
+            }
607
+        }
608
+
609
+        return [];
610
+    }
611
+
612
+    private function cleanupRemote($remote) {
613
+        $remote = substr($remote, strpos($remote, '://') + 3);
614
+
615
+        return rtrim($remote, '/');
616
+    }
617
+
618
+    /**
619
+     * recipient of a share request to re-share the file with another user
620
+     *
621
+     * @param string $id
622
+     * @param array $notification
623
+     * @return array
624
+     * @throws AuthenticationFailedException
625
+     * @throws BadRequestException
626
+     * @throws ProviderCouldNotAddShareException
627
+     * @throws ShareNotFound
628
+     */
629
+    protected function reshareRequested($id, array $notification) {
630
+
631
+        if (!isset($notification['sharedSecret'])) {
632
+            throw new BadRequestException(['sharedSecret']);
633
+        }
634
+        $token = $notification['sharedSecret'];
635
+
636
+        if (!isset($notification['shareWith'])) {
637
+            throw new BadRequestException(['shareWith']);
638
+        }
639
+        $shareWith = $notification['shareWith'];
640
+
641
+        if (!isset($notification['senderId'])) {
642
+            throw new BadRequestException(['senderId']);
643
+        }
644
+        $senderId = $notification['senderId'];
645
+
646
+        $share = $this->federatedShareProvider->getShareById($id);
647
+        // don't allow to share a file back to the owner
648
+        try {
649
+            list($user, $remote) = $this->addressHandler->splitUserRemote($shareWith);
650
+            $owner = $share->getShareOwner();
651
+            $currentServer = $this->addressHandler->generateRemoteURL();
652
+            if ($this->addressHandler->compareAddresses($user, $remote, $owner, $currentServer)) {
653
+                throw new ProviderCouldNotAddShareException('Resharing back to the owner is not allowed: ' . $id);
654
+            }
655
+        } catch (\Exception $e) {
656
+            throw new ProviderCouldNotAddShareException($e->getMessage());
657
+        }
658
+
659
+        $this->verifyShare($share, $token);
660
+
661
+        // check if re-sharing is allowed
662
+        if ($share->getPermissions() & Constants::PERMISSION_SHARE) {
663
+            // the recipient of the initial share is now the initiator for the re-share
664
+            $share->setSharedBy($share->getSharedWith());
665
+            $share->setSharedWith($shareWith);
666
+            $result = $this->federatedShareProvider->create($share);
667
+            $this->federatedShareProvider->storeRemoteId((int)$result->getId(), $senderId);
668
+            return ['token' => $result->getToken(), 'providerId' => $result->getId()];
669
+        } else {
670
+            throw new ProviderCouldNotAddShareException('resharing not allowed for share: ' . $id);
671
+        }
672
+
673
+    }
674
+
675
+    /**
676
+     * update permission of a re-share so that the share dialog shows the right
677
+     * permission if the owner or the sender changes the permission
678
+     *
679
+     * @param string $id
680
+     * @param array $notification
681
+     * @return array
682
+     * @throws AuthenticationFailedException
683
+     * @throws BadRequestException
684
+     */
685
+    protected function updateResharePermissions($id, array $notification) {
686
+
687
+        if (!isset($notification['sharedSecret'])) {
688
+            throw new BadRequestException(['sharedSecret']);
689
+        }
690
+        $token = $notification['sharedSecret'];
691
+
692
+        if (!isset($notification['permission'])) {
693
+            throw new BadRequestException(['permission']);
694
+        }
695
+        $ocmPermissions = $notification['permission'];
696
+
697
+        $share = $this->federatedShareProvider->getShareById($id);
698
+
699
+        $ncPermission = $this->ocmPermissions2ncPermissions($ocmPermissions);
700
+
701
+        $this->verifyShare($share, $token);
702
+        $this->updatePermissionsInDatabase($share, $ncPermission);
703
+
704
+        return [];
705
+    }
706
+
707
+    /**
708
+     * translate OCM Permissions to Nextcloud permissions
709
+     *
710
+     * @param array $ocmPermissions
711
+     * @return int
712
+     * @throws BadRequestException
713
+     */
714
+    protected function ocmPermissions2ncPermissions(array $ocmPermissions) {
715
+        $ncPermissions = 0;
716
+        foreach($ocmPermissions as $permission) {
717
+            switch (strtolower($permission)) {
718
+                case 'read':
719
+                    $ncPermissions += Constants::PERMISSION_READ;
720
+                    break;
721
+                case 'write':
722
+                    $ncPermissions += Constants::PERMISSION_CREATE + Constants::PERMISSION_UPDATE;
723
+                    break;
724
+                case 'share':
725
+                    $ncPermissions += Constants::PERMISSION_SHARE;
726
+                    break;
727
+                default:
728
+                    throw new BadRequestException(['permission']);
729
+            }
730
+
731
+        }
732
+
733
+        return $ncPermissions;
734
+    }
735
+
736
+    /**
737
+     * update permissions in database
738
+     *
739
+     * @param IShare $share
740
+     * @param int $permissions
741
+     */
742
+    protected function updatePermissionsInDatabase(IShare $share, $permissions) {
743
+        $query = $this->connection->getQueryBuilder();
744
+        $query->update('share')
745
+            ->where($query->expr()->eq('id', $query->createNamedParameter($share->getId())))
746
+            ->set('permissions', $query->createNamedParameter($permissions))
747
+            ->execute();
748
+    }
749
+
750
+
751
+    /**
752
+     * get file
753
+     *
754
+     * @param string $user
755
+     * @param int $fileSource
756
+     * @return array with internal path of the file and a absolute link to it
757
+     */
758
+    private function getFile($user, $fileSource) {
759
+        \OC_Util::setupFS($user);
760
+
761
+        try {
762
+            $file = Filesystem::getPath($fileSource);
763
+        } catch (NotFoundException $e) {
764
+            $file = null;
765
+        }
766
+        $args = Filesystem::is_dir($file) ? array('dir' => $file) : array('dir' => dirname($file), 'scrollto' => $file);
767
+        $link = Util::linkToAbsolute('files', 'index.php', $args);
768
+
769
+        return [$file, $link];
770
+
771
+    }
772
+
773
+    /**
774
+     * check if we are the initiator or the owner of a re-share and return the correct UID
775
+     *
776
+     * @param IShare $share
777
+     * @return string
778
+     */
779
+    protected function getCorrectUid(IShare $share) {
780
+        if ($this->userManager->userExists($share->getShareOwner())) {
781
+            return $share->getShareOwner();
782
+        }
783
+
784
+        return $share->getSharedBy();
785
+    }
786
+
787
+
788
+
789
+    /**
790
+     * check if we got the right share
791
+     *
792
+     * @param IShare $share
793
+     * @param string $token
794
+     * @return bool
795
+     * @throws AuthenticationFailedException
796
+     */
797
+    protected function verifyShare(IShare $share, $token) {
798
+        if (
799
+            $share->getShareType() === FederatedShareProvider::SHARE_TYPE_REMOTE &&
800
+            $share->getToken() === $token
801
+        ) {
802
+            return true;
803
+        }
804
+
805
+        throw new AuthenticationFailedException();
806
+    }
807
+
808
+
809
+
810
+    /**
811
+     * check if server-to-server sharing is enabled
812
+     *
813
+     * @param bool $incoming
814
+     * @return bool
815
+     */
816
+    private function isS2SEnabled($incoming = false) {
817
+
818
+        $result = $this->appManager->isEnabledForUser('files_sharing');
819
+
820
+        if ($incoming) {
821
+            $result = $result && $this->federatedShareProvider->isIncomingServer2serverShareEnabled();
822
+        } else {
823
+            $result = $result && $this->federatedShareProvider->isOutgoingServer2serverShareEnabled();
824
+        }
825
+
826
+        return $result;
827
+    }
828
+
829
+
830
+    /**
831
+     * get the supported share types, e.g. "user", "group", etc.
832
+     *
833
+     * @return array
834
+     *
835
+     * @since 14.0.0
836
+     */
837
+    public function getSupportedShareTypes() {
838
+        return ['user', 'group'];
839
+    }
840 840
 }
Please login to merge, or discard this patch.
Spacing   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -172,7 +172,7 @@  discard block
 block discarded – undo
172 172
 		// for backward compatibility make sure that the remote url stored in the
173 173
 		// database ends with a trailing slash
174 174
 		if (substr($remote, -1) !== '/') {
175
-			$remote = $remote . '/';
175
+			$remote = $remote.'/';
176 176
 		}
177 177
 
178 178
 		$token = $share->getShareSecret();
@@ -200,23 +200,23 @@  discard block
 block discarded – undo
200 200
 
201 201
 			// FIXME this should be a method in the user management instead
202 202
 			if ($shareType === Share::SHARE_TYPE_USER) {
203
-				$this->logger->debug('shareWith before, ' . $shareWith, ['app' => 'files_sharing']);
203
+				$this->logger->debug('shareWith before, '.$shareWith, ['app' => 'files_sharing']);
204 204
 				Util::emitHook(
205 205
 					'\OCA\Files_Sharing\API\Server2Server',
206 206
 					'preLoginNameUsedAsUserName',
207 207
 					array('uid' => &$shareWith)
208 208
 				);
209
-				$this->logger->debug('shareWith after, ' . $shareWith, ['app' => 'files_sharing']);
209
+				$this->logger->debug('shareWith after, '.$shareWith, ['app' => 'files_sharing']);
210 210
 
211 211
 				if (!$this->userManager->userExists($shareWith)) {
212
-					throw new ProviderCouldNotAddShareException('User does not exists', '',Http::STATUS_BAD_REQUEST);
212
+					throw new ProviderCouldNotAddShareException('User does not exists', '', Http::STATUS_BAD_REQUEST);
213 213
 				}
214 214
 
215 215
 				\OC_Util::setupFS($shareWith);
216 216
 			}
217 217
 
218 218
 			if ($shareType === Share::SHARE_TYPE_GROUP && !$this->groupManager->groupExists($shareWith)) {
219
-				throw new ProviderCouldNotAddShareException('Group does not exists', '',Http::STATUS_BAD_REQUEST);
219
+				throw new ProviderCouldNotAddShareException('Group does not exists', '', Http::STATUS_BAD_REQUEST);
220 220
 			}
221 221
 
222 222
 			$externalManager = new \OCA\Files_Sharing\External\Manager(
@@ -234,7 +234,7 @@  discard block
 block discarded – undo
234 234
 			);
235 235
 
236 236
 			try {
237
-				$externalManager->addShare($remote, $token, '', $name, $owner, $shareType,false, $shareWith, $remoteId);
237
+				$externalManager->addShare($remote, $token, '', $name, $owner, $shareType, false, $shareWith, $remoteId);
238 238
 				$shareId = \OC::$server->getDatabaseConnection()->lastInsertId('*PREFIX*share_external');
239 239
 
240 240
 				if ($shareType === Share::SHARE_TYPE_USER) {
@@ -243,7 +243,7 @@  discard block
 block discarded – undo
243 243
 						->setType('remote_share')
244 244
 						->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_RECEIVED, [$ownerFederatedId, trim($name, '/')])
245 245
 						->setAffectedUser($shareWith)
246
-						->setObject('remote_share', (int)$shareId, $name);
246
+						->setObject('remote_share', (int) $shareId, $name);
247 247
 					\OC::$server->getActivityManager()->publish($event);
248 248
 					$this->notifyAboutNewShare($shareWith, $shareId, $ownerFederatedId, $sharedByFederatedId, $name, $sharedBy, $owner);
249 249
 				} else {
@@ -254,7 +254,7 @@  discard block
 block discarded – undo
254 254
 							->setType('remote_share')
255 255
 							->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_RECEIVED, [$ownerFederatedId, trim($name, '/')])
256 256
 							->setAffectedUser($user->getUID())
257
-							->setObject('remote_share', (int)$shareId, $name);
257
+							->setObject('remote_share', (int) $shareId, $name);
258 258
 						\OC::$server->getActivityManager()->publish($event);
259 259
 						$this->notifyAboutNewShare($user->getUID(), $shareId, $ownerFederatedId, $sharedByFederatedId, $name, $sharedBy, $owner);
260 260
 					}
@@ -266,7 +266,7 @@  discard block
 block discarded – undo
266 266
 					'level' => ILogger::ERROR,
267 267
 					'app' => 'files_sharing'
268 268
 				]);
269
-				throw new ProviderCouldNotAddShareException('internal server error, was not able to add share from ' . $remote, '', HTTP::STATUS_INTERNAL_SERVER_ERROR);
269
+				throw new ProviderCouldNotAddShareException('internal server error, was not able to add share from '.$remote, '', HTTP::STATUS_INTERNAL_SERVER_ERROR);
270 270
 			}
271 271
 		}
272 272
 
@@ -343,12 +343,12 @@  discard block
 block discarded – undo
343 343
 
344 344
 		$declineAction = $notification->createAction();
345 345
 		$declineAction->setLabel('decline')
346
-			->setLink($this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkTo('', 'ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/' . $shareId)), 'DELETE');
346
+			->setLink($this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkTo('', 'ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/'.$shareId)), 'DELETE');
347 347
 		$notification->addAction($declineAction);
348 348
 
349 349
 		$acceptAction = $notification->createAction();
350 350
 		$acceptAction->setLabel('accept')
351
-			->setLink($this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkTo('', 'ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/' . $shareId)), 'POST');
351
+			->setLink($this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkTo('', 'ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/'.$shareId)), 'POST');
352 352
 		$notification->addAction($acceptAction);
353 353
 
354 354
 		$this->notificationManager->notify($notification);
@@ -408,7 +408,7 @@  discard block
 block discarded – undo
408 408
 	 */
409 409
 	protected function executeAcceptShare(IShare $share) {
410 410
 		try {
411
-			$fileId = (int)$share->getNode()->getId();
411
+			$fileId = (int) $share->getNode()->getId();
412 412
 			list($file, $link) = $this->getFile($this->getCorrectUid($share), $fileId);
413 413
 		} catch (\Exception $e) {
414 414
 			throw new ShareNotFound();
@@ -486,7 +486,7 @@  discard block
 block discarded – undo
486 486
 		$this->federatedShareProvider->removeShareFromTable($share);
487 487
 
488 488
 		try {
489
-			$fileId = (int)$share->getNode()->getId();
489
+			$fileId = (int) $share->getNode()->getId();
490 490
 			list($file, $link) = $this->getFile($this->getCorrectUid($share), $fileId);
491 491
 		} catch (\Exception $e) {
492 492
 			throw new ShareNotFound();
@@ -581,10 +581,10 @@  discard block
 block discarded – undo
581 581
 			// delete all child in case of a group share
582 582
 			$qb = $this->connection->getQueryBuilder();
583 583
 			$qb->delete('share_external')
584
-				->where($qb->expr()->eq('parent', $qb->createNamedParameter((int)$share['id'])));
584
+				->where($qb->expr()->eq('parent', $qb->createNamedParameter((int) $share['id'])));
585 585
 			$qb->execute();
586 586
 
587
-			if ((int)$share['share_type'] === Share::SHARE_TYPE_USER) {
587
+			if ((int) $share['share_type'] === Share::SHARE_TYPE_USER) {
588 588
 				if ($share['accepted']) {
589 589
 					$path = trim($mountpoint, '/');
590 590
 				} else {
@@ -593,7 +593,7 @@  discard block
 block discarded – undo
593 593
 				$notification = $this->notificationManager->createNotification();
594 594
 				$notification->setApp('files_sharing')
595 595
 					->setUser($share['user'])
596
-					->setObject('remote_share', (int)$share['id']);
596
+					->setObject('remote_share', (int) $share['id']);
597 597
 				$this->notificationManager->markProcessed($notification);
598 598
 
599 599
 				$event = $this->activityManager->generateEvent();
@@ -601,7 +601,7 @@  discard block
 block discarded – undo
601 601
 					->setType('remote_share')
602 602
 					->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_UNSHARED, [$owner->getId(), $path])
603 603
 					->setAffectedUser($user)
604
-					->setObject('remote_share', (int)$share['id'], $path);
604
+					->setObject('remote_share', (int) $share['id'], $path);
605 605
 				\OC::$server->getActivityManager()->publish($event);
606 606
 			}
607 607
 		}
@@ -650,7 +650,7 @@  discard block
 block discarded – undo
650 650
 			$owner = $share->getShareOwner();
651 651
 			$currentServer = $this->addressHandler->generateRemoteURL();
652 652
 			if ($this->addressHandler->compareAddresses($user, $remote, $owner, $currentServer)) {
653
-				throw new ProviderCouldNotAddShareException('Resharing back to the owner is not allowed: ' . $id);
653
+				throw new ProviderCouldNotAddShareException('Resharing back to the owner is not allowed: '.$id);
654 654
 			}
655 655
 		} catch (\Exception $e) {
656 656
 			throw new ProviderCouldNotAddShareException($e->getMessage());
@@ -664,10 +664,10 @@  discard block
 block discarded – undo
664 664
 			$share->setSharedBy($share->getSharedWith());
665 665
 			$share->setSharedWith($shareWith);
666 666
 			$result = $this->federatedShareProvider->create($share);
667
-			$this->federatedShareProvider->storeRemoteId((int)$result->getId(), $senderId);
667
+			$this->federatedShareProvider->storeRemoteId((int) $result->getId(), $senderId);
668 668
 			return ['token' => $result->getToken(), 'providerId' => $result->getId()];
669 669
 		} else {
670
-			throw new ProviderCouldNotAddShareException('resharing not allowed for share: ' . $id);
670
+			throw new ProviderCouldNotAddShareException('resharing not allowed for share: '.$id);
671 671
 		}
672 672
 
673 673
 	}
@@ -713,7 +713,7 @@  discard block
 block discarded – undo
713 713
 	 */
714 714
 	protected function ocmPermissions2ncPermissions(array $ocmPermissions) {
715 715
 		$ncPermissions = 0;
716
-		foreach($ocmPermissions as $permission) {
716
+		foreach ($ocmPermissions as $permission) {
717 717
 			switch (strtolower($permission)) {
718 718
 				case 'read':
719 719
 					$ncPermissions += Constants::PERMISSION_READ;
Please login to merge, or discard this patch.
apps/federatedfilesharing/lib/Notifier.php 1 patch
Indentation   +200 added lines, -200 removed lines patch added patch discarded remove patch
@@ -35,229 +35,229 @@
 block discarded – undo
35 35
 use OCP\Notification\INotifier;
36 36
 
37 37
 class Notifier implements INotifier {
38
-	/** @var IFactory */
39
-	protected $factory;
40
-	/** @var IManager */
41
-	protected $contactsManager;
42
-	/** @var IURLGenerator */
43
-	protected $url;
44
-	/** @var array */
45
-	protected $federatedContacts;
46
-	/** @var ICloudIdManager */
47
-	protected $cloudIdManager;
38
+    /** @var IFactory */
39
+    protected $factory;
40
+    /** @var IManager */
41
+    protected $contactsManager;
42
+    /** @var IURLGenerator */
43
+    protected $url;
44
+    /** @var array */
45
+    protected $federatedContacts;
46
+    /** @var ICloudIdManager */
47
+    protected $cloudIdManager;
48 48
 
49
-	/**
50
-	 * @param IFactory $factory
51
-	 * @param IManager $contactsManager
52
-	 * @param IURLGenerator $url
53
-	 * @param ICloudIdManager $cloudIdManager
54
-	 */
55
-	public function __construct(IFactory $factory, IManager $contactsManager, IURLGenerator $url, ICloudIdManager $cloudIdManager) {
56
-		$this->factory = $factory;
57
-		$this->contactsManager = $contactsManager;
58
-		$this->url = $url;
59
-		$this->cloudIdManager = $cloudIdManager;
60
-	}
49
+    /**
50
+     * @param IFactory $factory
51
+     * @param IManager $contactsManager
52
+     * @param IURLGenerator $url
53
+     * @param ICloudIdManager $cloudIdManager
54
+     */
55
+    public function __construct(IFactory $factory, IManager $contactsManager, IURLGenerator $url, ICloudIdManager $cloudIdManager) {
56
+        $this->factory = $factory;
57
+        $this->contactsManager = $contactsManager;
58
+        $this->url = $url;
59
+        $this->cloudIdManager = $cloudIdManager;
60
+    }
61 61
 
62
-	/**
63
-	 * Identifier of the notifier, only use [a-z0-9_]
64
-	 *
65
-	 * @return string
66
-	 * @since 17.0.0
67
-	 */
68
-	public function getID(): string {
69
-		return 'federatedfilesharing';
70
-	}
62
+    /**
63
+     * Identifier of the notifier, only use [a-z0-9_]
64
+     *
65
+     * @return string
66
+     * @since 17.0.0
67
+     */
68
+    public function getID(): string {
69
+        return 'federatedfilesharing';
70
+    }
71 71
 
72
-	/**
73
-	 * Human readable name describing the notifier
74
-	 *
75
-	 * @return string
76
-	 * @since 17.0.0
77
-	 */
78
-	public function getName(): string {
79
-		return $this->factory->get('federatedfilesharing')->t('Federated sharing');
80
-	}
72
+    /**
73
+     * Human readable name describing the notifier
74
+     *
75
+     * @return string
76
+     * @since 17.0.0
77
+     */
78
+    public function getName(): string {
79
+        return $this->factory->get('federatedfilesharing')->t('Federated sharing');
80
+    }
81 81
 
82
-	/**
83
-	 * @param INotification $notification
84
-	 * @param string $languageCode The code of the language that should be used to prepare the notification
85
-	 * @return INotification
86
-	 * @throws \InvalidArgumentException
87
-	 */
88
-	public function prepare(INotification $notification, string $languageCode): INotification {
89
-		if ($notification->getApp() !== 'files_sharing' || $notification->getObjectType() !== 'remote_share') {
90
-			// Not my app => throw
91
-			throw new \InvalidArgumentException();
92
-		}
82
+    /**
83
+     * @param INotification $notification
84
+     * @param string $languageCode The code of the language that should be used to prepare the notification
85
+     * @return INotification
86
+     * @throws \InvalidArgumentException
87
+     */
88
+    public function prepare(INotification $notification, string $languageCode): INotification {
89
+        if ($notification->getApp() !== 'files_sharing' || $notification->getObjectType() !== 'remote_share') {
90
+            // Not my app => throw
91
+            throw new \InvalidArgumentException();
92
+        }
93 93
 
94
-		// Read the language from the notification
95
-		$l = $this->factory->get('files_sharing', $languageCode);
94
+        // Read the language from the notification
95
+        $l = $this->factory->get('files_sharing', $languageCode);
96 96
 
97
-		switch ($notification->getSubject()) {
98
-			// Deal with known subjects
99
-			case 'remote_share':
100
-				$notification->setIcon($this->url->getAbsoluteURL($this->url->imagePath('core', 'actions/share.svg')));
97
+        switch ($notification->getSubject()) {
98
+            // Deal with known subjects
99
+            case 'remote_share':
100
+                $notification->setIcon($this->url->getAbsoluteURL($this->url->imagePath('core', 'actions/share.svg')));
101 101
 
102
-				$params = $notification->getSubjectParameters();
103
-				if ($params[0] !== $params[1] && $params[1] !== null) {
104
-					$notification->setParsedSubject(
105
-						$l->t('You received "%3$s" as a remote share from %4$s (%1$s) (on behalf of %5$s (%2$s))', $params)
106
-					);
102
+                $params = $notification->getSubjectParameters();
103
+                if ($params[0] !== $params[1] && $params[1] !== null) {
104
+                    $notification->setParsedSubject(
105
+                        $l->t('You received "%3$s" as a remote share from %4$s (%1$s) (on behalf of %5$s (%2$s))', $params)
106
+                    );
107 107
 
108
-					$initiator = $params[0];
109
-					$initiatorDisplay = isset($params[3]) ? $params[3] : null;
110
-					$owner = $params[1];
111
-					$ownerDisplay = isset($params[4]) ? $params[4] : null;
108
+                    $initiator = $params[0];
109
+                    $initiatorDisplay = isset($params[3]) ? $params[3] : null;
110
+                    $owner = $params[1];
111
+                    $ownerDisplay = isset($params[4]) ? $params[4] : null;
112 112
 
113
-					$notification->setRichSubject(
114
-						$l->t('You received {share} as a remote share from {user} (on behalf of {behalf})'),
115
-						[
116
-							'share' => [
117
-								'type' => 'pending-federated-share',
118
-								'id' => $notification->getObjectId(),
119
-								'name' => $params[2],
120
-							],
121
-							'user' => $this->createRemoteUser($initiator, $initiatorDisplay),
122
-							'behalf' => $this->createRemoteUser($owner, $ownerDisplay),
123
-						]
124
-					);
125
-				} else {
126
-					$notification->setParsedSubject(
127
-						$l->t('You received "%3$s" as a remote share from %4$s (%1$s)', $params)
128
-					);
113
+                    $notification->setRichSubject(
114
+                        $l->t('You received {share} as a remote share from {user} (on behalf of {behalf})'),
115
+                        [
116
+                            'share' => [
117
+                                'type' => 'pending-federated-share',
118
+                                'id' => $notification->getObjectId(),
119
+                                'name' => $params[2],
120
+                            ],
121
+                            'user' => $this->createRemoteUser($initiator, $initiatorDisplay),
122
+                            'behalf' => $this->createRemoteUser($owner, $ownerDisplay),
123
+                        ]
124
+                    );
125
+                } else {
126
+                    $notification->setParsedSubject(
127
+                        $l->t('You received "%3$s" as a remote share from %4$s (%1$s)', $params)
128
+                    );
129 129
 
130
-					$owner = $params[0];
131
-					$ownerDisplay = isset($params[3]) ? $params[3] : null;
130
+                    $owner = $params[0];
131
+                    $ownerDisplay = isset($params[3]) ? $params[3] : null;
132 132
 
133
-					$notification->setRichSubject(
134
-						$l->t('You received {share} as a remote share from {user}'),
135
-						[
136
-							'share' => [
137
-								'type' => 'pending-federated-share',
138
-								'id' => $notification->getObjectId(),
139
-								'name' => $params[2],
140
-							],
141
-							'user' => $this->createRemoteUser($owner, $ownerDisplay),
142
-						]
143
-					);
144
-				}
133
+                    $notification->setRichSubject(
134
+                        $l->t('You received {share} as a remote share from {user}'),
135
+                        [
136
+                            'share' => [
137
+                                'type' => 'pending-federated-share',
138
+                                'id' => $notification->getObjectId(),
139
+                                'name' => $params[2],
140
+                            ],
141
+                            'user' => $this->createRemoteUser($owner, $ownerDisplay),
142
+                        ]
143
+                    );
144
+                }
145 145
 
146
-				// Deal with the actions for a known subject
147
-				foreach ($notification->getActions() as $action) {
148
-					switch ($action->getLabel()) {
149
-						case 'accept':
150
-							$action->setParsedLabel(
151
-								(string) $l->t('Accept')
152
-							)
153
-							->setPrimary(true);
154
-							break;
146
+                // Deal with the actions for a known subject
147
+                foreach ($notification->getActions() as $action) {
148
+                    switch ($action->getLabel()) {
149
+                        case 'accept':
150
+                            $action->setParsedLabel(
151
+                                (string) $l->t('Accept')
152
+                            )
153
+                            ->setPrimary(true);
154
+                            break;
155 155
 
156
-						case 'decline':
157
-							$action->setParsedLabel(
158
-								(string) $l->t('Decline')
159
-							);
160
-							break;
161
-					}
156
+                        case 'decline':
157
+                            $action->setParsedLabel(
158
+                                (string) $l->t('Decline')
159
+                            );
160
+                            break;
161
+                    }
162 162
 
163
-					$notification->addParsedAction($action);
164
-				}
165
-				return $notification;
163
+                    $notification->addParsedAction($action);
164
+                }
165
+                return $notification;
166 166
 
167
-			default:
168
-				// Unknown subject => Unknown notification => throw
169
-				throw new \InvalidArgumentException();
170
-		}
171
-	}
167
+            default:
168
+                // Unknown subject => Unknown notification => throw
169
+                throw new \InvalidArgumentException();
170
+        }
171
+    }
172 172
 
173
-	/**
174
-	 * @param string $cloudId
175
-	 * @return array
176
-	 */
177
-	protected function createRemoteUser($cloudId, $displayName = null) {
178
-		try {
179
-			$resolvedId = $this->cloudIdManager->resolveCloudId($cloudId);
180
-			if ($displayName === null) {
181
-				$displayName = $this->getDisplayName($resolvedId);
182
-			}
183
-			$user = $resolvedId->getUser();
184
-			$server = $resolvedId->getRemote();
185
-		} catch (HintException $e) {
186
-			$user = $cloudId;
187
-			$displayName = $cloudId;
188
-			$server = '';
189
-		}
173
+    /**
174
+     * @param string $cloudId
175
+     * @return array
176
+     */
177
+    protected function createRemoteUser($cloudId, $displayName = null) {
178
+        try {
179
+            $resolvedId = $this->cloudIdManager->resolveCloudId($cloudId);
180
+            if ($displayName === null) {
181
+                $displayName = $this->getDisplayName($resolvedId);
182
+            }
183
+            $user = $resolvedId->getUser();
184
+            $server = $resolvedId->getRemote();
185
+        } catch (HintException $e) {
186
+            $user = $cloudId;
187
+            $displayName = $cloudId;
188
+            $server = '';
189
+        }
190 190
 
191
-		return [
192
-			'type' => 'user',
193
-			'id' => $user,
194
-			'name' => $displayName,
195
-			'server' => $server,
196
-		];
197
-	}
191
+        return [
192
+            'type' => 'user',
193
+            'id' => $user,
194
+            'name' => $displayName,
195
+            'server' => $server,
196
+        ];
197
+    }
198 198
 
199
-	/**
200
-	 * Try to find the user in the contacts
201
-	 *
202
-	 * @param ICloudId $cloudId
203
-	 * @return string
204
-	 */
205
-	protected function getDisplayName(ICloudId $cloudId) {
206
-		$server = $cloudId->getRemote();
207
-		$user = $cloudId->getUser();
208
-		if (strpos($server, 'http://') === 0) {
209
-			$server = substr($server, strlen('http://'));
210
-		} else if (strpos($server, 'https://') === 0) {
211
-			$server = substr($server, strlen('https://'));
212
-		}
199
+    /**
200
+     * Try to find the user in the contacts
201
+     *
202
+     * @param ICloudId $cloudId
203
+     * @return string
204
+     */
205
+    protected function getDisplayName(ICloudId $cloudId) {
206
+        $server = $cloudId->getRemote();
207
+        $user = $cloudId->getUser();
208
+        if (strpos($server, 'http://') === 0) {
209
+            $server = substr($server, strlen('http://'));
210
+        } else if (strpos($server, 'https://') === 0) {
211
+            $server = substr($server, strlen('https://'));
212
+        }
213 213
 
214
-		try {
215
-			return $this->getDisplayNameFromContact($cloudId->getId());
216
-		} catch (\OutOfBoundsException $e) {
217
-		}
214
+        try {
215
+            return $this->getDisplayNameFromContact($cloudId->getId());
216
+        } catch (\OutOfBoundsException $e) {
217
+        }
218 218
 
219
-		try {
220
-			$this->getDisplayNameFromContact($user . '@http://' . $server);
221
-		} catch (\OutOfBoundsException $e) {
222
-		}
219
+        try {
220
+            $this->getDisplayNameFromContact($user . '@http://' . $server);
221
+        } catch (\OutOfBoundsException $e) {
222
+        }
223 223
 
224
-		try {
225
-			$this->getDisplayNameFromContact($user . '@https://' . $server);
226
-		} catch (\OutOfBoundsException $e) {
227
-		}
224
+        try {
225
+            $this->getDisplayNameFromContact($user . '@https://' . $server);
226
+        } catch (\OutOfBoundsException $e) {
227
+        }
228 228
 
229
-		return $cloudId->getId();
230
-	}
229
+        return $cloudId->getId();
230
+    }
231 231
 
232
-	/**
233
-	 * Try to find the user in the contacts
234
-	 *
235
-	 * @param string $federatedCloudId
236
-	 * @return string
237
-	 * @throws \OutOfBoundsException when there is no contact for the id
238
-	 */
239
-	protected function getDisplayNameFromContact($federatedCloudId) {
240
-		if (isset($this->federatedContacts[$federatedCloudId])) {
241
-			if ($this->federatedContacts[$federatedCloudId] !== '') {
242
-				return $this->federatedContacts[$federatedCloudId];
243
-			} else {
244
-				throw new \OutOfBoundsException('No contact found for federated cloud id');
245
-			}
246
-		}
232
+    /**
233
+     * Try to find the user in the contacts
234
+     *
235
+     * @param string $federatedCloudId
236
+     * @return string
237
+     * @throws \OutOfBoundsException when there is no contact for the id
238
+     */
239
+    protected function getDisplayNameFromContact($federatedCloudId) {
240
+        if (isset($this->federatedContacts[$federatedCloudId])) {
241
+            if ($this->federatedContacts[$federatedCloudId] !== '') {
242
+                return $this->federatedContacts[$federatedCloudId];
243
+            } else {
244
+                throw new \OutOfBoundsException('No contact found for federated cloud id');
245
+            }
246
+        }
247 247
 
248
-		$addressBookEntries = $this->contactsManager->search($federatedCloudId, ['CLOUD']);
249
-		foreach ($addressBookEntries as $entry) {
250
-			if (isset($entry['CLOUD'])) {
251
-				foreach ($entry['CLOUD'] as $cloudID) {
252
-					if ($cloudID === $federatedCloudId) {
253
-						$this->federatedContacts[$federatedCloudId] = $entry['FN'];
254
-						return $entry['FN'];
255
-					}
256
-				}
257
-			}
258
-		}
248
+        $addressBookEntries = $this->contactsManager->search($federatedCloudId, ['CLOUD']);
249
+        foreach ($addressBookEntries as $entry) {
250
+            if (isset($entry['CLOUD'])) {
251
+                foreach ($entry['CLOUD'] as $cloudID) {
252
+                    if ($cloudID === $federatedCloudId) {
253
+                        $this->federatedContacts[$federatedCloudId] = $entry['FN'];
254
+                        return $entry['FN'];
255
+                    }
256
+                }
257
+            }
258
+        }
259 259
 
260
-		$this->federatedContacts[$federatedCloudId] = '';
261
-		throw new \OutOfBoundsException('No contact found for federated cloud id');
262
-	}
260
+        $this->federatedContacts[$federatedCloudId] = '';
261
+        throw new \OutOfBoundsException('No contact found for federated cloud id');
262
+    }
263 263
 }
Please login to merge, or discard this patch.