diff --git a/apps/dav/appinfo/v1/caldav.php b/apps/dav/appinfo/v1/caldav.php index ecc4fbb8b6..c2634a595a 100644 --- a/apps/dav/appinfo/v1/caldav.php +++ b/apps/dav/appinfo/v1/caldav.php @@ -47,6 +47,7 @@ $principalBackend = new Principal( \OC::$server->getShareManager(), \OC::$server->getUserSession(), \OC::$server->getConfig(), + \OC::$server->getAppManager(), 'principals/' ); $db = \OC::$server->getDatabaseConnection(); diff --git a/apps/dav/appinfo/v1/carddav.php b/apps/dav/appinfo/v1/carddav.php index a424d7afab..60669df60b 100644 --- a/apps/dav/appinfo/v1/carddav.php +++ b/apps/dav/appinfo/v1/carddav.php @@ -48,6 +48,7 @@ $principalBackend = new Principal( \OC::$server->getShareManager(), \OC::$server->getUserSession(), \OC::$server->getConfig(), + \OC::$server->getAppManager(), 'principals/' ); $db = \OC::$server->getDatabaseConnection(); 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/CardDAV/CardDavBackend.php b/apps/dav/lib/CardDAV/CardDavBackend.php index 699248f7b1..f30a12bba4 100644 --- a/apps/dav/lib/CardDAV/CardDavBackend.php +++ b/apps/dav/lib/CardDAV/CardDavBackend.php @@ -167,8 +167,10 @@ class CardDavBackend implements BackendInterface, SyncSupport { } $result->closeCursor(); - // query for shared calendars + // query for shared addressbooks $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/Command/CreateCalendar.php b/apps/dav/lib/Command/CreateCalendar.php index 45dd9ba941..8e3a4abf8c 100644 --- a/apps/dav/lib/Command/CreateCalendar.php +++ b/apps/dav/lib/Command/CreateCalendar.php @@ -78,7 +78,8 @@ class CreateCalendar extends Command { $this->groupManager, \OC::$server->getShareManager(), \OC::$server->getUserSession(), - \OC::$server->getConfig() + \OC::$server->getConfig(), + \OC::$server->getAppManager() ); $random = \OC::$server->getSecureRandom(); $logger = \OC::$server->getLogger(); diff --git a/apps/dav/lib/Connector/Sabre/Principal.php b/apps/dav/lib/Connector/Sabre/Principal.php index 2574fbcd43..a441e1c812 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 * @@ -32,6 +34,9 @@ namespace OCA\DAV\Connector\Sabre; +use OCA\Circles\Exceptions\CircleDoesNotExistException; +use OCP\App\IAppManager; +use OCP\AppFramework\QueryException; use OCP\IConfig; use OCP\IGroup; use OCP\IGroupManager; @@ -60,12 +65,18 @@ class Principal implements BackendInterface { /** @var IConfig */ private $config; + /** @var IAppManager */ + private $appManager; + /** @var string */ private $principalPrefix; /** @var bool */ private $hasGroups; + /** @var bool */ + private $hasCircles; + /** * @param IUserManager $userManager * @param IGroupManager $groupManager @@ -79,14 +90,16 @@ class Principal implements BackendInterface { IShareManager $shareManager, IUserSession $userSession, IConfig $config, + IAppManager $appManager, $principalPrefix = 'principals/users/') { $this->userManager = $userManager; $this->groupManager = $groupManager; $this->shareManager = $shareManager; $this->userSession = $userSession; $this->config = $config; + $this->appManager = $appManager; $this->principalPrefix = trim($principalPrefix, '/'); - $this->hasGroups = ($principalPrefix === 'principals/users/'); + $this->hasGroups = $this->hasCircles = ($principalPrefix === 'principals/users/'); } /** @@ -131,6 +144,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 +403,69 @@ class Principal implements BackendInterface { return $this->principalPrefix; } + /** + * @param string $circleUniqueId + * @return array|null + * @suppress PhanUndeclaredClassMethod + * @suppress PhanUndeclaredClassCatch + */ + protected function circleToPrincipal($circleUniqueId) { + if (!$this->appManager->isEnabledForUser('circles') || !class_exists('\OCA\Circles\Api\v1\Circles')) { + return null; + } + + try { + $circle = \OCA\Circles\Api\v1\Circles::detailsCircle($circleUniqueId, true); + } catch(QueryException $ex) { + return null; + } catch(CircleDoesNotExistException $ex) { + return null; + } + + 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 + * @suppress PhanUndeclaredClassMethod + */ + public function getCircleMembership($principal):array { + if (!$this->appManager->isEnabledForUser('circles') || !class_exists('\OCA\Circles\Api\v1\Circles')) { + 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'); + } + + $circles = \OCA\Circles\Api\v1\Circles::joinedCircles($name, true); + + $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..0228c2a84c 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; } diff --git a/apps/dav/lib/RootCollection.php b/apps/dav/lib/RootCollection.php index 9ad1ea5221..38c8b2f6b4 100644 --- a/apps/dav/lib/RootCollection.php +++ b/apps/dav/lib/RootCollection.php @@ -58,7 +58,8 @@ class RootCollection extends SimpleCollection { $groupManager, $shareManager, \OC::$server->getUserSession(), - $config + $config, + \OC::$server->getAppManager() ); $groupPrincipalBackend = new GroupPrincipalBackend($groupManager, $userSession, $shareManager, $l10n); $calendarResourcePrincipalBackend = new ResourcePrincipalBackend($db, $userSession, $groupManager, $logger); diff --git a/apps/dav/tests/unit/CalDAV/AbstractCalDavBackend.php b/apps/dav/tests/unit/CalDAV/AbstractCalDavBackend.php index 63d48910f8..795a04e2cb 100644 --- a/apps/dav/tests/unit/CalDAV/AbstractCalDavBackend.php +++ b/apps/dav/tests/unit/CalDAV/AbstractCalDavBackend.php @@ -27,6 +27,7 @@ namespace OCA\DAV\Tests\unit\CalDAV; use OCA\DAV\CalDAV\CalDavBackend; use OCA\DAV\Connector\Sabre\Principal; +use OCP\App\IAppManager; use OCP\IConfig; use OCP\IGroupManager; use OCP\ILogger; @@ -83,6 +84,7 @@ abstract class AbstractCalDavBackend extends TestCase { $this->createMock(ShareManager::class), $this->createMock(IUserSession::class), $this->createMock(IConfig::class), + $this->createMock(IAppManager::class), ]) ->setMethods(['getPrincipalByPath', 'getGroupMembership']) ->getMock(); diff --git a/apps/dav/tests/unit/CardDAV/CardDavBackendTest.php b/apps/dav/tests/unit/CardDAV/CardDavBackendTest.php index 00a485a7d9..86c85a972e 100644 --- a/apps/dav/tests/unit/CardDAV/CardDavBackendTest.php +++ b/apps/dav/tests/unit/CardDAV/CardDavBackendTest.php @@ -35,6 +35,7 @@ use InvalidArgumentException; use OCA\DAV\CardDAV\AddressBook; use OCA\DAV\CardDAV\CardDavBackend; use OCA\DAV\Connector\Sabre\Principal; +use OCP\App\IAppManager; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\IConfig; use OCP\IDBConnection; @@ -131,6 +132,7 @@ class CardDavBackendTest extends TestCase { $this->createMock(ShareManager::class), $this->createMock(IUserSession::class), $this->createMock(IConfig::class), + $this->createMock(IAppManager::class), ]) ->setMethods(['getPrincipalByPath', 'getGroupMembership']) ->getMock(); diff --git a/apps/dav/tests/unit/Connector/Sabre/PrincipalTest.php b/apps/dav/tests/unit/Connector/Sabre/PrincipalTest.php index b72ae0a743..b40cd3105a 100644 --- a/apps/dav/tests/unit/Connector/Sabre/PrincipalTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/PrincipalTest.php @@ -29,6 +29,7 @@ namespace OCA\DAV\Tests\unit\Connector\Sabre; use OC\User\User; +use OCP\App\IAppManager; use OCP\IConfig; use OCP\IGroup; use OCP\IGroupManager; @@ -59,19 +60,25 @@ class PrincipalTest extends TestCase { /** @var IConfig | \PHPUnit_Framework_MockObject_MockObject */ private $config; + /** @var IAppManager | \PHPUnit_Framework_MockObject_MockObject */ + private $appManager; + public function setUp() { $this->userManager = $this->createMock(IUserManager::class); $this->groupManager = $this->createMock(IGroupManager::class); $this->shareManager = $this->createMock(IManager::class); $this->userSession = $this->createMock(IUserSession::class); $this->config = $this->createMock(IConfig::class); + $this->appManager = $this->createMock(IAppManager::class); $this->connector = new \OCA\DAV\Connector\Sabre\Principal( $this->userManager, $this->groupManager, $this->shareManager, $this->userSession, - $this->config); + $this->config, + $this->appManager + ); parent::setUp(); } diff --git a/apps/files_trashbin/lib/AppInfo/Application.php b/apps/files_trashbin/lib/AppInfo/Application.php index 06a34e0df8..761298673a 100644 --- a/apps/files_trashbin/lib/AppInfo/Application.php +++ b/apps/files_trashbin/lib/AppInfo/Application.php @@ -61,7 +61,8 @@ class Application extends App { \OC::$server->getGroupManager(), \OC::$server->getShareManager(), \OC::$server->getUserSession(), - \OC::$server->getConfig() + \OC::$server->getConfig(), + \OC::$server->getAppManager() ); }); diff --git a/apps/files_versions/lib/AppInfo/Application.php b/apps/files_versions/lib/AppInfo/Application.php index 935556221f..45dc6da6e2 100644 --- a/apps/files_versions/lib/AppInfo/Application.php +++ b/apps/files_versions/lib/AppInfo/Application.php @@ -51,7 +51,8 @@ class Application extends App { $server->getGroupManager(), $server->getShareManager(), $server->getUserSession(), - $server->getConfig() + $server->getConfig(), + $server->getAppManager() ); });