summaryrefslogtreecommitdiffstats
path: root/apps/federatedfilesharing
diff options
context:
space:
mode:
authorBjoern Schiessle <bjoern@schiessle.org>2018-06-04 12:16:03 +0200
committerBjoern Schiessle <bjoern@schiessle.org>2018-07-02 11:29:28 +0200
commitfab4e561f4f3ea9a3cf90a01c39c8d1e87ee9eab (patch)
tree723753d2819808ab0ed16d7c9574a3fd6a74ab26 /apps/federatedfilesharing
parent41a1528888062610af58e319ce7bfa3ef8784da3 (diff)
downloadnextcloud-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')
-rw-r--r--apps/federatedfilesharing/lib/Controller/RequestHandlerController.php54
-rw-r--r--apps/federatedfilesharing/lib/FederatedShareProvider.php3
-rw-r--r--apps/federatedfilesharing/lib/Notifications.php52
-rw-r--r--apps/federatedfilesharing/lib/ocm/CloudFederationProviderFiles.php80
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