Completed
Pull Request — master (#9345)
by Björn
21:23
created
apps/federatedfilesharing/lib/ocm/CloudFederationProviderFiles.php 4 patches
Unused Use Statements   -1 removed lines patch added patch discarded remove patch
@@ -27,7 +27,6 @@
 block discarded – undo
27 27
 use OCA\FederatedFileSharing\AddressHandler;
28 28
 use OCA\FederatedFileSharing\FederatedShareProvider;
29 29
 use OCP\Activity\IManager as IActivityManager;
30
-use OCP\Activity\IManager;
31 30
 use OCP\App\IAppManager;
32 31
 use OCP\Constants;
33 32
 use OCP\Federation\Exceptions\ActionNotSupportedException;
Please login to merge, or discard this patch.
Doc Comments   +5 added lines, -2 removed lines patch added patch discarded remove patch
@@ -144,7 +144,7 @@  discard block
 block discarded – undo
144 144
 	 * share received from another server
145 145
 	 *
146 146
 	 * @param ICloudFederationShare $share
147
-	 * @return string provider specific unique ID of the share
147
+	 * @return integer provider specific unique ID of the share
148 148
 	 *
149 149
 	 * @throws ProviderCouldNotAddShareException
150 150
 	 * @throws \OCP\AppFramework\QueryException
@@ -468,6 +468,9 @@  discard block
 block discarded – undo
468 468
 		return [];
469 469
 	}
470 470
 
471
+	/**
472
+	 * @param string $id
473
+	 */
471 474
 	private function unshare($id, $notification) {
472 475
 
473 476
 		if (!$this->isS2SEnabled(true)) {
@@ -545,7 +548,7 @@  discard block
 block discarded – undo
545 548
 	/**
546 549
 	 * recipient of a share request to re-share the file with another user
547 550
 	 *
548
-	 * @param $id
551
+	 * @param string $id
549 552
 	 * @param $notification
550 553
 	 * @return array
551 554
 	 * @throws AuthenticationFailedException
Please login to merge, or discard this patch.
Spacing   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -189,16 +189,16 @@  discard block
 block discarded – undo
189 189
 			}
190 190
 
191 191
 			// FIXME this should be a method in the user management instead
192
-			$this->logger->debug('shareWith before, ' . $shareWith, ['app' => 'files_sharing']);
192
+			$this->logger->debug('shareWith before, '.$shareWith, ['app' => 'files_sharing']);
193 193
 			Util::emitHook(
194 194
 				'\OCA\Files_Sharing\API\Server2Server',
195 195
 				'preLoginNameUsedAsUserName',
196 196
 				array('uid' => &$shareWith)
197 197
 			);
198
-			$this->logger->debug('shareWith after, ' . $shareWith, ['app' => 'files_sharing']);
198
+			$this->logger->debug('shareWith after, '.$shareWith, ['app' => 'files_sharing']);
199 199
 
200 200
 			if (!$this->userManager->userExists($shareWith)) {
201
-				throw new ProviderCouldNotAddShareException('User does not exists', '',Http::STATUS_BAD_REQUEST);
201
+				throw new ProviderCouldNotAddShareException('User does not exists', '', Http::STATUS_BAD_REQUEST);
202 202
 			}
203 203
 
204 204
 			\OC_Util::setupFS($shareWith);
@@ -224,7 +224,7 @@  discard block
 block discarded – undo
224 224
 					->setType('remote_share')
225 225
 					->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_RECEIVED, [$ownerFederatedId, trim($name, '/')])
226 226
 					->setAffectedUser($shareWith)
227
-					->setObject('remote_share', (int)$shareId, $name);
227
+					->setObject('remote_share', (int) $shareId, $name);
228 228
 				\OC::$server->getActivityManager()->publish($event);
229 229
 
230 230
 				$notification = $this->notificationManager->createNotification();
@@ -236,12 +236,12 @@  discard block
 block discarded – undo
236 236
 
237 237
 				$declineAction = $notification->createAction();
238 238
 				$declineAction->setLabel('decline')
239
-					->setLink($this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkTo('', 'ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/' . $shareId)), 'DELETE');
239
+					->setLink($this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkTo('', 'ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/'.$shareId)), 'DELETE');
240 240
 				$notification->addAction($declineAction);
241 241
 
242 242
 				$acceptAction = $notification->createAction();
243 243
 				$acceptAction->setLabel('accept')
244
-					->setLink($this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkTo('', 'ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/' . $shareId)), 'POST');
244
+					->setLink($this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkTo('', 'ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/'.$shareId)), 'POST');
245 245
 				$notification->addAction($acceptAction);
246 246
 
247 247
 				$this->notificationManager->notify($notification);
@@ -253,7 +253,7 @@  discard block
 block discarded – undo
253 253
 					'level' => Util::ERROR,
254 254
 					'app' => 'files_sharing'
255 255
 				]);
256
-				throw new ProviderCouldNotAddShareException('internal server error, was not able to add share from ' . $remote, '', HTTP::STATUS_INTERNAL_SERVER_ERROR);
256
+				throw new ProviderCouldNotAddShareException('internal server error, was not able to add share from '.$remote, '', HTTP::STATUS_INTERNAL_SERVER_ERROR);
257 257
 			}
258 258
 		}
259 259
 
@@ -352,7 +352,7 @@  discard block
 block discarded – undo
352 352
 	 */
353 353
 	protected function executeAcceptShare(IShare $share) {
354 354
 		try {
355
-			$fileId = (int)$share->getNode()->getId();
355
+			$fileId = (int) $share->getNode()->getId();
356 356
 			list($file, $link) = $this->getFile($this->getCorrectUid($share), $fileId);
357 357
 		} catch (\Exception $e) {
358 358
 			throw new ShareNotFoundException();
@@ -431,7 +431,7 @@  discard block
 block discarded – undo
431 431
 		$this->federatedShareProvider->removeShareFromTable($share);
432 432
 
433 433
 		try {
434
-			$fileId = (int)$share->getNode()->getId();
434
+			$fileId = (int) $share->getNode()->getId();
435 435
 			list($file, $link) = $this->getFile($this->getCorrectUid($share), $fileId);
436 436
 		} catch (\Exception $e) {
437 437
 			throw new ShareNotFoundException();
@@ -524,7 +524,7 @@  discard block
 block discarded – undo
524 524
 			$notification = $this->notificationManager->createNotification();
525 525
 			$notification->setApp('files_sharing')
526 526
 				->setUser($share['user'])
527
-				->setObject('remote_share', (int)$share['id']);
527
+				->setObject('remote_share', (int) $share['id']);
528 528
 			$this->notificationManager->markProcessed($notification);
529 529
 
530 530
 			$event = $this->activityManager->generateEvent();
@@ -532,7 +532,7 @@  discard block
 block discarded – undo
532 532
 				->setType('remote_share')
533 533
 				->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_UNSHARED, [$owner->getId(), $path])
534 534
 				->setAffectedUser($user)
535
-				->setObject('remote_share', (int)$share['id'], $path);
535
+				->setObject('remote_share', (int) $share['id'], $path);
536 536
 			\OC::$server->getActivityManager()->publish($event);
537 537
 		}
538 538
 
@@ -581,7 +581,7 @@  discard block
 block discarded – undo
581 581
 			$owner = $share->getShareOwner();
582 582
 			$currentServer = $this->addressHandler->generateRemoteURL();
583 583
 			if ($this->addressHandler->compareAddresses($user, $remote, $owner, $currentServer)) {
584
-				throw new ProviderCouldNotAddShareException('Resharing back to the owner is not allowed: ' . $id);
584
+				throw new ProviderCouldNotAddShareException('Resharing back to the owner is not allowed: '.$id);
585 585
 			}
586 586
 		} catch (\Exception $e) {
587 587
 			throw new ProviderCouldNotAddShareException($e->getMessage());
@@ -595,10 +595,10 @@  discard block
 block discarded – undo
595 595
 			$share->setSharedBy($share->getSharedWith());
596 596
 			$share->setSharedWith($shareWith);
597 597
 			$result = $this->federatedShareProvider->create($share);
598
-			$this->federatedShareProvider->storeRemoteId((int)$result->getId(), $senderId);
598
+			$this->federatedShareProvider->storeRemoteId((int) $result->getId(), $senderId);
599 599
 			return ['token' => $result->getToken(), 'providerId' => $result->getId()];
600 600
 		} else {
601
-			throw new ProviderCouldNotAddShareException('resharing not allowed for share: ' . $id);
601
+			throw new ProviderCouldNotAddShareException('resharing not allowed for share: '.$id);
602 602
 		}
603 603
 
604 604
 		throw new BadRequestException([]);
@@ -645,9 +645,9 @@  discard block
 block discarded – undo
645 645
 	 * @throws BadRequestException
646 646
 	 */
647 647
 	protected function ocmPermissions2ncPermissions($ocmPermissions) {
648
-		error_log("ocm permissions: " . json_encode($ocmPermissions));
648
+		error_log("ocm permissions: ".json_encode($ocmPermissions));
649 649
 		$ncPermissions = 0;
650
-		foreach($ocmPermissions as $permission) {
650
+		foreach ($ocmPermissions as $permission) {
651 651
 			switch (strtolower($permission)) {
652 652
 				case 'read':
653 653
 					$ncPermissions += Constants::PERMISSION_READ;
@@ -662,7 +662,7 @@  discard block
 block discarded – undo
662 662
 					throw new BadRequestException(['permission']);
663 663
 			}
664 664
 
665
-			error_log("new permissions: " . $ncPermissions);
665
+			error_log("new permissions: ".$ncPermissions);
666 666
 		}
667 667
 
668 668
 		return $ncPermissions;
Please login to merge, or discard this patch.
Indentation   +707 added lines, -707 removed lines patch added patch discarded remove patch
@@ -53,713 +53,713 @@
 block discarded – undo
53 53
 
54 54
 class CloudFederationProviderFiles implements ICloudFederationProvider {
55 55
 
56
-	/** @var IAppManager */
57
-	private $appManager;
58
-
59
-	/** @var FederatedShareProvider */
60
-	private $federatedShareProvider;
61
-
62
-	/** @var AddressHandler */
63
-	private $addressHandler;
64
-
65
-	/** @var ILogger */
66
-	private $logger;
67
-
68
-	/** @var IUserManager */
69
-	private $userManager;
70
-
71
-	/** @var ICloudIdManager */
72
-	private $cloudIdManager;
73
-
74
-	/** @var IActivityManager */
75
-	private $activityManager;
76
-
77
-	/** @var INotificationManager */
78
-	private $notificationManager;
79
-
80
-	/** @var IURLGenerator */
81
-	private $urlGenerator;
82
-
83
-	/** @var ICloudFederationFactory */
84
-	private $cloudFederationFactory;
85
-
86
-	/** @var ICloudFederationProviderManager */
87
-	private $cloudFederationProviderManager;
88
-
89
-	/** @var IDBConnection */
90
-	private $connection;
91
-
92
-	/**
93
-	 * CloudFederationProvider constructor.
94
-	 *
95
-	 * @param IAppManager $appManager
96
-	 * @param FederatedShareProvider $federatedShareProvider
97
-	 * @param AddressHandler $addressHandler
98
-	 * @param ILogger $logger
99
-	 * @param IUserManager $userManager
100
-	 * @param ICloudIdManager $cloudIdManager
101
-	 * @param IActivityManager $activityManager
102
-	 * @param INotificationManager $notificationManager
103
-	 * @param IURLGenerator $urlGenerator
104
-	 * @param ICloudFederationFactory $cloudFederationFactory
105
-	 * @param ICloudFederationProviderManager $cloudFederationProviderManager
106
-	 * @param IDBConnection $connection
107
-	 */
108
-	public function __construct(IAppManager $appManager,
109
-								FederatedShareProvider $federatedShareProvider,
110
-								AddressHandler $addressHandler,
111
-								ILogger $logger,
112
-								IUserManager $userManager,
113
-								ICloudIdManager $cloudIdManager,
114
-								IActivityManager $activityManager,
115
-								INotificationManager $notificationManager,
116
-								IURLGenerator $urlGenerator,
117
-								ICloudFederationFactory $cloudFederationFactory,
118
-								ICloudFederationProviderManager $cloudFederationProviderManager,
119
-								IDBConnection $connection
120
-	) {
121
-		$this->appManager = $appManager;
122
-		$this->federatedShareProvider = $federatedShareProvider;
123
-		$this->addressHandler = $addressHandler;
124
-		$this->logger = $logger;
125
-		$this->userManager = $userManager;
126
-		$this->cloudIdManager = $cloudIdManager;
127
-		$this->activityManager = $activityManager;
128
-		$this->notificationManager = $notificationManager;
129
-		$this->urlGenerator = $urlGenerator;
130
-		$this->cloudFederationFactory = $cloudFederationFactory;
131
-		$this->cloudFederationProviderManager = $cloudFederationProviderManager;
132
-		$this->connection = $connection;
133
-	}
134
-
135
-
136
-
137
-	/**
138
-	 * @return string
139
-	 */
140
-	public function getShareType() {
141
-		return 'file';
142
-	}
143
-
144
-	/**
145
-	 * share received from another server
146
-	 *
147
-	 * @param ICloudFederationShare $share
148
-	 * @return string provider specific unique ID of the share
149
-	 *
150
-	 * @throws ProviderCouldNotAddShareException
151
-	 * @throws \OCP\AppFramework\QueryException
152
-	 * @throws \OC\HintException
153
-	 * @since 14.0.0
154
-	 */
155
-	public function shareReceived(ICloudFederationShare $share) {
156
-
157
-		if (!$this->isS2SEnabled(true)) {
158
-			throw new ProviderCouldNotAddShareException('Server does not support federated cloud sharing', '', Http::STATUS_SERVICE_UNAVAILABLE);
159
-		}
160
-
161
-		$protocol = $share->getProtocol();
162
-		if ($protocol['name'] !== 'webdav') {
163
-			throw new ProviderCouldNotAddShareException('Unsupported protocol for data exchange.', '', Http::STATUS_NOT_IMPLEMENTED);
164
-		}
165
-
166
-		list($ownerUid, $remote) = $this->addressHandler->splitUserRemote($share->getOwner());
167
-
168
-		$remote = $remote;
169
-		$token = $share->getShareSecret();
170
-		$name = $share->getResourceName();
171
-		$owner = $share->getOwnerDisplayName();
172
-		$sharedBy = $share->getSharedByDisplayName();
173
-		$shareWith = $share->getShareWith();
174
-		$remoteId = $share->getProviderId();
175
-		$sharedByFederatedId = $share->getSharedBy();
176
-		$ownerFederatedId = $share->getOwner();
177
-
178
-		// if no explicit information about the person who created the share was send
179
-		// we assume that the share comes from the owner
180
-		if ($sharedByFederatedId === null) {
181
-			$sharedBy = $owner;
182
-			$sharedByFederatedId = $ownerFederatedId;
183
-		}
184
-
185
-		if ($remote && $token && $name && $owner && $remoteId && $shareWith) {
186
-
187
-			if (!Util::isValidFileName($name)) {
188
-				throw new ProviderCouldNotAddShareException('The mountpoint name contains invalid characters.', '', Http::STATUS_BAD_REQUEST);
189
-			}
190
-
191
-			// FIXME this should be a method in the user management instead
192
-			$this->logger->debug('shareWith before, ' . $shareWith, ['app' => 'files_sharing']);
193
-			Util::emitHook(
194
-				'\OCA\Files_Sharing\API\Server2Server',
195
-				'preLoginNameUsedAsUserName',
196
-				array('uid' => &$shareWith)
197
-			);
198
-			$this->logger->debug('shareWith after, ' . $shareWith, ['app' => 'files_sharing']);
199
-
200
-			if (!$this->userManager->userExists($shareWith)) {
201
-				throw new ProviderCouldNotAddShareException('User does not exists', '',Http::STATUS_BAD_REQUEST);
202
-			}
203
-
204
-			\OC_Util::setupFS($shareWith);
205
-
206
-			$externalManager = new \OCA\Files_Sharing\External\Manager(
207
-				\OC::$server->getDatabaseConnection(),
208
-				Filesystem::getMountManager(),
209
-				Filesystem::getLoader(),
210
-				\OC::$server->getHTTPClientService(),
211
-				\OC::$server->getNotificationManager(),
212
-				\OC::$server->query(\OCP\OCS\IDiscoveryService::class),
213
-				\OC::$server->getCloudFederationProviderManager(),
214
-				\OC::$server->getCloudFederationFactory(),
215
-				$shareWith
216
-			);
217
-
218
-			try {
219
-				$externalManager->addShare($remote, $token, '', $name, $owner, false, $shareWith, $remoteId);
220
-				$shareId = \OC::$server->getDatabaseConnection()->lastInsertId('*PREFIX*share_external');
221
-
222
-				$event = $this->activityManager->generateEvent();
223
-				$event->setApp('files_sharing')
224
-					->setType('remote_share')
225
-					->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_RECEIVED, [$ownerFederatedId, trim($name, '/')])
226
-					->setAffectedUser($shareWith)
227
-					->setObject('remote_share', (int)$shareId, $name);
228
-				\OC::$server->getActivityManager()->publish($event);
229
-
230
-				$notification = $this->notificationManager->createNotification();
231
-				$notification->setApp('files_sharing')
232
-					->setUser($shareWith)
233
-					->setDateTime(new \DateTime())
234
-					->setObject('remote_share', $shareId)
235
-					->setSubject('remote_share', [$ownerFederatedId, $sharedByFederatedId, trim($name, '/')]);
236
-
237
-				$declineAction = $notification->createAction();
238
-				$declineAction->setLabel('decline')
239
-					->setLink($this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkTo('', 'ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/' . $shareId)), 'DELETE');
240
-				$notification->addAction($declineAction);
241
-
242
-				$acceptAction = $notification->createAction();
243
-				$acceptAction->setLabel('accept')
244
-					->setLink($this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkTo('', 'ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/' . $shareId)), 'POST');
245
-				$notification->addAction($acceptAction);
246
-
247
-				$this->notificationManager->notify($notification);
248
-
249
-				return $shareId;
250
-			} catch (\Exception $e) {
251
-				$this->logger->logException($e, [
252
-					'message' => 'Server can not add remote share.',
253
-					'level' => Util::ERROR,
254
-					'app' => 'files_sharing'
255
-				]);
256
-				throw new ProviderCouldNotAddShareException('internal server error, was not able to add share from ' . $remote, '', HTTP::STATUS_INTERNAL_SERVER_ERROR);
257
-			}
258
-		}
259
-
260
-		throw new ProviderCouldNotAddShareException('server can not add remote share, missing parameter', '', HTTP::STATUS_BAD_REQUEST);
261
-
262
-	}
263
-
264
-	/**
265
-	 * notification received from another server
266
-	 *
267
-	 * @param string $notificationType (e.g. SHARE_ACCEPTED)
268
-	 * @param string $providerId id of the share
269
-	 * @param array $notification payload of the notification
270
-	 * @return array data send back to the sender
271
-	 *
272
-	 * @throws ActionNotSupportedException
273
-	 * @throws AuthenticationFailedException
274
-	 * @throws BadRequestException
275
-	 * @throws ShareNotFoundException
276
-	 * @throws \OC\HintException
277
-	 * @since 14.0.0
278
-	 */
279
-	public function notificationReceived($notificationType, $providerId, array $notification) {
280
-
281
-		switch ($notificationType) {
282
-			case 'SHARE_ACCEPTED':
283
-				return $this->shareAccepted($providerId, $notification);
284
-			case 'SHARE_DECLINED':
285
-				return $this->shareDeclined($providerId, $notification);
286
-			case 'SHARE_UNSHARED':
287
-				return $this->unshare($providerId, $notification);
288
-			case 'REQUEST_RESHARE':
289
-				return $this->reshareRequested($providerId, $notification);
290
-			case 'RESHARE_UNDO':
291
-				return $this->undoReshare($providerId, $notification);
292
-			case 'RESHARE_CHANGE_PERMISSION':
293
-				return $this->updateResharePermissions($providerId, $notification);
294
-		}
295
-
296
-
297
-		throw new BadRequestException([$notificationType]);
298
-	}
299
-
300
-	/**
301
-	 * process notification that the recipient accepted a share
302
-	 *
303
-	 * @param string $id
304
-	 * @param array $notification
305
-	 * @return array
306
-	 * @throws ActionNotSupportedException
307
-	 * @throws AuthenticationFailedException
308
-	 * @throws BadRequestException
309
-	 * @throws ShareNotFoundException
310
-	 * @throws \OC\HintException
311
-	 */
312
-	private function shareAccepted($id, $notification) {
313
-
314
-		if (!$this->isS2SEnabled()) {
315
-			throw new ActionNotSupportedException('Server does not support federated cloud sharing');
316
-		}
317
-
318
-		if (!isset($notification['sharedSecret'])) {
319
-			throw new BadRequestException(['sharedSecret']);
320
-		}
321
-
322
-		$token = $notification['sharedSecret'];
323
-
324
-		$share = $this->federatedShareProvider->getShareById($id);
325
-
326
-		$this->verifyShare($share, $token);
327
-		$this->executeAcceptShare($share);
328
-		if ($share->getShareOwner() !== $share->getSharedBy()) {
329
-			list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy());
330
-			$remoteId = $this->federatedShareProvider->getRemoteId($share);
331
-			$notification = $this->cloudFederationFactory->getCloudFederationNotification();
332
-			$notification->setMessage(
333
-				'SHARE_ACCEPTED',
334
-				'file',
335
-				$remoteId,
336
-				[
337
-					'sharedSecret' => $token,
338
-					'message' => 'Recipient accepted the re-share'
339
-				]
340
-
341
-			);
342
-			$this->cloudFederationProviderManager->sendNotification($remote, $notification);
343
-
344
-		}
345
-
346
-		return [];
347
-	}
348
-
349
-	/**
350
-	 * @param IShare $share
351
-	 * @throws ShareNotFoundException
352
-	 */
353
-	protected function executeAcceptShare(IShare $share) {
354
-		try {
355
-			$fileId = (int)$share->getNode()->getId();
356
-			list($file, $link) = $this->getFile($this->getCorrectUid($share), $fileId);
357
-		} catch (\Exception $e) {
358
-			throw new ShareNotFoundException();
359
-		}
360
-
361
-		$event = $this->activityManager->generateEvent();
362
-		$event->setApp('files_sharing')
363
-			->setType('remote_share')
364
-			->setAffectedUser($this->getCorrectUid($share))
365
-			->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_ACCEPTED, [$share->getSharedWith(), [$fileId => $file]])
366
-			->setObject('files', $fileId, $file)
367
-			->setLink($link);
368
-		$this->activityManager->publish($event);
369
-	}
370
-
371
-	/**
372
-	 * process notification that the recipient declined a share
373
-	 *
374
-	 * @param string $id
375
-	 * @param array $notification
376
-	 * @return array
377
-	 * @throws ActionNotSupportedException
378
-	 * @throws AuthenticationFailedException
379
-	 * @throws BadRequestException
380
-	 * @throws ShareNotFound
381
-	 * @throws ShareNotFoundException
382
-	 * @throws \OC\HintException
383
-	 *
384
-	 */
385
-	protected function shareDeclined($id, $notification) {
386
-
387
-		if (!$this->isS2SEnabled()) {
388
-			throw new ActionNotSupportedException('Server does not support federated cloud sharing');
389
-		}
390
-
391
-		if (!isset($notification['sharedSecret'])) {
392
-			throw new BadRequestException(['sharedSecret']);
393
-		}
394
-
395
-		$token = $notification['sharedSecret'];
396
-
397
-		$share = $this->federatedShareProvider->getShareById($id);
398
-
399
-		$this->verifyShare($share, $token);
400
-
401
-		if ($share->getShareOwner() !== $share->getSharedBy()) {
402
-			list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy());
403
-			$remoteId = $this->federatedShareProvider->getRemoteId($share);
404
-			$notification = $this->cloudFederationFactory->getCloudFederationNotification();
405
-			$notification->setMessage(
406
-				'SHARE_DECLINED',
407
-				'file',
408
-				$remoteId,
409
-				[
410
-					'sharedSecret' => $token,
411
-					'message' => 'Recipient declined the re-share'
412
-				]
413
-
414
-			);
415
-			$this->cloudFederationProviderManager->sendNotification($remote, $notification);
416
-		}
417
-
418
-		$this->executeDeclineShare($share);
419
-
420
-		return [];
421
-
422
-	}
423
-
424
-	/**
425
-	 * delete declined share and create a activity
426
-	 *
427
-	 * @param IShare $share
428
-	 * @throws ShareNotFoundException
429
-	 */
430
-	protected function executeDeclineShare(IShare $share) {
431
-		$this->federatedShareProvider->removeShareFromTable($share);
432
-
433
-		try {
434
-			$fileId = (int)$share->getNode()->getId();
435
-			list($file, $link) = $this->getFile($this->getCorrectUid($share), $fileId);
436
-		} catch (\Exception $e) {
437
-			throw new ShareNotFoundException();
438
-		}
439
-
440
-		$event = $this->activityManager->generateEvent();
441
-		$event->setApp('files_sharing')
442
-			->setType('remote_share')
443
-			->setAffectedUser($this->getCorrectUid($share))
444
-			->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_DECLINED, [$share->getSharedWith(), [$fileId => $file]])
445
-			->setObject('files', $fileId, $file)
446
-			->setLink($link);
447
-		$this->activityManager->publish($event);
448
-
449
-	}
450
-
451
-	/**
452
-	 * received the notification that the owner unshared a file from you
453
-	 *
454
-	 * @param string $id
455
-	 * @param string $notification
456
-	 * @return array
457
-	 * @throws AuthenticationFailedException
458
-	 * @throws BadRequestException
459
-	 * @throws ShareNotFoundException
460
-	 */
461
-	private function undoReshare($id, $notification) {
462
-		if (!isset($notification['sharedSecret'])) {
463
-			throw new BadRequestException(['sharedSecret']);
464
-		}
465
-		$token = $notification['sharedSecret'];
466
-
467
-		$share = $this->federatedShareProvider->getShareById($id);
468
-
469
-		$this->verifyShare($share, $token);
470
-		$this->federatedShareProvider->removeShareFromTable($share);
471
-		return [];
472
-	}
473
-
474
-	private function unshare($id, $notification) {
475
-
476
-		if (!$this->isS2SEnabled(true)) {
477
-			throw new ActionNotSupportedException("incoming shares disabled!");
478
-		}
479
-
480
-		if (!isset($notification['sharedSecret'])) {
481
-			throw new BadRequestException(['sharedSecret']);
482
-		}
483
-		$token = $notification['sharedSecret'];
484
-
485
-		$qb = $this->connection->getQueryBuilder();
486
-		$qb->select('*')
487
-			->from('share_external')
488
-			->where(
489
-				$qb->expr()->andX(
490
-					$qb->expr()->eq('remote_id', $qb->createNamedParameter($id)),
491
-					$qb->expr()->eq('share_token', $qb->createNamedParameter($token))
492
-				)
493
-			);
494
-
495
-		$result = $qb->execute();
496
-		$share = $result->fetch();
497
-		$result->closeCursor();
498
-
499
-		if ($token && $id && !empty($share)) {
500
-
501
-			$remote = $this->cleanupRemote($share['remote']);
502
-
503
-			$owner = $this->cloudIdManager->getCloudId($share['owner'], $remote);
504
-			$mountpoint = $share['mountpoint'];
505
-			$user = $share['user'];
506
-
507
-			$qb = $this->connection->getQueryBuilder();
508
-			$qb->delete('share_external')
509
-				->where(
510
-					$qb->expr()->andX(
511
-						$qb->expr()->eq('remote_id', $qb->createNamedParameter($id)),
512
-						$qb->expr()->eq('share_token', $qb->createNamedParameter($token))
513
-					)
514
-				);
515
-
516
-			$qb->execute();
517
-
518
-			if ($share['accepted']) {
519
-				$path = trim($mountpoint, '/');
520
-			} else {
521
-				$path = trim($share['name'], '/');
522
-			}
523
-
524
-			$notification = $this->notificationManager->createNotification();
525
-			$notification->setApp('files_sharing')
526
-				->setUser($share['user'])
527
-				->setObject('remote_share', (int)$share['id']);
528
-			$this->notificationManager->markProcessed($notification);
529
-
530
-			$event = $this->activityManager->generateEvent();
531
-			$event->setApp('files_sharing')
532
-				->setType('remote_share')
533
-				->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_UNSHARED, [$owner->getId(), $path])
534
-				->setAffectedUser($user)
535
-				->setObject('remote_share', (int)$share['id'], $path);
536
-			\OC::$server->getActivityManager()->publish($event);
537
-		}
538
-
539
-		return [];
540
-	}
541
-
542
-	private function cleanupRemote($remote) {
543
-		$remote = substr($remote, strpos($remote, '://') + 3);
544
-
545
-		return rtrim($remote, '/');
546
-	}
547
-
548
-	/**
549
-	 * recipient of a share request to re-share the file with another user
550
-	 *
551
-	 * @param $id
552
-	 * @param $notification
553
-	 * @return array
554
-	 * @throws AuthenticationFailedException
555
-	 * @throws BadRequestException
556
-	 * @throws ProviderCouldNotAddShareException
557
-	 * @throws ShareNotFoundException
558
-	 * @throws ShareNotFound
559
-	 */
560
-	protected function reshareRequested($id, $notification) {
561
-
562
-		if (!isset($notification['sharedSecret'])) {
563
-			throw new BadRequestException(['sharedSecret']);
564
-		}
565
-		$token = $notification['sharedSecret'];
566
-
567
-		if (!isset($notification['shareWith'])) {
568
-			throw new BadRequestException(['shareWith']);
569
-		}
570
-		$shareWith = $notification['shareWith'];
571
-
572
-		if (!isset($notification['senderId'])) {
573
-			throw new BadRequestException(['senderId']);
574
-		}
575
-		$senderId = $notification['senderId'];
576
-
577
-		$share = $this->federatedShareProvider->getShareById($id);
578
-		// don't allow to share a file back to the owner
579
-		try {
580
-			list($user, $remote) = $this->addressHandler->splitUserRemote($shareWith);
581
-			$owner = $share->getShareOwner();
582
-			$currentServer = $this->addressHandler->generateRemoteURL();
583
-			if ($this->addressHandler->compareAddresses($user, $remote, $owner, $currentServer)) {
584
-				throw new ProviderCouldNotAddShareException('Resharing back to the owner is not allowed: ' . $id);
585
-			}
586
-		} catch (\Exception $e) {
587
-			throw new ProviderCouldNotAddShareException($e->getMessage());
588
-		}
589
-
590
-		$this->verifyShare($share, $token);
591
-
592
-		// check if re-sharing is allowed
593
-		if ($share->getPermissions() & Constants::PERMISSION_SHARE) {
594
-			// the recipient of the initial share is now the initiator for the re-share
595
-			$share->setSharedBy($share->getSharedWith());
596
-			$share->setSharedWith($shareWith);
597
-			$result = $this->federatedShareProvider->create($share);
598
-			$this->federatedShareProvider->storeRemoteId((int)$result->getId(), $senderId);
599
-			return ['token' => $result->getToken(), 'providerId' => $result->getId()];
600
-		} else {
601
-			throw new ProviderCouldNotAddShareException('resharing not allowed for share: ' . $id);
602
-		}
603
-
604
-		throw new BadRequestException([]);
605
-	}
606
-
607
-	/**
608
-	 * update permission of a re-share so that the share dialog shows the right
609
-	 * permission if the owner or the sender changes the permission
610
-	 *
611
-	 * @param string $id
612
-	 * @param array $notification
613
-	 * @return array
614
-	 * @throws AuthenticationFailedException
615
-	 * @throws BadRequestException
616
-	 * @throws ShareNotFoundException
617
-	 */
618
-	protected function updateResharePermissions($id, $notification) {
619
-
620
-		if (!isset($notification['sharedSecret'])) {
621
-			throw new BadRequestException(['sharedSecret']);
622
-		}
623
-		$token = $notification['sharedSecret'];
624
-
625
-		if (!isset($notification['permission'])) {
626
-			throw new BadRequestException(['permission']);
627
-		}
628
-		$ocmPermissions = $notification['permission'];
629
-
630
-		$share = $this->federatedShareProvider->getShareById($id);
631
-
632
-		$ncPermission = $this->ocmPermissions2ncPermissions($ocmPermissions);
633
-
634
-		$this->verifyShare($share, $token);
635
-		$this->updatePermissionsInDatabase($share, $ncPermission);
636
-
637
-		return [];
638
-	}
639
-
640
-	/**
641
-	 * translate OCM Permissions to Nextcloud permissions
642
-	 *
643
-	 * @param $ocmPermissions
644
-	 * @return int
645
-	 * @throws BadRequestException
646
-	 */
647
-	protected function ocmPermissions2ncPermissions($ocmPermissions) {
648
-		error_log("ocm permissions: " . json_encode($ocmPermissions));
649
-		$ncPermissions = 0;
650
-		foreach($ocmPermissions as $permission) {
651
-			switch (strtolower($permission)) {
652
-				case 'read':
653
-					$ncPermissions += Constants::PERMISSION_READ;
654
-					break;
655
-				case 'write':
656
-					$ncPermissions += Constants::PERMISSION_CREATE + Constants::PERMISSION_UPDATE;
657
-					break;
658
-				case 'share':
659
-					$ncPermissions += Constants::PERMISSION_SHARE;
660
-					break;
661
-				default:
662
-					throw new BadRequestException(['permission']);
663
-			}
664
-
665
-			error_log("new permissions: " . $ncPermissions);
666
-		}
667
-
668
-		return $ncPermissions;
669
-	}
670
-
671
-	/**
672
-	 * update permissions in database
673
-	 *
674
-	 * @param IShare $share
675
-	 * @param int $permissions
676
-	 */
677
-	protected function updatePermissionsInDatabase(IShare $share, $permissions) {
678
-		$query = $this->connection->getQueryBuilder();
679
-		$query->update('share')
680
-			->where($query->expr()->eq('id', $query->createNamedParameter($share->getId())))
681
-			->set('permissions', $query->createNamedParameter($permissions))
682
-			->execute();
683
-	}
684
-
685
-
686
-	/**
687
-	 * get file
688
-	 *
689
-	 * @param string $user
690
-	 * @param int $fileSource
691
-	 * @return array with internal path of the file and a absolute link to it
692
-	 */
693
-	private function getFile($user, $fileSource) {
694
-		\OC_Util::setupFS($user);
695
-
696
-		try {
697
-			$file = Filesystem::getPath($fileSource);
698
-		} catch (NotFoundException $e) {
699
-			$file = null;
700
-		}
701
-		$args = Filesystem::is_dir($file) ? array('dir' => $file) : array('dir' => dirname($file), 'scrollto' => $file);
702
-		$link = Util::linkToAbsolute('files', 'index.php', $args);
703
-
704
-		return array($file, $link);
705
-
706
-	}
707
-
708
-	/**
709
-	 * check if we are the initiator or the owner of a re-share and return the correct UID
710
-	 *
711
-	 * @param IShare $share
712
-	 * @return string
713
-	 */
714
-	protected function getCorrectUid(IShare $share) {
715
-		if ($this->userManager->userExists($share->getShareOwner())) {
716
-			return $share->getShareOwner();
717
-		}
718
-
719
-		return $share->getSharedBy();
720
-	}
721
-
722
-
723
-
724
-	/**
725
-	 * check if we got the right share
726
-	 *
727
-	 * @param IShare $share
728
-	 * @param string $token
729
-	 * @return bool
730
-	 * @throws AuthenticationFailedException
731
-	 */
732
-	protected function verifyShare(IShare $share, $token) {
733
-		if (
734
-			$share->getShareType() === FederatedShareProvider::SHARE_TYPE_REMOTE &&
735
-			$share->getToken() === $token
736
-		) {
737
-			return true;
738
-		}
739
-
740
-		throw new AuthenticationFailedException();
741
-	}
742
-
743
-
744
-
745
-	/**
746
-	 * check if server-to-server sharing is enabled
747
-	 *
748
-	 * @param bool $incoming
749
-	 * @return bool
750
-	 */
751
-	private function isS2SEnabled($incoming = false) {
752
-
753
-		$result = $this->appManager->isEnabledForUser('files_sharing');
754
-
755
-		if ($incoming) {
756
-			$result = $result && $this->federatedShareProvider->isIncomingServer2serverShareEnabled();
757
-		} else {
758
-			$result = $result && $this->federatedShareProvider->isOutgoingServer2serverShareEnabled();
759
-		}
760
-
761
-		return $result;
762
-	}
56
+    /** @var IAppManager */
57
+    private $appManager;
58
+
59
+    /** @var FederatedShareProvider */
60
+    private $federatedShareProvider;
61
+
62
+    /** @var AddressHandler */
63
+    private $addressHandler;
64
+
65
+    /** @var ILogger */
66
+    private $logger;
67
+
68
+    /** @var IUserManager */
69
+    private $userManager;
70
+
71
+    /** @var ICloudIdManager */
72
+    private $cloudIdManager;
73
+
74
+    /** @var IActivityManager */
75
+    private $activityManager;
76
+
77
+    /** @var INotificationManager */
78
+    private $notificationManager;
79
+
80
+    /** @var IURLGenerator */
81
+    private $urlGenerator;
82
+
83
+    /** @var ICloudFederationFactory */
84
+    private $cloudFederationFactory;
85
+
86
+    /** @var ICloudFederationProviderManager */
87
+    private $cloudFederationProviderManager;
88
+
89
+    /** @var IDBConnection */
90
+    private $connection;
91
+
92
+    /**
93
+     * CloudFederationProvider constructor.
94
+     *
95
+     * @param IAppManager $appManager
96
+     * @param FederatedShareProvider $federatedShareProvider
97
+     * @param AddressHandler $addressHandler
98
+     * @param ILogger $logger
99
+     * @param IUserManager $userManager
100
+     * @param ICloudIdManager $cloudIdManager
101
+     * @param IActivityManager $activityManager
102
+     * @param INotificationManager $notificationManager
103
+     * @param IURLGenerator $urlGenerator
104
+     * @param ICloudFederationFactory $cloudFederationFactory
105
+     * @param ICloudFederationProviderManager $cloudFederationProviderManager
106
+     * @param IDBConnection $connection
107
+     */
108
+    public function __construct(IAppManager $appManager,
109
+                                FederatedShareProvider $federatedShareProvider,
110
+                                AddressHandler $addressHandler,
111
+                                ILogger $logger,
112
+                                IUserManager $userManager,
113
+                                ICloudIdManager $cloudIdManager,
114
+                                IActivityManager $activityManager,
115
+                                INotificationManager $notificationManager,
116
+                                IURLGenerator $urlGenerator,
117
+                                ICloudFederationFactory $cloudFederationFactory,
118
+                                ICloudFederationProviderManager $cloudFederationProviderManager,
119
+                                IDBConnection $connection
120
+    ) {
121
+        $this->appManager = $appManager;
122
+        $this->federatedShareProvider = $federatedShareProvider;
123
+        $this->addressHandler = $addressHandler;
124
+        $this->logger = $logger;
125
+        $this->userManager = $userManager;
126
+        $this->cloudIdManager = $cloudIdManager;
127
+        $this->activityManager = $activityManager;
128
+        $this->notificationManager = $notificationManager;
129
+        $this->urlGenerator = $urlGenerator;
130
+        $this->cloudFederationFactory = $cloudFederationFactory;
131
+        $this->cloudFederationProviderManager = $cloudFederationProviderManager;
132
+        $this->connection = $connection;
133
+    }
134
+
135
+
136
+
137
+    /**
138
+     * @return string
139
+     */
140
+    public function getShareType() {
141
+        return 'file';
142
+    }
143
+
144
+    /**
145
+     * share received from another server
146
+     *
147
+     * @param ICloudFederationShare $share
148
+     * @return string provider specific unique ID of the share
149
+     *
150
+     * @throws ProviderCouldNotAddShareException
151
+     * @throws \OCP\AppFramework\QueryException
152
+     * @throws \OC\HintException
153
+     * @since 14.0.0
154
+     */
155
+    public function shareReceived(ICloudFederationShare $share) {
156
+
157
+        if (!$this->isS2SEnabled(true)) {
158
+            throw new ProviderCouldNotAddShareException('Server does not support federated cloud sharing', '', Http::STATUS_SERVICE_UNAVAILABLE);
159
+        }
160
+
161
+        $protocol = $share->getProtocol();
162
+        if ($protocol['name'] !== 'webdav') {
163
+            throw new ProviderCouldNotAddShareException('Unsupported protocol for data exchange.', '', Http::STATUS_NOT_IMPLEMENTED);
164
+        }
165
+
166
+        list($ownerUid, $remote) = $this->addressHandler->splitUserRemote($share->getOwner());
167
+
168
+        $remote = $remote;
169
+        $token = $share->getShareSecret();
170
+        $name = $share->getResourceName();
171
+        $owner = $share->getOwnerDisplayName();
172
+        $sharedBy = $share->getSharedByDisplayName();
173
+        $shareWith = $share->getShareWith();
174
+        $remoteId = $share->getProviderId();
175
+        $sharedByFederatedId = $share->getSharedBy();
176
+        $ownerFederatedId = $share->getOwner();
177
+
178
+        // if no explicit information about the person who created the share was send
179
+        // we assume that the share comes from the owner
180
+        if ($sharedByFederatedId === null) {
181
+            $sharedBy = $owner;
182
+            $sharedByFederatedId = $ownerFederatedId;
183
+        }
184
+
185
+        if ($remote && $token && $name && $owner && $remoteId && $shareWith) {
186
+
187
+            if (!Util::isValidFileName($name)) {
188
+                throw new ProviderCouldNotAddShareException('The mountpoint name contains invalid characters.', '', Http::STATUS_BAD_REQUEST);
189
+            }
190
+
191
+            // FIXME this should be a method in the user management instead
192
+            $this->logger->debug('shareWith before, ' . $shareWith, ['app' => 'files_sharing']);
193
+            Util::emitHook(
194
+                '\OCA\Files_Sharing\API\Server2Server',
195
+                'preLoginNameUsedAsUserName',
196
+                array('uid' => &$shareWith)
197
+            );
198
+            $this->logger->debug('shareWith after, ' . $shareWith, ['app' => 'files_sharing']);
199
+
200
+            if (!$this->userManager->userExists($shareWith)) {
201
+                throw new ProviderCouldNotAddShareException('User does not exists', '',Http::STATUS_BAD_REQUEST);
202
+            }
203
+
204
+            \OC_Util::setupFS($shareWith);
205
+
206
+            $externalManager = new \OCA\Files_Sharing\External\Manager(
207
+                \OC::$server->getDatabaseConnection(),
208
+                Filesystem::getMountManager(),
209
+                Filesystem::getLoader(),
210
+                \OC::$server->getHTTPClientService(),
211
+                \OC::$server->getNotificationManager(),
212
+                \OC::$server->query(\OCP\OCS\IDiscoveryService::class),
213
+                \OC::$server->getCloudFederationProviderManager(),
214
+                \OC::$server->getCloudFederationFactory(),
215
+                $shareWith
216
+            );
217
+
218
+            try {
219
+                $externalManager->addShare($remote, $token, '', $name, $owner, false, $shareWith, $remoteId);
220
+                $shareId = \OC::$server->getDatabaseConnection()->lastInsertId('*PREFIX*share_external');
221
+
222
+                $event = $this->activityManager->generateEvent();
223
+                $event->setApp('files_sharing')
224
+                    ->setType('remote_share')
225
+                    ->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_RECEIVED, [$ownerFederatedId, trim($name, '/')])
226
+                    ->setAffectedUser($shareWith)
227
+                    ->setObject('remote_share', (int)$shareId, $name);
228
+                \OC::$server->getActivityManager()->publish($event);
229
+
230
+                $notification = $this->notificationManager->createNotification();
231
+                $notification->setApp('files_sharing')
232
+                    ->setUser($shareWith)
233
+                    ->setDateTime(new \DateTime())
234
+                    ->setObject('remote_share', $shareId)
235
+                    ->setSubject('remote_share', [$ownerFederatedId, $sharedByFederatedId, trim($name, '/')]);
236
+
237
+                $declineAction = $notification->createAction();
238
+                $declineAction->setLabel('decline')
239
+                    ->setLink($this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkTo('', 'ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/' . $shareId)), 'DELETE');
240
+                $notification->addAction($declineAction);
241
+
242
+                $acceptAction = $notification->createAction();
243
+                $acceptAction->setLabel('accept')
244
+                    ->setLink($this->urlGenerator->getAbsoluteURL($this->urlGenerator->linkTo('', 'ocs/v2.php/apps/files_sharing/api/v1/remote_shares/pending/' . $shareId)), 'POST');
245
+                $notification->addAction($acceptAction);
246
+
247
+                $this->notificationManager->notify($notification);
248
+
249
+                return $shareId;
250
+            } catch (\Exception $e) {
251
+                $this->logger->logException($e, [
252
+                    'message' => 'Server can not add remote share.',
253
+                    'level' => Util::ERROR,
254
+                    'app' => 'files_sharing'
255
+                ]);
256
+                throw new ProviderCouldNotAddShareException('internal server error, was not able to add share from ' . $remote, '', HTTP::STATUS_INTERNAL_SERVER_ERROR);
257
+            }
258
+        }
259
+
260
+        throw new ProviderCouldNotAddShareException('server can not add remote share, missing parameter', '', HTTP::STATUS_BAD_REQUEST);
261
+
262
+    }
263
+
264
+    /**
265
+     * notification received from another server
266
+     *
267
+     * @param string $notificationType (e.g. SHARE_ACCEPTED)
268
+     * @param string $providerId id of the share
269
+     * @param array $notification payload of the notification
270
+     * @return array data send back to the sender
271
+     *
272
+     * @throws ActionNotSupportedException
273
+     * @throws AuthenticationFailedException
274
+     * @throws BadRequestException
275
+     * @throws ShareNotFoundException
276
+     * @throws \OC\HintException
277
+     * @since 14.0.0
278
+     */
279
+    public function notificationReceived($notificationType, $providerId, array $notification) {
280
+
281
+        switch ($notificationType) {
282
+            case 'SHARE_ACCEPTED':
283
+                return $this->shareAccepted($providerId, $notification);
284
+            case 'SHARE_DECLINED':
285
+                return $this->shareDeclined($providerId, $notification);
286
+            case 'SHARE_UNSHARED':
287
+                return $this->unshare($providerId, $notification);
288
+            case 'REQUEST_RESHARE':
289
+                return $this->reshareRequested($providerId, $notification);
290
+            case 'RESHARE_UNDO':
291
+                return $this->undoReshare($providerId, $notification);
292
+            case 'RESHARE_CHANGE_PERMISSION':
293
+                return $this->updateResharePermissions($providerId, $notification);
294
+        }
295
+
296
+
297
+        throw new BadRequestException([$notificationType]);
298
+    }
299
+
300
+    /**
301
+     * process notification that the recipient accepted a share
302
+     *
303
+     * @param string $id
304
+     * @param array $notification
305
+     * @return array
306
+     * @throws ActionNotSupportedException
307
+     * @throws AuthenticationFailedException
308
+     * @throws BadRequestException
309
+     * @throws ShareNotFoundException
310
+     * @throws \OC\HintException
311
+     */
312
+    private function shareAccepted($id, $notification) {
313
+
314
+        if (!$this->isS2SEnabled()) {
315
+            throw new ActionNotSupportedException('Server does not support federated cloud sharing');
316
+        }
317
+
318
+        if (!isset($notification['sharedSecret'])) {
319
+            throw new BadRequestException(['sharedSecret']);
320
+        }
321
+
322
+        $token = $notification['sharedSecret'];
323
+
324
+        $share = $this->federatedShareProvider->getShareById($id);
325
+
326
+        $this->verifyShare($share, $token);
327
+        $this->executeAcceptShare($share);
328
+        if ($share->getShareOwner() !== $share->getSharedBy()) {
329
+            list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy());
330
+            $remoteId = $this->federatedShareProvider->getRemoteId($share);
331
+            $notification = $this->cloudFederationFactory->getCloudFederationNotification();
332
+            $notification->setMessage(
333
+                'SHARE_ACCEPTED',
334
+                'file',
335
+                $remoteId,
336
+                [
337
+                    'sharedSecret' => $token,
338
+                    'message' => 'Recipient accepted the re-share'
339
+                ]
340
+
341
+            );
342
+            $this->cloudFederationProviderManager->sendNotification($remote, $notification);
343
+
344
+        }
345
+
346
+        return [];
347
+    }
348
+
349
+    /**
350
+     * @param IShare $share
351
+     * @throws ShareNotFoundException
352
+     */
353
+    protected function executeAcceptShare(IShare $share) {
354
+        try {
355
+            $fileId = (int)$share->getNode()->getId();
356
+            list($file, $link) = $this->getFile($this->getCorrectUid($share), $fileId);
357
+        } catch (\Exception $e) {
358
+            throw new ShareNotFoundException();
359
+        }
360
+
361
+        $event = $this->activityManager->generateEvent();
362
+        $event->setApp('files_sharing')
363
+            ->setType('remote_share')
364
+            ->setAffectedUser($this->getCorrectUid($share))
365
+            ->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_ACCEPTED, [$share->getSharedWith(), [$fileId => $file]])
366
+            ->setObject('files', $fileId, $file)
367
+            ->setLink($link);
368
+        $this->activityManager->publish($event);
369
+    }
370
+
371
+    /**
372
+     * process notification that the recipient declined a share
373
+     *
374
+     * @param string $id
375
+     * @param array $notification
376
+     * @return array
377
+     * @throws ActionNotSupportedException
378
+     * @throws AuthenticationFailedException
379
+     * @throws BadRequestException
380
+     * @throws ShareNotFound
381
+     * @throws ShareNotFoundException
382
+     * @throws \OC\HintException
383
+     *
384
+     */
385
+    protected function shareDeclined($id, $notification) {
386
+
387
+        if (!$this->isS2SEnabled()) {
388
+            throw new ActionNotSupportedException('Server does not support federated cloud sharing');
389
+        }
390
+
391
+        if (!isset($notification['sharedSecret'])) {
392
+            throw new BadRequestException(['sharedSecret']);
393
+        }
394
+
395
+        $token = $notification['sharedSecret'];
396
+
397
+        $share = $this->federatedShareProvider->getShareById($id);
398
+
399
+        $this->verifyShare($share, $token);
400
+
401
+        if ($share->getShareOwner() !== $share->getSharedBy()) {
402
+            list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy());
403
+            $remoteId = $this->federatedShareProvider->getRemoteId($share);
404
+            $notification = $this->cloudFederationFactory->getCloudFederationNotification();
405
+            $notification->setMessage(
406
+                'SHARE_DECLINED',
407
+                'file',
408
+                $remoteId,
409
+                [
410
+                    'sharedSecret' => $token,
411
+                    'message' => 'Recipient declined the re-share'
412
+                ]
413
+
414
+            );
415
+            $this->cloudFederationProviderManager->sendNotification($remote, $notification);
416
+        }
417
+
418
+        $this->executeDeclineShare($share);
419
+
420
+        return [];
421
+
422
+    }
423
+
424
+    /**
425
+     * delete declined share and create a activity
426
+     *
427
+     * @param IShare $share
428
+     * @throws ShareNotFoundException
429
+     */
430
+    protected function executeDeclineShare(IShare $share) {
431
+        $this->federatedShareProvider->removeShareFromTable($share);
432
+
433
+        try {
434
+            $fileId = (int)$share->getNode()->getId();
435
+            list($file, $link) = $this->getFile($this->getCorrectUid($share), $fileId);
436
+        } catch (\Exception $e) {
437
+            throw new ShareNotFoundException();
438
+        }
439
+
440
+        $event = $this->activityManager->generateEvent();
441
+        $event->setApp('files_sharing')
442
+            ->setType('remote_share')
443
+            ->setAffectedUser($this->getCorrectUid($share))
444
+            ->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_DECLINED, [$share->getSharedWith(), [$fileId => $file]])
445
+            ->setObject('files', $fileId, $file)
446
+            ->setLink($link);
447
+        $this->activityManager->publish($event);
448
+
449
+    }
450
+
451
+    /**
452
+     * received the notification that the owner unshared a file from you
453
+     *
454
+     * @param string $id
455
+     * @param string $notification
456
+     * @return array
457
+     * @throws AuthenticationFailedException
458
+     * @throws BadRequestException
459
+     * @throws ShareNotFoundException
460
+     */
461
+    private function undoReshare($id, $notification) {
462
+        if (!isset($notification['sharedSecret'])) {
463
+            throw new BadRequestException(['sharedSecret']);
464
+        }
465
+        $token = $notification['sharedSecret'];
466
+
467
+        $share = $this->federatedShareProvider->getShareById($id);
468
+
469
+        $this->verifyShare($share, $token);
470
+        $this->federatedShareProvider->removeShareFromTable($share);
471
+        return [];
472
+    }
473
+
474
+    private function unshare($id, $notification) {
475
+
476
+        if (!$this->isS2SEnabled(true)) {
477
+            throw new ActionNotSupportedException("incoming shares disabled!");
478
+        }
479
+
480
+        if (!isset($notification['sharedSecret'])) {
481
+            throw new BadRequestException(['sharedSecret']);
482
+        }
483
+        $token = $notification['sharedSecret'];
484
+
485
+        $qb = $this->connection->getQueryBuilder();
486
+        $qb->select('*')
487
+            ->from('share_external')
488
+            ->where(
489
+                $qb->expr()->andX(
490
+                    $qb->expr()->eq('remote_id', $qb->createNamedParameter($id)),
491
+                    $qb->expr()->eq('share_token', $qb->createNamedParameter($token))
492
+                )
493
+            );
494
+
495
+        $result = $qb->execute();
496
+        $share = $result->fetch();
497
+        $result->closeCursor();
498
+
499
+        if ($token && $id && !empty($share)) {
500
+
501
+            $remote = $this->cleanupRemote($share['remote']);
502
+
503
+            $owner = $this->cloudIdManager->getCloudId($share['owner'], $remote);
504
+            $mountpoint = $share['mountpoint'];
505
+            $user = $share['user'];
506
+
507
+            $qb = $this->connection->getQueryBuilder();
508
+            $qb->delete('share_external')
509
+                ->where(
510
+                    $qb->expr()->andX(
511
+                        $qb->expr()->eq('remote_id', $qb->createNamedParameter($id)),
512
+                        $qb->expr()->eq('share_token', $qb->createNamedParameter($token))
513
+                    )
514
+                );
515
+
516
+            $qb->execute();
517
+
518
+            if ($share['accepted']) {
519
+                $path = trim($mountpoint, '/');
520
+            } else {
521
+                $path = trim($share['name'], '/');
522
+            }
523
+
524
+            $notification = $this->notificationManager->createNotification();
525
+            $notification->setApp('files_sharing')
526
+                ->setUser($share['user'])
527
+                ->setObject('remote_share', (int)$share['id']);
528
+            $this->notificationManager->markProcessed($notification);
529
+
530
+            $event = $this->activityManager->generateEvent();
531
+            $event->setApp('files_sharing')
532
+                ->setType('remote_share')
533
+                ->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_UNSHARED, [$owner->getId(), $path])
534
+                ->setAffectedUser($user)
535
+                ->setObject('remote_share', (int)$share['id'], $path);
536
+            \OC::$server->getActivityManager()->publish($event);
537
+        }
538
+
539
+        return [];
540
+    }
541
+
542
+    private function cleanupRemote($remote) {
543
+        $remote = substr($remote, strpos($remote, '://') + 3);
544
+
545
+        return rtrim($remote, '/');
546
+    }
547
+
548
+    /**
549
+     * recipient of a share request to re-share the file with another user
550
+     *
551
+     * @param $id
552
+     * @param $notification
553
+     * @return array
554
+     * @throws AuthenticationFailedException
555
+     * @throws BadRequestException
556
+     * @throws ProviderCouldNotAddShareException
557
+     * @throws ShareNotFoundException
558
+     * @throws ShareNotFound
559
+     */
560
+    protected function reshareRequested($id, $notification) {
561
+
562
+        if (!isset($notification['sharedSecret'])) {
563
+            throw new BadRequestException(['sharedSecret']);
564
+        }
565
+        $token = $notification['sharedSecret'];
566
+
567
+        if (!isset($notification['shareWith'])) {
568
+            throw new BadRequestException(['shareWith']);
569
+        }
570
+        $shareWith = $notification['shareWith'];
571
+
572
+        if (!isset($notification['senderId'])) {
573
+            throw new BadRequestException(['senderId']);
574
+        }
575
+        $senderId = $notification['senderId'];
576
+
577
+        $share = $this->federatedShareProvider->getShareById($id);
578
+        // don't allow to share a file back to the owner
579
+        try {
580
+            list($user, $remote) = $this->addressHandler->splitUserRemote($shareWith);
581
+            $owner = $share->getShareOwner();
582
+            $currentServer = $this->addressHandler->generateRemoteURL();
583
+            if ($this->addressHandler->compareAddresses($user, $remote, $owner, $currentServer)) {
584
+                throw new ProviderCouldNotAddShareException('Resharing back to the owner is not allowed: ' . $id);
585
+            }
586
+        } catch (\Exception $e) {
587
+            throw new ProviderCouldNotAddShareException($e->getMessage());
588
+        }
589
+
590
+        $this->verifyShare($share, $token);
591
+
592
+        // check if re-sharing is allowed
593
+        if ($share->getPermissions() & Constants::PERMISSION_SHARE) {
594
+            // the recipient of the initial share is now the initiator for the re-share
595
+            $share->setSharedBy($share->getSharedWith());
596
+            $share->setSharedWith($shareWith);
597
+            $result = $this->federatedShareProvider->create($share);
598
+            $this->federatedShareProvider->storeRemoteId((int)$result->getId(), $senderId);
599
+            return ['token' => $result->getToken(), 'providerId' => $result->getId()];
600
+        } else {
601
+            throw new ProviderCouldNotAddShareException('resharing not allowed for share: ' . $id);
602
+        }
603
+
604
+        throw new BadRequestException([]);
605
+    }
606
+
607
+    /**
608
+     * update permission of a re-share so that the share dialog shows the right
609
+     * permission if the owner or the sender changes the permission
610
+     *
611
+     * @param string $id
612
+     * @param array $notification
613
+     * @return array
614
+     * @throws AuthenticationFailedException
615
+     * @throws BadRequestException
616
+     * @throws ShareNotFoundException
617
+     */
618
+    protected function updateResharePermissions($id, $notification) {
619
+
620
+        if (!isset($notification['sharedSecret'])) {
621
+            throw new BadRequestException(['sharedSecret']);
622
+        }
623
+        $token = $notification['sharedSecret'];
624
+
625
+        if (!isset($notification['permission'])) {
626
+            throw new BadRequestException(['permission']);
627
+        }
628
+        $ocmPermissions = $notification['permission'];
629
+
630
+        $share = $this->federatedShareProvider->getShareById($id);
631
+
632
+        $ncPermission = $this->ocmPermissions2ncPermissions($ocmPermissions);
633
+
634
+        $this->verifyShare($share, $token);
635
+        $this->updatePermissionsInDatabase($share, $ncPermission);
636
+
637
+        return [];
638
+    }
639
+
640
+    /**
641
+     * translate OCM Permissions to Nextcloud permissions
642
+     *
643
+     * @param $ocmPermissions
644
+     * @return int
645
+     * @throws BadRequestException
646
+     */
647
+    protected function ocmPermissions2ncPermissions($ocmPermissions) {
648
+        error_log("ocm permissions: " . json_encode($ocmPermissions));
649
+        $ncPermissions = 0;
650
+        foreach($ocmPermissions as $permission) {
651
+            switch (strtolower($permission)) {
652
+                case 'read':
653
+                    $ncPermissions += Constants::PERMISSION_READ;
654
+                    break;
655
+                case 'write':
656
+                    $ncPermissions += Constants::PERMISSION_CREATE + Constants::PERMISSION_UPDATE;
657
+                    break;
658
+                case 'share':
659
+                    $ncPermissions += Constants::PERMISSION_SHARE;
660
+                    break;
661
+                default:
662
+                    throw new BadRequestException(['permission']);
663
+            }
664
+
665
+            error_log("new permissions: " . $ncPermissions);
666
+        }
667
+
668
+        return $ncPermissions;
669
+    }
670
+
671
+    /**
672
+     * update permissions in database
673
+     *
674
+     * @param IShare $share
675
+     * @param int $permissions
676
+     */
677
+    protected function updatePermissionsInDatabase(IShare $share, $permissions) {
678
+        $query = $this->connection->getQueryBuilder();
679
+        $query->update('share')
680
+            ->where($query->expr()->eq('id', $query->createNamedParameter($share->getId())))
681
+            ->set('permissions', $query->createNamedParameter($permissions))
682
+            ->execute();
683
+    }
684
+
685
+
686
+    /**
687
+     * get file
688
+     *
689
+     * @param string $user
690
+     * @param int $fileSource
691
+     * @return array with internal path of the file and a absolute link to it
692
+     */
693
+    private function getFile($user, $fileSource) {
694
+        \OC_Util::setupFS($user);
695
+
696
+        try {
697
+            $file = Filesystem::getPath($fileSource);
698
+        } catch (NotFoundException $e) {
699
+            $file = null;
700
+        }
701
+        $args = Filesystem::is_dir($file) ? array('dir' => $file) : array('dir' => dirname($file), 'scrollto' => $file);
702
+        $link = Util::linkToAbsolute('files', 'index.php', $args);
703
+
704
+        return array($file, $link);
705
+
706
+    }
707
+
708
+    /**
709
+     * check if we are the initiator or the owner of a re-share and return the correct UID
710
+     *
711
+     * @param IShare $share
712
+     * @return string
713
+     */
714
+    protected function getCorrectUid(IShare $share) {
715
+        if ($this->userManager->userExists($share->getShareOwner())) {
716
+            return $share->getShareOwner();
717
+        }
718
+
719
+        return $share->getSharedBy();
720
+    }
721
+
722
+
723
+
724
+    /**
725
+     * check if we got the right share
726
+     *
727
+     * @param IShare $share
728
+     * @param string $token
729
+     * @return bool
730
+     * @throws AuthenticationFailedException
731
+     */
732
+    protected function verifyShare(IShare $share, $token) {
733
+        if (
734
+            $share->getShareType() === FederatedShareProvider::SHARE_TYPE_REMOTE &&
735
+            $share->getToken() === $token
736
+        ) {
737
+            return true;
738
+        }
739
+
740
+        throw new AuthenticationFailedException();
741
+    }
742
+
743
+
744
+
745
+    /**
746
+     * check if server-to-server sharing is enabled
747
+     *
748
+     * @param bool $incoming
749
+     * @return bool
750
+     */
751
+    private function isS2SEnabled($incoming = false) {
752
+
753
+        $result = $this->appManager->isEnabledForUser('files_sharing');
754
+
755
+        if ($incoming) {
756
+            $result = $result && $this->federatedShareProvider->isIncomingServer2serverShareEnabled();
757
+        } else {
758
+            $result = $result && $this->federatedShareProvider->isOutgoingServer2serverShareEnabled();
759
+        }
760
+
761
+        return $result;
762
+    }
763 763
 
764 764
 
765 765
 }
Please login to merge, or discard this patch.
lib/public/Federation/ICloudFederationProvider.php 1 patch
Indentation   +35 added lines, -35 removed lines patch added patch discarded remove patch
@@ -39,42 +39,42 @@
 block discarded – undo
39 39
 
40 40
 interface ICloudFederationProvider {
41 41
 
42
-	/**
43
-	 * get the name of the share type, handled by this provider
44
-	 *
45
-	 * @return string
46
-	 *
47
-	 * @since 14.0.0
48
-	 */
49
-	public function getShareType();
42
+    /**
43
+     * get the name of the share type, handled by this provider
44
+     *
45
+     * @return string
46
+     *
47
+     * @since 14.0.0
48
+     */
49
+    public function getShareType();
50 50
 
51
-	/**
52
-	 * share received from another server
53
-	 *
54
-	 * @param ICloudFederationShare $share
55
-	 * @return string provider specific unique ID of the share
56
-	 *
57
-	 * @throws ProviderCouldNotAddShareException
58
-	 *
59
-	 * @since 14.0.0
60
-	 */
61
-	public function shareReceived(ICloudFederationShare $share);
51
+    /**
52
+     * share received from another server
53
+     *
54
+     * @param ICloudFederationShare $share
55
+     * @return string provider specific unique ID of the share
56
+     *
57
+     * @throws ProviderCouldNotAddShareException
58
+     *
59
+     * @since 14.0.0
60
+     */
61
+    public function shareReceived(ICloudFederationShare $share);
62 62
 
63
-	/**
64
-	 * notification received from another server
65
-	 *
66
-	 * @param string $notificationType (e.g SHARE_ACCEPTED)
67
-	 * @param string $providerId share ID
68
-	 * @param array $notification provider specific notification
69
-	 * @return array $data send back to sender
70
-	 *
71
-	 * @throws ShareNotFoundException
72
-	 * @throws ActionNotSupportedException
73
-	 * @throws BadRequestException
74
-	 * @throws AuthenticationFailedException
75
-	 *
76
-	 * @since 14.0.0
77
-	 */
78
-	public function notificationReceived($notificationType, $providerId, array $notification);
63
+    /**
64
+     * notification received from another server
65
+     *
66
+     * @param string $notificationType (e.g SHARE_ACCEPTED)
67
+     * @param string $providerId share ID
68
+     * @param array $notification provider specific notification
69
+     * @return array $data send back to sender
70
+     *
71
+     * @throws ShareNotFoundException
72
+     * @throws ActionNotSupportedException
73
+     * @throws BadRequestException
74
+     * @throws AuthenticationFailedException
75
+     *
76
+     * @since 14.0.0
77
+     */
78
+    public function notificationReceived($notificationType, $providerId, array $notification);
79 79
 
80 80
 }
Please login to merge, or discard this patch.
lib/public/Federation/ICloudFederationProviderManager.php 1 patch
Indentation   +64 added lines, -64 removed lines patch added patch discarded remove patch
@@ -32,76 +32,76 @@
 block discarded – undo
32 32
  */
33 33
 interface ICloudFederationProviderManager {
34 34
 
35
-	/**
36
-	 * Registers an callback function which must return an cloud federation provider
37
-	 *
38
-	 * @param string $shareType which share type does the provider handles
39
-	 * @param string $displayName user facing name of the federated share provider
40
-	 * @param callable $callback
41
-	 * @throws Exceptions\ProviderAlreadyExistsException
42
-	 *
43
-	 * @since 14.0.0
44
-	 */
45
-	public function addCloudFederationProvider($shareType, $displayName, callable $callback);
35
+    /**
36
+     * Registers an callback function which must return an cloud federation provider
37
+     *
38
+     * @param string $shareType which share type does the provider handles
39
+     * @param string $displayName user facing name of the federated share provider
40
+     * @param callable $callback
41
+     * @throws Exceptions\ProviderAlreadyExistsException
42
+     *
43
+     * @since 14.0.0
44
+     */
45
+    public function addCloudFederationProvider($shareType, $displayName, callable $callback);
46 46
 
47
-	/**
48
-	 * remove cloud federation provider
49
-	 *
50
-	 * @param string $shareType
51
-	 *
52
-	 * @since 14.0.0
53
-	 */
54
-	public function removeCloudFederationProvider($shareType);
47
+    /**
48
+     * remove cloud federation provider
49
+     *
50
+     * @param string $shareType
51
+     *
52
+     * @since 14.0.0
53
+     */
54
+    public function removeCloudFederationProvider($shareType);
55 55
 
56
-	/**
57
-	 * get a list of all cloudFederationProviders
58
-	 *
59
-	 * @return array [id => ['id' => $id, 'displayName' => $displayName, 'callback' => callback]]
60
-	 *
61
-	 * @since 14.0.0
62
-	 */
63
-	public function getAllCloudFederationProviders();
56
+    /**
57
+     * get a list of all cloudFederationProviders
58
+     *
59
+     * @return array [id => ['id' => $id, 'displayName' => $displayName, 'callback' => callback]]
60
+     *
61
+     * @since 14.0.0
62
+     */
63
+    public function getAllCloudFederationProviders();
64 64
 
65
-	/**
66
-	 * get a specific cloud federation provider
67
-	 *
68
-	 * @param string $shareType
69
-	 * @return ICloudFederationProvider
70
-	 * @throws Exceptions\ProviderDoesNotExistsException;
71
-	 *
72
-	 * @since 14.0.0
73
-	 */
74
-	public function getCloudFederationProvider($shareType);
65
+    /**
66
+     * get a specific cloud federation provider
67
+     *
68
+     * @param string $shareType
69
+     * @return ICloudFederationProvider
70
+     * @throws Exceptions\ProviderDoesNotExistsException;
71
+     *
72
+     * @since 14.0.0
73
+     */
74
+    public function getCloudFederationProvider($shareType);
75 75
 
76
-	/**
77
-	 * send federated share
78
-	 *
79
-	 * @param ICloudFederationShare $share
80
-	 * @return bool
81
-	 *
82
-	 * @since 14.0.0
83
-	 */
84
-	public function sendShare(ICloudFederationShare $share);
76
+    /**
77
+     * send federated share
78
+     *
79
+     * @param ICloudFederationShare $share
80
+     * @return bool
81
+     *
82
+     * @since 14.0.0
83
+     */
84
+    public function sendShare(ICloudFederationShare $share);
85 85
 
86
-	/**
87
-	 * send notification about existing share
88
-	 *
89
-	 * @param string $url
90
-	 * @param ICloudFederationNotification $notification
91
-	 * @return mixed
92
-	 *
93
-	 * @since 14.0.0
94
-	 */
95
-	public function sendNotification($url, ICloudFederationNotification $notification);
86
+    /**
87
+     * send notification about existing share
88
+     *
89
+     * @param string $url
90
+     * @param ICloudFederationNotification $notification
91
+     * @return mixed
92
+     *
93
+     * @since 14.0.0
94
+     */
95
+    public function sendNotification($url, ICloudFederationNotification $notification);
96 96
 
97
-	/**
98
-	 * check if the new cloud federation API is ready to be used
99
-	 *
100
-	 * @return bool
101
-	 *
102
-	 * @since 14.0.0
103
-	 */
104
-	public function isReady();
97
+    /**
98
+     * check if the new cloud federation API is ready to be used
99
+     *
100
+     * @return bool
101
+     *
102
+     * @since 14.0.0
103
+     */
104
+    public function isReady();
105 105
 
106 106
 
107 107
 }
Please login to merge, or discard this patch.
apps/federatedfilesharing/lib/Notifications.php 2 patches
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -117,7 +117,7 @@  discard block
 block discarded – undo
117 117
 			$ocsStatus = isset($status['ocs']);
118 118
 			$ocsSuccess = $ocsStatus && ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200);
119 119
 
120
-			if ($result['success'] && (!$ocsStatus ||$ocsSuccess)) {
120
+			if ($result['success'] && (!$ocsStatus || $ocsSuccess)) {
121 121
 				\OC_Hook::emit('OCP\Share', 'federated_share_added', ['server' => $remote]);
122 122
 				return true;
123 123
 			}
@@ -160,7 +160,7 @@  discard block
 block discarded – undo
160 160
 			return [$ocmResult['token'], $ocmResult['providerId']];
161 161
 		}
162 162
 
163
-		$result = $this->tryLegacyEndPoint(rtrim($remote, '/'), '/' . $id . '/reshare', $fields);
163
+		$result = $this->tryLegacyEndPoint(rtrim($remote, '/'), '/'.$id.'/reshare', $fields);
164 164
 		$status = json_decode($result['result'], true);
165 165
 
166 166
 		$httpRequestSuccessful = $result['success'];
@@ -171,7 +171,7 @@  discard block
 block discarded – undo
171 171
 		if ($httpRequestSuccessful && $ocsCallSuccessful && $validToken && $validRemoteId) {
172 172
 			return [
173 173
 				$status['ocs']['data']['token'],
174
-				(int)$status['ocs']['data']['remoteId']
174
+				(int) $status['ocs']['data']['remoteId']
175 175
 			];
176 176
 		}
177 177
 
@@ -258,7 +258,7 @@  discard block
 block discarded – undo
258 258
 			$fields[$key] = $value;
259 259
 		}
260 260
 
261
-		$result = $this->tryHttpPostToShareEndpoint(rtrim($remote, '/'), '/' . $remoteId . '/' . $action, $fields, $action);
261
+		$result = $this->tryHttpPostToShareEndpoint(rtrim($remote, '/'), '/'.$remoteId.'/'.$action, $fields, $action);
262 262
 		$status = json_decode($result['result'], true);
263 263
 
264 264
 		if ($result['success'] &&
@@ -306,10 +306,10 @@  discard block
 block discarded – undo
306 306
 	 * @return array
307 307
 	 * @throws \Exception
308 308
 	 */
309
-	protected function tryHttpPostToShareEndpoint($remoteDomain, $urlSuffix, array $fields, $action="share") {
309
+	protected function tryHttpPostToShareEndpoint($remoteDomain, $urlSuffix, array $fields, $action = "share") {
310 310
 
311 311
 		if ($this->addressHandler->urlContainProtocol($remoteDomain) === false) {
312
-			$remoteDomain = 'https://' . $remoteDomain;
312
+			$remoteDomain = 'https://'.$remoteDomain;
313 313
 		}
314 314
 
315 315
 		$result = [
@@ -348,7 +348,7 @@  discard block
 block discarded – undo
348 348
 		$federationEndpoints = $this->discoveryService->discover($remoteDomain, 'FEDERATED_SHARING');
349 349
 		$endpoint = isset($federationEndpoints['share']) ? $federationEndpoints['share'] : '/ocs/v2.php/cloud/shares';
350 350
 		try {
351
-			$response = $client->post($remoteDomain . $endpoint . $urlSuffix . '?format=' . self::RESPONSE_FORMAT, [
351
+			$response = $client->post($remoteDomain.$endpoint.$urlSuffix.'?format='.self::RESPONSE_FORMAT, [
352 352
 				'body' => $fields,
353 353
 				'timeout' => 10,
354 354
 				'connect_timeout' => 10,
@@ -405,7 +405,7 @@  discard block
 block discarded – undo
405 405
 		switch ($action) {
406 406
 			case 'share':
407 407
 				$share = $this->cloudFederationFactory->getCloudFederationShare(
408
-					$fields['shareWith'] . '@' . $remoteDomain,
408
+					$fields['shareWith'].'@'.$remoteDomain,
409 409
 					$fields['name'],
410 410
 					'',
411 411
 					$fields['remoteId'],
Please login to merge, or discard this patch.
Indentation   +430 added lines, -430 removed lines patch added patch discarded remove patch
@@ -33,434 +33,434 @@
 block discarded – undo
33 33
 use OCP\OCS\IDiscoveryService;
34 34
 
35 35
 class Notifications {
36
-	const RESPONSE_FORMAT = 'json'; // default response format for ocs calls
37
-
38
-	/** @var AddressHandler */
39
-	private $addressHandler;
40
-
41
-	/** @var IClientService */
42
-	private $httpClientService;
43
-
44
-	/** @var IDiscoveryService */
45
-	private $discoveryService;
46
-
47
-	/** @var IJobList  */
48
-	private $jobList;
49
-
50
-	/** @var ICloudFederationProviderManager */
51
-	private $federationProviderManager;
52
-
53
-	/** @var ICloudFederationFactory */
54
-	private $cloudFederationFactory;
55
-
56
-	/**
57
-	 * @param AddressHandler $addressHandler
58
-	 * @param IClientService $httpClientService
59
-	 * @param IDiscoveryService $discoveryService
60
-	 * @param IJobList $jobList
61
-	 * @param ICloudFederationProviderManager $federationProviderManager
62
-	 * @param ICloudFederationFactory $cloudFederationFactory
63
-	 */
64
-	public function __construct(
65
-		AddressHandler $addressHandler,
66
-		IClientService $httpClientService,
67
-		IDiscoveryService $discoveryService,
68
-		IJobList $jobList,
69
-		ICloudFederationProviderManager $federationProviderManager,
70
-		ICloudFederationFactory $cloudFederationFactory
71
-	) {
72
-		$this->addressHandler = $addressHandler;
73
-		$this->httpClientService = $httpClientService;
74
-		$this->discoveryService = $discoveryService;
75
-		$this->jobList = $jobList;
76
-		$this->federationProviderManager = $federationProviderManager;
77
-		$this->cloudFederationFactory = $cloudFederationFactory;
78
-	}
79
-
80
-	/**
81
-	 * send server-to-server share to remote server
82
-	 *
83
-	 * @param string $token
84
-	 * @param string $shareWith
85
-	 * @param string $name
86
-	 * @param int $remote_id
87
-	 * @param string $owner
88
-	 * @param string $ownerFederatedId
89
-	 * @param string $sharedBy
90
-	 * @param string $sharedByFederatedId
91
-	 * @return bool
92
-	 * @throws \OC\HintException
93
-	 * @throws \OC\ServerNotAvailableException
94
-	 */
95
-	public function sendRemoteShare($token, $shareWith, $name, $remote_id, $owner, $ownerFederatedId, $sharedBy, $sharedByFederatedId) {
96
-
97
-		list($user, $remote) = $this->addressHandler->splitUserRemote($shareWith);
98
-
99
-		if ($user && $remote) {
100
-			$local = $this->addressHandler->generateRemoteURL();
101
-
102
-			$fields = array(
103
-				'shareWith' => $user,
104
-				'token' => $token,
105
-				'name' => $name,
106
-				'remoteId' => $remote_id,
107
-				'owner' => $owner,
108
-				'ownerFederatedId' => $ownerFederatedId,
109
-				'sharedBy' => $sharedBy,
110
-				'sharedByFederatedId' => $sharedByFederatedId,
111
-				'remote' => $local,
112
-			);
113
-
114
-			$result = $this->tryHttpPostToShareEndpoint($remote, '', $fields);
115
-			$status = json_decode($result['result'], true);
116
-
117
-			$ocsStatus = isset($status['ocs']);
118
-			$ocsSuccess = $ocsStatus && ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200);
119
-
120
-			if ($result['success'] && (!$ocsStatus ||$ocsSuccess)) {
121
-				\OC_Hook::emit('OCP\Share', 'federated_share_added', ['server' => $remote]);
122
-				return true;
123
-			}
124
-
125
-		}
126
-
127
-		return false;
128
-	}
129
-
130
-	/**
131
-	 * ask owner to re-share the file with the given user
132
-	 *
133
-	 * @param string $token
134
-	 * @param int $id remote Id
135
-	 * @param int $shareId internal share Id
136
-	 * @param string $remote remote address of the owner
137
-	 * @param string $shareWith
138
-	 * @param int $permission
139
-	 * @param string $filename
140
-	 * @return bool
141
-	 * @throws \OC\HintException
142
-	 * @throws \OC\ServerNotAvailableException
143
-	 */
144
-	public function requestReShare($token, $id, $shareId, $remote, $shareWith, $permission, $filename) {
145
-
146
-		$fields = array(
147
-			'shareWith' => $shareWith,
148
-			'token' => $token,
149
-			'permission' => $permission,
150
-			'remoteId' => $shareId,
151
-		);
152
-
153
-		$ocmFields = $fields;
154
-		$ocmFields['remoteId'] = $id;
155
-		$ocmFields['localId'] = $shareId;
156
-		$ocmFields['name'] = $filename;
157
-
158
-		$ocmResult = $this->tryOCMEndPoint($remote, $ocmFields, 'reshare');
159
-		if (is_array($ocmResult) && isset($ocmResult['token']) && isset($ocmResult['providerId'])) {
160
-			return [$ocmResult['token'], $ocmResult['providerId']];
161
-		}
162
-
163
-		$result = $this->tryLegacyEndPoint(rtrim($remote, '/'), '/' . $id . '/reshare', $fields);
164
-		$status = json_decode($result['result'], true);
165
-
166
-		$httpRequestSuccessful = $result['success'];
167
-		$ocsCallSuccessful = $status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200;
168
-		$validToken = isset($status['ocs']['data']['token']) && is_string($status['ocs']['data']['token']);
169
-		$validRemoteId = isset($status['ocs']['data']['remoteId']);
170
-
171
-		if ($httpRequestSuccessful && $ocsCallSuccessful && $validToken && $validRemoteId) {
172
-			return [
173
-				$status['ocs']['data']['token'],
174
-				(int)$status['ocs']['data']['remoteId']
175
-			];
176
-		}
177
-
178
-		return false;
179
-	}
180
-
181
-	/**
182
-	 * send server-to-server unshare to remote server
183
-	 *
184
-	 * @param string $remote url
185
-	 * @param int $id share id
186
-	 * @param string $token
187
-	 * @return bool
188
-	 */
189
-	public function sendRemoteUnShare($remote, $id, $token) {
190
-		$this->sendUpdateToRemote($remote, $id, $token, 'unshare');
191
-	}
192
-
193
-	/**
194
-	 * send server-to-server unshare to remote server
195
-	 *
196
-	 * @param string $remote url
197
-	 * @param int $id share id
198
-	 * @param string $token
199
-	 * @return bool
200
-	 */
201
-	public function sendRevokeShare($remote, $id, $token) {
202
-		$this->sendUpdateToRemote($remote, $id, $token, 'reshare_undo');
203
-	}
204
-
205
-	/**
206
-	 * send notification to remote server if the permissions was changed
207
-	 *
208
-	 * @param string $remote
209
-	 * @param int $remoteId
210
-	 * @param string $token
211
-	 * @param int $permissions
212
-	 * @return bool
213
-	 */
214
-	public function sendPermissionChange($remote, $remoteId, $token, $permissions) {
215
-		$this->sendUpdateToRemote($remote, $remoteId, $token, 'permissions', ['permissions' => $permissions]);
216
-	}
217
-
218
-	/**
219
-	 * forward accept reShare to remote server
220
-	 *
221
-	 * @param string $remote
222
-	 * @param int $remoteId
223
-	 * @param string $token
224
-	 */
225
-	public function sendAcceptShare($remote, $remoteId, $token) {
226
-		$this->sendUpdateToRemote($remote, $remoteId, $token, 'accept');
227
-	}
228
-
229
-	/**
230
-	 * forward decline reShare to remote server
231
-	 *
232
-	 * @param string $remote
233
-	 * @param int $remoteId
234
-	 * @param string $token
235
-	 */
236
-	public function sendDeclineShare($remote, $remoteId, $token) {
237
-		$this->sendUpdateToRemote($remote, $remoteId, $token, 'decline');
238
-	}
239
-
240
-	/**
241
-	 * inform remote server whether server-to-server share was accepted/declined
242
-	 *
243
-	 * @param string $remote
244
-	 * @param string $token
245
-	 * @param int $remoteId Share id on the remote host
246
-	 * @param string $action possible actions: accept, decline, unshare, revoke, permissions
247
-	 * @param array $data
248
-	 * @param int $try
249
-	 * @return boolean
250
-	 */
251
-	public function sendUpdateToRemote($remote, $remoteId, $token, $action, $data = [], $try = 0) {
252
-
253
-		$fields = [
254
-			'token' => $token,
255
-			'remoteId' => $remoteId
256
-			];
257
-		foreach ($data as $key => $value) {
258
-			$fields[$key] = $value;
259
-		}
260
-
261
-		$result = $this->tryHttpPostToShareEndpoint(rtrim($remote, '/'), '/' . $remoteId . '/' . $action, $fields, $action);
262
-		$status = json_decode($result['result'], true);
263
-
264
-		if ($result['success'] &&
265
-			($status['ocs']['meta']['statuscode'] === 100 ||
266
-				$status['ocs']['meta']['statuscode'] === 200
267
-			)
268
-		) {
269
-			return true;
270
-		} elseif ($try === 0) {
271
-			// only add new job on first try
272
-			$this->jobList->add('OCA\FederatedFileSharing\BackgroundJob\RetryJob',
273
-				[
274
-					'remote' => $remote,
275
-					'remoteId' => $remoteId,
276
-					'token' => $token,
277
-					'action' => $action,
278
-					'data' => json_encode($data),
279
-					'try' => $try,
280
-					'lastRun' => $this->getTimestamp()
281
-				]
282
-			);
283
-		}
284
-
285
-		return false;
286
-	}
287
-
288
-
289
-	/**
290
-	 * return current timestamp
291
-	 *
292
-	 * @return int
293
-	 */
294
-	protected function getTimestamp() {
295
-		return time();
296
-	}
297
-
298
-	/**
299
-	 * try http post with the given protocol, if no protocol is given we pick
300
-	 * the secure one (https)
301
-	 *
302
-	 * @param string $remoteDomain
303
-	 * @param string $urlSuffix
304
-	 * @param array $fields post parameters
305
-	 * @param string $action define the action (possible values: share, reshare, accept, decline, unshare, revoke, permissions)
306
-	 * @return array
307
-	 * @throws \Exception
308
-	 */
309
-	protected function tryHttpPostToShareEndpoint($remoteDomain, $urlSuffix, array $fields, $action="share") {
310
-
311
-		if ($this->addressHandler->urlContainProtocol($remoteDomain) === false) {
312
-			$remoteDomain = 'https://' . $remoteDomain;
313
-		}
314
-
315
-		$result = [
316
-			'success' => false,
317
-			'result' => '',
318
-		];
319
-
320
-		// if possible we use the new OCM API
321
-		$ocmResult = $this->tryOCMEndPoint($remoteDomain, $fields, $action);
322
-		if (is_array($ocmResult)) {
323
-			$result['success'] = true;
324
-			$result['result'] = json_encode([
325
-				'ocs' => ['meta' => ['statuscode' => 200]]]);
326
-			return $result;
327
-		}
328
-
329
-		return $this->tryLegacyEndPoint($remoteDomain, $urlSuffix, $fields);
330
-	}
331
-
332
-	/**
333
-	 * try old federated sharing API if the OCM api doesn't work
334
-	 *
335
-	 * @param $remoteDomain
336
-	 * @param $urlSuffix
337
-	 * @param array $fields
338
-	 * @return mixed
339
-	 * @throws \Exception
340
-	 */
341
-	protected function tryLegacyEndPoint($remoteDomain, $urlSuffix, array $fields) {
342
-
343
-		$result = [
344
-			'success' => false,
345
-			'result' => '',
346
-		];
347
-
348
-		// Fall back to old API
349
-		$client = $this->httpClientService->newClient();
350
-		$federationEndpoints = $this->discoveryService->discover($remoteDomain, 'FEDERATED_SHARING');
351
-		$endpoint = isset($federationEndpoints['share']) ? $federationEndpoints['share'] : '/ocs/v2.php/cloud/shares';
352
-		try {
353
-			$response = $client->post($remoteDomain . $endpoint . $urlSuffix . '?format=' . self::RESPONSE_FORMAT, [
354
-				'body' => $fields,
355
-				'timeout' => 10,
356
-				'connect_timeout' => 10,
357
-			]);
358
-			$result['result'] = $response->getBody();
359
-			$result['success'] = true;
360
-		} catch (\Exception $e) {
361
-			// if flat re-sharing is not supported by the remote server
362
-			// we re-throw the exception and fall back to the old behaviour.
363
-			// (flat re-shares has been introduced in Nextcloud 9.1)
364
-			if ($e->getCode() === Http::STATUS_INTERNAL_SERVER_ERROR) {
365
-				throw $e;
366
-			}
367
-		}
368
-
369
-		return $result;
370
-
371
-	}
372
-
373
-	/**
374
-	 * check if server supports the new OCM api and ask for the correct end-point
375
-	 *
376
-	 * @param string $url
377
-	 * @return string
378
-	 */
379
-	protected function getOCMEndPoint($url) {
380
-		$client = $this->httpClientService->newClient();
381
-		try {
382
-			$response = $client->get($url, ['timeout' => 10, 'connect_timeout' => 10]);
383
-		} catch (\Exception $e) {
384
-			return '';
385
-		}
386
-
387
-		$result = $response->getBody();
388
-		$result = json_decode($result, true);
389
-
390
-		if (isset($result['end-point'])) {
391
-			return $result['end-point'];
392
-		}
393
-
394
-		return '';
395
-	}
396
-
397
-	/**
398
-	 * send action regarding federated sharing to the remote server using the OCM API
399
-	 *
400
-	 * @param $remoteDomain
401
-	 * @param $fields
402
-	 * @param $action
403
-	 *
404
-	 * @return bool
405
-	 */
406
-	protected function tryOCMEndPoint($remoteDomain, $fields, $action) {
407
-		switch ($action) {
408
-			case 'share':
409
-				$share = $this->cloudFederationFactory->getCloudFederationShare(
410
-					$fields['shareWith'] . '@' . $remoteDomain,
411
-					$fields['name'],
412
-					'',
413
-					$fields['remoteId'],
414
-					$fields['ownerFederatedId'],
415
-					$fields['owner'],
416
-					$fields['sharedByFederatedId'],
417
-					$fields['sharedBy'],
418
-					$fields['token'],
419
-					'user',
420
-					'file'
421
-				);
422
-				return $this->federationProviderManager->sendShare($share);
423
-			case 'reshare':
424
-				// ask owner to reshare a file
425
-				$notification = $this->cloudFederationFactory->getCloudFederationNotification();
426
-				$notification->setMessage('REQUEST_RESHARE',
427
-					'file',
428
-					$fields['remoteId'],
429
-					[
430
-						'sharedSecret' => $fields['token'],
431
-						'shareWith' => $fields['shareWith'],
432
-						'senderId' => $fields['localId'],
433
-						'message' => 'Ask owner to reshare the file'
434
-					]
435
-				);
436
-				return $this->federationProviderManager->sendNotification($remoteDomain, $notification);
437
-			case 'unshare':
438
-				//owner unshares the file from the recipient again
439
-				$notification = $this->cloudFederationFactory->getCloudFederationNotification();
440
-				$notification->setMessage('SHARE_UNSHARED',
441
-					'file',
442
-					$fields['remoteId'],
443
-					[
444
-						'sharedSecret' => $fields['token'],
445
-						'messgage' => 'file is no longer shared with you'
446
-					]
447
-				);
448
-				return $this->federationProviderManager->sendNotification($remoteDomain, $notification);
449
-			case 'reshare_undo':
450
-				// if a reshare was unshared we send the information to the initiator/owner
451
-				$notification = $this->cloudFederationFactory->getCloudFederationNotification();
452
-				$notification->setMessage('RESHARE_UNDO',
453
-					'file',
454
-					$fields['remoteId'],
455
-					[
456
-						'sharedSecret' => $fields['token'],
457
-						'message' => 'reshare was revoked'
458
-					]
459
-				);
460
-				return $this->federationProviderManager->sendNotification($remoteDomain, $notification);
461
-		}
462
-
463
-		return false;
464
-
465
-	}
36
+    const RESPONSE_FORMAT = 'json'; // default response format for ocs calls
37
+
38
+    /** @var AddressHandler */
39
+    private $addressHandler;
40
+
41
+    /** @var IClientService */
42
+    private $httpClientService;
43
+
44
+    /** @var IDiscoveryService */
45
+    private $discoveryService;
46
+
47
+    /** @var IJobList  */
48
+    private $jobList;
49
+
50
+    /** @var ICloudFederationProviderManager */
51
+    private $federationProviderManager;
52
+
53
+    /** @var ICloudFederationFactory */
54
+    private $cloudFederationFactory;
55
+
56
+    /**
57
+     * @param AddressHandler $addressHandler
58
+     * @param IClientService $httpClientService
59
+     * @param IDiscoveryService $discoveryService
60
+     * @param IJobList $jobList
61
+     * @param ICloudFederationProviderManager $federationProviderManager
62
+     * @param ICloudFederationFactory $cloudFederationFactory
63
+     */
64
+    public function __construct(
65
+        AddressHandler $addressHandler,
66
+        IClientService $httpClientService,
67
+        IDiscoveryService $discoveryService,
68
+        IJobList $jobList,
69
+        ICloudFederationProviderManager $federationProviderManager,
70
+        ICloudFederationFactory $cloudFederationFactory
71
+    ) {
72
+        $this->addressHandler = $addressHandler;
73
+        $this->httpClientService = $httpClientService;
74
+        $this->discoveryService = $discoveryService;
75
+        $this->jobList = $jobList;
76
+        $this->federationProviderManager = $federationProviderManager;
77
+        $this->cloudFederationFactory = $cloudFederationFactory;
78
+    }
79
+
80
+    /**
81
+     * send server-to-server share to remote server
82
+     *
83
+     * @param string $token
84
+     * @param string $shareWith
85
+     * @param string $name
86
+     * @param int $remote_id
87
+     * @param string $owner
88
+     * @param string $ownerFederatedId
89
+     * @param string $sharedBy
90
+     * @param string $sharedByFederatedId
91
+     * @return bool
92
+     * @throws \OC\HintException
93
+     * @throws \OC\ServerNotAvailableException
94
+     */
95
+    public function sendRemoteShare($token, $shareWith, $name, $remote_id, $owner, $ownerFederatedId, $sharedBy, $sharedByFederatedId) {
96
+
97
+        list($user, $remote) = $this->addressHandler->splitUserRemote($shareWith);
98
+
99
+        if ($user && $remote) {
100
+            $local = $this->addressHandler->generateRemoteURL();
101
+
102
+            $fields = array(
103
+                'shareWith' => $user,
104
+                'token' => $token,
105
+                'name' => $name,
106
+                'remoteId' => $remote_id,
107
+                'owner' => $owner,
108
+                'ownerFederatedId' => $ownerFederatedId,
109
+                'sharedBy' => $sharedBy,
110
+                'sharedByFederatedId' => $sharedByFederatedId,
111
+                'remote' => $local,
112
+            );
113
+
114
+            $result = $this->tryHttpPostToShareEndpoint($remote, '', $fields);
115
+            $status = json_decode($result['result'], true);
116
+
117
+            $ocsStatus = isset($status['ocs']);
118
+            $ocsSuccess = $ocsStatus && ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200);
119
+
120
+            if ($result['success'] && (!$ocsStatus ||$ocsSuccess)) {
121
+                \OC_Hook::emit('OCP\Share', 'federated_share_added', ['server' => $remote]);
122
+                return true;
123
+            }
124
+
125
+        }
126
+
127
+        return false;
128
+    }
129
+
130
+    /**
131
+     * ask owner to re-share the file with the given user
132
+     *
133
+     * @param string $token
134
+     * @param int $id remote Id
135
+     * @param int $shareId internal share Id
136
+     * @param string $remote remote address of the owner
137
+     * @param string $shareWith
138
+     * @param int $permission
139
+     * @param string $filename
140
+     * @return bool
141
+     * @throws \OC\HintException
142
+     * @throws \OC\ServerNotAvailableException
143
+     */
144
+    public function requestReShare($token, $id, $shareId, $remote, $shareWith, $permission, $filename) {
145
+
146
+        $fields = array(
147
+            'shareWith' => $shareWith,
148
+            'token' => $token,
149
+            'permission' => $permission,
150
+            'remoteId' => $shareId,
151
+        );
152
+
153
+        $ocmFields = $fields;
154
+        $ocmFields['remoteId'] = $id;
155
+        $ocmFields['localId'] = $shareId;
156
+        $ocmFields['name'] = $filename;
157
+
158
+        $ocmResult = $this->tryOCMEndPoint($remote, $ocmFields, 'reshare');
159
+        if (is_array($ocmResult) && isset($ocmResult['token']) && isset($ocmResult['providerId'])) {
160
+            return [$ocmResult['token'], $ocmResult['providerId']];
161
+        }
162
+
163
+        $result = $this->tryLegacyEndPoint(rtrim($remote, '/'), '/' . $id . '/reshare', $fields);
164
+        $status = json_decode($result['result'], true);
165
+
166
+        $httpRequestSuccessful = $result['success'];
167
+        $ocsCallSuccessful = $status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200;
168
+        $validToken = isset($status['ocs']['data']['token']) && is_string($status['ocs']['data']['token']);
169
+        $validRemoteId = isset($status['ocs']['data']['remoteId']);
170
+
171
+        if ($httpRequestSuccessful && $ocsCallSuccessful && $validToken && $validRemoteId) {
172
+            return [
173
+                $status['ocs']['data']['token'],
174
+                (int)$status['ocs']['data']['remoteId']
175
+            ];
176
+        }
177
+
178
+        return false;
179
+    }
180
+
181
+    /**
182
+     * send server-to-server unshare to remote server
183
+     *
184
+     * @param string $remote url
185
+     * @param int $id share id
186
+     * @param string $token
187
+     * @return bool
188
+     */
189
+    public function sendRemoteUnShare($remote, $id, $token) {
190
+        $this->sendUpdateToRemote($remote, $id, $token, 'unshare');
191
+    }
192
+
193
+    /**
194
+     * send server-to-server unshare to remote server
195
+     *
196
+     * @param string $remote url
197
+     * @param int $id share id
198
+     * @param string $token
199
+     * @return bool
200
+     */
201
+    public function sendRevokeShare($remote, $id, $token) {
202
+        $this->sendUpdateToRemote($remote, $id, $token, 'reshare_undo');
203
+    }
204
+
205
+    /**
206
+     * send notification to remote server if the permissions was changed
207
+     *
208
+     * @param string $remote
209
+     * @param int $remoteId
210
+     * @param string $token
211
+     * @param int $permissions
212
+     * @return bool
213
+     */
214
+    public function sendPermissionChange($remote, $remoteId, $token, $permissions) {
215
+        $this->sendUpdateToRemote($remote, $remoteId, $token, 'permissions', ['permissions' => $permissions]);
216
+    }
217
+
218
+    /**
219
+     * forward accept reShare to remote server
220
+     *
221
+     * @param string $remote
222
+     * @param int $remoteId
223
+     * @param string $token
224
+     */
225
+    public function sendAcceptShare($remote, $remoteId, $token) {
226
+        $this->sendUpdateToRemote($remote, $remoteId, $token, 'accept');
227
+    }
228
+
229
+    /**
230
+     * forward decline reShare to remote server
231
+     *
232
+     * @param string $remote
233
+     * @param int $remoteId
234
+     * @param string $token
235
+     */
236
+    public function sendDeclineShare($remote, $remoteId, $token) {
237
+        $this->sendUpdateToRemote($remote, $remoteId, $token, 'decline');
238
+    }
239
+
240
+    /**
241
+     * inform remote server whether server-to-server share was accepted/declined
242
+     *
243
+     * @param string $remote
244
+     * @param string $token
245
+     * @param int $remoteId Share id on the remote host
246
+     * @param string $action possible actions: accept, decline, unshare, revoke, permissions
247
+     * @param array $data
248
+     * @param int $try
249
+     * @return boolean
250
+     */
251
+    public function sendUpdateToRemote($remote, $remoteId, $token, $action, $data = [], $try = 0) {
252
+
253
+        $fields = [
254
+            'token' => $token,
255
+            'remoteId' => $remoteId
256
+            ];
257
+        foreach ($data as $key => $value) {
258
+            $fields[$key] = $value;
259
+        }
260
+
261
+        $result = $this->tryHttpPostToShareEndpoint(rtrim($remote, '/'), '/' . $remoteId . '/' . $action, $fields, $action);
262
+        $status = json_decode($result['result'], true);
263
+
264
+        if ($result['success'] &&
265
+            ($status['ocs']['meta']['statuscode'] === 100 ||
266
+                $status['ocs']['meta']['statuscode'] === 200
267
+            )
268
+        ) {
269
+            return true;
270
+        } elseif ($try === 0) {
271
+            // only add new job on first try
272
+            $this->jobList->add('OCA\FederatedFileSharing\BackgroundJob\RetryJob',
273
+                [
274
+                    'remote' => $remote,
275
+                    'remoteId' => $remoteId,
276
+                    'token' => $token,
277
+                    'action' => $action,
278
+                    'data' => json_encode($data),
279
+                    'try' => $try,
280
+                    'lastRun' => $this->getTimestamp()
281
+                ]
282
+            );
283
+        }
284
+
285
+        return false;
286
+    }
287
+
288
+
289
+    /**
290
+     * return current timestamp
291
+     *
292
+     * @return int
293
+     */
294
+    protected function getTimestamp() {
295
+        return time();
296
+    }
297
+
298
+    /**
299
+     * try http post with the given protocol, if no protocol is given we pick
300
+     * the secure one (https)
301
+     *
302
+     * @param string $remoteDomain
303
+     * @param string $urlSuffix
304
+     * @param array $fields post parameters
305
+     * @param string $action define the action (possible values: share, reshare, accept, decline, unshare, revoke, permissions)
306
+     * @return array
307
+     * @throws \Exception
308
+     */
309
+    protected function tryHttpPostToShareEndpoint($remoteDomain, $urlSuffix, array $fields, $action="share") {
310
+
311
+        if ($this->addressHandler->urlContainProtocol($remoteDomain) === false) {
312
+            $remoteDomain = 'https://' . $remoteDomain;
313
+        }
314
+
315
+        $result = [
316
+            'success' => false,
317
+            'result' => '',
318
+        ];
319
+
320
+        // if possible we use the new OCM API
321
+        $ocmResult = $this->tryOCMEndPoint($remoteDomain, $fields, $action);
322
+        if (is_array($ocmResult)) {
323
+            $result['success'] = true;
324
+            $result['result'] = json_encode([
325
+                'ocs' => ['meta' => ['statuscode' => 200]]]);
326
+            return $result;
327
+        }
328
+
329
+        return $this->tryLegacyEndPoint($remoteDomain, $urlSuffix, $fields);
330
+    }
331
+
332
+    /**
333
+     * try old federated sharing API if the OCM api doesn't work
334
+     *
335
+     * @param $remoteDomain
336
+     * @param $urlSuffix
337
+     * @param array $fields
338
+     * @return mixed
339
+     * @throws \Exception
340
+     */
341
+    protected function tryLegacyEndPoint($remoteDomain, $urlSuffix, array $fields) {
342
+
343
+        $result = [
344
+            'success' => false,
345
+            'result' => '',
346
+        ];
347
+
348
+        // Fall back to old API
349
+        $client = $this->httpClientService->newClient();
350
+        $federationEndpoints = $this->discoveryService->discover($remoteDomain, 'FEDERATED_SHARING');
351
+        $endpoint = isset($federationEndpoints['share']) ? $federationEndpoints['share'] : '/ocs/v2.php/cloud/shares';
352
+        try {
353
+            $response = $client->post($remoteDomain . $endpoint . $urlSuffix . '?format=' . self::RESPONSE_FORMAT, [
354
+                'body' => $fields,
355
+                'timeout' => 10,
356
+                'connect_timeout' => 10,
357
+            ]);
358
+            $result['result'] = $response->getBody();
359
+            $result['success'] = true;
360
+        } catch (\Exception $e) {
361
+            // if flat re-sharing is not supported by the remote server
362
+            // we re-throw the exception and fall back to the old behaviour.
363
+            // (flat re-shares has been introduced in Nextcloud 9.1)
364
+            if ($e->getCode() === Http::STATUS_INTERNAL_SERVER_ERROR) {
365
+                throw $e;
366
+            }
367
+        }
368
+
369
+        return $result;
370
+
371
+    }
372
+
373
+    /**
374
+     * check if server supports the new OCM api and ask for the correct end-point
375
+     *
376
+     * @param string $url
377
+     * @return string
378
+     */
379
+    protected function getOCMEndPoint($url) {
380
+        $client = $this->httpClientService->newClient();
381
+        try {
382
+            $response = $client->get($url, ['timeout' => 10, 'connect_timeout' => 10]);
383
+        } catch (\Exception $e) {
384
+            return '';
385
+        }
386
+
387
+        $result = $response->getBody();
388
+        $result = json_decode($result, true);
389
+
390
+        if (isset($result['end-point'])) {
391
+            return $result['end-point'];
392
+        }
393
+
394
+        return '';
395
+    }
396
+
397
+    /**
398
+     * send action regarding federated sharing to the remote server using the OCM API
399
+     *
400
+     * @param $remoteDomain
401
+     * @param $fields
402
+     * @param $action
403
+     *
404
+     * @return bool
405
+     */
406
+    protected function tryOCMEndPoint($remoteDomain, $fields, $action) {
407
+        switch ($action) {
408
+            case 'share':
409
+                $share = $this->cloudFederationFactory->getCloudFederationShare(
410
+                    $fields['shareWith'] . '@' . $remoteDomain,
411
+                    $fields['name'],
412
+                    '',
413
+                    $fields['remoteId'],
414
+                    $fields['ownerFederatedId'],
415
+                    $fields['owner'],
416
+                    $fields['sharedByFederatedId'],
417
+                    $fields['sharedBy'],
418
+                    $fields['token'],
419
+                    'user',
420
+                    'file'
421
+                );
422
+                return $this->federationProviderManager->sendShare($share);
423
+            case 'reshare':
424
+                // ask owner to reshare a file
425
+                $notification = $this->cloudFederationFactory->getCloudFederationNotification();
426
+                $notification->setMessage('REQUEST_RESHARE',
427
+                    'file',
428
+                    $fields['remoteId'],
429
+                    [
430
+                        'sharedSecret' => $fields['token'],
431
+                        'shareWith' => $fields['shareWith'],
432
+                        'senderId' => $fields['localId'],
433
+                        'message' => 'Ask owner to reshare the file'
434
+                    ]
435
+                );
436
+                return $this->federationProviderManager->sendNotification($remoteDomain, $notification);
437
+            case 'unshare':
438
+                //owner unshares the file from the recipient again
439
+                $notification = $this->cloudFederationFactory->getCloudFederationNotification();
440
+                $notification->setMessage('SHARE_UNSHARED',
441
+                    'file',
442
+                    $fields['remoteId'],
443
+                    [
444
+                        'sharedSecret' => $fields['token'],
445
+                        'messgage' => 'file is no longer shared with you'
446
+                    ]
447
+                );
448
+                return $this->federationProviderManager->sendNotification($remoteDomain, $notification);
449
+            case 'reshare_undo':
450
+                // if a reshare was unshared we send the information to the initiator/owner
451
+                $notification = $this->cloudFederationFactory->getCloudFederationNotification();
452
+                $notification->setMessage('RESHARE_UNDO',
453
+                    'file',
454
+                    $fields['remoteId'],
455
+                    [
456
+                        'sharedSecret' => $fields['token'],
457
+                        'message' => 'reshare was revoked'
458
+                    ]
459
+                );
460
+                return $this->federationProviderManager->sendNotification($remoteDomain, $notification);
461
+        }
462
+
463
+        return false;
464
+
465
+    }
466 466
 }
Please login to merge, or discard this patch.
apps/federatedfilesharing/lib/AppInfo/Application.php 1 patch
Indentation   +102 added lines, -102 removed lines patch added patch discarded remove patch
@@ -39,114 +39,114 @@
 block discarded – undo
39 39
 
40 40
 class Application extends App {
41 41
 
42
-	/** @var FederatedShareProvider */
43
-	protected $federatedShareProvider;
42
+    /** @var FederatedShareProvider */
43
+    protected $federatedShareProvider;
44 44
 
45
-	public function __construct() {
46
-		parent::__construct('federatedfilesharing');
45
+    public function __construct() {
46
+        parent::__construct('federatedfilesharing');
47 47
 
48
-		$container = $this->getContainer();
49
-		$server = $container->getServer();
48
+        $container = $this->getContainer();
49
+        $server = $container->getServer();
50 50
 
51
-		$cloudFederationManager = $server->getCloudFederationProviderManager();
52
-		$cloudFederationManager->addCloudFederationProvider('file',
53
-			'Federated Files Sharing',
54
-			function() use ($container) {
55
-				$server = $container->getServer();
56
-				return new CloudFederationProviderFiles(
57
-					$server->getAppManager(),
58
-					$server->query(FederatedShareProvider::class),
59
-					$server->query(AddressHandler::class),
60
-					$server->getLogger(),
61
-					$server->getUserManager(),
62
-					$server->getCloudIdManager(),
63
-					$server->getActivityManager(),
64
-					$server->getNotificationManager(),
65
-					$server->getURLGenerator(),
66
-					$server->getCloudFederationFactory(),
67
-					$server->getCloudFederationProviderManager(),
68
-					$server->getDatabaseConnection()
69
-				);
70
-			});
51
+        $cloudFederationManager = $server->getCloudFederationProviderManager();
52
+        $cloudFederationManager->addCloudFederationProvider('file',
53
+            'Federated Files Sharing',
54
+            function() use ($container) {
55
+                $server = $container->getServer();
56
+                return new CloudFederationProviderFiles(
57
+                    $server->getAppManager(),
58
+                    $server->query(FederatedShareProvider::class),
59
+                    $server->query(AddressHandler::class),
60
+                    $server->getLogger(),
61
+                    $server->getUserManager(),
62
+                    $server->getCloudIdManager(),
63
+                    $server->getActivityManager(),
64
+                    $server->getNotificationManager(),
65
+                    $server->getURLGenerator(),
66
+                    $server->getCloudFederationFactory(),
67
+                    $server->getCloudFederationProviderManager(),
68
+                    $server->getDatabaseConnection()
69
+                );
70
+            });
71 71
 
72
-		$container->registerService('RequestHandlerController', function(SimpleContainer $c) use ($server) {
73
-			$addressHandler = new AddressHandler(
74
-				$server->getURLGenerator(),
75
-				$server->getL10N('federatedfilesharing'),
76
-				$server->getCloudIdManager()
77
-			);
78
-			$notification = new Notifications(
79
-				$addressHandler,
80
-				$server->getHTTPClientService(),
81
-				$server->query(\OCP\OCS\IDiscoveryService::class),
82
-				\OC::$server->getJobList(),
83
-				\OC::$server->getCloudFederationProviderManager(),
84
-				\OC::$server->getCloudFederationFactory()
85
-			);
86
-			return new RequestHandlerController(
87
-				$c->query('AppName'),
88
-				$server->getRequest(),
89
-				$this->getFederatedShareProvider(),
90
-				$server->getDatabaseConnection(),
91
-				$server->getShareManager(),
92
-				$notification,
93
-				$addressHandler,
94
-				$server->getUserManager(),
95
-				$server->getCloudIdManager(),
96
-				$server->getLogger(),
97
-				$server->getCloudFederationFactory(),
98
-				$server->getCloudFederationProviderManager()
99
-			);
100
-		});
101
-	}
72
+        $container->registerService('RequestHandlerController', function(SimpleContainer $c) use ($server) {
73
+            $addressHandler = new AddressHandler(
74
+                $server->getURLGenerator(),
75
+                $server->getL10N('federatedfilesharing'),
76
+                $server->getCloudIdManager()
77
+            );
78
+            $notification = new Notifications(
79
+                $addressHandler,
80
+                $server->getHTTPClientService(),
81
+                $server->query(\OCP\OCS\IDiscoveryService::class),
82
+                \OC::$server->getJobList(),
83
+                \OC::$server->getCloudFederationProviderManager(),
84
+                \OC::$server->getCloudFederationFactory()
85
+            );
86
+            return new RequestHandlerController(
87
+                $c->query('AppName'),
88
+                $server->getRequest(),
89
+                $this->getFederatedShareProvider(),
90
+                $server->getDatabaseConnection(),
91
+                $server->getShareManager(),
92
+                $notification,
93
+                $addressHandler,
94
+                $server->getUserManager(),
95
+                $server->getCloudIdManager(),
96
+                $server->getLogger(),
97
+                $server->getCloudFederationFactory(),
98
+                $server->getCloudFederationProviderManager()
99
+            );
100
+        });
101
+    }
102 102
 
103
-	/**
104
-	 * get instance of federated share provider
105
-	 *
106
-	 * @return FederatedShareProvider
107
-	 */
108
-	public function getFederatedShareProvider() {
109
-		if ($this->federatedShareProvider === null) {
110
-			$this->initFederatedShareProvider();
111
-		}
112
-		return $this->federatedShareProvider;
113
-	}
103
+    /**
104
+     * get instance of federated share provider
105
+     *
106
+     * @return FederatedShareProvider
107
+     */
108
+    public function getFederatedShareProvider() {
109
+        if ($this->federatedShareProvider === null) {
110
+            $this->initFederatedShareProvider();
111
+        }
112
+        return $this->federatedShareProvider;
113
+    }
114 114
 
115
-	/**
116
-	 * initialize federated share provider
117
-	 */
118
-	protected function initFederatedShareProvider() {
119
-		$c = $this->getContainer();
120
-		$addressHandler = new \OCA\FederatedFileSharing\AddressHandler(
121
-			\OC::$server->getURLGenerator(),
122
-			\OC::$server->getL10N('federatedfilesharing'),
123
-			\OC::$server->getCloudIdManager()
124
-		);
125
-		$notifications = new \OCA\FederatedFileSharing\Notifications(
126
-			$addressHandler,
127
-			\OC::$server->getHTTPClientService(),
128
-			\OC::$server->query(\OCP\OCS\IDiscoveryService::class),
129
-			\OC::$server->getJobList(),
130
-			\OC::$server->getCloudFederationProviderManager(),
131
-			\OC::$server->getCloudFederationFactory()
132
-		);
133
-		$tokenHandler = new \OCA\FederatedFileSharing\TokenHandler(
134
-			\OC::$server->getSecureRandom()
135
-		);
115
+    /**
116
+     * initialize federated share provider
117
+     */
118
+    protected function initFederatedShareProvider() {
119
+        $c = $this->getContainer();
120
+        $addressHandler = new \OCA\FederatedFileSharing\AddressHandler(
121
+            \OC::$server->getURLGenerator(),
122
+            \OC::$server->getL10N('federatedfilesharing'),
123
+            \OC::$server->getCloudIdManager()
124
+        );
125
+        $notifications = new \OCA\FederatedFileSharing\Notifications(
126
+            $addressHandler,
127
+            \OC::$server->getHTTPClientService(),
128
+            \OC::$server->query(\OCP\OCS\IDiscoveryService::class),
129
+            \OC::$server->getJobList(),
130
+            \OC::$server->getCloudFederationProviderManager(),
131
+            \OC::$server->getCloudFederationFactory()
132
+        );
133
+        $tokenHandler = new \OCA\FederatedFileSharing\TokenHandler(
134
+            \OC::$server->getSecureRandom()
135
+        );
136 136
 
137
-		$this->federatedShareProvider = new \OCA\FederatedFileSharing\FederatedShareProvider(
138
-			\OC::$server->getDatabaseConnection(),
139
-			$addressHandler,
140
-			$notifications,
141
-			$tokenHandler,
142
-			\OC::$server->getL10N('federatedfilesharing'),
143
-			\OC::$server->getLogger(),
144
-			\OC::$server->getLazyRootFolder(),
145
-			\OC::$server->getConfig(),
146
-			\OC::$server->getUserManager(),
147
-			\OC::$server->getCloudIdManager(),
148
-			$c->query(IConfig::class)
149
-		);
150
-	}
137
+        $this->federatedShareProvider = new \OCA\FederatedFileSharing\FederatedShareProvider(
138
+            \OC::$server->getDatabaseConnection(),
139
+            $addressHandler,
140
+            $notifications,
141
+            $tokenHandler,
142
+            \OC::$server->getL10N('federatedfilesharing'),
143
+            \OC::$server->getLogger(),
144
+            \OC::$server->getLazyRootFolder(),
145
+            \OC::$server->getConfig(),
146
+            \OC::$server->getUserManager(),
147
+            \OC::$server->getCloudIdManager(),
148
+            $c->query(IConfig::class)
149
+        );
150
+    }
151 151
 
152 152
 }
Please login to merge, or discard this patch.
apps/federatedfilesharing/lib/Controller/RequestHandlerController.php 4 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -450,7 +450,7 @@
 block discarded – undo
450 450
 	/**
451 451
 	 * translate Nextcloud permissions to OCM Permissions
452 452
 	 *
453
-	 * @param $ncPermissions
453
+	 * @param integer $ncPermissions
454 454
 	 * @return array
455 455
 	 */
456 456
 	protected function ncPermissions2ocmPermissions($ncPermissions) {
Please login to merge, or discard this patch.
Unused Use Statements   -5 removed lines patch added patch discarded remove patch
@@ -29,7 +29,6 @@  discard block
 block discarded – undo
29 29
 
30 30
 namespace OCA\FederatedFileSharing\Controller;
31 31
 
32
-use OCA\Files_Sharing\Activity\Providers\RemoteShares;
33 32
 use OCA\FederatedFileSharing\AddressHandler;
34 33
 use OCA\FederatedFileSharing\FederatedShareProvider;
35 34
 use OCA\FederatedFileSharing\Notifications;
@@ -40,21 +39,17 @@  discard block
 block discarded – undo
40 39
 use OCP\AppFramework\OCS\OCSNotFoundException;
41 40
 use OCP\AppFramework\OCSController;
42 41
 use OCP\Constants;
43
-use OCP\Federation\Exceptions\AuthenticationFailedException;
44
-use OCP\Federation\Exceptions\BadRequestException;
45 42
 use OCP\Federation\Exceptions\ProviderCouldNotAddShareException;
46 43
 use OCP\Federation\Exceptions\ProviderDoesNotExistsException;
47 44
 use OCP\Federation\Exceptions\ShareNotFoundException;
48 45
 use OCP\Federation\ICloudFederationFactory;
49 46
 use OCP\Federation\ICloudFederationProviderManager;
50 47
 use OCP\Federation\ICloudIdManager;
51
-use OCP\Files\NotFoundException;
52 48
 use OCP\IDBConnection;
53 49
 use OCP\ILogger;
54 50
 use OCP\IRequest;
55 51
 use OCP\IUserManager;
56 52
 use OCP\Share;
57
-use OCP\Share\IShare;
58 53
 
59 54
 class RequestHandlerController extends OCSController {
60 55
 
Please login to merge, or discard this patch.
Indentation   +453 added lines, -453 removed lines patch added patch discarded remove patch
@@ -58,457 +58,457 @@
 block discarded – undo
58 58
 
59 59
 class RequestHandlerController extends OCSController {
60 60
 
61
-	/** @var FederatedShareProvider */
62
-	private $federatedShareProvider;
63
-
64
-	/** @var IDBConnection */
65
-	private $connection;
66
-
67
-	/** @var Share\IManager */
68
-	private $shareManager;
69
-
70
-	/** @var Notifications */
71
-	private $notifications;
72
-
73
-	/** @var AddressHandler */
74
-	private $addressHandler;
75
-
76
-	/** @var  IUserManager */
77
-	private $userManager;
78
-
79
-	/** @var string */
80
-	private $shareTable = 'share';
81
-
82
-	/** @var ICloudIdManager */
83
-	private $cloudIdManager;
84
-
85
-	/** @var ILogger */
86
-	private $logger;
87
-
88
-	/** @var ICloudFederationFactory */
89
-	private $cloudFederationFactory;
90
-
91
-	/** @var ICloudFederationProviderManager */
92
-	private $cloudFederationProviderManager;
93
-
94
-	/**
95
-	 * Server2Server constructor.
96
-	 *
97
-	 * @param string $appName
98
-	 * @param IRequest $request
99
-	 * @param FederatedShareProvider $federatedShareProvider
100
-	 * @param IDBConnection $connection
101
-	 * @param Share\IManager $shareManager
102
-	 * @param Notifications $notifications
103
-	 * @param AddressHandler $addressHandler
104
-	 * @param IUserManager $userManager
105
-	 * @param ICloudIdManager $cloudIdManager
106
-	 * @param ILogger $logger
107
-	 * @param ICloudFederationFactory $cloudFederationFactory
108
-	 * @param ICloudFederationProviderManager $cloudFederationProviderManager
109
-	 */
110
-	public function __construct($appName,
111
-								IRequest $request,
112
-								FederatedShareProvider $federatedShareProvider,
113
-								IDBConnection $connection,
114
-								Share\IManager $shareManager,
115
-								Notifications $notifications,
116
-								AddressHandler $addressHandler,
117
-								IUserManager $userManager,
118
-								ICloudIdManager $cloudIdManager,
119
-								ILogger $logger,
120
-								ICloudFederationFactory $cloudFederationFactory,
121
-								ICloudFederationProviderManager $cloudFederationProviderManager
122
-	) {
123
-		parent::__construct($appName, $request);
124
-
125
-		$this->federatedShareProvider = $federatedShareProvider;
126
-		$this->connection = $connection;
127
-		$this->shareManager = $shareManager;
128
-		$this->notifications = $notifications;
129
-		$this->addressHandler = $addressHandler;
130
-		$this->userManager = $userManager;
131
-		$this->cloudIdManager = $cloudIdManager;
132
-		$this->logger = $logger;
133
-		$this->cloudFederationFactory = $cloudFederationFactory;
134
-		$this->cloudFederationProviderManager = $cloudFederationProviderManager;
135
-	}
136
-
137
-	/**
138
-	 * @NoCSRFRequired
139
-	 * @PublicPage
140
-	 *
141
-	 * create a new share
142
-	 *
143
-	 * @return Http\DataResponse
144
-	 * @throws OCSException
145
-	 */
146
-	public function createShare() {
147
-
148
-		$remote = isset($_POST['remote']) ? $_POST['remote'] : null;
149
-		$token = isset($_POST['token']) ? $_POST['token'] : null;
150
-		$name = isset($_POST['name']) ? $_POST['name'] : null;
151
-		$owner = isset($_POST['owner']) ? $_POST['owner'] : null;
152
-		$sharedBy = isset($_POST['sharedBy']) ? $_POST['sharedBy'] : null;
153
-		$shareWith = isset($_POST['shareWith']) ? $_POST['shareWith'] : null;
154
-		$remoteId = isset($_POST['remoteId']) ? (int)$_POST['remoteId'] : null;
155
-		$sharedByFederatedId = isset($_POST['sharedByFederatedId']) ? $_POST['sharedByFederatedId'] : null;
156
-		$ownerFederatedId = isset($_POST['ownerFederatedId']) ? $_POST['ownerFederatedId'] : null;
157
-
158
-		if ($ownerFederatedId === null) {
159
-			$ownerFederatedId = $this->cloudIdManager->getCloudId($owner, $this->cleanupRemote($remote))->getId();
160
-		}
161
-		// if the owner of the share and the initiator are the same user
162
-		// we also complete the federated share ID for the initiator
163
-		if ($sharedByFederatedId === null && $owner === $sharedBy) {
164
-			$sharedByFederatedId = $ownerFederatedId;
165
-		}
166
-
167
-		$share = $this->cloudFederationFactory->getCloudFederationShare(
168
-			$shareWith,
169
-			$name,
170
-			'',
171
-			$remoteId,
172
-			$ownerFederatedId,
173
-			$owner,
174
-			$sharedByFederatedId,
175
-			$sharedBy,
176
-			$token,
177
-			'user',
178
-			'file'
179
-		);
180
-
181
-		try {
182
-			$provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
183
-			$provider->shareReceived($share);
184
-		} catch (ProviderDoesNotExistsException $e) {
185
-			throw new OCSException('Server does not support federated cloud sharing', 503);
186
-		} catch (ProviderCouldNotAddShareException $e) {
187
-			throw new OCSException($e->getMessage(), $e->getCode());
188
-		} catch (\Exception $e) {
189
-			throw new OCSException('internal server error, was not able to add share from ' . $remote, 500);
190
-		}
191
-
192
-		return new Http\DataResponse();
193
-	}
194
-
195
-	/**
196
-	 * @NoCSRFRequired
197
-	 * @PublicPage
198
-	 *
199
-	 * create re-share on behalf of another user
200
-	 *
201
-	 * @param int $id
202
-	 * @return Http\DataResponse
203
-	 * @throws OCSBadRequestException
204
-	 * @throws OCSForbiddenException
205
-	 * @throws OCSNotFoundException
206
-	 */
207
-	public function reShare($id) {
208
-
209
-		$token = $this->request->getParam('token', null);
210
-		$shareWith = $this->request->getParam('shareWith', null);
211
-		$permission = (int)$this->request->getParam('permission', null);
212
-		$remoteId = (int)$this->request->getParam('remoteId', null);
213
-
214
-		if ($id === null ||
215
-			$token === null ||
216
-			$shareWith === null ||
217
-			$permission === null ||
218
-			$remoteId === null
219
-		) {
220
-			throw new OCSBadRequestException();
221
-		}
222
-
223
-		$notification = [
224
-			'sharedSecret' => $token,
225
-			'shareWith' => $shareWith,
226
-			'senderId' => $remoteId,
227
-			'message' => 'Recipient of a share ask the owner to reshare the file'
228
-		];
229
-
230
-		try {
231
-			$provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
232
-			list($newToken, $localId) = $provider->notificationReceived('REQUEST_RESHARE', $id, $notification);
233
-			return new Http\DataResponse([
234
-				'token' => $newToken,
235
-				'remoteId' => $localId
236
-			]);
237
-		} catch (ProviderDoesNotExistsException $e) {
238
-			throw new OCSException('Server does not support federated cloud sharing', 503);
239
-		} catch (ShareNotFoundException $e) {
240
-			$this->logger->debug('Share not found: ' . $e->getMessage());
241
-		} catch (ProviderCouldNotAddShareException $e) {
242
-			$this->logger->debug('Could not add reshare: ' . $e->getMessage());
243
-			throw new OCSForbiddenException();
244
-		} catch (\Exception $e) {
245
-			$this->logger->debug('internal server error, can not process notification: ' . $e->getMessage());
246
-		}
247
-
248
-		throw new OCSBadRequestException();
249
-	}
250
-
251
-
252
-	/**
253
-	 * @NoCSRFRequired
254
-	 * @PublicPage
255
-	 *
256
-	 * accept server-to-server share
257
-	 *
258
-	 * @param int $id
259
-	 * @return Http\DataResponse
260
-	 * @throws OCSException
261
-	 * @throws Share\Exceptions\ShareNotFound
262
-	 * @throws \OC\HintException
263
-	 */
264
-	public function acceptShare($id) {
265
-
266
-		$token = isset($_POST['token']) ? $_POST['token'] : null;
267
-
268
-		$notification = [
269
-			'sharedSecret' => $token,
270
-			'message' => 'Recipient accept the share'
271
-		];
272
-
273
-		try {
274
-			$provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
275
-			$provider->notificationReceived('SHARE_ACCEPTED', $id, $notification);
276
-		} catch (ProviderDoesNotExistsException $e) {
277
-			throw new OCSException('Server does not support federated cloud sharing', 503);
278
-		} catch (ShareNotFoundException $e) {
279
-			$this->logger->debug('Share not found: ' . $e->getMessage());
280
-		} catch (\Exception $e) {
281
-			$this->logger->debug('internal server error, can not process notification: ' . $e->getMessage());
282
-		}
283
-
284
-		return new Http\DataResponse();
285
-	}
286
-
287
-	/**
288
-	 * @NoCSRFRequired
289
-	 * @PublicPage
290
-	 *
291
-	 * decline server-to-server share
292
-	 *
293
-	 * @param int $id
294
-	 * @return Http\DataResponse
295
-	 * @throws OCSException
296
-	 */
297
-	public function declineShare($id) {
298
-
299
-		$token = isset($_POST['token']) ? $_POST['token'] : null;
300
-
301
-		$notification = [
302
-			'sharedSecret' => $token,
303
-			'message' => 'Recipient declined the share'
304
-		];
305
-
306
-		try {
307
-			$provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
308
-			$provider->notificationReceived('SHARE_DECLINED', $id, $notification);
309
-		} catch (ProviderDoesNotExistsException $e) {
310
-			throw new OCSException('Server does not support federated cloud sharing', 503);
311
-		} catch (ShareNotFoundException $e) {
312
-			$this->logger->debug('Share not found: ' . $e->getMessage());
313
-		} catch (\Exception $e) {
314
-			$this->logger->debug('internal server error, can not process notification: ' . $e->getMessage());
315
-		}
316
-
317
-		return new Http\DataResponse();
318
-	}
319
-
320
-	/**
321
-	 * @NoCSRFRequired
322
-	 * @PublicPage
323
-	 *
324
-	 * remove server-to-server share if it was unshared by the owner
325
-	 *
326
-	 * @param int $id
327
-	 * @return Http\DataResponse
328
-	 * @throws OCSException
329
-	 */
330
-	public function unshare($id) {
331
-
332
-		if (!$this->isS2SEnabled()) {
333
-			throw new OCSException('Server does not support federated cloud sharing', 503);
334
-		}
335
-
336
-		$token = isset($_POST['token']) ? $_POST['token'] : null;
337
-
338
-		try {
339
-			$provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
340
-			$notification = ['sharedSecret' => $token];
341
-			$provider->notificationReceived('SHARE_UNSHARED', $id, $notification);
342
-		} catch (\Exception $e) {
343
-			$this->logger->debug('processing unshare notification failed: ' . $e->getMessage());
344
-		}
345
-
346
-		return new Http\DataResponse();
347
-	}
348
-
349
-	private function cleanupRemote($remote) {
350
-		$remote = substr($remote, strpos($remote, '://') + 3);
351
-
352
-		return rtrim($remote, '/');
353
-	}
354
-
355
-
356
-	/**
357
-	 * @NoCSRFRequired
358
-	 * @PublicPage
359
-	 *
360
-	 * federated share was revoked, either by the owner or the re-sharer
361
-	 *
362
-	 * @param int $id
363
-	 * @return Http\DataResponse
364
-	 * @throws OCSBadRequestException
365
-	 */
366
-	public function revoke($id) {
367
-
368
-		$token = $this->request->getParam('token');
369
-
370
-		try {
371
-			$provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
372
-			$notification = ['sharedSecret' => $token];
373
-			$provider->notificationReceived('RESHARE_UNDO', $id, $notification);
374
-			return new Http\DataResponse();
375
-		} catch (\Exception $e) {
376
-			throw new OCSBadRequestException();
377
-		}
378
-
379
-	}
380
-
381
-	/**
382
-	 * get share
383
-	 *
384
-	 * @param int $id
385
-	 * @param string $token
386
-	 * @return array|bool
387
-	 */
388
-	protected function getShare($id, $token) {
389
-		$query = $this->connection->getQueryBuilder();
390
-		$query->select('*')->from($this->shareTable)
391
-			->where($query->expr()->eq('token', $query->createNamedParameter($token)))
392
-			->andWhere($query->expr()->eq('share_type', $query->createNamedParameter(FederatedShareProvider::SHARE_TYPE_REMOTE)))
393
-			->andWhere($query->expr()->eq('id', $query->createNamedParameter($id)));
394
-
395
-		$result = $query->execute()->fetchAll();
396
-
397
-		if (!empty($result) && isset($result[0])) {
398
-			return $result[0];
399
-		}
400
-
401
-		return false;
402
-	}
403
-
404
-	/**
405
-	 * check if server-to-server sharing is enabled
406
-	 *
407
-	 * @param bool $incoming
408
-	 * @return bool
409
-	 */
410
-	private function isS2SEnabled($incoming = false) {
411
-
412
-		$result = \OCP\App::isEnabled('files_sharing');
413
-
414
-		if ($incoming) {
415
-			$result = $result && $this->federatedShareProvider->isIncomingServer2serverShareEnabled();
416
-		} else {
417
-			$result = $result && $this->federatedShareProvider->isOutgoingServer2serverShareEnabled();
418
-		}
419
-
420
-		return $result;
421
-	}
422
-
423
-	/**
424
-	 * @NoCSRFRequired
425
-	 * @PublicPage
426
-	 *
427
-	 * update share information to keep federated re-shares in sync
428
-	 *
429
-	 * @param int $id
430
-	 * @return Http\DataResponse
431
-	 * @throws OCSBadRequestException
432
-	 */
433
-	public function updatePermissions($id) {
434
-		$token = $this->request->getParam('token', null);
435
-		$ncPermissions = $this->request->getParam('permissions', null);
436
-
437
-		try {
438
-			$provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
439
-			$ocmPermissions = $this->ncPermissions2ocmPermissions((int)$ncPermissions);
440
-			$notification = ['sharedSecret' => $token, 'permission' => $ocmPermissions];
441
-			$provider->notificationReceived('RESHARE_CHANGE_PERMISSION', $id, $notification);
442
-		} catch (\Exception $e) {
443
-			$this->logger->debug($e->getMessage());
444
-			throw new OCSBadRequestException();
445
-		}
446
-
447
-		return new Http\DataResponse();
448
-	}
449
-
450
-	/**
451
-	 * translate Nextcloud permissions to OCM Permissions
452
-	 *
453
-	 * @param $ncPermissions
454
-	 * @return array
455
-	 */
456
-	protected function ncPermissions2ocmPermissions($ncPermissions) {
457
-
458
-		$ocmPermissions = [];
459
-
460
-		if ($ncPermissions & Constants::PERMISSION_SHARE) {
461
-			$ocmPermissions[] = 'share';
462
-		}
463
-
464
-		if ($ncPermissions & Constants::PERMISSION_READ) {
465
-			$ocmPermissions[] = 'read';
466
-		}
467
-
468
-		if (($ncPermissions & Constants::PERMISSION_CREATE) ||
469
-			($ncPermissions & Constants::PERMISSION_UPDATE)) {
470
-			$ocmPermissions[] = 'write';
471
-		}
472
-
473
-		return $ocmPermissions;
474
-
475
-	}
476
-
477
-	/**
478
-	 * @NoCSRFRequired
479
-	 * @PublicPage
480
-	 *
481
-	 * change the owner of a server-to-server share
482
-	 *
483
-	 * @param int $id
484
-	 * @return Http\DataResponse
485
-	 * @throws \InvalidArgumentException
486
-	 * @throws OCSException
487
-	 */
488
-	public function move($id) {
489
-
490
-		if (!$this->isS2SEnabled()) {
491
-			throw new OCSException('Server does not support federated cloud sharing', 503);
492
-		}
493
-
494
-		$token = $this->request->getParam('token');
495
-		$remote = $this->request->getParam('remote');
496
-		$newRemoteId = $this->request->getParam('remote_id', $id);
497
-		$cloudId = $this->cloudIdManager->resolveCloudId($remote);
498
-
499
-		$qb = $this->connection->getQueryBuilder();
500
-		$query = $qb->update('share_external')
501
-			->set('remote', $qb->createNamedParameter($cloudId->getRemote()))
502
-			->set('owner', $qb->createNamedParameter($cloudId->getUser()))
503
-			->set('remote_id', $qb->createNamedParameter($newRemoteId))
504
-			->where($qb->expr()->eq('remote_id', $qb->createNamedParameter($id)))
505
-			->andWhere($qb->expr()->eq('share_token', $qb->createNamedParameter($token)));
506
-		$affected = $query->execute();
507
-
508
-		if ($affected > 0) {
509
-			return new Http\DataResponse(['remote' => $cloudId->getRemote(), 'owner' => $cloudId->getUser()]);
510
-		} else {
511
-			throw new OCSBadRequestException('Share not found or token invalid');
512
-		}
513
-	}
61
+    /** @var FederatedShareProvider */
62
+    private $federatedShareProvider;
63
+
64
+    /** @var IDBConnection */
65
+    private $connection;
66
+
67
+    /** @var Share\IManager */
68
+    private $shareManager;
69
+
70
+    /** @var Notifications */
71
+    private $notifications;
72
+
73
+    /** @var AddressHandler */
74
+    private $addressHandler;
75
+
76
+    /** @var  IUserManager */
77
+    private $userManager;
78
+
79
+    /** @var string */
80
+    private $shareTable = 'share';
81
+
82
+    /** @var ICloudIdManager */
83
+    private $cloudIdManager;
84
+
85
+    /** @var ILogger */
86
+    private $logger;
87
+
88
+    /** @var ICloudFederationFactory */
89
+    private $cloudFederationFactory;
90
+
91
+    /** @var ICloudFederationProviderManager */
92
+    private $cloudFederationProviderManager;
93
+
94
+    /**
95
+     * Server2Server constructor.
96
+     *
97
+     * @param string $appName
98
+     * @param IRequest $request
99
+     * @param FederatedShareProvider $federatedShareProvider
100
+     * @param IDBConnection $connection
101
+     * @param Share\IManager $shareManager
102
+     * @param Notifications $notifications
103
+     * @param AddressHandler $addressHandler
104
+     * @param IUserManager $userManager
105
+     * @param ICloudIdManager $cloudIdManager
106
+     * @param ILogger $logger
107
+     * @param ICloudFederationFactory $cloudFederationFactory
108
+     * @param ICloudFederationProviderManager $cloudFederationProviderManager
109
+     */
110
+    public function __construct($appName,
111
+                                IRequest $request,
112
+                                FederatedShareProvider $federatedShareProvider,
113
+                                IDBConnection $connection,
114
+                                Share\IManager $shareManager,
115
+                                Notifications $notifications,
116
+                                AddressHandler $addressHandler,
117
+                                IUserManager $userManager,
118
+                                ICloudIdManager $cloudIdManager,
119
+                                ILogger $logger,
120
+                                ICloudFederationFactory $cloudFederationFactory,
121
+                                ICloudFederationProviderManager $cloudFederationProviderManager
122
+    ) {
123
+        parent::__construct($appName, $request);
124
+
125
+        $this->federatedShareProvider = $federatedShareProvider;
126
+        $this->connection = $connection;
127
+        $this->shareManager = $shareManager;
128
+        $this->notifications = $notifications;
129
+        $this->addressHandler = $addressHandler;
130
+        $this->userManager = $userManager;
131
+        $this->cloudIdManager = $cloudIdManager;
132
+        $this->logger = $logger;
133
+        $this->cloudFederationFactory = $cloudFederationFactory;
134
+        $this->cloudFederationProviderManager = $cloudFederationProviderManager;
135
+    }
136
+
137
+    /**
138
+     * @NoCSRFRequired
139
+     * @PublicPage
140
+     *
141
+     * create a new share
142
+     *
143
+     * @return Http\DataResponse
144
+     * @throws OCSException
145
+     */
146
+    public function createShare() {
147
+
148
+        $remote = isset($_POST['remote']) ? $_POST['remote'] : null;
149
+        $token = isset($_POST['token']) ? $_POST['token'] : null;
150
+        $name = isset($_POST['name']) ? $_POST['name'] : null;
151
+        $owner = isset($_POST['owner']) ? $_POST['owner'] : null;
152
+        $sharedBy = isset($_POST['sharedBy']) ? $_POST['sharedBy'] : null;
153
+        $shareWith = isset($_POST['shareWith']) ? $_POST['shareWith'] : null;
154
+        $remoteId = isset($_POST['remoteId']) ? (int)$_POST['remoteId'] : null;
155
+        $sharedByFederatedId = isset($_POST['sharedByFederatedId']) ? $_POST['sharedByFederatedId'] : null;
156
+        $ownerFederatedId = isset($_POST['ownerFederatedId']) ? $_POST['ownerFederatedId'] : null;
157
+
158
+        if ($ownerFederatedId === null) {
159
+            $ownerFederatedId = $this->cloudIdManager->getCloudId($owner, $this->cleanupRemote($remote))->getId();
160
+        }
161
+        // if the owner of the share and the initiator are the same user
162
+        // we also complete the federated share ID for the initiator
163
+        if ($sharedByFederatedId === null && $owner === $sharedBy) {
164
+            $sharedByFederatedId = $ownerFederatedId;
165
+        }
166
+
167
+        $share = $this->cloudFederationFactory->getCloudFederationShare(
168
+            $shareWith,
169
+            $name,
170
+            '',
171
+            $remoteId,
172
+            $ownerFederatedId,
173
+            $owner,
174
+            $sharedByFederatedId,
175
+            $sharedBy,
176
+            $token,
177
+            'user',
178
+            'file'
179
+        );
180
+
181
+        try {
182
+            $provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
183
+            $provider->shareReceived($share);
184
+        } catch (ProviderDoesNotExistsException $e) {
185
+            throw new OCSException('Server does not support federated cloud sharing', 503);
186
+        } catch (ProviderCouldNotAddShareException $e) {
187
+            throw new OCSException($e->getMessage(), $e->getCode());
188
+        } catch (\Exception $e) {
189
+            throw new OCSException('internal server error, was not able to add share from ' . $remote, 500);
190
+        }
191
+
192
+        return new Http\DataResponse();
193
+    }
194
+
195
+    /**
196
+     * @NoCSRFRequired
197
+     * @PublicPage
198
+     *
199
+     * create re-share on behalf of another user
200
+     *
201
+     * @param int $id
202
+     * @return Http\DataResponse
203
+     * @throws OCSBadRequestException
204
+     * @throws OCSForbiddenException
205
+     * @throws OCSNotFoundException
206
+     */
207
+    public function reShare($id) {
208
+
209
+        $token = $this->request->getParam('token', null);
210
+        $shareWith = $this->request->getParam('shareWith', null);
211
+        $permission = (int)$this->request->getParam('permission', null);
212
+        $remoteId = (int)$this->request->getParam('remoteId', null);
213
+
214
+        if ($id === null ||
215
+            $token === null ||
216
+            $shareWith === null ||
217
+            $permission === null ||
218
+            $remoteId === null
219
+        ) {
220
+            throw new OCSBadRequestException();
221
+        }
222
+
223
+        $notification = [
224
+            'sharedSecret' => $token,
225
+            'shareWith' => $shareWith,
226
+            'senderId' => $remoteId,
227
+            'message' => 'Recipient of a share ask the owner to reshare the file'
228
+        ];
229
+
230
+        try {
231
+            $provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
232
+            list($newToken, $localId) = $provider->notificationReceived('REQUEST_RESHARE', $id, $notification);
233
+            return new Http\DataResponse([
234
+                'token' => $newToken,
235
+                'remoteId' => $localId
236
+            ]);
237
+        } catch (ProviderDoesNotExistsException $e) {
238
+            throw new OCSException('Server does not support federated cloud sharing', 503);
239
+        } catch (ShareNotFoundException $e) {
240
+            $this->logger->debug('Share not found: ' . $e->getMessage());
241
+        } catch (ProviderCouldNotAddShareException $e) {
242
+            $this->logger->debug('Could not add reshare: ' . $e->getMessage());
243
+            throw new OCSForbiddenException();
244
+        } catch (\Exception $e) {
245
+            $this->logger->debug('internal server error, can not process notification: ' . $e->getMessage());
246
+        }
247
+
248
+        throw new OCSBadRequestException();
249
+    }
250
+
251
+
252
+    /**
253
+     * @NoCSRFRequired
254
+     * @PublicPage
255
+     *
256
+     * accept server-to-server share
257
+     *
258
+     * @param int $id
259
+     * @return Http\DataResponse
260
+     * @throws OCSException
261
+     * @throws Share\Exceptions\ShareNotFound
262
+     * @throws \OC\HintException
263
+     */
264
+    public function acceptShare($id) {
265
+
266
+        $token = isset($_POST['token']) ? $_POST['token'] : null;
267
+
268
+        $notification = [
269
+            'sharedSecret' => $token,
270
+            'message' => 'Recipient accept the share'
271
+        ];
272
+
273
+        try {
274
+            $provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
275
+            $provider->notificationReceived('SHARE_ACCEPTED', $id, $notification);
276
+        } catch (ProviderDoesNotExistsException $e) {
277
+            throw new OCSException('Server does not support federated cloud sharing', 503);
278
+        } catch (ShareNotFoundException $e) {
279
+            $this->logger->debug('Share not found: ' . $e->getMessage());
280
+        } catch (\Exception $e) {
281
+            $this->logger->debug('internal server error, can not process notification: ' . $e->getMessage());
282
+        }
283
+
284
+        return new Http\DataResponse();
285
+    }
286
+
287
+    /**
288
+     * @NoCSRFRequired
289
+     * @PublicPage
290
+     *
291
+     * decline server-to-server share
292
+     *
293
+     * @param int $id
294
+     * @return Http\DataResponse
295
+     * @throws OCSException
296
+     */
297
+    public function declineShare($id) {
298
+
299
+        $token = isset($_POST['token']) ? $_POST['token'] : null;
300
+
301
+        $notification = [
302
+            'sharedSecret' => $token,
303
+            'message' => 'Recipient declined the share'
304
+        ];
305
+
306
+        try {
307
+            $provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
308
+            $provider->notificationReceived('SHARE_DECLINED', $id, $notification);
309
+        } catch (ProviderDoesNotExistsException $e) {
310
+            throw new OCSException('Server does not support federated cloud sharing', 503);
311
+        } catch (ShareNotFoundException $e) {
312
+            $this->logger->debug('Share not found: ' . $e->getMessage());
313
+        } catch (\Exception $e) {
314
+            $this->logger->debug('internal server error, can not process notification: ' . $e->getMessage());
315
+        }
316
+
317
+        return new Http\DataResponse();
318
+    }
319
+
320
+    /**
321
+     * @NoCSRFRequired
322
+     * @PublicPage
323
+     *
324
+     * remove server-to-server share if it was unshared by the owner
325
+     *
326
+     * @param int $id
327
+     * @return Http\DataResponse
328
+     * @throws OCSException
329
+     */
330
+    public function unshare($id) {
331
+
332
+        if (!$this->isS2SEnabled()) {
333
+            throw new OCSException('Server does not support federated cloud sharing', 503);
334
+        }
335
+
336
+        $token = isset($_POST['token']) ? $_POST['token'] : null;
337
+
338
+        try {
339
+            $provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
340
+            $notification = ['sharedSecret' => $token];
341
+            $provider->notificationReceived('SHARE_UNSHARED', $id, $notification);
342
+        } catch (\Exception $e) {
343
+            $this->logger->debug('processing unshare notification failed: ' . $e->getMessage());
344
+        }
345
+
346
+        return new Http\DataResponse();
347
+    }
348
+
349
+    private function cleanupRemote($remote) {
350
+        $remote = substr($remote, strpos($remote, '://') + 3);
351
+
352
+        return rtrim($remote, '/');
353
+    }
354
+
355
+
356
+    /**
357
+     * @NoCSRFRequired
358
+     * @PublicPage
359
+     *
360
+     * federated share was revoked, either by the owner or the re-sharer
361
+     *
362
+     * @param int $id
363
+     * @return Http\DataResponse
364
+     * @throws OCSBadRequestException
365
+     */
366
+    public function revoke($id) {
367
+
368
+        $token = $this->request->getParam('token');
369
+
370
+        try {
371
+            $provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
372
+            $notification = ['sharedSecret' => $token];
373
+            $provider->notificationReceived('RESHARE_UNDO', $id, $notification);
374
+            return new Http\DataResponse();
375
+        } catch (\Exception $e) {
376
+            throw new OCSBadRequestException();
377
+        }
378
+
379
+    }
380
+
381
+    /**
382
+     * get share
383
+     *
384
+     * @param int $id
385
+     * @param string $token
386
+     * @return array|bool
387
+     */
388
+    protected function getShare($id, $token) {
389
+        $query = $this->connection->getQueryBuilder();
390
+        $query->select('*')->from($this->shareTable)
391
+            ->where($query->expr()->eq('token', $query->createNamedParameter($token)))
392
+            ->andWhere($query->expr()->eq('share_type', $query->createNamedParameter(FederatedShareProvider::SHARE_TYPE_REMOTE)))
393
+            ->andWhere($query->expr()->eq('id', $query->createNamedParameter($id)));
394
+
395
+        $result = $query->execute()->fetchAll();
396
+
397
+        if (!empty($result) && isset($result[0])) {
398
+            return $result[0];
399
+        }
400
+
401
+        return false;
402
+    }
403
+
404
+    /**
405
+     * check if server-to-server sharing is enabled
406
+     *
407
+     * @param bool $incoming
408
+     * @return bool
409
+     */
410
+    private function isS2SEnabled($incoming = false) {
411
+
412
+        $result = \OCP\App::isEnabled('files_sharing');
413
+
414
+        if ($incoming) {
415
+            $result = $result && $this->federatedShareProvider->isIncomingServer2serverShareEnabled();
416
+        } else {
417
+            $result = $result && $this->federatedShareProvider->isOutgoingServer2serverShareEnabled();
418
+        }
419
+
420
+        return $result;
421
+    }
422
+
423
+    /**
424
+     * @NoCSRFRequired
425
+     * @PublicPage
426
+     *
427
+     * update share information to keep federated re-shares in sync
428
+     *
429
+     * @param int $id
430
+     * @return Http\DataResponse
431
+     * @throws OCSBadRequestException
432
+     */
433
+    public function updatePermissions($id) {
434
+        $token = $this->request->getParam('token', null);
435
+        $ncPermissions = $this->request->getParam('permissions', null);
436
+
437
+        try {
438
+            $provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
439
+            $ocmPermissions = $this->ncPermissions2ocmPermissions((int)$ncPermissions);
440
+            $notification = ['sharedSecret' => $token, 'permission' => $ocmPermissions];
441
+            $provider->notificationReceived('RESHARE_CHANGE_PERMISSION', $id, $notification);
442
+        } catch (\Exception $e) {
443
+            $this->logger->debug($e->getMessage());
444
+            throw new OCSBadRequestException();
445
+        }
446
+
447
+        return new Http\DataResponse();
448
+    }
449
+
450
+    /**
451
+     * translate Nextcloud permissions to OCM Permissions
452
+     *
453
+     * @param $ncPermissions
454
+     * @return array
455
+     */
456
+    protected function ncPermissions2ocmPermissions($ncPermissions) {
457
+
458
+        $ocmPermissions = [];
459
+
460
+        if ($ncPermissions & Constants::PERMISSION_SHARE) {
461
+            $ocmPermissions[] = 'share';
462
+        }
463
+
464
+        if ($ncPermissions & Constants::PERMISSION_READ) {
465
+            $ocmPermissions[] = 'read';
466
+        }
467
+
468
+        if (($ncPermissions & Constants::PERMISSION_CREATE) ||
469
+            ($ncPermissions & Constants::PERMISSION_UPDATE)) {
470
+            $ocmPermissions[] = 'write';
471
+        }
472
+
473
+        return $ocmPermissions;
474
+
475
+    }
476
+
477
+    /**
478
+     * @NoCSRFRequired
479
+     * @PublicPage
480
+     *
481
+     * change the owner of a server-to-server share
482
+     *
483
+     * @param int $id
484
+     * @return Http\DataResponse
485
+     * @throws \InvalidArgumentException
486
+     * @throws OCSException
487
+     */
488
+    public function move($id) {
489
+
490
+        if (!$this->isS2SEnabled()) {
491
+            throw new OCSException('Server does not support federated cloud sharing', 503);
492
+        }
493
+
494
+        $token = $this->request->getParam('token');
495
+        $remote = $this->request->getParam('remote');
496
+        $newRemoteId = $this->request->getParam('remote_id', $id);
497
+        $cloudId = $this->cloudIdManager->resolveCloudId($remote);
498
+
499
+        $qb = $this->connection->getQueryBuilder();
500
+        $query = $qb->update('share_external')
501
+            ->set('remote', $qb->createNamedParameter($cloudId->getRemote()))
502
+            ->set('owner', $qb->createNamedParameter($cloudId->getUser()))
503
+            ->set('remote_id', $qb->createNamedParameter($newRemoteId))
504
+            ->where($qb->expr()->eq('remote_id', $qb->createNamedParameter($id)))
505
+            ->andWhere($qb->expr()->eq('share_token', $qb->createNamedParameter($token)));
506
+        $affected = $query->execute();
507
+
508
+        if ($affected > 0) {
509
+            return new Http\DataResponse(['remote' => $cloudId->getRemote(), 'owner' => $cloudId->getUser()]);
510
+        } else {
511
+            throw new OCSBadRequestException('Share not found or token invalid');
512
+        }
513
+    }
514 514
 }
Please login to merge, or discard this patch.
Spacing   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -151,7 +151,7 @@  discard block
 block discarded – undo
151 151
 		$owner = isset($_POST['owner']) ? $_POST['owner'] : null;
152 152
 		$sharedBy = isset($_POST['sharedBy']) ? $_POST['sharedBy'] : null;
153 153
 		$shareWith = isset($_POST['shareWith']) ? $_POST['shareWith'] : null;
154
-		$remoteId = isset($_POST['remoteId']) ? (int)$_POST['remoteId'] : null;
154
+		$remoteId = isset($_POST['remoteId']) ? (int) $_POST['remoteId'] : null;
155 155
 		$sharedByFederatedId = isset($_POST['sharedByFederatedId']) ? $_POST['sharedByFederatedId'] : null;
156 156
 		$ownerFederatedId = isset($_POST['ownerFederatedId']) ? $_POST['ownerFederatedId'] : null;
157 157
 
@@ -186,7 +186,7 @@  discard block
 block discarded – undo
186 186
 		} catch (ProviderCouldNotAddShareException $e) {
187 187
 			throw new OCSException($e->getMessage(), $e->getCode());
188 188
 		} catch (\Exception $e) {
189
-			throw new OCSException('internal server error, was not able to add share from ' . $remote, 500);
189
+			throw new OCSException('internal server error, was not able to add share from '.$remote, 500);
190 190
 		}
191 191
 
192 192
 		return new Http\DataResponse();
@@ -208,8 +208,8 @@  discard block
 block discarded – undo
208 208
 
209 209
 		$token = $this->request->getParam('token', null);
210 210
 		$shareWith = $this->request->getParam('shareWith', null);
211
-		$permission = (int)$this->request->getParam('permission', null);
212
-		$remoteId = (int)$this->request->getParam('remoteId', null);
211
+		$permission = (int) $this->request->getParam('permission', null);
212
+		$remoteId = (int) $this->request->getParam('remoteId', null);
213 213
 
214 214
 		if ($id === null ||
215 215
 			$token === null ||
@@ -237,12 +237,12 @@  discard block
 block discarded – undo
237 237
 		} catch (ProviderDoesNotExistsException $e) {
238 238
 			throw new OCSException('Server does not support federated cloud sharing', 503);
239 239
 		} catch (ShareNotFoundException $e) {
240
-			$this->logger->debug('Share not found: ' . $e->getMessage());
240
+			$this->logger->debug('Share not found: '.$e->getMessage());
241 241
 		} catch (ProviderCouldNotAddShareException $e) {
242
-			$this->logger->debug('Could not add reshare: ' . $e->getMessage());
242
+			$this->logger->debug('Could not add reshare: '.$e->getMessage());
243 243
 			throw new OCSForbiddenException();
244 244
 		} catch (\Exception $e) {
245
-			$this->logger->debug('internal server error, can not process notification: ' . $e->getMessage());
245
+			$this->logger->debug('internal server error, can not process notification: '.$e->getMessage());
246 246
 		}
247 247
 
248 248
 		throw new OCSBadRequestException();
@@ -276,9 +276,9 @@  discard block
 block discarded – undo
276 276
 		} catch (ProviderDoesNotExistsException $e) {
277 277
 			throw new OCSException('Server does not support federated cloud sharing', 503);
278 278
 		} catch (ShareNotFoundException $e) {
279
-			$this->logger->debug('Share not found: ' . $e->getMessage());
279
+			$this->logger->debug('Share not found: '.$e->getMessage());
280 280
 		} catch (\Exception $e) {
281
-			$this->logger->debug('internal server error, can not process notification: ' . $e->getMessage());
281
+			$this->logger->debug('internal server error, can not process notification: '.$e->getMessage());
282 282
 		}
283 283
 
284 284
 		return new Http\DataResponse();
@@ -309,9 +309,9 @@  discard block
 block discarded – undo
309 309
 		} catch (ProviderDoesNotExistsException $e) {
310 310
 			throw new OCSException('Server does not support federated cloud sharing', 503);
311 311
 		} catch (ShareNotFoundException $e) {
312
-			$this->logger->debug('Share not found: ' . $e->getMessage());
312
+			$this->logger->debug('Share not found: '.$e->getMessage());
313 313
 		} catch (\Exception $e) {
314
-			$this->logger->debug('internal server error, can not process notification: ' . $e->getMessage());
314
+			$this->logger->debug('internal server error, can not process notification: '.$e->getMessage());
315 315
 		}
316 316
 
317 317
 		return new Http\DataResponse();
@@ -340,7 +340,7 @@  discard block
 block discarded – undo
340 340
 			$notification = ['sharedSecret' => $token];
341 341
 			$provider->notificationReceived('SHARE_UNSHARED', $id, $notification);
342 342
 		} catch (\Exception $e) {
343
-			$this->logger->debug('processing unshare notification failed: ' . $e->getMessage());
343
+			$this->logger->debug('processing unshare notification failed: '.$e->getMessage());
344 344
 		}
345 345
 
346 346
 		return new Http\DataResponse();
@@ -436,7 +436,7 @@  discard block
 block discarded – undo
436 436
 
437 437
 		try {
438 438
 			$provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file');
439
-			$ocmPermissions = $this->ncPermissions2ocmPermissions((int)$ncPermissions);
439
+			$ocmPermissions = $this->ncPermissions2ocmPermissions((int) $ncPermissions);
440 440
 			$notification = ['sharedSecret' => $token, 'permission' => $ocmPermissions];
441 441
 			$provider->notificationReceived('RESHARE_CHANGE_PERMISSION', $id, $notification);
442 442
 		} catch (\Exception $e) {
Please login to merge, or discard this patch.