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

github.com/nextcloud/lookup-server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjoern Schiessle <bjoern@schiessle.org>2017-06-22 18:14:50 +0300
committerBjoern Schiessle <bjoern@schiessle.org>2017-06-22 18:27:54 +0300
commitf79f34ef1327a88bcce35df25b0d6ca1c2f11903 (patch)
treefeafb8807c73026ed32f5c73eaa3f423c8e67d8d
parent7ec825e8021a00d5f4c5b2b8fb07e8d6239c12a4 (diff)
cleanup search logic
Signed-off-by: Bjoern Schiessle <bjoern@schiessle.org>
-rw-r--r--server/lib/UserManager.php119
1 files changed, 44 insertions, 75 deletions
diff --git a/server/lib/UserManager.php b/server/lib/UserManager.php
index cf04e40..52a895e 100644
--- a/server/lib/UserManager.php
+++ b/server/lib/UserManager.php
@@ -64,34 +64,62 @@ class UserManager {
}
$search = $params['search'];
- $searchCloudId = isset($params['exactCloudId']) ? $params['exactCloudId'] : '0';
- $gssSearch = isset($params['gss']) ? $params['gss'] : '0';
+ // search for a specific federated cloud ID
+ $searchCloudId = isset($params['exactCloudId']) ? $params['exactCloudId'] === '1' : '0';
+ // return unique exact match, e.g. the user with a specific email address
+ $exactMatch = isset($params['exact']) ? $params['exact'] === '1' : false;
+
+ // parameters allow you to specify which keys should be checked for a search query
+ // by default we check all keys, this way you can for example search for email addresses only
+ $parameters = [];
+ if ($exactMatch === true) {
+ $keys = isset($params['keys']) ? $params['keys'] : '{}';
+ $keysDecoded = json_decode($keys, false, 2);
+ if (is_array($keysDecoded)) {
+ $parameters = $keysDecoded;
+ }
+ }
- if ($searchCloudId === '1') {
+ if ($searchCloudId === true) {
$users = $this->getExactCloudId($search);
- } else if ($gssSearch === '1') {
- // lookup request from a global site selector to login the user
- $users = $this->gssLookup($search);
} else if ($this->globalScaleMode === true) {
// in a global scale setup we ignore the karma
- // this is used to find people you want to share with
- $users = $this->searchNoKarma();
+ // the lookup server is populated by the admin and we know
+ // that it contain only valid user information
+ $users = $this->performSearch($search, $exactMatch, $parameters, 0);
} else {
- $users = $this->searchKarma();
+ // in a general setup we only return users who validated at least one personal date
+ $users = $this->performSearch($search, $exactMatch, $parameters, 1);
+ }
+
+ // if we look for a exact match we return only this one result, not a list of one element
+ if($exactMatch && !empty($users)) {
+ $users = $users[0];
}
$response->getBody()->write(json_encode($users));
return $response;
}
+
+
/**
* search user, for example to share with them
* return all results with karma >= 1
*
- * @param $search
+ * @param string $search
+ * @param bool $exactMatch
+ * @param array $parameters
+ * @param int $minKarma
* @return array
*/
- private function searchKarma($search) {
+ private function performSearch($search, $exactMatch, $parameters, $minKarma) {
+
+ $operator = $exactMatch ? ' = ' : ' LIKE ';
+ $limit = $exactMatch ? ' 1 ' : ' 50 ';
+ $constraint = empty($parameters) ? '' : ' AND k IN (\'' . implode( '\', \'', $parameters ) . '\') ';
+
+
$stmt = $this->db->prepare('SELECT *
FROM (
SELECT userId AS userId, SUM(valid) AS karma
@@ -99,52 +127,17 @@ FROM (
WHERE userId IN (
SELECT DISTINCT userId
FROM `store`
- WHERE v LIKE :search
+ WHERE v ' . $operator . ' :search ' . $constraint .'
)
GROUP BY userId
) AS tmp
-WHERE karma > 0
+WHERE karma >= ' . $minKarma . '
ORDER BY karma
-LIMIT 50');
- $search = '%' . $search . '%';
- $stmt->bindParam(':search', $search, \PDO::PARAM_STR);
- $stmt->execute();
-
- /*
- * TODO: Better fuzzy search?
- */
+LIMIT ' . $limit);
- $users = [];
- while($data = $stmt->fetch()) {
- $users[] = $this->getForUserId((int)$data['userId']);
- }
- $stmt->closeCursor();
-
- return $users;
- }
-
-
- /**
- * search user, for example to share with them
- * return all results, ignoring the karma
- * in a global scale setup we assume that all
- * entries are trustworthy
- *
- * @param $search
- * @return array
- */
- private function searchNoKarma($search) {
- $stmt = $this->db->prepare('SELECT *
-FROM `store`
- WHERE userId IN (
- SELECT DISTINCT userId
- FROM `store`
- WHERE v LIKE :search
- )
- GROUP BY userId
- LIMIT 50');
- $search = '%' . $search . '%';
+ $search = $exactMatch ? $search : '%' . $search . '%';
$stmt->bindParam(':search', $search, \PDO::PARAM_STR);
+
$stmt->execute();
/*
@@ -160,30 +153,6 @@ FROM `store`
return $users;
}
- /**
- * find the user who want to login in a global scale setup
- * we return the first exact match
- *
- * @param $search
- * @return array
- */
- private function gssLookup($search) {
- $stmt = $this->db->prepare('SELECT * FROM `store` WHERE v = :search LIMIT 1');
- $stmt->bindParam(':search', $search, \PDO::PARAM_STR);
- $stmt->execute();
-
- $data = $stmt->fetch();
- $stmt->closeCursor();
-
- $user = [];
-
- if (isset($data['userId'])) {
- $user = $this->getForUserId((int)$data['userId']);
- }
-
- return $user;
- }
-
private function getExactCloudId($cloudId) {
$stmt = $this->db->prepare('SELECT id FROM users WHERE federationId = :id');