diff --git a/apps/dav/appinfo/v2/publicremote.php b/apps/dav/appinfo/v2/publicremote.php index 53e85d556eb9f..7e664df68d0a0 100644 --- a/apps/dav/appinfo/v2/publicremote.php +++ b/apps/dav/appinfo/v2/publicremote.php @@ -12,6 +12,7 @@ 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 @@ $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 @@ \OCP\Server::get(ITagManager::class), $request, \OCP\Server::get(IPreview::class), - \OCP\Server::get(IEventDispatcher::class), + $eventDispatcher, $l10nFactory->get('dav'), ); @@ -131,5 +133,9 @@ $server->addPlugin($linkCheckPlugin); $server->addPlugin($filesDropPlugin); +// allow setup of additional plugins +$event = new BeforeSabrePubliclyLoadedEvent($server); +$eventDispatcher->dispatchTyped($event); + // And off we go! $server->exec(); diff --git a/apps/dav/lib/Server.php b/apps/dav/lib/Server.php index 4bfc80192186f..129bc9ef5b395 100644 --- a/apps/dav/lib/Server.php +++ b/apps/dav/lib/Server.php @@ -48,7 +48,6 @@ use OCA\DAV\Files\LazySearchBackend; use OCA\DAV\Profiler\ProfilerPlugin; use OCA\DAV\Provisioning\Apple\AppleProvisioningPlugin; -use OCA\DAV\SystemTag\SystemTagPlugin; use OCA\DAV\Upload\ChunkingPlugin; use OCA\DAV\Upload\ChunkingV2Plugin; use OCA\Theming\ThemingDefaults; @@ -197,9 +196,6 @@ public function __construct(IRequest $request, string $baseUri) { $this->server->addPlugin(\OCP\Server::get(CardDavValidatePlugin::class)); } - // system tags plugins - $this->server->addPlugin(\OC::$server->get(SystemTagPlugin::class)); - // comments plugin $this->server->addPlugin(new CommentsPlugin( \OC::$server->getCommentsManager(), diff --git a/apps/dav/lib/SystemTag/SystemTagList.php b/apps/dav/lib/SystemTag/SystemTagList.php index cbdf98b752fcb..087c84fabd905 100644 --- a/apps/dav/lib/SystemTag/SystemTagList.php +++ b/apps/dav/lib/SystemTag/SystemTagList.php @@ -20,12 +20,14 @@ 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 bf7e5e00053f6..6098a41ab3b0d 100644 --- a/apps/dav/lib/SystemTag/SystemTagPlugin.php +++ b/apps/dav/lib/SystemTag/SystemTagPlugin.php @@ -305,9 +305,6 @@ private function propfindForFile(PropFind $propFind, Node $node): void { $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 @@ private function propfindForFile(PropFind $propFind, Node $node): void { * @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 66d788547c6fb..20174ee466797 100644 --- a/apps/systemtags/composer/composer/autoload_classmap.php +++ b/apps/systemtags/composer/composer/autoload_classmap.php @@ -13,6 +13,9 @@ '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 c1ea863518192..04dae4aa52f2a 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 2fbdf7853e7b3..82c6682f2066a 100644 --- a/apps/systemtags/lib/AppInfo/Application.php +++ b/apps/systemtags/lib/AppInfo/Application.php @@ -9,13 +9,18 @@ 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 @@ public function __construct() { 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 0000000000000..3abcce85eae17 --- /dev/null +++ b/apps/systemtags/lib/Listeners/BeforeSabrePubliclyLoadedListener.php @@ -0,0 +1,26 @@ + + */ +class BeforeSabrePubliclyLoadedListener implements IEventListener { + public function handle(Event $event): void { + if (!$event instanceof BeforeSabrePubliclyLoadedEvent) { + return; + } + $event->getServer()->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 0000000000000..74fa6bd03fef2 --- /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 0000000000000..7d00bf44fc438 --- /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 1a0d8fb618a02..e57da8de8999f 100644 --- a/lib/private/SystemTag/SystemTagManager.php +++ b/lib/private/SystemTag/SystemTagManager.php @@ -305,7 +305,11 @@ public function deleteTags($tagIds): void { /** * {@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,16 @@ public function canUserAssignTag(ISystemTag $tag, IUser $user): bool { /** * {@inheritdoc} */ - public function canUserSeeTag(ISystemTag $tag, IUser $user): bool { + public function canUserSeeTag(ISystemTag $tag, ?IUser $user): bool { if ($tag->isUserVisible()) { return true; } + // If no user and not user visible, then it's invisible + 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 8d0241e752fad..1c08d3b22e144 100644 --- a/lib/public/SystemTag/ISystemTagManager.php +++ b/lib/public/SystemTag/ISystemTagManager.php @@ -106,25 +106,27 @@ public function deleteTags($tagIds); * 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.