Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorRobin Appelman <robin@icewind.nl>2019-11-08 17:05:21 +0300
committerJohn Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>2019-12-03 15:49:37 +0300
commitc62637da8b42ec184c252e3152bb033bd8f11561 (patch)
tree24c69bdaeb65a7900ba080cd9a1d5262efc496e1 /lib
parent2b19da84d5488ea35c6c27c26c78678fd8c5affb (diff)
Allow filtering the search results to the users home storage
This is done by adding a ```xml <d:eq> <d:prop> <oc:owner-id/> </d:prop> <d:literal>$userId</d:literal> </d:eq> ``` clause to the search query. Searching by `owner-id` can only be done with the current user id and the comparison can not be inside a `<d:not>` or `<d:or>` statement Signed-off-by: Robin Appelman <robin@icewind.nl>
Diffstat (limited to 'lib')
-rw-r--r--lib/private/Files/Cache/Cache.php5
-rw-r--r--lib/private/Files/Cache/QuerySearchHelper.php13
-rw-r--r--lib/private/Files/Node/Folder.php38
-rw-r--r--lib/private/Files/Search/SearchQuery.php16
-rw-r--r--lib/public/Files/Search/ISearchQuery.php7
5 files changed, 60 insertions, 19 deletions
diff --git a/lib/private/Files/Cache/Cache.php b/lib/private/Files/Cache/Cache.php
index a90617f5c53..842704d1471 100644
--- a/lib/private/Files/Cache/Cache.php
+++ b/lib/private/Files/Cache/Cache.php
@@ -793,7 +793,10 @@ class Cache implements ICache {
->andWhere($builder->expr()->eq('tag.uid', $builder->createNamedParameter($searchQuery->getUser()->getUID())));
}
- $query->andWhere($this->querySearchHelper->searchOperatorToDBExpr($builder, $searchQuery->getSearchOperation()));
+ $searchExpr = $this->querySearchHelper->searchOperatorToDBExpr($builder, $searchQuery->getSearchOperation());
+ if ($searchExpr) {
+ $query->andWhere($searchExpr);
+ }
$this->querySearchHelper->addSearchOrdersToQuery($query, $searchQuery->getOrder());
diff --git a/lib/private/Files/Cache/QuerySearchHelper.php b/lib/private/Files/Cache/QuerySearchHelper.php
index 2d9d8f374f7..a80156bc853 100644
--- a/lib/private/Files/Cache/QuerySearchHelper.php
+++ b/lib/private/Files/Cache/QuerySearchHelper.php
@@ -88,14 +88,18 @@ class QuerySearchHelper {
* @param ISearchOperator $operator
*/
public function searchOperatorArrayToDBExprArray(IQueryBuilder $builder, array $operators) {
- return array_map(function ($operator) use ($builder) {
+ return array_filter(array_map(function ($operator) use ($builder) {
return $this->searchOperatorToDBExpr($builder, $operator);
- }, $operators);
+ }, $operators));
}
public function searchOperatorToDBExpr(IQueryBuilder $builder, ISearchOperator $operator) {
$expr = $builder->expr();
if ($operator instanceof ISearchBinaryOperator) {
+ if (count($operator->getArguments()) === 0) {
+ return null;
+ }
+
switch ($operator->getType()) {
case ISearchBinaryOperator::OPERATOR_NOT:
$negativeOperator = $operator->getArguments()[0];
@@ -121,6 +125,11 @@ class QuerySearchHelper {
private function searchComparisonToDBExpr(IQueryBuilder $builder, ISearchComparison $comparison, array $operatorMap) {
$this->validateComparison($comparison);
+ // "owner" search is done by limiting the storages queries and should not be put in the sql
+ if ($comparison->getField() === 'owner') {
+ return null;
+ }
+
list($field, $value, $type) = $this->getOperatorFieldAndValue($comparison);
if (isset($operatorMap[$type])) {
$queryOperator = $operatorMap[$type];
diff --git a/lib/private/Files/Node/Folder.php b/lib/private/Files/Node/Folder.php
index 4a134cdcdbf..56ec39d86a8 100644
--- a/lib/private/Files/Node/Folder.php
+++ b/lib/private/Files/Node/Folder.php
@@ -34,7 +34,7 @@ use OCP\Files\FileInfo;
use OCP\Files\Mount\IMountPoint;
use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException;
-use OCP\Files\Search\ISearchOperator;
+use OCP\Files\Search\ISearchQuery;
class Folder extends Node implements \OCP\Files\Folder {
/**
@@ -191,7 +191,7 @@ class Folder extends Node implements \OCP\Files\Folder {
/**
* search for files with the name matching $query
*
- * @param string|ISearchOperator $query
+ * @param string|ISearchQuery $query
* @return \OC\Files\Node\Node[]
*/
public function search($query) {
@@ -229,6 +229,11 @@ class Folder extends Node implements \OCP\Files\Folder {
* @return \OC\Files\Node\Node[]
*/
private function searchCommon($method, $args) {
+ $limitToHome = ($method === 'searchQuery')? $args[0]->limitToHome(): false;
+ if ($limitToHome && count(explode('/', $this->path)) !== 3) {
+ throw new \InvalidArgumentException('searching by owner is only allows on the users home folder');
+ }
+
$files = array();
$rootLength = strlen($this->path);
$mount = $this->root->getMount($this->path);
@@ -252,19 +257,22 @@ class Folder extends Node implements \OCP\Files\Folder {
}
}
- $mounts = $this->root->getMountsIn($this->path);
- foreach ($mounts as $mount) {
- $storage = $mount->getStorage();
- if ($storage) {
- $cache = $storage->getCache('');
-
- $relativeMountPoint = ltrim(substr($mount->getMountPoint(), $rootLength), '/');
- $results = call_user_func_array(array($cache, $method), $args);
- foreach ($results as $result) {
- $result['internalPath'] = $result['path'];
- $result['path'] = $relativeMountPoint . $result['path'];
- $result['storage'] = $storage;
- $files[] = new \OC\Files\FileInfo($this->path . '/' . $result['path'], $storage, $result['internalPath'], $result, $mount);
+ if (!$limitToHome) {
+ $mounts = $this->root->getMountsIn($this->path);
+ foreach ($mounts as $mount) {
+ $storage = $mount->getStorage();
+ if ($storage) {
+ $cache = $storage->getCache('');
+
+ $relativeMountPoint = ltrim(substr($mount->getMountPoint(), $rootLength), '/');
+ $results = call_user_func_array([$cache, $method], $args);
+ foreach ($results as $result) {
+ $result['internalPath'] = $result['path'];
+ $result['path'] = $relativeMountPoint . $result['path'];
+ $result['storage'] = $storage;
+ $files[] = new \OC\Files\FileInfo($this->path . '/' . $result['path'], $storage,
+ $result['internalPath'], $result, $mount);
+ }
}
}
}
diff --git a/lib/private/Files/Search/SearchQuery.php b/lib/private/Files/Search/SearchQuery.php
index a22db2f60b3..ddad1fb49de 100644
--- a/lib/private/Files/Search/SearchQuery.php
+++ b/lib/private/Files/Search/SearchQuery.php
@@ -39,6 +39,7 @@ class SearchQuery implements ISearchQuery {
private $order;
/** @var IUser */
private $user;
+ private $limitToHome;
/**
* SearchQuery constructor.
@@ -48,13 +49,22 @@ class SearchQuery implements ISearchQuery {
* @param int $offset
* @param array $order
* @param IUser $user
+ * @param bool $limitToHome
*/
- public function __construct(ISearchOperator $searchOperation, $limit, $offset, array $order, IUser $user) {
+ public function __construct(
+ ISearchOperator $searchOperation,
+ int $limit,
+ int $offset,
+ array $order,
+ IUser $user,
+ bool $limitToHome = false
+ ) {
$this->searchOperation = $searchOperation;
$this->limit = $limit;
$this->offset = $offset;
$this->order = $order;
$this->user = $user;
+ $this->limitToHome = $limitToHome;
}
/**
@@ -91,4 +101,8 @@ class SearchQuery implements ISearchQuery {
public function getUser() {
return $this->user;
}
+
+ public function limitToHome(): bool {
+ return $this->limitToHome;
+ }
}
diff --git a/lib/public/Files/Search/ISearchQuery.php b/lib/public/Files/Search/ISearchQuery.php
index 0929a190489..7c355ec1ef3 100644
--- a/lib/public/Files/Search/ISearchQuery.php
+++ b/lib/public/Files/Search/ISearchQuery.php
@@ -66,4 +66,11 @@ interface ISearchQuery {
* @since 12.0.0
*/
public function getUser();
+
+ /**
+ * Whether or not the search should be limited to the users home storage
+ *
+ * @return bool
+ */
+ public function limitToHome(): bool;
}