summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorg Ehrke <developer@georgehrke.com>2019-08-01 18:37:50 +0200
committerGeorg Ehrke <developer@georgehrke.com>2019-08-01 19:40:27 +0200
commitab6add54c7d11d34230b2ce55f30e87f68b1c28d (patch)
tree2627de0f137a5a29b521781dc45ade360bd0cc45
parentb246e58a1ed1e37401503ac0212d6b61bfe83cb7 (diff)
downloadnextcloud-server-ab6add54c7d11d34230b2ce55f30e87f68b1c28d.tar.gz
nextcloud-server-ab6add54c7d11d34230b2ce55f30e87f68b1c28d.zip
Allow to do a principal property search based on metadata keys
Signed-off-by: Georg Ehrke <developer@georgehrke.com>
-rw-r--r--apps/dav/lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php74
-rw-r--r--apps/dav/tests/unit/CalDAV/ResourceBooking/AbstractPrincipalBackendTest.php20
2 files changed, 93 insertions, 1 deletions
diff --git a/apps/dav/lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php b/apps/dav/lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php
index bc96041d915..aab5fcab8ad 100644
--- a/apps/dav/lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php
+++ b/apps/dav/lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php
@@ -185,6 +185,37 @@ abstract class AbstractPrincipalBackend implements BackendInterface {
}
/**
+ * @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
*
* @param string $principal
@@ -296,7 +327,15 @@ abstract class AbstractPrincipalBackend implements BackendInterface {
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;
}
}
@@ -318,6 +357,39 @@ abstract class AbstractPrincipalBackend implements BackendInterface {
}
/**
+ * 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
* @return null|string
diff --git a/apps/dav/tests/unit/CalDAV/ResourceBooking/AbstractPrincipalBackendTest.php b/apps/dav/tests/unit/CalDAV/ResourceBooking/AbstractPrincipalBackendTest.php
index eb9faa574a1..f4019d86e2b 100644
--- a/apps/dav/tests/unit/CalDAV/ResourceBooking/AbstractPrincipalBackendTest.php
+++ b/apps/dav/tests/unit/CalDAV/ResourceBooking/AbstractPrincipalBackendTest.php
@@ -219,6 +219,26 @@ abstract class AbstractPrincipalBackendTest extends TestCase {
];
}
+ 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')