From 41a1528888062610af58e319ce7bfa3ef8784da3 Mon Sep 17 00:00:00 2001 From: Bjoern Schiessle Date: Wed, 30 May 2018 17:44:08 +0200 Subject: [PATCH] implement decline share Signed-off-by: Bjoern Schiessle --- .../lib/AppInfo/Application.php | 4 +- .../Controller/RequestHandlerController.php | 50 +++------ .../lib/FederatedShareProvider.php | 2 +- .../lib/ocm/CloudFederationProviderFiles.php | 105 ++++++++++++++++-- apps/files_sharing/lib/External/Manager.php | 17 ++- 5 files changed, 131 insertions(+), 47 deletions(-) diff --git a/apps/federatedfilesharing/lib/AppInfo/Application.php b/apps/federatedfilesharing/lib/AppInfo/Application.php index 0b61e0a0b0..093e1e44f9 100644 --- a/apps/federatedfilesharing/lib/AppInfo/Application.php +++ b/apps/federatedfilesharing/lib/AppInfo/Application.php @@ -62,7 +62,9 @@ class Application extends App { $server->getCloudIdManager(), $server->getActivityManager(), $server->getNotificationManager(), - $server->getURLGenerator() + $server->getURLGenerator(), + $server->getCloudFederationFactory(), + $server->getCloudFederationProviderManager() ); }); diff --git a/apps/federatedfilesharing/lib/Controller/RequestHandlerController.php b/apps/federatedfilesharing/lib/Controller/RequestHandlerController.php index 628e306e99..8514adb5e8 100644 --- a/apps/federatedfilesharing/lib/Controller/RequestHandlerController.php +++ b/apps/federatedfilesharing/lib/Controller/RequestHandlerController.php @@ -304,51 +304,27 @@ class RequestHandlerController extends OCSController { */ public function declineShare($id) { - if (!$this->isS2SEnabled()) { - throw new OCSException('Server does not support federated cloud sharing', 503); - } - $token = isset($_POST['token']) ? $_POST['token'] : null; - try { - $share = $this->federatedShareProvider->getShareById($id); - } catch (Share\Exceptions\ShareNotFound $e) { - return new Http\DataResponse(); - } + $notification = [ + 'sharedSecret' => $token, + 'message' => 'Recipient declined the share' + ]; - if ($this->verifyShare($share, $token)) { - if ($share->getShareOwner() !== $share->getSharedBy()) { - list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy()); - $remoteId = $this->federatedShareProvider->getRemoteId($share); - $this->notifications->sendDeclineShare($remote, $remoteId, $share->getToken()); - } - $this->executeDeclineShare($share); + try { + $provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file'); + $provider->notificationReceived('SHARE_DECLINED', $id, $notification); + } catch (ProviderDoesNotExistsException $e) { + throw new OCSException('Server does not support federated cloud sharing', 503); + } catch (ShareNotFoundException $e) { + $this->logger->debug('Share not found: ' . $e->getMessage()); + } catch (\Exception $e) { + $this->logger->debug('internal server error, can not process notification: ' . $e->getMessage()); } return new Http\DataResponse(); } - /** - * delete declined share and create a activity - * - * @param Share\IShare $share - */ - protected function executeDeclineShare(Share\IShare $share) { - $this->federatedShareProvider->removeShareFromTable($share); - $fileId = (int) $share->getNode()->getId(); - list($file, $link) = $this->getFile($this->getCorrectUid($share), $fileId); - - $event = \OC::$server->getActivityManager()->generateEvent(); - $event->setApp('files_sharing') - ->setType('remote_share') - ->setAffectedUser($this->getCorrectUid($share)) - ->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_DECLINED, [$share->getSharedWith(), [$fileId => $file]]) - ->setObject('files', $fileId, $file) - ->setLink($link); - \OC::$server->getActivityManager()->publish($event); - - } - /** * @NoCSRFRequired * @PublicPage diff --git a/apps/federatedfilesharing/lib/FederatedShareProvider.php b/apps/federatedfilesharing/lib/FederatedShareProvider.php index 07597cae8e..84aeb8b78c 100644 --- a/apps/federatedfilesharing/lib/FederatedShareProvider.php +++ b/apps/federatedfilesharing/lib/FederatedShareProvider.php @@ -709,7 +709,7 @@ class FederatedShareProvider implements IShareProvider { $cursor->closeCursor(); if ($data === false) { - throw new ShareNotFoundException(); + throw new ShareNotFoundException('Can not find share with ID: ' . $id); } try { diff --git a/apps/federatedfilesharing/lib/ocm/CloudFederationProviderFiles.php b/apps/federatedfilesharing/lib/ocm/CloudFederationProviderFiles.php index 798b0bef3f..a271fd454b 100644 --- a/apps/federatedfilesharing/lib/ocm/CloudFederationProviderFiles.php +++ b/apps/federatedfilesharing/lib/ocm/CloudFederationProviderFiles.php @@ -34,7 +34,9 @@ use OCP\Federation\Exceptions\AuthenticationFailedException; use OCP\Federation\Exceptions\BadRequestException; use OCP\Federation\Exceptions\ProviderCouldNotAddShareException; use OCP\Federation\Exceptions\ShareNotFoundException; +use OCP\Federation\ICloudFederationFactory; use OCP\Federation\ICloudFederationProvider; +use OCP\Federation\ICloudFederationProviderManager; use OCP\Federation\ICloudFederationShare; use OCP\Federation\ICloudIdManager; use OCP\Files\NotFoundException; @@ -75,6 +77,12 @@ class CloudFederationProviderFiles implements ICloudFederationProvider { /** @var IURLGenerator */ private $urlGenerator; + /** @var ICloudFederationFactory */ + private $cloudFederationFactory; + + /** @var ICloudFederationProviderManager */ + private $cloudFederationProviderManager; + /** * CloudFederationProvider constructor. * @@ -87,6 +95,8 @@ class CloudFederationProviderFiles implements ICloudFederationProvider { * @param IActivityManager $activityManager * @param INotificationManager $notificationManager * @param IURLGenerator $urlGenerator + * @param ICloudFederationFactory $cloudFederationFactory + * @param ICloudFederationProviderManager $cloudFederationProviderManager */ public function __construct(IAppManager $appManager, FederatedShareProvider $federatedShareProvider, @@ -96,7 +106,9 @@ class CloudFederationProviderFiles implements ICloudFederationProvider { ICloudIdManager $cloudIdManager, IActivityManager $activityManager, INotificationManager $notificationManager, - IURLGenerator $urlGenerator + IURLGenerator $urlGenerator, + ICloudFederationFactory $cloudFederationFactory, + ICloudFederationProviderManager $cloudFederationProviderManager ) { $this->appManager = $appManager; $this->federatedShareProvider = $federatedShareProvider; @@ -107,6 +119,8 @@ class CloudFederationProviderFiles implements ICloudFederationProvider { $this->activityManager = $activityManager; $this->notificationManager = $notificationManager; $this->urlGenerator = $urlGenerator; + $this->cloudFederationFactory = $cloudFederationFactory; + $this->cloudFederationProviderManager = $cloudFederationProviderManager; } @@ -258,15 +272,18 @@ class CloudFederationProviderFiles implements ICloudFederationProvider { case 'SHARE_ACCEPTED': $this->shareAccepted($providerId, $notification); return; + case 'SHARE_DECLINED': + $this->shareDeclined($providerId, $notification); + return; } - throw new ActionNotSupportedException($notification); + throw new BadRequestException([$notificationType]); } /** - * @param $id - * @param $notification + * @param string $id + * @param array $notification * @return bool * @throws ActionNotSupportedException * @throws AuthenticationFailedException @@ -276,8 +293,8 @@ class CloudFederationProviderFiles implements ICloudFederationProvider { */ private function shareAccepted($id, $notification) { - if (!$this->isS2SEnabled(true)) { - throw new ActionNotSupportedException('Server does not support federated cloud sharing', '', Http::STATUS_SERVICE_UNAVAILABLE); + if (!$this->isS2SEnabled()) { + throw new ActionNotSupportedException('Server does not support federated cloud sharing'); } if (!isset($notification['sharedSecret'])) { @@ -311,7 +328,6 @@ class CloudFederationProviderFiles implements ICloudFederationProvider { return true; } - /** * @param IShare $share * @throws ShareNotFoundException @@ -334,6 +350,81 @@ class CloudFederationProviderFiles implements ICloudFederationProvider { $this->activityManager->publish($event); } + /** + * @param string $id + * @param array $notification + * @throws ActionNotSupportedException + * @throws AuthenticationFailedException + * @throws BadRequestException + * @throws ShareNotFound + * @throws ShareNotFoundException + * @throws \OC\HintException + */ + protected function shareDeclined($id, $notification) { + + if (!$this->isS2SEnabled()) { + throw new ActionNotSupportedException('Server does not support federated cloud sharing'); + } + + if (!isset($notification['sharedSecret'])) { + throw new BadRequestException(['sharedSecret']); + } + + $token = $notification['sharedSecret']; + + $share = $this->federatedShareProvider->getShareById($id); + + $this->verifyShare($share, $token); + + if ($share->getShareOwner() !== $share->getSharedBy()) { + list(, $remote) = $this->addressHandler->splitUserRemote($share->getSharedBy()); + $remoteId = $this->federatedShareProvider->getRemoteId($share); + $notification = $this->cloudFederationFactory->getCloudFederationNotification(); + $notification->setMessage( + 'SHARE_DECLINED', + 'file', + $remoteId, + [ + 'sharedSecret' => $token, + 'message' => 'Recipient declined the re-share' + ] + + ); + $this->cloudFederationProviderManager->sendNotification($remote, $notification); + } + + $this->executeDeclineShare($share); + + } + + /** + * delete declined share and create a activity + * + * @param IShare $share + * @throws ShareNotFoundException + */ + protected function executeDeclineShare(IShare $share) { + $this->federatedShareProvider->removeShareFromTable($share); + + try { + $fileId = (int)$share->getNode()->getId(); + list($file, $link) = $this->getFile($this->getCorrectUid($share), $fileId); + } catch (\Exception $e) { + throw new ShareNotFoundException(); + } + + $event = $this->activityManager->generateEvent(); + $event->setApp('files_sharing') + ->setType('remote_share') + ->setAffectedUser($this->getCorrectUid($share)) + ->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_DECLINED, [$share->getSharedWith(), [$fileId => $file]]) + ->setObject('files', $fileId, $file) + ->setLink($link); + $this->activityManager->publish($event); + + } + + /** * get file * diff --git a/apps/files_sharing/lib/External/Manager.php b/apps/files_sharing/lib/External/Manager.php index 0bbbbea767..02783560af 100644 --- a/apps/files_sharing/lib/External/Manager.php +++ b/apps/files_sharing/lib/External/Manager.php @@ -326,7 +326,7 @@ class Manager { * @param string $token * @param $remoteId id of the share * @param string $feedback - * @return mixed + * @return bool */ protected function tryOCMEndPoint($remoteDomain, $token, $remoteId, $feedback) { switch ($feedback) { @@ -341,10 +341,25 @@ class Manager { 'message' => 'Recipient accept the share' ] + ); + return $this->cloudFederationProviderManager->sendNotification($remoteDomain, $notification); + case 'decline': + $notification = $this->cloudFederationFactory->getCloudFederationNotification(); + $notification->setMessage( + 'SHARE_DECLINED', + 'file', + $remoteId, + [ + 'sharedSecret' => $token, + 'message' => 'Recipient declined the share' + ] + ); return $this->cloudFederationProviderManager->sendNotification($remoteDomain, $notification); } + return false; + }