From 9357b997f795cebda4ebcda42a074ce695068d03 Mon Sep 17 00:00:00 2001 From: Vinicius Cubas Brand Date: Thu, 14 Sep 2017 12:34:33 -0300 Subject: [PATCH 1/6] Provide calendars shared w/ current user's circles This commit allows the user to view the calendars that are shared with any circle s/he belongs to. 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 | 1 + 3 files changed, 75 insertions(+), 1 deletion(-) diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index 2c34f6d6d31ea..810d61d76e026 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -8,6 +8,8 @@ * @author Thomas Citharel * @author Thomas Müller * @author Georg Ehrke + * @author Vinicius Cubas Brand + * @author Daniel Tygel * * @license AGPL-3.0 * @@ -280,6 +282,8 @@ function getCalendarsForUser($principalUri) { // 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 dfcbf1e1ca056..bae24735729bf 100644 --- a/apps/dav/lib/Connector/Sabre/Principal.php +++ b/apps/dav/lib/Connector/Sabre/Principal.php @@ -10,6 +10,8 @@ * @author Thomas Müller * @author Thomas Tanghus * @author Vincent Petry + * @author Vinicius Cubas Brand + * @author Daniel Tygel * * @license AGPL-3.0 * @@ -52,6 +54,9 @@ class Principal implements BackendInterface { /** @var bool */ private $hasGroups; + /** @var bool */ + private $hasCircles; + /** * @param IUserManager $userManager * @param IGroupManager $groupManager @@ -63,7 +68,7 @@ public function __construct(IUserManager $userManager, $this->userManager = $userManager; $this->groupManager = $groupManager; $this->principalPrefix = trim($principalPrefix, '/'); - $this->hasGroups = ($principalPrefix === 'principals/users/'); + $this->hasGroups = $this->hasCircles = ($principalPrefix === 'principals/users/'); } /** @@ -108,6 +113,8 @@ public function getPrincipalByPath($path) { if (!is_null($user)) { return $this->userToPrincipal($user); } + } else if ($prefix === 'principals/circles') { + return $this->circleToPrincipal($name); } return null; } @@ -232,4 +239,66 @@ public function getPrincipalPrefix() { 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) = URLUtil::splitPath($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 9b06ef0781088..c6d7106d10c77 100644 --- a/apps/dav/lib/Connector/Sabre/SharesPlugin.php +++ b/apps/dav/lib/Connector/Sabre/SharesPlugin.php @@ -120,6 +120,7 @@ private function getShareTypes(\OCP\Files\Node $node) { \OCP\Share::SHARE_TYPE_LINK, \OCP\Share::SHARE_TYPE_REMOTE, \OCP\Share::SHARE_TYPE_EMAIL, + \OCP\Share::SHARE_TYPE_CIRCLE, ]; foreach ($requestedShareTypes as $requestedShareType) { // one of each type is enough to find out about the types From 253b263109700cf28b36c96e21e59f638f5b5def Mon Sep 17 00:00:00 2001 From: Vinicius Cubas Brand Date: Fri, 29 Sep 2017 18:43:04 -0300 Subject: [PATCH 2/6] Created infrastructure to show circles' shared files There is a proposal to allow users to filter files shared to circles. This commit is needed to provide the infrastucture for it. Issue: https://github.com/nextcloud/circles/issues/137 Signed-off-by: Vinicius Cubas Brand --- .../lib/Connector/Sabre/FilesReportPlugin.php | 38 +++++++++++++++++++ core/js/files/client.js | 8 +++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/apps/dav/lib/Connector/Sabre/FilesReportPlugin.php b/apps/dav/lib/Connector/Sabre/FilesReportPlugin.php index 81c082b9105e3..93000ac5bffdf 100644 --- a/apps/dav/lib/Connector/Sabre/FilesReportPlugin.php +++ b/apps/dav/lib/Connector/Sabre/FilesReportPlugin.php @@ -45,6 +45,7 @@ class FilesReportPlugin extends ServerPlugin { const NS_OWNCLOUD = 'http://owncloud.org/ns'; const REPORT_NAME = '{http://owncloud.org/ns}filter-files'; const SYSTEMTAG_PROPERTYNAME = '{http://owncloud.org/ns}systemtag'; + const CIRCLE_PROPERTYNAME = '{http://owncloud.org/ns}circle'; /** * Reference to main server object @@ -255,14 +256,19 @@ protected function processFilterRules($filterRules) { $ns = '{' . $this::NS_OWNCLOUD . '}'; $resultFileIds = null; $systemTagIds = []; + $circlesIds = []; $favoriteFilter = null; foreach ($filterRules as $filterRule) { if ($filterRule['name'] === $ns . 'systemtag') { $systemTagIds[] = $filterRule['value']; } + if ($filterRule['name'] === $ns . 'circle') { + $circlesIds[] = $filterRule['value']; + } if ($filterRule['name'] === $ns . 'favorite') { $favoriteFilter = true; } + } if ($favoriteFilter !== null) { @@ -281,6 +287,15 @@ protected function processFilterRules($filterRules) { } } + if (!empty($circlesIds)) { + $fileIds = $this->getCirclesFileIds($circlesIds); + if (empty($resultFileIds)) { + $resultFileIds = $fileIds; + } else { + $resultFileIds = array_intersect($fileIds, $resultFileIds); + } + } + return $resultFileIds; } @@ -327,6 +342,29 @@ private function getSystemTagFileIds($systemTagIds) { return $resultFileIds; } + private function getCirclesFileIds($circlesIds) { + + // check user permissions, if applicable + /* + if (!$this->isAdmin()) { + // check visibility/permission + $tags = $this->tagManager->getTagsByIds($circlesIds); + $unknownTagIds = []; + foreach ($tags as $tag) { + if (!$tag->isUserVisible()) { + $unknownTagIds[] = $tag->getId(); + } + } + + if (!empty($unknownTagIds)) { + throw new TagNotFoundException('Tag with ids ' . implode(', ', $unknownTagIds) . ' not found'); + } + } + */ + + return \OCA\Circles\Api\v1\Circles::getObjectIdsForCircles($circlesIds); + } + /** * Prepare propfind response for the given nodes * diff --git a/core/js/files/client.js b/core/js/files/client.js index dc9f6ade64178..ef2c32d30a8f2 100644 --- a/core/js/files/client.js +++ b/core/js/files/client.js @@ -454,7 +454,7 @@ /** * Fetches a flat list of files filtered by a given filter criteria. - * (currently only system tags is supported) + * (currently system tags and circles are supported) * * @param {Object} filter filter criteria * @param {Object} [filter.systemTagIds] list of system tag ids to filter by @@ -476,7 +476,8 @@ properties = options.properties; } - if (!filter || (!filter.systemTagIds && _.isUndefined(filter.favorite))) { + if (!filter || + (!filter.systemTagIds && _.isUndefined(filter.favorite) && !filter.circlesIds) ) { throw 'Missing filter argument'; } @@ -502,6 +503,9 @@ _.each(filter.systemTagIds, function(systemTagIds) { body += ' ' + escapeHTML(systemTagIds) + '\n'; }); + _.each(filter.circlesIds, function(circlesIds) { + body += ' ' + escapeHTML(circlesIds) + '\n'; + }); if (filter.favorite) { body += ' ' + (filter.favorite ? '1': '0') + '\n'; } From 87c60b65e7b4c5ba1c62f743f941c5fd09c11da0 Mon Sep 17 00:00:00 2001 From: Vinicius Cubas Brand Date: Wed, 25 Oct 2017 13:59:45 -0200 Subject: [PATCH 3/6] Changes to comply to https://github.com/coletivoEITA/circles/pull/2 Signed-off-by: Vinicius Cubas Brand --- apps/dav/lib/Connector/Sabre/FilesReportPlugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dav/lib/Connector/Sabre/FilesReportPlugin.php b/apps/dav/lib/Connector/Sabre/FilesReportPlugin.php index 93000ac5bffdf..6d7257e352304 100644 --- a/apps/dav/lib/Connector/Sabre/FilesReportPlugin.php +++ b/apps/dav/lib/Connector/Sabre/FilesReportPlugin.php @@ -362,7 +362,7 @@ private function getCirclesFileIds($circlesIds) { } */ - return \OCA\Circles\Api\v1\Circles::getObjectIdsForCircles($circlesIds); + return \OCA\Circles\Api\v1\Circles::getFilesForCircles($circlesIds); } /** From 3e623e11b830f07e7befcb629562d8aa2d188baa Mon Sep 17 00:00:00 2001 From: Vinicius Cubas Brand Date: Wed, 1 Nov 2017 10:06:33 -0200 Subject: [PATCH 4/6] Polishing: get files shared to circles in caldav Signed-off-by: Vinicius Cubas Brand --- .../lib/Connector/Sabre/FilesReportPlugin.php | 22 +++---------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/apps/dav/lib/Connector/Sabre/FilesReportPlugin.php b/apps/dav/lib/Connector/Sabre/FilesReportPlugin.php index 6d7257e352304..9550413da5bf7 100644 --- a/apps/dav/lib/Connector/Sabre/FilesReportPlugin.php +++ b/apps/dav/lib/Connector/Sabre/FilesReportPlugin.php @@ -45,7 +45,7 @@ class FilesReportPlugin extends ServerPlugin { const NS_OWNCLOUD = 'http://owncloud.org/ns'; const REPORT_NAME = '{http://owncloud.org/ns}filter-files'; const SYSTEMTAG_PROPERTYNAME = '{http://owncloud.org/ns}systemtag'; - const CIRCLE_PROPERTYNAME = '{http://owncloud.org/ns}circle'; + const CIRCLE_PROPERTYNAME = '{http://nextcloud.com/ns}circle'; /** * Reference to main server object @@ -343,25 +343,9 @@ private function getSystemTagFileIds($systemTagIds) { } private function getCirclesFileIds($circlesIds) { - - // check user permissions, if applicable - /* - if (!$this->isAdmin()) { - // check visibility/permission - $tags = $this->tagManager->getTagsByIds($circlesIds); - $unknownTagIds = []; - foreach ($tags as $tag) { - if (!$tag->isUserVisible()) { - $unknownTagIds[] = $tag->getId(); - } - } - - if (!empty($unknownTagIds)) { - throw new TagNotFoundException('Tag with ids ' . implode(', ', $unknownTagIds) . ' not found'); - } + if (!\OC::$server->getAppManager()->isEnabledForUser('circles') || !class_exists('\OCA\Circles\ShareByCircleProvider')) { + return array(); } - */ - return \OCA\Circles\Api\v1\Circles::getFilesForCircles($circlesIds); } From e840dc5eff28eb922d686a35bddf1678501e83b7 Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Tue, 7 Nov 2017 15:11:27 -0100 Subject: [PATCH 5/6] fixing Signed-off-by: Maxence Lange --- apps/dav/lib/Connector/Sabre/FilesReportPlugin.php | 7 ++++++- apps/dav/lib/Connector/Sabre/Principal.php | 13 +++---------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/apps/dav/lib/Connector/Sabre/FilesReportPlugin.php b/apps/dav/lib/Connector/Sabre/FilesReportPlugin.php index 9550413da5bf7..a58e0c30acb80 100644 --- a/apps/dav/lib/Connector/Sabre/FilesReportPlugin.php +++ b/apps/dav/lib/Connector/Sabre/FilesReportPlugin.php @@ -342,13 +342,18 @@ private function getSystemTagFileIds($systemTagIds) { return $resultFileIds; } - private function getCirclesFileIds($circlesIds) { + /** + * @param array $circlesIds + * @return array + */ + private function getCirclesFileIds(array $circlesIds) { if (!\OC::$server->getAppManager()->isEnabledForUser('circles') || !class_exists('\OCA\Circles\ShareByCircleProvider')) { return array(); } return \OCA\Circles\Api\v1\Circles::getFilesForCircles($circlesIds); } + /** * Prepare propfind response for the given nodes * diff --git a/apps/dav/lib/Connector/Sabre/Principal.php b/apps/dav/lib/Connector/Sabre/Principal.php index bae24735729bf..9c2db8091e2f7 100644 --- a/apps/dav/lib/Connector/Sabre/Principal.php +++ b/apps/dav/lib/Connector/Sabre/Principal.php @@ -266,7 +266,6 @@ protected function circleToPrincipal($circleUniqueId) { * Returns the list of circles a principal is a member of * * @param string $principal - * @param bool $needGroups * @return array * @throws Exception */ @@ -283,21 +282,15 @@ public function getCircleMembership($principal) { 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) { + $circles = \OCA\Circles\Api\v1\Circles::joinedCircles($user->getUID()); + $circles = array_map(function ($circle) { /** @var \OCA\Circles\Model\Circle $group */ return 'principals/circles/' . urlencode($circle->getUniqueId()); }, $circles); return $circles; - } + return []; } From 7063683290a709d89db12fdc8548645848a3eaa2 Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Mon, 13 Nov 2017 08:51:19 -0100 Subject: [PATCH 6/6] using CIRCLE__PROPERTYNAME Signed-off-by: Maxence Lange --- apps/dav/lib/Connector/Sabre/FilesReportPlugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dav/lib/Connector/Sabre/FilesReportPlugin.php b/apps/dav/lib/Connector/Sabre/FilesReportPlugin.php index a9648b7137657..5a4833398bda7 100644 --- a/apps/dav/lib/Connector/Sabre/FilesReportPlugin.php +++ b/apps/dav/lib/Connector/Sabre/FilesReportPlugin.php @@ -263,7 +263,7 @@ protected function processFilterRules($filterRules) { if ($filterRule['name'] === $ns . 'systemtag') { $systemTagIds[] = $filterRule['value']; } - if ($filterRule['name'] === $ns . 'circle') { + if ($filterRule['name'] === self::CIRCLE_PROPERTYNAME) { $circlesIds[] = $filterRule['value']; } if ($filterRule['name'] === $ns . 'favorite') {