Browse Source

Merge pull request #21138 from nextcloud/fix/noid/search-in-group-displayname-email

Search also the email and displayname in user mangement for groups
Morris Jobke 3 years ago
parent
commit
79fc7e78b7

+ 47 - 1
build/integration/features/bootstrap/Provisioning.php

@@ -69,6 +69,23 @@ trait Provisioning {
 		Assert::assertEquals(200, $this->response->getStatusCode());
 	}
 
+	/**
+	 * @Given /^user "([^"]*)" with displayname "([^"]*)" exists$/
+	 * @param string $user
+	 */
+	public function assureUserWithDisplaynameExists($user, $displayname) {
+		try {
+			$this->userExists($user);
+		} catch (\GuzzleHttp\Exception\ClientException $ex) {
+			$previous_user = $this->currentUser;
+			$this->currentUser = "admin";
+			$this->creatingTheUser($user, $displayname);
+			$this->currentUser = $previous_user;
+		}
+		$this->userExists($user);
+		Assert::assertEquals(200, $this->response->getStatusCode());
+	}
+
 	/**
 	 * @Given /^user "([^"]*)" does not exist$/
 	 * @param string $user
@@ -93,7 +110,7 @@ trait Provisioning {
 		}
 	}
 
-	public function creatingTheUser($user) {
+	public function creatingTheUser($user, $displayname = '') {
 		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users";
 		$client = new Client();
 		$options = [];
@@ -105,6 +122,9 @@ trait Provisioning {
 			'userid' => $user,
 			'password' => '123456'
 		];
+		if ($displayname !== '') {
+			$options['form_params']['displayName'] = $displayname;
+		}
 		$options['headers'] = [
 			'OCS-APIREQUEST' => 'true',
 		];
@@ -540,6 +560,20 @@ trait Provisioning {
 		}
 	}
 
+	/**
+	 * @Then /^detailed users returned are$/
+	 * @param \Behat\Gherkin\Node\TableNode|null $usersList
+	 */
+	public function theDetailedUsersShouldBe($usersList) {
+		if ($usersList instanceof \Behat\Gherkin\Node\TableNode) {
+			$users = $usersList->getRows();
+			$usersSimplified = $this->simplifyArray($users);
+			$respondedArray = $this->getArrayOfDetailedUsersResponded($this->response);
+			$respondedArray = array_keys($respondedArray);
+			Assert::assertEquals($usersSimplified, $respondedArray);
+		}
+	}
+
 	/**
 	 * @Then /^groups returned are$/
 	 * @param \Behat\Gherkin\Node\TableNode|null $groupsList
@@ -599,6 +633,18 @@ trait Provisioning {
 		return $extractedElementsArray;
 	}
 
+	/**
+	 * Parses the xml answer to get the array of detailed users returned.
+	 *
+	 * @param ResponseInterface $resp
+	 * @return array
+	 */
+	public function getArrayOfDetailedUsersResponded($resp) {
+		$listCheckedElements = simplexml_load_string($resp->getBody())->data[0]->users;
+		$extractedElementsArray = json_decode(json_encode($listCheckedElements), 1);
+		return $extractedElementsArray;
+	}
+
 	/**
 	 * Parses the xml answer to get the array of groups returned.
 	 *

+ 14 - 0
build/integration/features/provisioning-v2.feature

@@ -19,3 +19,17 @@ Feature: provisioning
     Then the OCS status code should be "998"
     And the HTTP status code should be "404"
 
+  Scenario: Searching by displayname in groups
+    Given As an "admin"
+    And user "user-in-group" with displayname "specific-name" exists
+    And user "user-in-group2" with displayname "another-name" exists
+    And user "user-not-in-group" with displayname "specific-name" exists
+    And user "user-not-in-group2" with displayname "another-name" exists
+    And group "group-search" exists
+    And user "user-in-group" belongs to group "group-search"
+    And user "user-in-group2" belongs to group "group-search"
+    When sending "GET" to "/cloud/groups/group-search/users/details?offset=0&limit=25&search=ifi"
+    Then the OCS status code should be "200"
+    And the HTTP status code should be "200"
+    And detailed users returned are
+      | user-in-group |

+ 18 - 6
lib/private/Group/Database.php

@@ -348,15 +348,27 @@ class Database extends ABackend implements
 		$this->fixDI();
 
 		$query = $this->dbConn->getQueryBuilder();
-		$query->select('uid')
-			->from('group_user')
+		$query->select('g.uid')
+			->from('group_user', 'g')
 			->where($query->expr()->eq('gid', $query->createNamedParameter($gid)))
-			->orderBy('uid', 'ASC');
+			->orderBy('g.uid', 'ASC');
 
 		if ($search !== '') {
-			$query->andWhere($query->expr()->like('uid', $query->createNamedParameter(
-				'%' . $this->dbConn->escapeLikeParameter($search) . '%'
-			)));
+			$query->leftJoin('g', 'users', 'u', $query->expr()->eq('g.uid', 'u.uid'))
+				->leftJoin('u', 'preferences', 'p', $query->expr()->andX(
+					$query->expr()->eq('p.userid', 'u.uid'),
+					$query->expr()->eq('p.appid', $query->expr()->literal('settings')),
+					$query->expr()->eq('p.configkey', $query->expr()->literal('email')))
+				)
+				// sqlite doesn't like re-using a single named parameter here
+				->andWhere(
+					$query->expr()->orX(
+						$query->expr()->ilike('g.uid', $query->createNamedParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%')),
+						$query->expr()->ilike('u.displayname', $query->createNamedParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%')),
+						$query->expr()->ilike('p.configvalue', $query->createNamedParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%'))
+					)
+				)
+				->orderBy('u.uid_lower', 'ASC');
 		}
 
 		if ($limit !== -1) {