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:
authorBjörn Schießle <bjoern@schiessle.org>2017-07-17 17:07:59 +0300
committerGitHub <noreply@github.com>2017-07-17 17:07:59 +0300
commit1fa5777efe124da2da0cb0ba03ee512b46ce3e41 (patch)
tree17f56a42101e25fdf919f50ab8539a8af92598a6
parent98e8f448626a62aba037c6fec61083c539218b2f (diff)
parentad2808c70b4bc7cce9d66b4b77690d5c61f9d1db (diff)
Merge pull request #15 from nextcloud/gss-v2
allow the global site selector to search one specific user across all user data
-rwxr-xr-xdoc/architecture.md9
-rw-r--r--server/lib/UserManager.php95
2 files changed, 56 insertions, 48 deletions
diff --git a/doc/architecture.md b/doc/architecture.md
index 2a39f09..1c47e69 100755
--- a/doc/architecture.md
+++ b/doc/architecture.md
@@ -113,6 +113,15 @@ This call can be used to search for a user in a fuzzy way
Example:
curl -X GET http://dev/nextcloud/lookup-server/server/users?search=searchstring
+Add a additional parameter to search for an exact match, for example:
+curl -X GET http://dev/nextcloud/lookup-server/server/users?search=searchstring&exact=1
+
+If you want to limit the exact search to a specific parameter, e.g the email address you can do following:
+curl -X GET http://dev/nextcloud/lookup-server/server/users?search=searchstring&exact=1&keys=["email"]
+
+To get the verification result of a users Twitter account or email address we can search for a specific users cloud ID:
+curl -X GET http://dev/nextcloud/lookup-server/server/users?search=<federated-cloud-id>&exactCloudId=1
+
### Get replication log
This call is used for master-master replication between different nodes.
Example:
diff --git a/server/lib/UserManager.php b/server/lib/UserManager.php
index 1ad85ba..52a895e 100644
--- a/server/lib/UserManager.php
+++ b/server/lib/UserManager.php
@@ -64,32 +64,62 @@ class UserManager {
}
$search = $params['search'];
- $searchCloudId = $params['exactCloudId'];
-
- if ($searchCloudId === '1') {
- $user = $this->getExactCloudId($search);
- $response->getBody()->write(json_encode($user));
- return $response;
+ // 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 ($this->globalScaleMode === true) {
+ if ($searchCloudId === true) {
+ $users = $this->getExactCloudId($search);
+ } else if ($this->globalScaleMode === true) {
// in a global scale setup we ignore the karma
- $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
@@ -97,49 +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?
- */
-
- $users = [];
- while($data = $stmt->fetch()) {
- $users[] = $this->getForUserId((int)$data['userId']);
- }
- $stmt->closeCursor();
-
- return $users;
- }
-
+LIMIT ' . $limit);
- /**
- * return all results, ignoring the karma
- *
- * @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();
/*
@@ -155,6 +153,7 @@ FROM `store`
return $users;
}
+
private function getExactCloudId($cloudId) {
$stmt = $this->db->prepare('SELECT id FROM users WHERE federationId = :id');
$stmt->bindParam(':id', $cloudId);