summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorArthur Schiwon <blizzz@arthur-schiwon.de>2023-06-15 22:46:04 +0200
committerArthur Schiwon <blizzz@arthur-schiwon.de>2023-07-06 21:52:51 +0200
commit66a7064db3e0318fe122c0b51c89ffb5b586ecd7 (patch)
tree6c87643b004da841d812f30384d0e96851aa72b2 /lib
parent4ac77f0f7ad35249d0c3221ad19b56386a9b7f63 (diff)
downloadnextcloud-server-66a7064db3e0318fe122c0b51c89ffb5b586ecd7.tar.gz
nextcloud-server-66a7064db3e0318fe122c0b51c89ffb5b586ecd7.zip
fix: include invisible tags for admins
Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
Diffstat (limited to 'lib')
-rw-r--r--lib/private/Files/Cache/QuerySearchHelper.php60
-rw-r--r--lib/private/Files/Cache/SearchBuilder.php17
-rw-r--r--lib/private/SystemTag/SystemTagManager.php9
-rw-r--r--lib/public/SystemTag/ISystemTagManager.php5
4 files changed, 46 insertions, 45 deletions
diff --git a/lib/private/Files/Cache/QuerySearchHelper.php b/lib/private/Files/Cache/QuerySearchHelper.php
index 356da501dbd..15c089a0f11 100644
--- a/lib/private/Files/Cache/QuerySearchHelper.php
+++ b/lib/private/Files/Cache/QuerySearchHelper.php
@@ -36,9 +36,9 @@ use OCP\Files\IMimeTypeLoader;
use OCP\Files\IRootFolder;
use OCP\Files\Mount\IMountPoint;
use OCP\Files\Search\ISearchBinaryOperator;
-use OCP\Files\Search\ISearchComparison;
use OCP\Files\Search\ISearchQuery;
use OCP\IDBConnection;
+use OCP\IGroupManager;
use OCP\IUser;
use Psr\Log\LoggerInterface;
@@ -54,6 +54,7 @@ class QuerySearchHelper {
private $searchBuilder;
/** @var QueryOptimizer */
private $queryOptimizer;
+ private IGroupManager $groupManager;
public function __construct(
IMimeTypeLoader $mimetypeLoader,
@@ -61,7 +62,8 @@ class QuerySearchHelper {
SystemConfig $systemConfig,
LoggerInterface $logger,
SearchBuilder $searchBuilder,
- QueryOptimizer $queryOptimizer
+ QueryOptimizer $queryOptimizer,
+ IGroupManager $groupManager,
) {
$this->mimetypeLoader = $mimetypeLoader;
$this->connection = $connection;
@@ -69,6 +71,7 @@ class QuerySearchHelper {
$this->logger = $logger;
$this->searchBuilder = $searchBuilder;
$this->queryOptimizer = $queryOptimizer;
+ $this->groupManager = $groupManager;
}
protected function getQueryBuilder() {
@@ -118,16 +121,16 @@ class QuerySearchHelper {
return $tags;
}
- protected function equipQueryForSystemTags(CacheQueryBuilder $query): void {
- $query
- ->leftJoin('file', 'systemtag_object_mapping', 'systemtagmap', $query->expr()->andX(
- $query->expr()->eq('file.fileid', $query->expr()->castColumn('systemtagmap.objectid', IQueryBuilder::PARAM_INT)),
- $query->expr()->eq('systemtagmap.objecttype', $query->createNamedParameter('files'))
- ))
- ->leftJoin('systemtagmap', 'systemtag', 'systemtag', $query->expr()->andX(
- $query->expr()->eq('systemtag.id', 'systemtagmap.systemtagid'),
- $query->expr()->eq('systemtag.visibility', $query->createNamedParameter(true))
- ));
+ protected function equipQueryForSystemTags(CacheQueryBuilder $query, IUser $user): void {
+ $query->leftJoin('file', 'systemtag_object_mapping', 'systemtagmap', $query->expr()->andX(
+ $query->expr()->eq('file.fileid', $query->expr()->castColumn('systemtagmap.objectid', IQueryBuilder::PARAM_INT)),
+ $query->expr()->eq('systemtagmap.objecttype', $query->createNamedParameter('files'))
+ ));
+ $on = $query->expr()->andX($query->expr()->eq('systemtag.id', 'systemtagmap.systemtagid'));
+ if (!$this->groupManager->isAdmin($user->getUID())) {
+ $on->add($query->expr()->eq('systemtag.visibility', $query->createNamedParameter(true)));
+ }
+ $query->leftJoin('systemtagmap', 'systemtag', 'systemtag', $on);
}
protected function equipQueryForDavTags(CacheQueryBuilder $query, IUser $user): void {
@@ -171,25 +174,12 @@ class QuerySearchHelper {
$query = $builder->selectFileCache('file', false);
- if ($this->searchBuilder->shouldJoinTags($searchQuery->getSearchOperation())) {
- $user = $searchQuery->getUser();
- if ($user === null) {
- throw new \InvalidArgumentException("Searching by tag requires the user to be set in the query");
- }
- if ($searchQuery->getSearchOperation() instanceof ISearchComparison) {
- switch ($searchQuery->getSearchOperation()->getField()) {
- case 'systemtag':
- $this->equipQueryForSystemTags($query);
- break;
- case 'tagname':
- case 'favorite':
- $this->equipQueryForDavTags($query, $user);
- break;
- }
- } elseif ($searchQuery->getSearchOperation() instanceof SearchBinaryOperator) {
- $this->equipQueryForSystemTags($query);
- $this->equipQueryForDavTags($query, $user);
- }
+ $requestedFields = $this->searchBuilder->extractRequestedFields($searchQuery->getSearchOperation());
+ if (in_array('systemtag', $requestedFields)) {
+ $this->equipQueryForSystemTags($query, $this->requireUser($searchQuery));
+ }
+ if (in_array('tagname', $requestedFields) || in_array('favorite', $requestedFields)) {
+ $this->equipQueryForDavTags($query, $this->requireUser($searchQuery));
}
$this->applySearchConstraints($query, $searchQuery, $caches);
@@ -217,6 +207,14 @@ class QuerySearchHelper {
return $results;
}
+ protected function requireUser(ISearchQuery $searchQuery): IUser {
+ $user = $searchQuery->getUser();
+ if ($user === null) {
+ throw new \InvalidArgumentException("This search operation requires the user to be set in the query");
+ }
+ return $user;
+ }
+
/**
* @return list{0?: array<array-key, ICache>, 1?: array<array-key, IMountPoint>}
*/
diff --git a/lib/private/Files/Cache/SearchBuilder.php b/lib/private/Files/Cache/SearchBuilder.php
index 63dc4b9cd0e..0d15a7bba6f 100644
--- a/lib/private/Files/Cache/SearchBuilder.php
+++ b/lib/private/Files/Cache/SearchBuilder.php
@@ -69,20 +69,17 @@ class SearchBuilder {
}
/**
- * Whether or not the tag tables should be joined to complete the search
- *
- * @param ISearchOperator $operator
- * @return boolean
+ * @return string[]
*/
- public function shouldJoinTags(ISearchOperator $operator) {
+ public function extractRequestedFields(ISearchOperator $operator): array {
if ($operator instanceof ISearchBinaryOperator) {
- return array_reduce($operator->getArguments(), function ($shouldJoin, ISearchOperator $operator) {
- return $shouldJoin || $this->shouldJoinTags($operator);
- }, false);
+ return array_reduce($operator->getArguments(), function (array $fields, ISearchOperator $operator) {
+ return array_unique(array_merge($fields, $this->extractRequestedFields($operator)));
+ }, []);
} elseif ($operator instanceof ISearchComparison) {
- return $operator->getField() === 'tagname' || $operator->getField() === 'favorite' || $operator->getField() === 'systemtag';
+ return [$operator->getField()];
}
- return false;
+ return [];
}
/**
diff --git a/lib/private/SystemTag/SystemTagManager.php b/lib/private/SystemTag/SystemTagManager.php
index 79c5adcf450..65046ebf000 100644
--- a/lib/private/SystemTag/SystemTagManager.php
+++ b/lib/private/SystemTag/SystemTagManager.php
@@ -91,7 +91,7 @@ class SystemTagManager implements ISystemTagManager {
/**
* {@inheritdoc}
*/
- public function getTagsByIds($tagIds): array {
+ public function getTagsByIds($tagIds, ?IUser $user = null): array {
if (!\is_array($tagIds)) {
$tagIds = [$tagIds];
}
@@ -116,7 +116,12 @@ class SystemTagManager implements ISystemTagManager {
$result = $query->execute();
while ($row = $result->fetch()) {
- $tags[$row['id']] = $this->createSystemTagFromRow($row);
+ $tag = $this->createSystemTagFromRow($row);
+ if ($user && !$this->canUserSeeTag($tag, $user)) {
+ // if a user is given, hide invisible tags
+ continue;
+ }
+ $tags[$row['id']] = $tag;
}
$result->closeCursor();
diff --git a/lib/public/SystemTag/ISystemTagManager.php b/lib/public/SystemTag/ISystemTagManager.php
index 1cf7263b456..0f5c373c49f 100644
--- a/lib/public/SystemTag/ISystemTagManager.php
+++ b/lib/public/SystemTag/ISystemTagManager.php
@@ -38,6 +38,7 @@ interface ISystemTagManager {
* Returns the tag objects matching the given tag ids.
*
* @param array|string $tagIds id or array of unique ids of the tag to retrieve
+ * @param ?IUser $user optional user to run a visibility check against for each tag
*
* @return ISystemTag[] array of system tags with tag id as key
*
@@ -45,9 +46,9 @@ interface ISystemTagManager {
* @throws TagNotFoundException if at least one given tag ids did no exist
* The message contains a json_encoded array of the ids that could not be found
*
- * @since 9.0.0
+ * @since 9.0.0, optional parameter $user added in 28.0.0
*/
- public function getTagsByIds($tagIds): array;
+ public function getTagsByIds($tagIds, ?IUser $user = null): array;
/**
* Returns the tag object matching the given attributes.