diff options
author | Bjoern Schiessle <bjoern@schiessle.org> | 2018-06-04 12:16:03 +0200 |
---|---|---|
committer | Bjoern Schiessle <bjoern@schiessle.org> | 2018-07-02 11:29:28 +0200 |
commit | fab4e561f4f3ea9a3cf90a01c39c8d1e87ee9eab (patch) | |
tree | 723753d2819808ab0ed16d7c9574a3fd6a74ab26 /apps/federatedfilesharing | |
parent | 41a1528888062610af58e319ce7bfa3ef8784da3 (diff) | |
download | nextcloud-server-fab4e561f4f3ea9a3cf90a01c39c8d1e87ee9eab.tar.gz nextcloud-server-fab4e561f4f3ea9a3cf90a01c39c8d1e87ee9eab.zip |
send reshare over OCM API
Signed-off-by: Bjoern Schiessle <bjoern@schiessle.org>
Diffstat (limited to 'apps/federatedfilesharing')
4 files changed, 147 insertions, 42 deletions
diff --git a/apps/federatedfilesharing/lib/Controller/RequestHandlerController.php b/apps/federatedfilesharing/lib/Controller/RequestHandlerController.php index 8514adb5e89..041232c83e6 100644 --- a/apps/federatedfilesharing/lib/Controller/RequestHandlerController.php +++ b/apps/federatedfilesharing/lib/Controller/RequestHandlerController.php @@ -218,45 +218,35 @@ class RequestHandlerController extends OCSController { throw new OCSBadRequestException(); } - try { - $share = $this->federatedShareProvider->getShareById($id); - } catch (Share\Exceptions\ShareNotFound $e) { - throw new OCSNotFoundException(); - } + $notification = [ + 'sharedSecret' => $token, + 'shareWith' => $shareWith, + 'senderId' => $remoteId, + 'message' => 'Recipient of a share ask the owner to reshare the file' + ]; - // don't allow to share a file back to the owner - list($user, $remote) = $this->addressHandler->splitUserRemote($shareWith); - $owner = $share->getShareOwner(); - $currentServer = $this->addressHandler->generateRemoteURL(); - if ($this->addressHandler->compareAddresses($user, $remote, $owner, $currentServer)) { + try { + $provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file'); + list($newToken, $localId) = $provider->notificationReceived('REQUEST_RESHARE', $id, $notification); + return new Http\DataResponse([ + 'token' => $newToken, + 'remoteId' => $localId + ]); + } 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 (ProviderCouldNotAddShareException $e) { + $this->logger->debug('Could not add reshare: ' . $e->getMessage()); throw new OCSForbiddenException(); + } catch (\Exception $e) { + $this->logger->debug('internal server error, can not process notification: ' . $e->getMessage()); } - if ($this->verifyShare($share, $token)) { - - // check if re-sharing is allowed - if ($share->getPermissions() | ~Constants::PERMISSION_SHARE) { - $share->setPermissions($share->getPermissions() & $permission); - // the recipient of the initial share is now the initiator for the re-share - $share->setSharedBy($share->getSharedWith()); - $share->setSharedWith($shareWith); - try { - $result = $this->federatedShareProvider->create($share); - $this->federatedShareProvider->storeRemoteId((int)$result->getId(), $remoteId); - return new Http\DataResponse([ - 'token' => $result->getToken(), - 'remoteId' => $result->getId() - ]); - } catch (\Exception $e) { - throw new OCSBadRequestException(); - } - } else { - throw new OCSForbiddenException(); - } - } throw new OCSBadRequestException(); } + /** * @NoCSRFRequired * @PublicPage diff --git a/apps/federatedfilesharing/lib/FederatedShareProvider.php b/apps/federatedfilesharing/lib/FederatedShareProvider.php index 84aeb8b78cb..62be96dfa00 100644 --- a/apps/federatedfilesharing/lib/FederatedShareProvider.php +++ b/apps/federatedfilesharing/lib/FederatedShareProvider.php @@ -304,7 +304,8 @@ class FederatedShareProvider implements IShareProvider { $shareId, $remote, $shareWith, - $share->getPermissions() + $share->getPermissions(), + $share->getNode()->getName() ); return [$token, $remoteId]; diff --git a/apps/federatedfilesharing/lib/Notifications.php b/apps/federatedfilesharing/lib/Notifications.php index e0f8735f900..33254774e28 100644 --- a/apps/federatedfilesharing/lib/Notifications.php +++ b/apps/federatedfilesharing/lib/Notifications.php @@ -136,20 +136,31 @@ class Notifications { * @param string $remote remote address of the owner * @param string $shareWith * @param int $permission + * @param string $filename * @return bool * @throws \OC\HintException * @throws \OC\ServerNotAvailableException */ - public function requestReShare($token, $id, $shareId, $remote, $shareWith, $permission) { + public function requestReShare($token, $id, $shareId, $remote, $shareWith, $permission, $filename) { $fields = array( 'shareWith' => $shareWith, 'token' => $token, 'permission' => $permission, - 'remoteId' => $shareId + 'remoteId' => $shareId, ); - $result = $this->tryHttpPostToShareEndpoint(rtrim($remote, '/'), '/' . $id . '/reshare', $fields); + $ocmFields = $fields; + $ocmFields['remoteId'] = $id; + $ocmFields['localId'] = $shareId; + $ocmFields['name'] = $filename; + + $ocmResult = $this->tryOCMEndPoint($remote, $ocmFields, 'reshare'); + if (is_array($ocmResult) && isset($ocmResult['token']) && isset($ocmResult['providerId'])) { + return [$ocmResult['token'], $ocmResult['providerId']]; + } + + $result = $this->tryLegacyEndPoint(rtrim($remote, '/'), '/' . $id . '/reshare', $fields); $status = json_decode($result['result'], true); $httpRequestSuccessful = $result['success']; @@ -310,6 +321,25 @@ class Notifications { return $result; } + return $this->tryLegacyEndPoint($remoteDomain, $urlSuffix, $fields); + } + + /** + * try old federated sharing API if the OCM api doesn't work + * + * @param $remoteDomain + * @param $urlSuffix + * @param array $fields + * @return mixed + * @throws \Exception + */ + protected function tryLegacyEndPoint($remoteDomain, $urlSuffix, array $fields) { + + $result = [ + 'success' => false, + 'result' => '', + ]; + // Fall back to old API $client = $this->httpClientService->newClient(); $federationEndpoints = $this->discoveryService->discover($remoteDomain, 'FEDERATED_SHARING'); @@ -332,6 +362,7 @@ class Notifications { } return $result; + } /** @@ -384,7 +415,22 @@ class Notifications { 'file' ); return $this->federationProviderManager->sendShare($share); + case 'reshare': + $notification = $this->cloudFederationFactory->getCloudFederationNotification(); + $notification->setMessage('REQUEST_RESHARE', + 'file', + $fields['remoteId'], + [ + 'sharedSecret' => $fields['token'], + 'shareWith' => $fields['shareWith'], + 'senderId' => $fields['localId'], + 'message' => 'Ask owner to reshare the file' + ] + ); + return $this->federationProviderManager->sendNotification($remoteDomain, $notification); } + return false; + } } diff --git a/apps/federatedfilesharing/lib/ocm/CloudFederationProviderFiles.php b/apps/federatedfilesharing/lib/ocm/CloudFederationProviderFiles.php index a271fd454b2..565a46c6cf2 100644 --- a/apps/federatedfilesharing/lib/ocm/CloudFederationProviderFiles.php +++ b/apps/federatedfilesharing/lib/ocm/CloudFederationProviderFiles.php @@ -29,6 +29,7 @@ use OCA\FederatedFileSharing\FederatedShareProvider; use OCP\Activity\IManager as IActivityManager; use OCP\Activity\IManager; use OCP\App\IAppManager; +use OCP\Constants; use OCP\Federation\Exceptions\ActionNotSupportedException; use OCP\Federation\Exceptions\AuthenticationFailedException; use OCP\Federation\Exceptions\BadRequestException; @@ -258,6 +259,7 @@ class CloudFederationProviderFiles implements ICloudFederationProvider { * @param string $notificationType (e.g. SHARE_ACCEPTED) * @param string $providerId id of the share * @param array $notification payload of the notification + * @return array data send back to the sender * * @throws ActionNotSupportedException * @throws AuthenticationFailedException @@ -270,11 +272,11 @@ class CloudFederationProviderFiles implements ICloudFederationProvider { switch ($notificationType) { case 'SHARE_ACCEPTED': - $this->shareAccepted($providerId, $notification); - return; + return $this->shareAccepted($providerId, $notification); case 'SHARE_DECLINED': - $this->shareDeclined($providerId, $notification); - return; + return $this->shareDeclined($providerId, $notification); + case 'REQUEST_RESHARE': + return $this->reshareRequested($providerId, $notification); } @@ -282,9 +284,11 @@ class CloudFederationProviderFiles implements ICloudFederationProvider { } /** + * process notification that the recipient accepted a share + * * @param string $id * @param array $notification - * @return bool + * @return array * @throws ActionNotSupportedException * @throws AuthenticationFailedException * @throws BadRequestException @@ -325,7 +329,7 @@ class CloudFederationProviderFiles implements ICloudFederationProvider { } - return true; + return []; } /** @@ -351,14 +355,18 @@ class CloudFederationProviderFiles implements ICloudFederationProvider { } /** + * process notification that the recipient declined a share + * * @param string $id * @param array $notification + * @return array * @throws ActionNotSupportedException * @throws AuthenticationFailedException * @throws BadRequestException * @throws ShareNotFound * @throws ShareNotFoundException * @throws \OC\HintException + * */ protected function shareDeclined($id, $notification) { @@ -395,6 +403,8 @@ class CloudFederationProviderFiles implements ICloudFederationProvider { $this->executeDeclineShare($share); + return []; + } /** @@ -424,6 +434,64 @@ class CloudFederationProviderFiles implements ICloudFederationProvider { } + /** + * recipient of a share request to re-share the file with another user + * + * @param $id + * @param $notification + * @return array + * @throws AuthenticationFailedException + * @throws BadRequestException + * @throws ProviderCouldNotAddShareException + * @throws ShareNotFoundException + * @throws ShareNotFound + */ + protected function reshareRequested($id, $notification) { + + if (!isset($notification['sharedSecret'])) { + throw new BadRequestException(['sharedSecret']); + } + $token = $notification['sharedSecret']; + + if (!isset($notification['shareWith'])) { + throw new BadRequestException(['shareWith']); + } + $shareWith = $notification['shareWith']; + + if (!isset($notification['senderId'])) { + throw new BadRequestException(['senderId']); + } + $senderId = $notification['senderId']; + + $share = $this->federatedShareProvider->getShareById($id); + // don't allow to share a file back to the owner + try { + list($user, $remote) = $this->addressHandler->splitUserRemote($shareWith); + $owner = $share->getShareOwner(); + $currentServer = $this->addressHandler->generateRemoteURL(); + if ($this->addressHandler->compareAddresses($user, $remote, $owner, $currentServer)) { + throw new ProviderCouldNotAddShareException('Resharing back to the owner is not allowed: ' . $id); + } + } catch (\Exception $e) { + throw new ProviderCouldNotAddShareException($e->getMessage()); + } + + $this->verifyShare($share, $token); + + // check if re-sharing is allowed + if ($share->getPermissions() | ~Constants::PERMISSION_SHARE) { + // the recipient of the initial share is now the initiator for the re-share + $share->setSharedBy($share->getSharedWith()); + $share->setSharedWith($shareWith); + $result = $this->federatedShareProvider->create($share); + $this->federatedShareProvider->storeRemoteId((int)$result->getId(), $senderId); + return ['token' => $result->getToken(), 'providerId' => $result->getId()]; + } else { + throw new ProviderCouldNotAddShareException('resharing not allowed for share: ' . $id); + } + + throw new BadRequestException([]); + } /** * get file |