return $this->rowToPrincipal($row, $metadata);
}
+ /**
+ * @param int $id
+ * @return array|null
+ */
+ public function getPrincipalById($id):?array {
+ $query = $this->db->getQueryBuilder();
+ $query->select(['id', 'backend_id', 'resource_id', 'email', 'displayname'])
+ ->from($this->dbTableName)
+ ->where($query->expr()->eq('id', $query->createNamedParameter($id)));
+ $stmt = $query->execute();
+ $row = $stmt->fetch(\PDO::FETCH_ASSOC);
+
+ if(!$row) {
+ return null;
+ }
+
+ $metaDataQuery = $this->db->getQueryBuilder();
+ $metaDataQuery->select(['key', 'value'])
+ ->from($this->dbMetaDataTableName)
+ ->where($metaDataQuery->expr()->eq($this->dbForeignKeyName, $metaDataQuery->createNamedParameter($row['id'])));
+ $metaDataStmt = $metaDataQuery->execute();
+ $metaDataRows = $metaDataStmt->fetchAll(\PDO::FETCH_ASSOC);
+ $metadata = [];
+
+ foreach($metaDataRows as $metaDataRow) {
+ $metadata[$metaDataRow['key']] = $metaDataRow['value'];
+ }
+
+ return $this->rowToPrincipal($row, $metadata);
+ }
+
/**
* Returns the list of members for a group-principal
*
break;
default:
- $results[] = [];
+ $rowsByMetadata = $this->searchPrincipalsByMetadataKey($prop, $value);
+ $filteredRows = array_filter($rowsByMetadata, function($row) use ($usersGroups) {
+ return $this->isAllowedToAccessResource($row, $usersGroups);
+ });
+
+ $results[] = array_map(function($row) {
+ return $row['uri'];
+ }, $filteredRows);
+
break;
}
}
}
}
+ /**
+ * Searches principals based on their metadata keys.
+ * This allows to search for all principals with a specific key.
+ * e.g.:
+ * '{http://nextcloud.com/ns}room-building-address' => 'ABC Street 123, ...'
+ *
+ * @param $key
+ * @param $value
+ * @return array
+ */
+ private function searchPrincipalsByMetadataKey($key, $value):array {
+ $query = $this->db->getQueryBuilder();
+ $query->select([$this->dbForeignKeyName])
+ ->from($this->dbMetaDataTableName)
+ ->where($query->expr()->eq('key', $query->createNamedParameter($key)))
+ ->andWhere($query->expr()->iLike('value', $query->createNamedParameter('%' . $this->db->escapeLikeParameter($value) . '%')));
+ $stmt = $query->execute();
+
+ $rows = [];
+ while($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
+ $id = $row[$this->dbForeignKeyName];
+
+ $principalRow = $this->getPrincipalById($id);
+ if (!$principalRow) {
+ continue;
+ }
+
+ $rows[] = $principalRow;
+ }
+
+ return $rows;
+ }
+
/**
* @param string $uri
* @param string $principalPrefix
];
}
+ public function testSearchPrincipalsByMetadataKey() {
+ $user = $this->createMock(IUser::class);
+ $this->userSession->expects($this->once())
+ ->method('getUser')
+ ->with()
+ ->will($this->returnValue($user));
+ $this->groupManager->expects($this->once())
+ ->method('getUserGroupIds')
+ ->with($user)
+ ->will($this->returnValue(['group1', 'group2']));
+
+ $actual = $this->principalBackend->searchPrincipals($this->principalPrefix, [
+ '{http://nextcloud.com/ns}meta3' => 'value',
+ ]);
+
+ $this->assertEquals([
+ $this->principalPrefix . '/backend2-res4',
+ ], $actual);
+ }
+
public function testSearchPrincipalsByCalendarUserAddressSet() {
$user = $this->createMock(IUser::class);
$this->userSession->method('getUser')