aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files_sharing/lib/Controller/DeletedShareAPIController.php
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files_sharing/lib/Controller/DeletedShareAPIController.php')
-rw-r--r--apps/files_sharing/lib/Controller/DeletedShareAPIController.php240
1 files changed, 240 insertions, 0 deletions
diff --git a/apps/files_sharing/lib/Controller/DeletedShareAPIController.php b/apps/files_sharing/lib/Controller/DeletedShareAPIController.php
new file mode 100644
index 00000000000..2fa4d7c668f
--- /dev/null
+++ b/apps/files_sharing/lib/Controller/DeletedShareAPIController.php
@@ -0,0 +1,240 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\Files_Sharing\Controller;
+
+use OCA\Deck\Sharing\ShareAPIHelper;
+use OCA\Files_Sharing\ResponseDefinitions;
+use OCP\App\IAppManager;
+use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\Attribute\NoAdminRequired;
+use OCP\AppFramework\Http\DataResponse;
+use OCP\AppFramework\OCS\OCSException;
+use OCP\AppFramework\OCS\OCSNotFoundException;
+use OCP\AppFramework\OCSController;
+use OCP\AppFramework\QueryException;
+use OCP\Files\Folder;
+use OCP\Files\IRootFolder;
+use OCP\Files\NotFoundException;
+use OCP\IGroupManager;
+use OCP\IRequest;
+use OCP\IUserManager;
+use OCP\Server;
+use OCP\Share\Exceptions\GenericShareException;
+use OCP\Share\Exceptions\ShareNotFound;
+use OCP\Share\IManager as ShareManager;
+use OCP\Share\IShare;
+
+/**
+ * @psalm-import-type Files_SharingDeletedShare from ResponseDefinitions
+ */
+class DeletedShareAPIController extends OCSController {
+
+ public function __construct(
+ string $appName,
+ IRequest $request,
+ private ShareManager $shareManager,
+ private ?string $userId,
+ private IUserManager $userManager,
+ private IGroupManager $groupManager,
+ private IRootFolder $rootFolder,
+ private IAppManager $appManager,
+ ) {
+ parent::__construct($appName, $request);
+ }
+
+ /**
+ * @suppress PhanUndeclaredClassMethod
+ *
+ * @return Files_SharingDeletedShare
+ */
+ private function formatShare(IShare $share): array {
+ $result = [
+ 'id' => $share->getFullId(),
+ 'share_type' => $share->getShareType(),
+ 'uid_owner' => $share->getSharedBy(),
+ 'displayname_owner' => $this->userManager->get($share->getSharedBy())->getDisplayName(),
+ 'permissions' => 0,
+ 'stime' => $share->getShareTime()->getTimestamp(),
+ 'parent' => null,
+ 'expiration' => null,
+ 'token' => null,
+ 'uid_file_owner' => $share->getShareOwner(),
+ 'displayname_file_owner' => $this->userManager->get($share->getShareOwner())->getDisplayName(),
+ 'path' => $share->getTarget(),
+ ];
+ $userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
+ $node = $userFolder->getFirstNodeById($share->getNodeId());
+ if (!$node) {
+ // fallback to guessing the path
+ $node = $userFolder->get($share->getTarget());
+ if ($node === null || $share->getTarget() === '') {
+ throw new NotFoundException();
+ }
+ }
+
+ $result['path'] = $userFolder->getRelativePath($node->getPath());
+ if ($node instanceof Folder) {
+ $result['item_type'] = 'folder';
+ } else {
+ $result['item_type'] = 'file';
+ }
+ $result['mimetype'] = $node->getMimetype();
+ $result['storage_id'] = $node->getStorage()->getId();
+ $result['storage'] = $node->getStorage()->getCache()->getNumericStorageId();
+ $result['item_source'] = $node->getId();
+ $result['file_source'] = $node->getId();
+ $result['file_parent'] = $node->getParent()->getId();
+ $result['file_target'] = $share->getTarget();
+ $result['item_size'] = $node->getSize();
+ $result['item_mtime'] = $node->getMTime();
+
+ $expiration = $share->getExpirationDate();
+ if ($expiration !== null) {
+ $result['expiration'] = $expiration->format('Y-m-d 00:00:00');
+ }
+
+ if ($share->getShareType() === IShare::TYPE_GROUP) {
+ $group = $this->groupManager->get($share->getSharedWith());
+ $result['share_with'] = $share->getSharedWith();
+ $result['share_with_displayname'] = $group !== null ? $group->getDisplayName() : $share->getSharedWith();
+ } elseif ($share->getShareType() === IShare::TYPE_ROOM) {
+ $result['share_with'] = $share->getSharedWith();
+ $result['share_with_displayname'] = '';
+
+ try {
+ $result = array_merge($result, $this->getRoomShareHelper()->formatShare($share));
+ } catch (QueryException $e) {
+ }
+ } elseif ($share->getShareType() === IShare::TYPE_DECK) {
+ $result['share_with'] = $share->getSharedWith();
+ $result['share_with_displayname'] = '';
+
+ try {
+ $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) {
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * Get a list of all deleted shares
+ *
+ * @return DataResponse<Http::STATUS_OK, list<Files_SharingDeletedShare>, array{}>
+ *
+ * 200: Deleted shares returned
+ */
+ #[NoAdminRequired]
+ public function index(): DataResponse {
+ $groupShares = $this->shareManager->getDeletedSharedWith($this->userId, IShare::TYPE_GROUP, null, -1, 0);
+ $teamShares = $this->shareManager->getDeletedSharedWith($this->userId, IShare::TYPE_CIRCLE, null, -1, 0);
+ $roomShares = $this->shareManager->getDeletedSharedWith($this->userId, IShare::TYPE_ROOM, null, -1, 0);
+ $deckShares = $this->shareManager->getDeletedSharedWith($this->userId, IShare::TYPE_DECK, null, -1, 0);
+ $sciencemeshShares = $this->shareManager->getDeletedSharedWith($this->userId, IShare::TYPE_SCIENCEMESH, null, -1, 0);
+
+ $shares = array_merge($groupShares, $teamShares, $roomShares, $deckShares, $sciencemeshShares);
+
+ $shares = array_values(array_map(function (IShare $share) {
+ return $this->formatShare($share);
+ }, $shares));
+
+ return new DataResponse($shares);
+ }
+
+ /**
+ * Undelete a deleted share
+ *
+ * @param string $id ID of the share
+ * @return DataResponse<Http::STATUS_OK, list<empty>, array{}>
+ * @throws OCSException
+ * @throws OCSNotFoundException Share not found
+ *
+ * 200: Share undeleted successfully
+ */
+ #[NoAdminRequired]
+ public function undelete(string $id): DataResponse {
+ try {
+ $share = $this->shareManager->getShareById($id, $this->userId);
+ } catch (ShareNotFound $e) {
+ throw new OCSNotFoundException('Share not found');
+ }
+
+ if ($share->getPermissions() !== 0) {
+ throw new OCSNotFoundException('No deleted share found');
+ }
+
+ try {
+ $this->shareManager->restoreShare($share, $this->userId);
+ } catch (GenericShareException $e) {
+ throw new OCSException('Something went wrong');
+ }
+
+ return new DataResponse([]);
+ }
+
+ /**
+ * Returns the helper of DeletedShareAPIController for room shares.
+ *
+ * If the Talk application is not enabled or the helper is not available
+ * a QueryException is thrown instead.
+ *
+ * @return \OCA\Talk\Share\Helper\DeletedShareAPIController
+ * @throws QueryException
+ */
+ private function getRoomShareHelper() {
+ if (!$this->appManager->isEnabledForUser('spreed')) {
+ throw new QueryException();
+ }
+
+ return Server::get('\OCA\Talk\Share\Helper\DeletedShareAPIController');
+ }
+
+ /**
+ * Returns the helper of DeletedShareAPIHelper for deck shares.
+ *
+ * If the Deck application is not enabled or the helper is not available
+ * a QueryException is thrown instead.
+ *
+ * @return ShareAPIHelper
+ * @throws QueryException
+ */
+ private function getDeckShareHelper() {
+ if (!$this->appManager->isEnabledForUser('deck')) {
+ throw new QueryException();
+ }
+
+ return Server::get('\OCA\Deck\Sharing\ShareAPIHelper');
+ }
+
+ /**
+ * Returns the helper of DeletedShareAPIHelper for sciencemesh shares.
+ *
+ * If the sciencemesh application is not enabled or the helper is not available
+ * a QueryException is thrown instead.
+ *
+ * @return ShareAPIHelper
+ * @throws QueryException
+ */
+ private function getSciencemeshShareHelper() {
+ if (!$this->appManager->isEnabledForUser('sciencemesh')) {
+ throw new QueryException();
+ }
+
+ return Server::get('\OCA\ScienceMesh\Sharing\ShareAPIHelper');
+ }
+}