From aec5edc05bf855e3e112b01f1335e70a89d1f841 Mon Sep 17 00:00:00 2001 From: Micke Nordin Date: Fri, 16 Aug 2024 10:37:00 +0200 Subject: [PATCH] feat(CloudFederationApi): send 1.1.0 shares if possible, fall back to 1.0 Signed-off-by: Micke Nordin --- .../CloudFederationProviderManager.php | 41 +++++++++++++------ .../Federation/CloudFederationShare.php | 30 ++++++++++++++ .../Federation/ICloudFederationShare.php | 9 ++++ 3 files changed, 67 insertions(+), 13 deletions(-) diff --git a/lib/private/Federation/CloudFederationProviderManager.php b/lib/private/Federation/CloudFederationProviderManager.php index 79b37b44c828d..e73aac5a381c2 100644 --- a/lib/private/Federation/CloudFederationProviderManager.php +++ b/lib/private/Federation/CloudFederationProviderManager.php @@ -6,6 +6,7 @@ * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ + namespace OC\Federation; use OC\AppFramework\Http; @@ -30,7 +31,8 @@ * * @package OC\Federation */ -class CloudFederationProviderManager implements ICloudFederationProviderManager { +class CloudFederationProviderManager implements ICloudFederationProviderManager +{ /** @var array list of available cloud federation providers */ private array $cloudFederationProvider = []; @@ -41,8 +43,7 @@ public function __construct( private ICloudIdManager $cloudIdManager, private IOCMDiscoveryService $discoveryService, private LoggerInterface $logger - ) { - } + ) {} /** @@ -52,7 +53,8 @@ public function __construct( * @param string $displayName user facing name of the federated share provider * @param callable $callback */ - public function addCloudFederationProvider($resourceType, $displayName, callable $callback) { + public function addCloudFederationProvider($resourceType, $displayName, callable $callback) + { $this->cloudFederationProvider[$resourceType] = [ 'resourceType' => $resourceType, 'displayName' => $displayName, @@ -65,7 +67,8 @@ public function addCloudFederationProvider($resourceType, $displayName, callable * * @param string $providerId */ - public function removeCloudFederationProvider($providerId) { + public function removeCloudFederationProvider($providerId) + { unset($this->cloudFederationProvider[$providerId]); } @@ -74,7 +77,8 @@ public function removeCloudFederationProvider($providerId) { * * @return array [resourceType => ['resourceType' => $resourceType, 'displayName' => $displayName, 'callback' => callback]] */ - public function getAllCloudFederationProviders() { + public function getAllCloudFederationProviders() + { return $this->cloudFederationProvider; } @@ -85,7 +89,8 @@ public function getAllCloudFederationProviders() { * @return ICloudFederationProvider * @throws ProviderDoesNotExistsException */ - public function getCloudFederationProvider($resourceType) { + public function getCloudFederationProvider($resourceType) + { if (isset($this->cloudFederationProvider[$resourceType])) { return call_user_func($this->cloudFederationProvider[$resourceType]['callback']); } else { @@ -96,7 +101,8 @@ public function getCloudFederationProvider($resourceType) { /** * @deprecated 29.0.0 - Use {@see sendCloudShare()} instead and handle errors manually */ - public function sendShare(ICloudFederationShare $share) { + public function sendShare(ICloudFederationShare $share) + { $cloudID = $this->cloudIdManager->resolveCloudId($share->getShareWith()); try { $ocmProvider = $this->discoveryService->discover($cloudID->getRemote()); @@ -137,14 +143,20 @@ public function sendShare(ICloudFederationShare $share) { * @return IResponse * @throws OCMProviderException */ - public function sendCloudShare(ICloudFederationShare $share): IResponse { + public function sendCloudShare(ICloudFederationShare $share): IResponse + { $cloudID = $this->cloudIdManager->resolveCloudId($share->getShareWith()); $ocmProvider = $this->discoveryService->discover($cloudID->getRemote()); + $version = $ocmProvider->getApiVersion(); + $send_share = $share->getShare(); + if (str_starts_with($version, '1.0')) { + $send_share = $share->toLegacyShare(); + } $client = $this->httpClientService->newClient(); try { return $client->post($ocmProvider->getEndPoint() . '/shares', [ - 'body' => json_encode($share->getShare()), + 'body' => json_encode($send_share), 'headers' => ['content-type' => 'application/json'], 'verify' => !$this->config->getSystemValueBool('sharing.federation.allowSelfSignedCertificates', false), 'timeout' => 10, @@ -166,7 +178,8 @@ public function sendCloudShare(ICloudFederationShare $share): IResponse { * @return array|false * @deprecated 29.0.0 - Use {@see sendCloudNotification()} instead and handle errors manually */ - public function sendNotification($url, ICloudFederationNotification $notification) { + public function sendNotification($url, ICloudFederationNotification $notification) + { try { $ocmProvider = $this->discoveryService->discover($url); } catch (OCMProviderException $e) { @@ -200,7 +213,8 @@ public function sendNotification($url, ICloudFederationNotification $notificatio * @return IResponse * @throws OCMProviderException */ - public function sendCloudNotification(string $url, ICloudFederationNotification $notification): IResponse { + public function sendCloudNotification(string $url, ICloudFederationNotification $notification): IResponse + { $ocmProvider = $this->discoveryService->discover($url); $client = $this->httpClientService->newClient(); @@ -227,7 +241,8 @@ public function sendCloudNotification(string $url, ICloudFederationNotification * * @return bool */ - public function isReady() { + public function isReady() + { return $this->appManager->isEnabledForUser('cloud_federation_api'); } } diff --git a/lib/private/Federation/CloudFederationShare.php b/lib/private/Federation/CloudFederationShare.php index f70edef65aa43..b5013fe10a4db 100644 --- a/lib/private/Federation/CloudFederationShare.php +++ b/lib/private/Federation/CloudFederationShare.php @@ -74,6 +74,36 @@ public function __construct( $this->setResourceType($resourceType); } + /** + * get the share in 1.0 format ready to send out + * + * @return array + * + * @since 30.0.0 + */ + public function toLegacyShare() + { + $sharedSecret = $this->getShareSecret(); + $protocol = array( + 'name' => 'webdav', + 'options' => array('sharedSecret' => $sharedSecret, 'permissions' => '{http://open-cloud-mesh.org/ns}share-permissions') + ); + $share = [ + 'shareWith' => $this->getShareWith(), + 'name' => $this->getResourceName(), + 'description' => $this->getDescription(), + 'providerId' => $this->getProviderId(), + 'owner' => $this->getOwner(), + 'sender' => $this->getSender(), + 'ownerDisplayName' => $this->getOwnerDisplayName(), + 'senderDisplayName' => $this->getSenderDisplayName(), + 'shareType' => $this->getShareType(), + 'resourceType' => $this->getResourceType(), + 'protocol' => $protocol, + ]; + return $share; + } + /** * set uid of the recipient * diff --git a/lib/public/Federation/ICloudFederationShare.php b/lib/public/Federation/ICloudFederationShare.php index 2cc519ce62417..2872cc8208e10 100644 --- a/lib/public/Federation/ICloudFederationShare.php +++ b/lib/public/Federation/ICloudFederationShare.php @@ -12,6 +12,15 @@ * @since 14.0.0 */ interface ICloudFederationShare { + /** + * get the share in 1.0 format ready to send out + * + * @return array + * + * @since 30.0.0 + */ + public function toLegacyShare(); + /** * set uid of the recipient *