From 5e37b52241381e5b0f57c58a88a5dbcf0870b3bd Mon Sep 17 00:00:00 2001 From: Vinicius Cubas Brand Date: Thu, 7 Feb 2019 21:30:00 -0200 Subject: [PATCH] Share calendar to circle * Allow user to share calendar with a circle * Allow user to see calendars shared with his/her circles Signed-off-by: Vinicius Cubas Brand --- apps/dav/lib/CalDAV/CalDavBackend.php | 4 ++ apps/dav/lib/Connector/Sabre/Principal.php | 71 ++++++++++++++++++- apps/dav/lib/Connector/Sabre/SharesPlugin.php | 3 + apps/dav/lib/DAV/Sharing/Backend.php | 2 +- 4 files changed, 78 insertions(+), 2 deletions(-) diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index 88ee778e82..14de848013 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -12,6 +12,8 @@ * @author Stefan Weil * @author Thomas Citharel * @author Thomas Müller + * @author Vinicius Cubas Brand + * @author Daniel Tygel * * @license AGPL-3.0 * @@ -301,6 +303,8 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription // query for shared calendars $principals = $this->principalBackend->getGroupMembership($principalUriOriginal, true); + $principals = array_merge($principals, $this->principalBackend->getCircleMembership($principalUriOriginal)); + $principals = array_map(function($principal) { return urldecode($principal); }, $principals); diff --git a/apps/dav/lib/Connector/Sabre/Principal.php b/apps/dav/lib/Connector/Sabre/Principal.php index 2574fbcd43..39b4da683a 100644 --- a/apps/dav/lib/Connector/Sabre/Principal.php +++ b/apps/dav/lib/Connector/Sabre/Principal.php @@ -13,6 +13,8 @@ * @author Thomas Tanghus * @author Vincent Petry * @author Georg Ehrke + * @author Vinicius Cubas Brand + * @author Daniel Tygel * * @license AGPL-3.0 * @@ -66,6 +68,9 @@ class Principal implements BackendInterface { /** @var bool */ private $hasGroups; + /** @var bool */ + private $hasCircles; + /** * @param IUserManager $userManager * @param IGroupManager $groupManager @@ -86,7 +91,7 @@ class Principal implements BackendInterface { $this->userSession = $userSession; $this->config = $config; $this->principalPrefix = trim($principalPrefix, '/'); - $this->hasGroups = ($principalPrefix === 'principals/users/'); + $this->hasGroups = $this->hasCircles = ($principalPrefix === 'principals/users/'); } /** @@ -131,6 +136,8 @@ class Principal implements BackendInterface { if ($user !== null) { return $this->userToPrincipal($user); } + } else if ($prefix === 'principals/circles') { + return $this->circleToPrincipal($name); } return null; } @@ -388,4 +395,66 @@ class Principal implements BackendInterface { return $this->principalPrefix; } + /** + * @param string $circleUniqueId + * @return array|null + */ + protected function circleToPrincipal($circleUniqueId) { + if (!\OC::$server->getAppManager()->isEnabledForUser('circles') || !class_exists('\OCA\Circles\ShareByCircleProvider')) { + return null; + } + + $circle = \OCA\Circles\Api\v1\Circles::detailsCircle($circleUniqueId); + + if (!$circle) { + return null; + } + + $principal = [ + 'uri' => 'principals/circles/' . $circleUniqueId, + '{DAV:}displayname' => $circle->getName(), + ]; + + return $principal; + } + + /** + * Returns the list of circles a principal is a member of + * + * @param string $principal + * @param bool $needGroups + * @return array + * @throws Exception + */ + public function getCircleMembership($principal) { + if (!\OC::$server->getAppManager()->isEnabledForUser('circles') || !class_exists('\OCA\Circles\ShareByCircleProvider')) { + return []; + } + + list($prefix, $name) = \Sabre\Uri\split($principal); + + if ($this->hasCircles && $prefix === $this->principalPrefix) { + $user = $this->userManager->get($name); + if (!$user) { + throw new Exception('Principal not found'); + } + + $userSession = \OC::$server->getUserSession(); + $currentUser = $userSession->getUser(); + + $userSession->setUser($user); + $circles = \OCA\Circles\Api\v1\Circles::joinedCircles(); + $userSession->setUser($currentUser); + + $circles = array_map(function($circle) { + /** @var \OCA\Circles\Model\Circle $group */ + return 'principals/circles/' . urlencode($circle->getUniqueId()); + }, $circles); + + return $circles; + + } + return []; + } + } diff --git a/apps/dav/lib/Connector/Sabre/SharesPlugin.php b/apps/dav/lib/Connector/Sabre/SharesPlugin.php index 990cc4a808..46174c8118 100644 --- a/apps/dav/lib/Connector/Sabre/SharesPlugin.php +++ b/apps/dav/lib/Connector/Sabre/SharesPlugin.php @@ -7,6 +7,8 @@ * @author Robin Appelman * @author Roeland Jago Douma * @author Vincent Petry + * @author Vinicius Cubas Brand + * @author Daniel Tygel * * @license AGPL-3.0 * @@ -125,6 +127,7 @@ class SharesPlugin extends \Sabre\DAV\ServerPlugin { \OCP\Share::SHARE_TYPE_REMOTE, \OCP\Share::SHARE_TYPE_EMAIL, \OCP\Share::SHARE_TYPE_ROOM, + \OCP\Share::SHARE_TYPE_CIRCLE, ]; foreach ($requestedShareTypes as $requestedShareType) { // one of each type is enough to find out about the types diff --git a/apps/dav/lib/DAV/Sharing/Backend.php b/apps/dav/lib/DAV/Sharing/Backend.php index 433d9db9c0..ebb63b41c9 100644 --- a/apps/dav/lib/DAV/Sharing/Backend.php +++ b/apps/dav/lib/DAV/Sharing/Backend.php @@ -99,7 +99,7 @@ class Backend { } $principal = explode('/', $parts[1], 3); - if (count($principal) !== 3 || $principal[0] !== 'principals' || !in_array($principal[1], ['users', 'groups'], true)) { + if (count($principal) !== 3 || $principal[0] !== 'principals' || !in_array($principal[1], ['users', 'groups','circles'], true)) { // Invalid principal return; }