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

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorg Ehrke <developer@georgehrke.com>2018-06-05 22:26:29 +0300
committerGeorg Ehrke <developer@georgehrke.com>2018-06-25 05:58:07 +0300
commitb832edabbfce23daca6edbb010c4bf180123930f (patch)
tree9543d288a056d15da0b0fa879b9a345de20ef5b7 /apps/dav/lib
parent2da510af0b537e3bef7d0563eff828bade51fcbd (diff)
apply group restrictions to resources
Signed-off-by: Georg Ehrke <developer@georgehrke.com>
Diffstat (limited to 'apps/dav/lib')
-rw-r--r--apps/dav/lib/CalDAV/Plugin.php2
-rw-r--r--apps/dav/lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php104
-rw-r--r--apps/dav/lib/CalDAV/ResourceBooking/ResourcePrincipalBackend.php7
-rw-r--r--apps/dav/lib/CalDAV/ResourceBooking/RoomPrincipalBackend.php7
-rw-r--r--apps/dav/lib/RootCollection.php4
5 files changed, 95 insertions, 29 deletions
diff --git a/apps/dav/lib/CalDAV/Plugin.php b/apps/dav/lib/CalDAV/Plugin.php
index b9ec8241faa..f37d9c571a0 100644
--- a/apps/dav/lib/CalDAV/Plugin.php
+++ b/apps/dav/lib/CalDAV/Plugin.php
@@ -32,8 +32,6 @@ class Plugin extends \Sabre\CalDAV\Plugin {
*/
function getCalendarHomeForPrincipal($principalUrl):string {
- //TODO - debug this
-
if (strrpos($principalUrl, 'principals/users', -strlen($principalUrl)) !== false) {
list(, $principalId) = \Sabre\Uri\split($principalUrl);
return self::CALENDAR_ROOT . '/' . $principalId;
diff --git a/apps/dav/lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php b/apps/dav/lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php
index 0b3b9cda146..135bbe5827e 100644
--- a/apps/dav/lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php
+++ b/apps/dav/lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php
@@ -24,6 +24,7 @@ namespace OCA\DAV\CalDAV\ResourceBooking;
use OCP\IDBConnection;
use OCP\IGroupManager;
+use OCP\ILogger;
use OCP\IUserSession;
use Sabre\DAVACL\PrincipalBackend\BackendInterface;
use Sabre\DAV\Exception;
@@ -40,6 +41,9 @@ abstract class AbstractPrincipalBackend implements BackendInterface {
/** @var IGroupManager */
private $groupManager;
+ /** @var ILogger */
+ private $logger;
+
/** @var string */
private $principalPrefix;
@@ -50,16 +54,19 @@ abstract class AbstractPrincipalBackend implements BackendInterface {
* @param IDBConnection $dbConnection
* @param IUserSession $userSession
* @param IGroupManager $groupManager
+ * @param ILogger $logger
* @param string $principalPrefix
* @param string $dbPrefix
*/
public function __construct(IDBConnection $dbConnection,
IUserSession $userSession,
IGroupManager $groupManager,
+ ILogger $logger,
$principalPrefix, $dbPrefix) {
$this->db = $dbConnection;
$this->userSession = $userSession;
$this->groupManager = $groupManager;
+ $this->logger = $logger;
$this->principalPrefix = $principalPrefix;
$this->dbTableName = 'calendar_' . $dbPrefix . '_cache';
}
@@ -82,7 +89,7 @@ abstract class AbstractPrincipalBackend implements BackendInterface {
if ($prefixPath === $this->principalPrefix) {
$query = $this->db->getQueryBuilder();
- $query->select(['backend_id', 'resource_id', 'email', 'displayname'])
+ $query->select(['id', 'backend_id', 'resource_id', 'email', 'displayname'])
->from($this->dbTableName);
$stmt = $query->execute();
@@ -113,7 +120,7 @@ abstract class AbstractPrincipalBackend implements BackendInterface {
list($backendId, $resourceId) = explode('-', $name, 2);
$query = $this->db->getQueryBuilder();
- $query->select(['backend_id', 'resource_id', 'email', 'displayname'])
+ $query->select(['id', 'backend_id', 'resource_id', 'email', 'displayname'])
->from($this->dbTableName)
->where($query->expr()->eq('backend_id', $query->createNamedParameter($backendId)))
->andWhere($query->expr()->eq('resource_id', $query->createNamedParameter($resourceId)));
@@ -132,7 +139,6 @@ abstract class AbstractPrincipalBackend implements BackendInterface {
*
* @param string $principal
* @return string[]
- * @throws Exception
*/
public function getGroupMemberSet($principal) {
return [];
@@ -143,7 +149,6 @@ abstract class AbstractPrincipalBackend implements BackendInterface {
*
* @param string $principal
* @return array
- * @throws Exception
*/
public function getGroupMembership($principal) {
return [];
@@ -188,7 +193,7 @@ abstract class AbstractPrincipalBackend implements BackendInterface {
$user = $this->userSession->getUser();
if (!$user) {
- return null;
+ return [];
}
$usersGroups = $this->groupManager->getUserGroupIds($user);
@@ -196,30 +201,38 @@ abstract class AbstractPrincipalBackend implements BackendInterface {
switch ($prop) {
case '{http://sabredav.org/ns}email-address':
$query = $this->db->getQueryBuilder();
- $query->select(['backend_id', 'resource_id', 'email', 'displayname', 'group_restrictions'])
+ $query->select(['id', 'backend_id', 'resource_id', 'email', 'displayname', 'group_restrictions'])
->from($this->dbTableName)
- ->where($query->expr()->eq('email', $query->createNamedParameter($value)));
+ ->where($query->expr()->iLike('email', $query->createNamedParameter('%' . $this->db->escapeLikeParameter($value) . '%')));
$stmt = $query->execute();
+ $principals = [];
while($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
- // TODO - check for group restrictions
- $results[] = $this->rowToPrincipal($row)['uri'];
+ if (!$this->isAllowedToAccessResource($row, $usersGroups)) {
+ continue;
+ }
+ $principals[] = $this->rowToPrincipal($row)['uri'];
}
+ $results[] = $principals;
$stmt->closeCursor();
break;
case '{DAV:}displayname':
$query = $this->db->getQueryBuilder();
- $query->select(['backend_id', 'resource_id', 'email', 'displayname', 'group_restrictions'])
+ $query->select(['id', 'backend_id', 'resource_id', 'email', 'displayname', 'group_restrictions'])
->from($this->dbTableName)
- ->where($query->expr()->eq('displayname', $query->createNamedParameter($value)));
+ ->where($query->expr()->iLike('displayname', $query->createNamedParameter('%' . $this->db->escapeLikeParameter($value) . '%')));
$stmt = $query->execute();
+ $principals = [];
while($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
- // TODO - check for group restrictions
- $results[] = $this->rowToPrincipal($row)['uri'];
+ if (!$this->isAllowedToAccessResource($row, $usersGroups)) {
+ continue;
+ }
+ $principals[] = $this->rowToPrincipal($row)['uri'];
}
+ $results[] = $principals;
$stmt->closeCursor();
break;
@@ -233,16 +246,16 @@ abstract class AbstractPrincipalBackend implements BackendInterface {
// results is an array of arrays, so this is not the first search result
// but the results of the first searchProperty
if (count($results) === 1) {
- return $results;
+ return $results[0];
}
switch ($test) {
case 'anyof':
- return array_unique(array_merge(...$results));
+ return array_values(array_unique(array_merge(...$results)));
case 'allof':
default:
- return array_intersect(...$results);
+ return array_values(array_intersect(...$results));
}
}
@@ -261,7 +274,7 @@ abstract class AbstractPrincipalBackend implements BackendInterface {
if (strpos($uri, 'mailto:') === 0) {
$email = substr($uri, 7);
$query = $this->db->getQueryBuilder();
- $query->select(['backend_id', 'resource_id', 'email', 'displayname', 'group_restrictions'])
+ $query->select(['id', 'backend_id', 'resource_id', 'email', 'displayname', 'group_restrictions'])
->from($this->dbTableName)
->where($query->expr()->eq('email', $query->createNamedParameter($email)));
@@ -271,16 +284,38 @@ abstract class AbstractPrincipalBackend implements BackendInterface {
if(!$row) {
return null;
}
+ if (!$this->isAllowedToAccessResource($row, $usersGroups)) {
+ return null;
+ }
return $this->rowToPrincipal($row)['uri'];
}
+
if (strpos($uri, 'principal:') === 0) {
- $principal = substr($uri, 10);
- $principal = $this->getPrincipalByPath($principal);
+ $path = substr($uri, 10);
+ if (strpos($path, $this->principalPrefix) !== 0) {
+ return null;
+ }
+
+ list(, $name) = \Sabre\Uri\split($path);
+ list($backendId, $resourceId) = explode('-', $name, 2);
+
+ $query = $this->db->getQueryBuilder();
+ $query->select(['id', 'backend_id', 'resource_id', 'email', 'displayname', 'group_restrictions'])
+ ->from($this->dbTableName)
+ ->where($query->expr()->eq('backend_id', $query->createNamedParameter($backendId)))
+ ->andWhere($query->expr()->eq('resource_id', $query->createNamedParameter($resourceId)));
+ $stmt = $query->execute();
+ $row = $stmt->fetch(\PDO::FETCH_ASSOC);
- if ($principal !== null) {
- return $principal['uri'];
+ if(!$row) {
+ return null;
+ }
+ if (!$this->isAllowedToAccessResource($row, $usersGroups)) {
+ return null;
}
+
+ return $this->rowToPrincipal($row)['uri'];
}
return null;
@@ -296,4 +331,31 @@ abstract class AbstractPrincipalBackend implements BackendInterface {
'{http://sabredav.org/ns}email-address' => $row['email']
];
}
+
+ /**
+ * @param $row
+ * @param $userGroups
+ * @return bool
+ */
+ private function isAllowedToAccessResource($row, $userGroups) {
+ if (!isset($row['group_restrictions']) ||
+ $row['group_restrictions'] === null ||
+ $row['group_restrictions'] === '') {
+ return true;
+ }
+
+ // group restrictions contains something, but not parsable, deny access and log warning
+ $json = json_decode($row['group_restrictions']);
+ if (!\is_array($json)) {
+ $this->logger->info('group_restrictions field could not be parsed for ' . $this->dbTableName . '::' . $row['id'] . ', denying access to resource');
+ return false;
+ }
+
+ // empty array => no group restrictions
+ if (empty($json)) {
+ return true;
+ }
+
+ return !empty(array_intersect($json, $userGroups));
+ }
}
diff --git a/apps/dav/lib/CalDAV/ResourceBooking/ResourcePrincipalBackend.php b/apps/dav/lib/CalDAV/ResourceBooking/ResourcePrincipalBackend.php
index 053be5dae3a..a1030376c11 100644
--- a/apps/dav/lib/CalDAV/ResourceBooking/ResourcePrincipalBackend.php
+++ b/apps/dav/lib/CalDAV/ResourceBooking/ResourcePrincipalBackend.php
@@ -24,6 +24,7 @@ namespace OCA\DAV\CalDAV\ResourceBooking;
use OCP\IDBConnection;
use OCP\IGroupManager;
+use OCP\ILogger;
use OCP\IUserSession;
class ResourcePrincipalBackend extends AbstractPrincipalBackend {
@@ -32,11 +33,13 @@ class ResourcePrincipalBackend extends AbstractPrincipalBackend {
* @param IDBConnection $dbConnection
* @param IUserSession $userSession
* @param IGroupManager $groupManager
+ * @param ILogger $logger
*/
public function __construct(IDBConnection $dbConnection,
IUserSession $userSession,
- IGroupManager $groupManager) {
- parent::__construct($dbConnection, $userSession, $groupManager,
+ IGroupManager $groupManager,
+ ILogger $logger) {
+ parent::__construct($dbConnection, $userSession, $groupManager, $logger,
'principals/calendar-resources', 'resources');
}
}
diff --git a/apps/dav/lib/CalDAV/ResourceBooking/RoomPrincipalBackend.php b/apps/dav/lib/CalDAV/ResourceBooking/RoomPrincipalBackend.php
index 0052ee9e62c..1d22299515f 100644
--- a/apps/dav/lib/CalDAV/ResourceBooking/RoomPrincipalBackend.php
+++ b/apps/dav/lib/CalDAV/ResourceBooking/RoomPrincipalBackend.php
@@ -24,6 +24,7 @@ namespace OCA\DAV\CalDAV\ResourceBooking;
use OCP\IDBConnection;
use OCP\IGroupManager;
+use OCP\ILogger;
use OCP\IUserSession;
class RoomPrincipalBackend extends AbstractPrincipalBackend {
@@ -32,11 +33,13 @@ class RoomPrincipalBackend extends AbstractPrincipalBackend {
* @param IDBConnection $dbConnection
* @param IUserSession $userSession
* @param IGroupManager $groupManager
+ * @param ILogger $logger
*/
public function __construct(IDBConnection $dbConnection,
IUserSession $userSession,
- IGroupManager $groupManager) {
- parent::__construct($dbConnection, $userSession, $groupManager,
+ IGroupManager $groupManager,
+ ILogger $logger) {
+ parent::__construct($dbConnection, $userSession, $groupManager, $logger,
'principals/calendar-rooms', 'rooms');
}
}
diff --git a/apps/dav/lib/RootCollection.php b/apps/dav/lib/RootCollection.php
index 787e869770b..9a3261c388c 100644
--- a/apps/dav/lib/RootCollection.php
+++ b/apps/dav/lib/RootCollection.php
@@ -58,8 +58,8 @@ class RootCollection extends SimpleCollection {
$config
);
$groupPrincipalBackend = new GroupPrincipalBackend($groupManager);
- $calendarResourcePrincipalBackend = new ResourcePrincipalBackend($db, $userSession, $groupManager);
- $calendarRoomPrincipalBackend = new RoomPrincipalBackend($db, $userSession, $groupManager);
+ $calendarResourcePrincipalBackend = new ResourcePrincipalBackend($db, $userSession, $groupManager, $logger);
+ $calendarRoomPrincipalBackend = new RoomPrincipalBackend($db, $userSession, $groupManager, $logger);
// as soon as debug mode is enabled we allow listing of principals
$disableListing = !$config->getSystemValue('debug', false);