From: John Molakvoæ (skjnldsv) Date: Thu, 19 Sep 2024 12:33:57 +0000 (+0200) Subject: feat: make systemtags public visible X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=refs%2Fheads%2Ffeat%2Fsystemtags-public;p=nextcloud-server.git feat: make systemtags public visible Signed-off-by: John Molakvoæ (skjnldsv) --- diff --git a/apps/dav/appinfo/v2/publicremote.php b/apps/dav/appinfo/v2/publicremote.php index 0b7480872cb..cc2d1ed5bc8 100644 --- a/apps/dav/appinfo/v2/publicremote.php +++ b/apps/dav/appinfo/v2/publicremote.php @@ -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(); diff --git a/apps/dav/lib/SystemTag/SystemTagList.php b/apps/dav/lib/SystemTag/SystemTagList.php index cbdf98b752f..087c84fabd9 100644 --- a/apps/dav/lib/SystemTag/SystemTagList.php +++ b/apps/dav/lib/SystemTag/SystemTagList.php @@ -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; diff --git a/apps/dav/lib/SystemTag/SystemTagPlugin.php b/apps/dav/lib/SystemTag/SystemTagPlugin.php index bf7e5e00053..6098a41ab3b 100644 --- a/apps/dav/lib/SystemTag/SystemTagPlugin.php +++ b/apps/dav/lib/SystemTag/SystemTagPlugin.php @@ -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 { diff --git a/apps/systemtags/composer/composer/autoload_classmap.php b/apps/systemtags/composer/composer/autoload_classmap.php index 66d788547c6..20174ee4667 100644 --- a/apps/systemtags/composer/composer/autoload_classmap.php +++ b/apps/systemtags/composer/composer/autoload_classmap.php @@ -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', ); diff --git a/apps/systemtags/composer/composer/autoload_static.php b/apps/systemtags/composer/composer/autoload_static.php index c1ea8635181..04dae4aa52f 100644 --- a/apps/systemtags/composer/composer/autoload_static.php +++ b/apps/systemtags/composer/composer/autoload_static.php @@ -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', ); diff --git a/apps/systemtags/lib/AppInfo/Application.php b/apps/systemtags/lib/AppInfo/Application.php index 2fbdf7853e7..82c6682f206 100644 --- a/apps/systemtags/lib/AppInfo/Application.php +++ b/apps/systemtags/lib/AppInfo/Application.php @@ -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 index 00000000000..e89ed47a104 --- /dev/null +++ b/apps/systemtags/lib/Listeners/BeforeSabrePubliclyLoadedListener.php @@ -0,0 +1,32 @@ + + */ +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 index 00000000000..74fa6bd03fe --- /dev/null +++ b/apps/systemtags/lib/Listeners/BeforeTemplateRenderedListener.php @@ -0,0 +1,26 @@ + + */ +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 index 00000000000..7d00bf44fc4 --- /dev/null +++ b/apps/systemtags/lib/Listeners/LoadAdditionalScriptsListener.php @@ -0,0 +1,26 @@ + + */ +class LoadAdditionalScriptsListener implements IEventListener { + public function handle(Event $event): void { + if (!$event instanceof LoadAdditionalScriptsEvent) { + return; + } + Util::addInitScript(Application::APP_ID, 'init'); + } +} diff --git a/lib/private/SystemTag/SystemTagManager.php b/lib/private/SystemTag/SystemTagManager.php index 1a0d8fb618a..cbba9968656 100644 --- a/lib/private/SystemTag/SystemTagManager.php +++ b/lib/private/SystemTag/SystemTagManager.php @@ -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; } diff --git a/lib/public/SystemTag/ISystemTagManager.php b/lib/public/SystemTag/ISystemTagManager.php index 8d0241e752f..1c08d3b22e1 100644 --- a/lib/public/SystemTag/ISystemTagManager.php +++ b/lib/public/SystemTag/ISystemTagManager.php @@ -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.