diff options
author | Bjoern Schiessle <bjoern@schiessle.org> | 2018-06-04 16:36:37 +0200 |
---|---|---|
committer | Bjoern Schiessle <bjoern@schiessle.org> | 2018-07-02 11:29:28 +0200 |
commit | a176a1f318501ecf344a43b66811985eee99c426 (patch) | |
tree | a00458c6ea91393ac5101bf4173d32e5e271a6dc /apps/federatedfilesharing/lib | |
parent | fab4e561f4f3ea9a3cf90a01c39c8d1e87ee9eab (diff) | |
download | nextcloud-server-a176a1f318501ecf344a43b66811985eee99c426.tar.gz nextcloud-server-a176a1f318501ecf344a43b66811985eee99c426.zip |
implement unshare notification
Signed-off-by: Bjoern Schiessle <bjoern@schiessle.org>
Diffstat (limited to 'apps/federatedfilesharing/lib')
4 files changed, 145 insertions, 63 deletions
diff --git a/apps/federatedfilesharing/lib/AppInfo/Application.php b/apps/federatedfilesharing/lib/AppInfo/Application.php index 093e1e44f94..70347831211 100644 --- a/apps/federatedfilesharing/lib/AppInfo/Application.php +++ b/apps/federatedfilesharing/lib/AppInfo/Application.php @@ -64,7 +64,8 @@ class Application extends App { $server->getNotificationManager(), $server->getURLGenerator(), $server->getCloudFederationFactory(), - $server->getCloudFederationProviderManager() + $server->getCloudFederationProviderManager(), + $server->getDatabaseConnection() ); }); diff --git a/apps/federatedfilesharing/lib/Controller/RequestHandlerController.php b/apps/federatedfilesharing/lib/Controller/RequestHandlerController.php index 041232c83e6..0b490b57575 100644 --- a/apps/federatedfilesharing/lib/Controller/RequestHandlerController.php +++ b/apps/federatedfilesharing/lib/Controller/RequestHandlerController.php @@ -333,60 +333,12 @@ class RequestHandlerController extends OCSController { $token = isset($_POST['token']) ? $_POST['token'] : null; - $qb = $this->connection->getQueryBuilder(); - $qb->select('*') - ->from('share_external') - ->where( - $qb->expr()->andX( - $qb->expr()->eq('remote_id', $qb->createNamedParameter($id)), - $qb->expr()->eq('share_token', $qb->createNamedParameter($token)) - ) - ); - - $result = $qb->execute(); - $share = $result->fetch(); - $result->closeCursor(); - - if ($token && $id && !empty($share)) { - - $remote = $this->cleanupRemote($share['remote']); - - $owner = $this->cloudIdManager->getCloudId($share['owner'], $remote); - $mountpoint = $share['mountpoint']; - $user = $share['user']; - - $qb = $this->connection->getQueryBuilder(); - $qb->delete('share_external') - ->where( - $qb->expr()->andX( - $qb->expr()->eq('remote_id', $qb->createNamedParameter($id)), - $qb->expr()->eq('share_token', $qb->createNamedParameter($token)) - ) - ); - - $result = $qb->execute(); - $result->closeCursor(); - - if ($share['accepted']) { - $path = trim($mountpoint, '/'); - } else { - $path = trim($share['name'], '/'); - } - - $notificationManager = \OC::$server->getNotificationManager(); - $notification = $notificationManager->createNotification(); - $notification->setApp('files_sharing') - ->setUser($share['user']) - ->setObject('remote_share', (int)$share['id']); - $notificationManager->markProcessed($notification); - - $event = \OC::$server->getActivityManager()->generateEvent(); - $event->setApp('files_sharing') - ->setType('remote_share') - ->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_UNSHARED, [$owner->getId(), $path]) - ->setAffectedUser($user) - ->setObject('remote_share', (int)$share['id'], $path); - \OC::$server->getActivityManager()->publish($event); + try { + $provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file'); + $notification = ['sharedSecret' => $token]; + $provider->notificationReceived('SHARE_UNSHARED', $id, $notification); + } catch (\Exception $e) { + $this->logger->debug('processing unshare notification failed: ' . $e->getMessage()); } return new Http\DataResponse(); @@ -410,16 +362,20 @@ class RequestHandlerController extends OCSController { * @throws OCSBadRequestException */ public function revoke($id) { + $token = $this->request->getParam('token'); - $share = $this->federatedShareProvider->getShareById($id); + $notification = $this->cloudFederationFactory->getCloudFederationNotification(); + $notification->setMessage(['sharedSecret' => $token]); - if ($this->verifyShare($share, $token)) { - $this->federatedShareProvider->removeShareFromTable($share); + try { + $provider = $this->cloudFederationProviderManager->getCloudFederationProvider('file'); + $provider->notificationReceived('SHARE_UNSHARE', $id, $notification); return new Http\DataResponse(); + } catch (\Exception $e) { + throw new OCSBadRequestException(); } - throw new OCSBadRequestException(); } /** diff --git a/apps/federatedfilesharing/lib/Notifications.php b/apps/federatedfilesharing/lib/Notifications.php index 33254774e28..36eb88e31a2 100644 --- a/apps/federatedfilesharing/lib/Notifications.php +++ b/apps/federatedfilesharing/lib/Notifications.php @@ -199,7 +199,7 @@ class Notifications { * @return bool */ public function sendRevokeShare($remote, $id, $token) { - $this->sendUpdateToRemote($remote, $id, $token, 'revoke'); + $this->sendUpdateToRemote($remote, $id, $token, 'reshare_undo'); } /** @@ -250,12 +250,15 @@ class Notifications { */ public function sendUpdateToRemote($remote, $remoteId, $token, $action, $data = [], $try = 0) { - $fields = array('token' => $token); + $fields = [ + 'token' => $token, + 'remoteId' => $remoteId + ]; foreach ($data as $key => $value) { $fields[$key] = $value; } - $result = $this->tryHttpPostToShareEndpoint(rtrim($remote, '/'), '/' . $remoteId . '/' . $action, $fields); + $result = $this->tryHttpPostToShareEndpoint(rtrim($remote, '/'), '/' . $remoteId . '/' . $action, $fields, $action); $status = json_decode($result['result'], true); if ($result['success'] && @@ -416,6 +419,7 @@ class Notifications { ); return $this->federationProviderManager->sendShare($share); case 'reshare': + // ask owner to reshare a file $notification = $this->cloudFederationFactory->getCloudFederationNotification(); $notification->setMessage('REQUEST_RESHARE', 'file', @@ -428,6 +432,18 @@ class Notifications { ] ); return $this->federationProviderManager->sendNotification($remoteDomain, $notification); + case 'unshare': + //owner unshares the file from the recipient again + $notification = $this->cloudFederationFactory->getCloudFederationNotification(); + $notification->setMessage('SHARE_UNSHARED', + 'file', + $fields['remoteId'], + [ + 'sharedSecret' => $fields['token'], + ] + ); + return $this->federationProviderManager->sendNotification($remoteDomain, $notification); + return false; } return false; diff --git a/apps/federatedfilesharing/lib/ocm/CloudFederationProviderFiles.php b/apps/federatedfilesharing/lib/ocm/CloudFederationProviderFiles.php index 565a46c6cf2..dc022e4f9c8 100644 --- a/apps/federatedfilesharing/lib/ocm/CloudFederationProviderFiles.php +++ b/apps/federatedfilesharing/lib/ocm/CloudFederationProviderFiles.php @@ -41,6 +41,7 @@ use OCP\Federation\ICloudFederationProviderManager; use OCP\Federation\ICloudFederationShare; use OCP\Federation\ICloudIdManager; use OCP\Files\NotFoundException; +use OCP\IDBConnection; use OCP\ILogger; use OCP\IURLGenerator; use OCP\IUserManager; @@ -84,6 +85,9 @@ class CloudFederationProviderFiles implements ICloudFederationProvider { /** @var ICloudFederationProviderManager */ private $cloudFederationProviderManager; + /** @var IDBConnection */ + private $connection; + /** * CloudFederationProvider constructor. * @@ -98,6 +102,7 @@ class CloudFederationProviderFiles implements ICloudFederationProvider { * @param IURLGenerator $urlGenerator * @param ICloudFederationFactory $cloudFederationFactory * @param ICloudFederationProviderManager $cloudFederationProviderManager + * @param IDBConnection $connection */ public function __construct(IAppManager $appManager, FederatedShareProvider $federatedShareProvider, @@ -109,7 +114,8 @@ class CloudFederationProviderFiles implements ICloudFederationProvider { INotificationManager $notificationManager, IURLGenerator $urlGenerator, ICloudFederationFactory $cloudFederationFactory, - ICloudFederationProviderManager $cloudFederationProviderManager + ICloudFederationProviderManager $cloudFederationProviderManager, + IDBConnection $connection ) { $this->appManager = $appManager; $this->federatedShareProvider = $federatedShareProvider; @@ -122,6 +128,7 @@ class CloudFederationProviderFiles implements ICloudFederationProvider { $this->urlGenerator = $urlGenerator; $this->cloudFederationFactory = $cloudFederationFactory; $this->cloudFederationProviderManager = $cloudFederationProviderManager; + $this->connection = $connection; } @@ -275,8 +282,12 @@ class CloudFederationProviderFiles implements ICloudFederationProvider { return $this->shareAccepted($providerId, $notification); case 'SHARE_DECLINED': return $this->shareDeclined($providerId, $notification); + case 'SHARE_UNSHARED': + return $this->unshare($providerId, $notification); case 'REQUEST_RESHARE': return $this->reshareRequested($providerId, $notification); + case 'RESHARE_UNDO': + return $this->undoReshare($providerId, $notification); } @@ -435,6 +446,104 @@ class CloudFederationProviderFiles implements ICloudFederationProvider { } /** + * received the notification that the owner unshared a file from you + * + * @param string $id + * @param string $notification + * @return array + * @throws AuthenticationFailedException + * @throws BadRequestException + * @throws ShareNotFoundException + */ + private function undoReshare($id, $notification) { + + if (!isset($notification['sharedSecret'])) { + throw new BadRequestException(['sharedSecret']); + } + $token = $notification['sharedSecret']; + + $share = $this->federatedShareProvider->getShareById($id); + + $this->verifyShare($share, $token); + $this->federatedShareProvider->removeShareFromTable($share); + return []; + } + + private function unshare($id, $notification) { + error_log("new unshare!"); + if (!$this->isS2SEnabled(true)) { + throw new ActionNotSupportedException("incoming shares disabled!"); + } + + if (!isset($notification['sharedSecret'])) { + throw new BadRequestException(['sharedSecret']); + } + $token = $notification['sharedSecret']; + + $qb = $this->connection->getQueryBuilder(); + $qb->select('*') + ->from('share_external') + ->where( + $qb->expr()->andX( + $qb->expr()->eq('remote_id', $qb->createNamedParameter($id)), + $qb->expr()->eq('share_token', $qb->createNamedParameter($token)) + ) + ); + + $result = $qb->execute(); + $share = $result->fetch(); + $result->closeCursor(); + + if ($token && $id && !empty($share)) { + + $remote = $this->cleanupRemote($share['remote']); + + $owner = $this->cloudIdManager->getCloudId($share['owner'], $remote); + $mountpoint = $share['mountpoint']; + $user = $share['user']; + + $qb = $this->connection->getQueryBuilder(); + $qb->delete('share_external') + ->where( + $qb->expr()->andX( + $qb->expr()->eq('remote_id', $qb->createNamedParameter($id)), + $qb->expr()->eq('share_token', $qb->createNamedParameter($token)) + ) + ); + + $qb->execute(); + + if ($share['accepted']) { + $path = trim($mountpoint, '/'); + } else { + $path = trim($share['name'], '/'); + } + + $notification = $this->notificationManager->createNotification(); + $notification->setApp('files_sharing') + ->setUser($share['user']) + ->setObject('remote_share', (int)$share['id']); + $this->notificationManager->markProcessed($notification); + + $event = $this->activityManager->generateEvent(); + $event->setApp('files_sharing') + ->setType('remote_share') + ->setSubject(RemoteShares::SUBJECT_REMOTE_SHARE_UNSHARED, [$owner->getId(), $path]) + ->setAffectedUser($user) + ->setObject('remote_share', (int)$share['id'], $path); + \OC::$server->getActivityManager()->publish($event); + } + + return []; + } + + private function cleanupRemote($remote) { + $remote = substr($remote, strpos($remote, '://') + 3); + + return rtrim($remote, '/'); + } + + /** * recipient of a share request to re-share the file with another user * * @param $id |