/** * Delete a share * * @param \OCP\Share\IShare $share * @throws ShareNotFound * @throws \InvalidArgumentException */ public function deleteShare(\OCP\Share\IShare $share) { try { $share->getFullId(); } catch (\UnexpectedValueException $e) { throw new \InvalidArgumentException('Share does not have a full id'); } $formatHookParams = function (\OCP\Share\IShare $share) { // Prepare hook $shareType = $share->getShareType(); $sharedWith = ''; if ($shareType === \OCP\Share::SHARE_TYPE_USER) { $sharedWith = $share->getSharedWith(); } else { if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) { $sharedWith = $share->getSharedWith(); } else { if ($shareType === \OCP\Share::SHARE_TYPE_REMOTE) { $sharedWith = $share->getSharedWith(); } } } $hookParams = ['id' => $share->getId(), 'itemType' => $share->getNodeType(), 'itemSource' => $share->getNodeId(), 'shareType' => $shareType, 'shareWith' => $sharedWith, 'itemparent' => method_exists($share, 'getParent') ? $share->getParent() : '', 'uidOwner' => $share->getSharedBy(), 'fileSource' => $share->getNodeId(), 'fileTarget' => $share->getTarget()]; return $hookParams; }; $hookParams = $formatHookParams($share); // Emit pre-hook \OC_Hook::emit('OCP\\Share', 'pre_unshare', $hookParams); // Get all children and delete them as well $deletedShares = $this->deleteChildren($share); // Do the actual delete $provider = $this->factory->getProviderForType($share->getShareType()); $provider->delete($share); // All the deleted shares caused by this delete $deletedShares[] = $share; //Format hook info $formattedDeletedShares = array_map(function ($share) use($formatHookParams) { return $formatHookParams($share); }, $deletedShares); $hookParams['deletedShares'] = $formattedDeletedShares; // Emit post hook \OC_Hook::emit('OCP\\Share', 'post_unshare', $hookParams); }
/** * 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; }
/** * return share type, can be "file" or "folder" * * @return string */ public function getItemType() { return $this->superShare->getNodeType(); }
/** * throws hooks when a share is attempted to be accessed * * @param \OCP\Share\IShare|string $share the Share instance if available, * otherwise token * @param int $errorCode * @param string $errorMessage * @throws OC\HintException * @throws OC\ServerNotAvailableException */ protected function emitAccessShareHook($share, $errorCode = 200, $errorMessage = '') { $itemType = $itemSource = $uidOwner = ''; $token = $share; $exception = null; if ($share instanceof \OCP\Share\IShare) { try { $token = $share->getToken(); $uidOwner = $share->getSharedBy(); $itemType = $share->getNodeType(); $itemSource = $share->getNodeId(); } catch (\Exception $e) { // we log what we know and pass on the exception afterwards $exception = $e; } } \OC_Hook::emit('OCP\\Share', 'share_link_access', ['itemType' => $itemType, 'itemSource' => $itemSource, 'uidOwner' => $uidOwner, 'token' => $token, 'errorCode' => $errorCode, 'errorMessage' => $errorMessage]); if (!is_null($exception)) { throw $exception; } }
/** * Makes sure an item type was set for that token * * @param IShare $share * * @throws CheckException */ private function checkItemType($share) { if ($share->getNodeType() === null) { $message = 'No item type set for share id: ' . $share->getId(); throw new CheckException($message, Http::STATUS_NOT_FOUND); } }
/** * 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 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; }