]> source.dussan.org Git - nextcloud-server.git/commitdiff
feat: make systemtags public visible feat/systemtags-public 48206/head
authorJohn Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
Thu, 19 Sep 2024 12:33:57 +0000 (14:33 +0200)
committerJohn Molakvoæ <skjnldsv@users.noreply.github.com>
Fri, 11 Oct 2024 14:06:44 +0000 (16:06 +0200)
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
apps/dav/appinfo/v2/publicremote.php
apps/dav/lib/SystemTag/SystemTagList.php
apps/dav/lib/SystemTag/SystemTagPlugin.php
apps/systemtags/composer/composer/autoload_classmap.php
apps/systemtags/composer/composer/autoload_static.php
apps/systemtags/lib/AppInfo/Application.php
apps/systemtags/lib/Listeners/BeforeSabrePubliclyLoadedListener.php [new file with mode: 0644]
apps/systemtags/lib/Listeners/BeforeTemplateRenderedListener.php [new file with mode: 0644]
apps/systemtags/lib/Listeners/LoadAdditionalScriptsListener.php [new file with mode: 0644]
lib/private/SystemTag/SystemTagManager.php
lib/public/SystemTag/ISystemTagManager.php

index 0b7480872cb6ae0cb4703cab5ed1abfcf145f996..cc2d1ed5bc88f924be302dcfb2e0b57e75ca6fae 100644 (file)
@@ -12,6 +12,7 @@ use OC\Files\View;
 use OCA\DAV\Storage\PublicOwnerWrapper;
 use OCA\DAV\Storage\PublicShareWrapper;
 use OCA\FederatedFileSharing\FederatedShareProvider;
+use OCP\BeforeSabrePubliclyLoadedEvent;
 use OCP\EventDispatcher\IEventDispatcher;
 use OCP\Files\Mount\IMountManager;
 use OCP\IConfig;
@@ -35,6 +36,7 @@ OC_Util::obEnd();
 
 $session = \OCP\Server::get(ISession::class);
 $request = \OCP\Server::get(IRequest::class);
+$eventDispatcher = \OCP\Server::get(IEventDispatcher::class);
 
 $session->close();
 $requestUri = $request->getRequestUri();
@@ -59,7 +61,7 @@ $serverFactory = new OCA\DAV\Connector\Sabre\ServerFactory(
        \OCP\Server::get(ITagManager::class),
        $request,
        \OCP\Server::get(IPreview::class),
-       \OCP\Server::get(IEventDispatcher::class),
+       $eventDispatcher,
        $l10nFactory->get('dav'),
 );
 
@@ -135,5 +137,9 @@ $server = $serverFactory->createServer($baseuri, $requestUri, $authPlugin, funct
 $server->addPlugin($linkCheckPlugin);
 $server->addPlugin($filesDropPlugin);
 
+// allow setup of additional plugins
+$event = new BeforeSabrePubliclyLoadedEvent($server);
+$eventDispatcher->dispatchTyped($event);
+
 // And off we go!
 $server->start();
index cbdf98b752fcb6006690cd489e958231ee86078a..087c84fabd90581e8c2b6bf6a61b0a0c83c95752 100644 (file)
@@ -20,12 +20,14 @@ use Sabre\Xml\Writer;
 class SystemTagList implements Element {
        public const NS_NEXTCLOUD = 'http://nextcloud.org/ns';
 
-       /** @var ISystemTag[] */
-       private array $tags;
-       private ISystemTagManager $tagManager;
-       private IUser $user;
-
-       public function __construct(array $tags, ISystemTagManager $tagManager, IUser $user) {
+       /**
+        * @param ISystemTag[] $tags
+        */
+       public function __construct(
+               private array $tags,
+               private ISystemTagManager $tagManager,
+               private ?IUser $user,
+       ) {
                $this->tags = $tags;
                $this->tagManager = $tagManager;
                $this->user = $user;
index bf7e5e00053f68176c2cf9d25e225067b524fbf3..6098a41ab3b0d8054031b7b0eb7c687b8b0123a5 100644 (file)
@@ -305,9 +305,6 @@ class SystemTagPlugin extends \Sabre\DAV\ServerPlugin {
 
                $propFind->handle(self::SYSTEM_TAGS_PROPERTYNAME, function () use ($node) {
                        $user = $this->userSession->getUser();
-                       if ($user === null) {
-                               return;
-                       }
 
                        $tags = $this->getTagsForFile($node->getId(), $user);
                        usort($tags, function (ISystemTag $tagA, ISystemTag $tagB): int {
@@ -321,8 +318,7 @@ class SystemTagPlugin extends \Sabre\DAV\ServerPlugin {
         * @param int $fileId
         * @return ISystemTag[]
         */
-       private function getTagsForFile(int $fileId, IUser $user): array {
-
+       private function getTagsForFile(int $fileId, ?IUser $user): array {
                if (isset($this->cachedTagMappings[$fileId])) {
                        $tagIds = $this->cachedTagMappings[$fileId];
                } else {
index 66d788547c6fb4657a434286547280c956e6ac90..20174ee46679717acb9ab47817ee58dabea3c311 100644 (file)
@@ -13,6 +13,9 @@ return array(
     'OCA\\SystemTags\\AppInfo\\Application' => $baseDir . '/../lib/AppInfo/Application.php',
     'OCA\\SystemTags\\Capabilities' => $baseDir . '/../lib/Capabilities.php',
     'OCA\\SystemTags\\Controller\\LastUsedController' => $baseDir . '/../lib/Controller/LastUsedController.php',
+    'OCA\\SystemTags\\Listeners\\BeforeSabrePubliclyLoadedListener' => $baseDir . '/../lib/Listeners/BeforeSabrePubliclyLoadedListener.php',
+    'OCA\\SystemTags\\Listeners\\BeforeTemplateRenderedListener' => $baseDir . '/../lib/Listeners/BeforeTemplateRenderedListener.php',
+    'OCA\\SystemTags\\Listeners\\LoadAdditionalScriptsListener' => $baseDir . '/../lib/Listeners/LoadAdditionalScriptsListener.php',
     'OCA\\SystemTags\\Search\\TagSearchProvider' => $baseDir . '/../lib/Search/TagSearchProvider.php',
     'OCA\\SystemTags\\Settings\\Admin' => $baseDir . '/../lib/Settings/Admin.php',
 );
index c1ea86351819215a92a853f4cc95626eb1b982f3..04dae4aa52f2ab9580f8d9a3e76494e85f6ae642 100644 (file)
@@ -28,6 +28,9 @@ class ComposerStaticInitSystemTags
         'OCA\\SystemTags\\AppInfo\\Application' => __DIR__ . '/..' . '/../lib/AppInfo/Application.php',
         'OCA\\SystemTags\\Capabilities' => __DIR__ . '/..' . '/../lib/Capabilities.php',
         'OCA\\SystemTags\\Controller\\LastUsedController' => __DIR__ . '/..' . '/../lib/Controller/LastUsedController.php',
+        'OCA\\SystemTags\\Listeners\\BeforeSabrePubliclyLoadedListener' => __DIR__ . '/..' . '/../lib/Listeners/BeforeSabrePubliclyLoadedListener.php',
+        'OCA\\SystemTags\\Listeners\\BeforeTemplateRenderedListener' => __DIR__ . '/..' . '/../lib/Listeners/BeforeTemplateRenderedListener.php',
+        'OCA\\SystemTags\\Listeners\\LoadAdditionalScriptsListener' => __DIR__ . '/..' . '/../lib/Listeners/LoadAdditionalScriptsListener.php',
         'OCA\\SystemTags\\Search\\TagSearchProvider' => __DIR__ . '/..' . '/../lib/Search/TagSearchProvider.php',
         'OCA\\SystemTags\\Settings\\Admin' => __DIR__ . '/..' . '/../lib/Settings/Admin.php',
     );
index 2fbdf7853e7b3484ef05ac80397488c917ed4f56..82c6682f2066a23e568a64ecaac4f8c04d78ddcb 100644 (file)
@@ -9,13 +9,18 @@ declare(strict_types=1);
 namespace OCA\SystemTags\AppInfo;
 
 use OCA\Files\Event\LoadAdditionalScriptsEvent;
+use OCA\Files_Sharing\Event\BeforeTemplateRenderedEvent;
 use OCA\SystemTags\Activity\Listener;
 use OCA\SystemTags\Capabilities;
+use OCA\SystemTags\Listeners\BeforeSabrePubliclyLoadedListener;
+use OCA\SystemTags\Listeners\BeforeTemplateRenderedListener;
+use OCA\SystemTags\Listeners\LoadAdditionalScriptsListener;
 use OCA\SystemTags\Search\TagSearchProvider;
 use OCP\AppFramework\App;
 use OCP\AppFramework\Bootstrap\IBootContext;
 use OCP\AppFramework\Bootstrap\IBootstrap;
 use OCP\AppFramework\Bootstrap\IRegistrationContext;
+use OCP\BeforeSabrePubliclyLoadedEvent;
 use OCP\EventDispatcher\IEventDispatcher;
 use OCP\SystemTag\ManagerEvent;
 use OCP\SystemTag\MapperEvent;
@@ -30,6 +35,9 @@ class Application extends App implements IBootstrap {
        public function register(IRegistrationContext $context): void {
                $context->registerSearchProvider(TagSearchProvider::class);
                $context->registerCapability(Capabilities::class);
+               $context->registerEventListener(LoadAdditionalScriptsEvent::class, LoadAdditionalScriptsListener::class);
+               $context->registerEventListener(BeforeTemplateRenderedEvent::class, BeforeTemplateRenderedListener::class);
+               $context->registerEventListener(BeforeSabrePubliclyLoadedEvent::class, BeforeSabrePubliclyLoadedListener::class);
        }
 
        public function boot(IBootContext $context): void {
diff --git a/apps/systemtags/lib/Listeners/BeforeSabrePubliclyLoadedListener.php b/apps/systemtags/lib/Listeners/BeforeSabrePubliclyLoadedListener.php
new file mode 100644 (file)
index 0000000..e89ed47
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\SystemTags\Listeners;
+
+use OCA\DAV\SystemTag\SystemTagPlugin;
+use OCP\BeforeSabrePubliclyLoadedEvent;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use OCP\Server;
+
+/**
+ * @template-implements IEventListener<BeforeSabrePubliclyLoadedEvent>
+ */
+class BeforeSabrePubliclyLoadedListener implements IEventListener {
+       public function handle(Event $event): void {
+               if (!$event instanceof BeforeSabrePubliclyLoadedEvent) {
+                       return;
+               }
+
+               $server = $event->getServer();
+               if ($server === null) {
+                       return;
+               }
+
+               $server->addPlugin(Server::get(SystemTagPlugin::class));
+       }
+}
diff --git a/apps/systemtags/lib/Listeners/BeforeTemplateRenderedListener.php b/apps/systemtags/lib/Listeners/BeforeTemplateRenderedListener.php
new file mode 100644 (file)
index 0000000..74fa6bd
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\SystemTags\Listeners;
+
+use OCA\Files_Sharing\Event\BeforeTemplateRenderedEvent;
+use OCA\SystemTags\AppInfo\Application;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use OCP\Util;
+
+/**
+ * @template-implements IEventListener<BeforeTemplateRenderedEvent>
+ */
+class BeforeTemplateRenderedListener implements IEventListener {
+       public function handle(Event $event): void {
+               if (!$event instanceof BeforeTemplateRenderedEvent) {
+                       return;
+               }
+               Util::addInitScript(Application::APP_ID, 'init');
+       }
+}
diff --git a/apps/systemtags/lib/Listeners/LoadAdditionalScriptsListener.php b/apps/systemtags/lib/Listeners/LoadAdditionalScriptsListener.php
new file mode 100644 (file)
index 0000000..7d00bf4
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCA\SystemTags\Listeners;
+
+use OCA\Files\Event\LoadAdditionalScriptsEvent;
+use OCA\SystemTags\AppInfo\Application;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use OCP\Util;
+
+/**
+ * @template-implements IEventListener<LoadAdditionalScriptsEvent>
+ */
+class LoadAdditionalScriptsListener implements IEventListener {
+       public function handle(Event $event): void {
+               if (!$event instanceof LoadAdditionalScriptsEvent) {
+                       return;
+               }
+               Util::addInitScript(Application::APP_ID, 'init');
+       }
+}
index 1a0d8fb618a0257ad5e71c79c88d2b20ff678404..cbba9968656f4da3cb1eabf0cb344ad215bdb1d5 100644 (file)
@@ -305,7 +305,11 @@ class SystemTagManager implements ISystemTagManager {
        /**
         * {@inheritdoc}
         */
-       public function canUserAssignTag(ISystemTag $tag, IUser $user): bool {
+       public function canUserAssignTag(ISystemTag $tag, ?IUser $user): bool {
+               if ($user === null) {
+                       return false;
+               }
+
                // early check to avoid unneeded group lookups
                if ($tag->isUserAssignable() && $tag->isUserVisible()) {
                        return true;
@@ -333,11 +337,21 @@ class SystemTagManager implements ISystemTagManager {
        /**
         * {@inheritdoc}
         */
-       public function canUserSeeTag(ISystemTag $tag, IUser $user): bool {
+       public function canUserSeeTag(ISystemTag $tag, ?IUser $user): bool {
+               // If no user, then we only show public tags
+               if (!$user && $tag->getAccessLevel() === ISystemTag::ACCESS_LEVEL_PUBLIC) {
+                       return true;
+               }
+
                if ($tag->isUserVisible()) {
                        return true;
                }
 
+               // if not returned yet, and user is not logged in, then the tag is not visible
+               if ($user === null) {
+                       return false;
+               }
+
                if ($this->groupManager->isAdmin($user->getUID())) {
                        return true;
                }
index 8d0241e752fad01f72eaf2dfb243284385b9343e..1c08d3b22e14408cd5e516035d93fc9f882eb4e0 100644 (file)
@@ -106,25 +106,27 @@ interface ISystemTagManager {
         * given id.
         *
         * @param ISystemTag $tag tag to check permission for
-        * @param IUser $user user to check permission for
+        * @param IUser|null $user user to check permission for
         *
         * @return bool true if the user is allowed to assign/unassign the tag, false otherwise
         *
         * @since 9.1.0
+        * @since 31.0.0 `$user` can be null to check anonymous permissions
         */
-       public function canUserAssignTag(ISystemTag $tag, IUser $user): bool;
+       public function canUserAssignTag(ISystemTag $tag, ?IUser $user): bool;
 
        /**
         * Checks whether the given user is allowed to see the tag with the given id.
         *
         * @param ISystemTag $tag tag to check permission for
-        * @param IUser $user user to check permission for
+        * @param IUser|null $user user to check permission for
         *
         * @return bool true if the user can see the tag, false otherwise
         *
         * @since 9.1.0
+        * @since 31.0.0 `$user` can be null to check anonymous permissions
         */
-       public function canUserSeeTag(ISystemTag $tag, IUser $user): bool;
+       public function canUserSeeTag(ISystemTag $tag, ?IUser $user): bool;
 
        /**
         * Set groups that can assign a given tag.