diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/dav/composer/composer/autoload_classmap.php | 1 | ||||
-rw-r--r-- | apps/dav/composer/composer/autoload_static.php | 1 | ||||
-rw-r--r-- | apps/dav/lib/RootCollection.php | 4 | ||||
-rw-r--r-- | apps/dav/lib/SystemTag/SystemTagNode.php | 19 | ||||
-rw-r--r-- | apps/dav/lib/SystemTag/SystemTagPlugin.php | 24 | ||||
-rw-r--r-- | apps/dav/lib/SystemTag/SystemTagsInUseCollection.php | 108 |
6 files changed, 157 insertions, 0 deletions
diff --git a/apps/dav/composer/composer/autoload_classmap.php b/apps/dav/composer/composer/autoload_classmap.php index 2cbf361eaf7..f5c44579ed9 100644 --- a/apps/dav/composer/composer/autoload_classmap.php +++ b/apps/dav/composer/composer/autoload_classmap.php @@ -311,6 +311,7 @@ return array( 'OCA\\DAV\\SystemTag\\SystemTagNode' => $baseDir . '/../lib/SystemTag/SystemTagNode.php', 'OCA\\DAV\\SystemTag\\SystemTagPlugin' => $baseDir . '/../lib/SystemTag/SystemTagPlugin.php', 'OCA\\DAV\\SystemTag\\SystemTagsByIdCollection' => $baseDir . '/../lib/SystemTag/SystemTagsByIdCollection.php', + 'OCA\\DAV\\SystemTag\\SystemTagsInUseCollection' => $baseDir . '/../lib/SystemTag/SystemTagsInUseCollection.php', 'OCA\\DAV\\SystemTag\\SystemTagsObjectMappingCollection' => $baseDir . '/../lib/SystemTag/SystemTagsObjectMappingCollection.php', 'OCA\\DAV\\SystemTag\\SystemTagsObjectTypeCollection' => $baseDir . '/../lib/SystemTag/SystemTagsObjectTypeCollection.php', 'OCA\\DAV\\SystemTag\\SystemTagsRelationsCollection' => $baseDir . '/../lib/SystemTag/SystemTagsRelationsCollection.php', diff --git a/apps/dav/composer/composer/autoload_static.php b/apps/dav/composer/composer/autoload_static.php index f939841f2e2..ea7da582b3e 100644 --- a/apps/dav/composer/composer/autoload_static.php +++ b/apps/dav/composer/composer/autoload_static.php @@ -326,6 +326,7 @@ class ComposerStaticInitDAV 'OCA\\DAV\\SystemTag\\SystemTagNode' => __DIR__ . '/..' . '/../lib/SystemTag/SystemTagNode.php', 'OCA\\DAV\\SystemTag\\SystemTagPlugin' => __DIR__ . '/..' . '/../lib/SystemTag/SystemTagPlugin.php', 'OCA\\DAV\\SystemTag\\SystemTagsByIdCollection' => __DIR__ . '/..' . '/../lib/SystemTag/SystemTagsByIdCollection.php', + 'OCA\\DAV\\SystemTag\\SystemTagsInUseCollection' => __DIR__ . '/..' . '/../lib/SystemTag/SystemTagsInUseCollection.php', 'OCA\\DAV\\SystemTag\\SystemTagsObjectMappingCollection' => __DIR__ . '/..' . '/../lib/SystemTag/SystemTagsObjectMappingCollection.php', 'OCA\\DAV\\SystemTag\\SystemTagsObjectTypeCollection' => __DIR__ . '/..' . '/../lib/SystemTag/SystemTagsObjectTypeCollection.php', 'OCA\\DAV\\SystemTag\\SystemTagsRelationsCollection' => __DIR__ . '/..' . '/../lib/SystemTag/SystemTagsRelationsCollection.php', diff --git a/apps/dav/lib/RootCollection.php b/apps/dav/lib/RootCollection.php index bacb550b415..6e009875ddc 100644 --- a/apps/dav/lib/RootCollection.php +++ b/apps/dav/lib/RootCollection.php @@ -48,6 +48,7 @@ use OCP\Accounts\IAccountManager; use OCP\App\IAppManager; use OCP\AppFramework\Utility\ITimeFactory; use OCP\EventDispatcher\IEventDispatcher; +use OCP\Files\IRootFolder; use OCP\IConfig; use Psr\Log\LoggerInterface; use Sabre\DAV\SimpleCollection; @@ -65,6 +66,7 @@ class RootCollection extends SimpleCollection { $dispatcher = \OC::$server->get(IEventDispatcher::class); $config = \OC::$server->get(IConfig::class); $proxyMapper = \OC::$server->query(ProxyMapper::class); + $rootFolder = \OCP\Server::get(IRootFolder::class); $userPrincipalBackend = new Principal( $userManager, @@ -131,6 +133,7 @@ class RootCollection extends SimpleCollection { $groupManager, \OC::$server->getEventDispatcher() ); + $systemTagInUseCollection = \OCP\Server::get(SystemTag\SystemTagsInUseCollection::class); $commentsCollection = new Comments\RootCollection( \OC::$server->getCommentsManager(), $userManager, @@ -179,6 +182,7 @@ class RootCollection extends SimpleCollection { $systemAddressBookRoot]), $systemTagCollection, $systemTagRelationsCollection, + $systemTagInUseCollection, $commentsCollection, $uploadCollection, $avatarCollection, diff --git a/apps/dav/lib/SystemTag/SystemTagNode.php b/apps/dav/lib/SystemTag/SystemTagNode.php index 7310cdb19a2..8ade5085b03 100644 --- a/apps/dav/lib/SystemTag/SystemTagNode.php +++ b/apps/dav/lib/SystemTag/SystemTagNode.php @@ -64,6 +64,9 @@ class SystemTagNode implements \Sabre\DAV\INode { */ protected $isAdmin; + protected int $numberOfFiles = -1; + protected int $referenceFileId = -1; + /** * Sets up the node, expects a full path name * @@ -179,4 +182,20 @@ class SystemTagNode implements \Sabre\DAV\INode { throw new NotFound('Tag with id ' . $this->tag->getId() . ' not found', 0, $e); } } + + public function getNumberOfFiles(): int { + return $this->numberOfFiles; + } + + public function setNumberOfFiles(int $numberOfFiles): void { + $this->numberOfFiles = $numberOfFiles; + } + + public function getReferenceFileId(): int { + return $this->referenceFileId; + } + + public function setReferenceFileId(int $referenceFileId): void { + $this->referenceFileId = $referenceFileId; + } } diff --git a/apps/dav/lib/SystemTag/SystemTagPlugin.php b/apps/dav/lib/SystemTag/SystemTagPlugin.php index 3c834bf71eb..c5d200d578e 100644 --- a/apps/dav/lib/SystemTag/SystemTagPlugin.php +++ b/apps/dav/lib/SystemTag/SystemTagPlugin.php @@ -62,6 +62,8 @@ class SystemTagPlugin extends \Sabre\DAV\ServerPlugin { public const GROUPS_PROPERTYNAME = '{http://owncloud.org/ns}groups'; public const CANASSIGN_PROPERTYNAME = '{http://owncloud.org/ns}can-assign'; public const SYSTEM_TAGS_PROPERTYNAME = '{http://nextcloud.org/ns}system-tags'; + public const NUM_FILES_PROPERTYNAME = '{http://nextcloud.org/ns}files-assigned'; + public const FILEID_PROPERTYNAME = '{http://nextcloud.org/ns}reference-fileid'; /** * @var \Sabre\DAV\Server $server @@ -243,6 +245,11 @@ class SystemTagPlugin extends \Sabre\DAV\ServerPlugin { return; } + // child nodes from systemtags-assigned should point to normal tag endpoint + if (preg_match('/^systemtags-assigned\/[0-9]+/', $propFind->getPath())) { + $propFind->setPath(str_replace('systemtags-assigned/', 'systemtags/', $propFind->getPath())); + } + $propFind->handle(self::ID_PROPERTYNAME, function () use ($node) { return $node->getSystemTag()->getId(); }); @@ -277,6 +284,16 @@ class SystemTagPlugin extends \Sabre\DAV\ServerPlugin { } return implode('|', $groups); }); + + if ($node instanceof SystemTagNode) { + $propFind->handle(self::NUM_FILES_PROPERTYNAME, function () use ($node): int { + return $node->getNumberOfFiles(); + }); + + $propFind->handle(self::FILEID_PROPERTYNAME, function () use ($node): int { + return $node->getReferenceFileId(); + }); + } } private function propfindForFile(PropFind $propFind, Node $node): void { @@ -374,6 +391,8 @@ class SystemTagPlugin extends \Sabre\DAV\ServerPlugin { self::USERVISIBLE_PROPERTYNAME, self::USERASSIGNABLE_PROPERTYNAME, self::GROUPS_PROPERTYNAME, + self::NUM_FILES_PROPERTYNAME, + self::FILEID_PROPERTYNAME, ], function ($props) use ($node) { $tag = $node->getSystemTag(); $name = $tag->getName(); @@ -410,6 +429,11 @@ class SystemTagPlugin extends \Sabre\DAV\ServerPlugin { $this->tagManager->setTagGroups($tag, $groupIds); } + if (isset($props[self::NUM_FILES_PROPERTYNAME]) || isset($props[self::FILEID_PROPERTYNAME])) { + // read-only properties + throw new Forbidden(); + } + if ($updateTag) { $node->update($name, $userVisible, $userAssignable); } diff --git a/apps/dav/lib/SystemTag/SystemTagsInUseCollection.php b/apps/dav/lib/SystemTag/SystemTagsInUseCollection.php new file mode 100644 index 00000000000..b57e685e7e7 --- /dev/null +++ b/apps/dav/lib/SystemTag/SystemTagsInUseCollection.php @@ -0,0 +1,108 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2023 Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @author Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +namespace OCA\DAV\SystemTag; + +use OC\SystemTag\SystemTag; +use OC\SystemTag\SystemTagsInFilesDetector; +use OC\User\NoUserException; +use OCP\Files\IRootFolder; +use OCP\Files\NotPermittedException; +use OCP\IUserSession; +use OCP\SystemTag\ISystemTagManager; +use Sabre\DAV\Exception\Forbidden; +use Sabre\DAV\Exception\NotFound; +use Sabre\DAV\SimpleCollection; + +class SystemTagsInUseCollection extends SimpleCollection { + protected IUserSession $userSession; + protected IRootFolder $rootFolder; + protected string $mediaType; + protected ISystemTagManager $systemTagManager; + protected SystemTagsInFilesDetector $systemTagsInFilesDetector; + + /** @noinspection PhpMissingParentConstructorInspection */ + public function __construct( + IUserSession $userSession, + IRootFolder $rootFolder, + ISystemTagManager $systemTagManager, + SystemTagsInFilesDetector $systemTagsInFilesDetector, + string $mediaType = '' + ) { + $this->userSession = $userSession; + $this->rootFolder = $rootFolder; + $this->systemTagManager = $systemTagManager; + $this->mediaType = $mediaType; + $this->systemTagsInFilesDetector = $systemTagsInFilesDetector; + $this->name = 'systemtags-assigned'; + if ($this->mediaType != '') { + $this->name .= '/' . $this->mediaType; + } + } + + public function setName($name): void { + throw new Forbidden('Permission denied to rename this collection'); + } + + public function getChild($name): self { + if ($this->mediaType !== '') { + throw new NotFound('Invalid media type'); + } + return new self($this->userSession, $this->rootFolder, $this->systemTagManager, $this->systemTagsInFilesDetector, $name); + } + + /** + * @return SystemTagNode[] + * @throws NotPermittedException + * @throws Forbidden + */ + public function getChildren(): array { + $user = $this->userSession->getUser(); + $userFolder = null; + try { + if ($user) { + $userFolder = $this->rootFolder->getUserFolder($user->getUID()); + } + } catch (NoUserException) { + // will throw a Sabre exception in the next step. + } + if ($user === null || $userFolder === null) { + throw new Forbidden('Permission denied to read this collection'); + } + + $result = $this->systemTagsInFilesDetector->detectAssignedSystemTagsIn($userFolder, $this->mediaType); + $children = []; + foreach ($result as $tagData) { + $tag = new SystemTag((string)$tagData['id'], $tagData['name'], (bool)$tagData['visibility'], (bool)$tagData['editable']); + // read only, so we can submit the isAdmin parameter as false generally + $node = new SystemTagNode($tag, $user, false, $this->systemTagManager); + $node->setNumberOfFiles($tagData['number_files']); + $node->setReferenceFileId($tagData['ref_file_id']); + $children[] = $node; + } + return $children; + } +} |