diff --git a/apps/files_sharing/lib/Controller/ShareAPIController.php b/apps/files_sharing/lib/Controller/ShareAPIController.php index 069cba42bb6d1..de055b1987587 100644 --- a/apps/files_sharing/lib/Controller/ShareAPIController.php +++ b/apps/files_sharing/lib/Controller/ShareAPIController.php @@ -317,6 +317,14 @@ protected function formatShare(IShare $share, Node $recipientNode = null): array $result = array_merge($result, $this->getDeckShareHelper()->formatShare($share)); } catch (QueryException $e) { } + } elseif ($share->getShareType() === IShare::TYPE_SCIENCEMESH) { + $result['share_with'] = $share->getSharedWith(); + $result['share_with_displayname'] = ''; + + try { + $result = array_merge($result, $this->getScienceMeshShareHelper()->formatShare($share)); + } catch (QueryException $e) { + } } @@ -662,6 +670,12 @@ public function createShare( } catch (QueryException $e) { throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not support room shares', [$node->getPath()])); } + } elseif ($shareType === IShare::TYPE_SCIENCEMESH) { + try { + $this->getScienceMeshShareHelper()->createShare($share, $shareWith, $permissions, $expireDate); + } catch (QueryException $e) { + throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not support sciencemesh shares', [$path->getPath()])); + } } else { throw new OCSBadRequestException($this->l->t('Unknown share type')); } @@ -1567,6 +1581,15 @@ private function getShareById(string $id): IShare { // Do nothing, just try the other share type } + try { + if ($this->shareManager->shareProviderExists(IShare::TYPE_SCIENCEMESH)) { + $share = $this->shareManager->getShareById('sciencemesh:' . $id, $this->currentUser); + return $share; + } + } catch (ShareNotFound $e) { + // Do nothing, just try the other share type + } + if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) { throw new ShareNotFound(); } @@ -1630,6 +1653,23 @@ private function getDeckShareHelper() { return $this->serverContainer->get('\OCA\Deck\Sharing\ShareAPIHelper'); } + /** + * Returns the helper of ShareAPIHelper for sciencemesh shares. + * + * If the ScienceMesh application is not enabled or the helper is not available + * a QueryException is thrown instead. + * + * @return \OCA\ScienceMesh\ShareProvider\ShareAPIHelper + * @throws QueryException + */ + private function getScienceMeshShareHelper() { + if (!$this->appManager->isEnabledForUser('sciencemesh')) { + throw new QueryException(); + } + + return $this->serverContainer->get('\OCA\ScienceMesh\ShareProvider\ShareAPIHelper'); + } + /** * @param string $viewer * @param Node $node @@ -1645,7 +1685,8 @@ private function getSharesFromNode(string $viewer, $node, bool $reShares): array IShare::TYPE_EMAIL, IShare::TYPE_CIRCLE, IShare::TYPE_ROOM, - IShare::TYPE_DECK + IShare::TYPE_DECK, + IShare::TYPE_SCIENCEMESH ]; // Should we assume that the (currentUser) viewer is the owner of the node !? @@ -1800,6 +1841,9 @@ private function getAllShares(?Node $path = null, bool $reshares = false) { $deckShares = $this->shareManager->getSharesBy($this->currentUser, IShare::TYPE_DECK, $path, $reshares, -1, 0); + // SCIENCEMESH SHARES + $scienceMeshShares = $this->shareManager->getSharesBy($this->currentUser, IShare::TYPE_SCIENCEMESH, $path, $reshares, -1, 0); + // FEDERATION if ($this->shareManager->outgoingServer2ServerSharesAllowed()) { $federatedShares = $this->shareManager->getSharesBy($this->currentUser, IShare::TYPE_REMOTE, $path, $reshares, -1, 0); @@ -1812,7 +1856,7 @@ private function getAllShares(?Node $path = null, bool $reshares = false) { $federatedGroupShares = []; } - return array_merge($userShares, $groupShares, $linkShares, $mailShares, $circleShares, $roomShares, $deckShares, $federatedShares, $federatedGroupShares); + return array_merge($userShares, $groupShares, $linkShares, $mailShares, $circleShares, $roomShares, $deckShares, $federatedShares, $federatedGroupShares, $scienceMeshShares); } diff --git a/lib/private/Share20/Manager.php b/lib/private/Share20/Manager.php index 3fca9e3fe149b..315bed9692585 100644 --- a/lib/private/Share20/Manager.php +++ b/lib/private/Share20/Manager.php @@ -211,43 +211,47 @@ protected function verifyPassword($password) { * @suppress PhanUndeclaredClassMethod */ protected function generalCreateChecks(IShare $share) { - if ($share->getShareType() === IShare::TYPE_USER) { - // We expect a valid user as sharedWith for user shares - if (!$this->userManager->userExists($share->getSharedWith())) { - throw new \InvalidArgumentException('SharedWith is not a valid user'); - } - } elseif ($share->getShareType() === IShare::TYPE_GROUP) { - // We expect a valid group as sharedWith for group shares - if (!$this->groupManager->groupExists($share->getSharedWith())) { - throw new \InvalidArgumentException('SharedWith is not a valid group'); - } - } elseif ($share->getShareType() === IShare::TYPE_LINK) { - // No check for TYPE_EMAIL here as we have a recipient for them - if ($share->getSharedWith() !== null) { - throw new \InvalidArgumentException('SharedWith should be empty'); - } - } elseif ($share->getShareType() === IShare::TYPE_EMAIL) { - if ($share->getSharedWith() === null) { - throw new \InvalidArgumentException('SharedWith should not be empty'); - } - } elseif ($share->getShareType() === IShare::TYPE_REMOTE) { - if ($share->getSharedWith() === null) { - throw new \InvalidArgumentException('SharedWith should not be empty'); - } - } elseif ($share->getShareType() === IShare::TYPE_REMOTE_GROUP) { - if ($share->getSharedWith() === null) { - throw new \InvalidArgumentException('SharedWith should not be empty'); - } - } elseif ($share->getShareType() === IShare::TYPE_CIRCLE) { - $circle = \OCA\Circles\Api\v1\Circles::detailsCircle($share->getSharedWith()); - if ($circle === null) { - throw new \InvalidArgumentException('SharedWith is not a valid circle'); - } - } elseif ($share->getShareType() === IShare::TYPE_ROOM) { - } elseif ($share->getShareType() === IShare::TYPE_DECK) { - } else { - // We cannot handle other types yet - throw new \InvalidArgumentException('unknown share type'); + $shareType = $share->getShareType(); + if (!$this->factory->getProviderForType($shareType)) { + // We can't handle other types yet + throw new \InvalidArgumentException('unknown share type, no provider found'); + } + + // verify sharedWith for this share type; + switch ($shareType) { + case IShare::TYPE_USER: + // We expect a valid user as sharedWith for user shares + if (!$this->userManager->userExists($share->getSharedWith())) { + throw new \InvalidArgumentException('SharedWith is not a valid user'); + } + break; + case IShare::TYPE_GROUP: + // We expect a valid group as sharedWith for group shares + if (!$this->groupManager->groupExists($share->getSharedWith())) { + throw new \InvalidArgumentException('SharedWith is not a valid group'); + } + break; + case IShare::TYPE_LINK: + if ($share->getSharedWith() !== null) { + throw new \InvalidArgumentException('SharedWith should be empty'); + } + break; + case IShare::TYPE_REMOTE: + case IShare::TYPE_REMOTE_GROUP: + case IShare::TYPE_EMAIL: + if ($share->getSharedWith() === null) { + throw new \InvalidArgumentException('SharedWith should not be empty'); + } + break; + case IShare::TYPE_CIRCLE: + $circle = \OCA\Circles\Api\v1\Circles::detailsCircle($share->getSharedWith()); + if ($circle === null) { + throw new \InvalidArgumentException('SharedWith is not a valid circle'); + } + break; + default: + // no checks by default; + break; } // Verify the initiator of the share is set diff --git a/lib/private/Share20/ProviderFactory.php b/lib/private/Share20/ProviderFactory.php index 42677d6bcf7f1..3da872c5e4c19 100644 --- a/lib/private/Share20/ProviderFactory.php +++ b/lib/private/Share20/ProviderFactory.php @@ -308,25 +308,49 @@ public function getProvider($id) { */ public function getProviderForType($shareType) { $provider = null; - - if ($shareType === IShare::TYPE_USER || - $shareType === IShare::TYPE_GROUP || - $shareType === IShare::TYPE_LINK - ) { - $provider = $this->defaultShareProvider(); - } elseif ($shareType === IShare::TYPE_REMOTE || $shareType === IShare::TYPE_REMOTE_GROUP) { - $provider = $this->federatedShareProvider(); - } elseif ($shareType === IShare::TYPE_EMAIL) { - $provider = $this->getShareByMailProvider(); - } elseif ($shareType === IShare::TYPE_CIRCLE) { - $provider = $this->getShareByCircleProvider(); - } elseif ($shareType === IShare::TYPE_ROOM) { - $provider = $this->getRoomShareProvider(); - } elseif ($shareType === IShare::TYPE_DECK) { - $provider = $this->getProvider('deck'); + + switch ($shareType) { + case IShare::TYPE_USER: + case IShare::TYPE_GROUP: + case IShare::TYPE_LINK: + $provider = $this->defaultShareProvider(); + break; + case IShare::TYPE_REMOTE: + case IShare::TYPE_REMOTE_GROUP: + $provider = $this->federatedShareProvider(); + break; + case IShare::TYPE_EMAIL: + $provider = $this->getShareByMailProvider(); + break; + case IShare::TYPE_CIRCLE: + $provider = $this->getShareByCircleProvider(); + break; + case IShare::TYPE_ROOM: + $provider = $this->getRoomShareProvider(); + break; + case IShare::TYPE_DECK: + $provider = $this->getProvider('deck'); + break; +// case IShare::TYPE_SCIENCEMESH: +// $provider = $this->getProvider('sciencemesh'); +// break; + default: + // try to autodetect in the registered providers; + foreach ($this->registeredShareProviders as $shareProvider) { + /** @var IShareProvider $instance */ + $instance = $this->serverContainer->get($shareProvider); + + // not all instances will have the isShareTypeSupported function; + if (method_exists($instance, "isShareTypeSupported")) { + if ($instance->isShareTypeSupported($shareType)) { + $provider = $this->getProvider($instance->identifier()); + break; + } + } + } + break; } - if ($provider === null) { throw new ProviderException('No share provider for share type ' . $shareType); } diff --git a/lib/public/Share/IShare.php b/lib/public/Share/IShare.php index 8ff3f5f0394ea..afe837e4a707b 100644 --- a/lib/public/Share/IShare.php +++ b/lib/public/Share/IShare.php @@ -116,6 +116,11 @@ interface IShare { */ public const TYPE_DECK_USER = 13; + /** + * @since ? + */ + public const TYPE_SCIENCEMESH = 1000; + /** * @since 18.0.0 */