/** * send server-to-server share to remote server * * @param string $token * @param string $shareWith * @param string $name * @param int $remote_id * @param string $owner * @return bool */ public function sendRemoteShare($token, $shareWith, $name, $remote_id, $owner) { list($user, $remote) = $this->addressHandler->splitUserRemote($shareWith); if ($user && $remote) { $url = $remote; $local = $this->addressHandler->generateRemoteURL(); $fields = array('shareWith' => $user, 'token' => $token, 'name' => $name, 'remoteId' => $remote_id, 'owner' => $owner, 'remote' => $local); $url = $this->addressHandler->removeProtocolFromUrl($url); $result = $this->tryHttpPostToShareEndpoint($url, '', $fields); $status = json_decode($result['result'], true); if ($result['success'] && ($status['ocs']['meta']['statuscode'] === 100 || $status['ocs']['meta']['statuscode'] === 200)) { \OC_Hook::emit('OCP\\Share', 'federated_share_added', ['server' => $remote]); return true; } } return false; }
/** * create federated share and inform the recipient * * @param IShare $share * @return int * @throws ShareNotFound * @throws \Exception */ protected function createFederatedShare(IShare $share) { $token = $this->tokenHandler->generateToken(); $shareId = $this->addShareToDB($share->getNodeId(), $share->getNodeType(), $share->getSharedWith(), $share->getSharedBy(), $share->getShareOwner(), $share->getPermissions(), $token); $sharedByFederatedId = $share->getSharedBy(); if ($this->userManager->userExists($sharedByFederatedId)) { $sharedByFederatedId = $sharedByFederatedId . '@' . $this->addressHandler->generateRemoteURL(); } $send = $this->notifications->sendRemoteShare($token, $share->getSharedWith(), $share->getNode()->getName(), $shareId, $share->getShareOwner(), $share->getShareOwner() . '@' . $this->addressHandler->generateRemoteURL(), $share->getSharedBy(), $sharedByFederatedId); if ($send === false) { $data = $this->getRawShare($shareId); $share = $this->createShareObject($data); $this->removeShareFromTable($share); $message_t = $this->l->t('Sharing %s failed, could not find %s, maybe the server is currently unreachable.', [$share->getNode()->getName(), $share->getSharedWith()]); throw new \Exception($message_t); } return $shareId; }
/** * create re-share on behalf of another user * * @param $params * @return \OC_OCS_Result */ public function reShare($params) { $id = isset($params['id']) ? (int) $params['id'] : null; $token = $this->request->getParam('token', null); $shareWith = $this->request->getParam('shareWith', null); $permission = (int) $this->request->getParam('permission', null); $remoteId = (int) $this->request->getParam('remoteId', null); if ($id === null || $token === null || $shareWith === null || $permission === null || $remoteId === null) { return new \OC_OCS_Result(null, Http::STATUS_BAD_REQUEST); } try { $share = $this->federatedShareProvider->getShareById($id); } catch (Share\Exceptions\ShareNotFound $e) { return new \OC_OCS_Result(null, Http::STATUS_NOT_FOUND); } // 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)) { return new \OC_OCS_Result(null, Http::STATUS_FORBIDDEN); } 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 \OC_OCS_Result(['token' => $result->getToken(), 'remoteId' => $result->getId()]); } catch (\Exception $e) { return new \OC_OCS_Result(null, Http::STATUS_BAD_REQUEST); } } else { return new \OC_OCS_Result(null, Http::STATUS_FORBIDDEN); } } return new \OC_OCS_Result(null, Http::STATUS_BAD_REQUEST); }
/** * Share a path * * @param IShare $share * @return IShare The share object * @throws ShareNotFound * @throws \Exception */ public function create(IShare $share) { $shareWith = $share->getSharedWith(); $itemSource = $share->getNodeId(); $itemType = $share->getNodeType(); $uidOwner = $share->getShareOwner(); $permissions = $share->getPermissions(); $sharedBy = $share->getSharedBy(); /* * Check if file is not already shared with the remote user */ $alreadyShared = $this->getSharedWith($shareWith, self::SHARE_TYPE_REMOTE, $share->getNode(), 1, 0); if (!empty($alreadyShared)) { $message = 'Sharing %s failed, because this item is already shared with %s'; $message_t = $this->l->t('Sharing %s failed, because this item is already shared with %s', array($share->getNode()->getName(), $shareWith)); $this->logger->debug(sprintf($message, $share->getNode()->getName(), $shareWith), ['app' => 'Federated File Sharing']); throw new \Exception($message_t); } // don't allow federated shares if source and target server are the same list($user, $remote) = $this->addressHandler->splitUserRemote($shareWith); $currentServer = $this->addressHandler->generateRemoteURL(); $currentUser = $sharedBy; if ($this->addressHandler->compareAddresses($user, $remote, $currentUser, $currentServer)) { $message = 'Not allowed to create a federated share with the same user.'; $message_t = $this->l->t('Not allowed to create a federated share with the same user'); $this->logger->debug($message, ['app' => 'Federated File Sharing']); throw new \Exception($message_t); } $token = $this->tokenHandler->generateToken(); $shareWith = $user . '@' . $remote; $shareId = $this->addShareToDB($itemSource, $itemType, $shareWith, $sharedBy, $uidOwner, $permissions, $token); $send = $this->notifications->sendRemoteShare($token, $shareWith, $share->getNode()->getName(), $shareId, $share->getSharedBy()); $data = $this->getRawShare($shareId); $share = $this->createShare($data); if ($send === false) { $this->delete($share); $message_t = $this->l->t('Sharing %s failed, could not find %s, maybe the server is currently unreachable.', [$share->getNode()->getName(), $shareWith]); throw new \Exception($message_t); } return $share; }
/** * create federated share and inform the recipient * * @param IShare $share * @return int * @throws ShareNotFound * @throws \Exception */ protected function createFederatedShare(IShare $share) { $token = $this->tokenHandler->generateToken(); $shareId = $this->addShareToDB($share->getNodeId(), $share->getNodeType(), $share->getSharedWith(), $share->getSharedBy(), $share->getShareOwner(), $share->getPermissions(), $token); try { $sharedByFederatedId = $share->getSharedBy(); if ($this->userManager->userExists($sharedByFederatedId)) { $sharedByFederatedId = $sharedByFederatedId . '@' . $this->addressHandler->generateRemoteURL(); } $send = $this->notifications->sendRemoteShare($token, $share->getSharedWith(), $share->getNode()->getName(), $shareId, $share->getShareOwner(), $share->getShareOwner() . '@' . $this->addressHandler->generateRemoteURL(), $share->getSharedBy(), $sharedByFederatedId); if ($send === false) { $message_t = $this->l->t('Sharing %s failed, could not find %s, maybe the server is currently unreachable.', [$share->getNode()->getName(), $share->getSharedWith()]); throw new \Exception($message_t); } } catch (\Exception $e) { $this->logger->error('Failed to notify remote server of federated share, removing share (' . $e->getMessage() . ')'); $this->removeShareFromTableById($shareId); throw $e; } return $shareId; }