diff options
author | Roeland Jago Douma <rullzer@users.noreply.github.com> | 2018-10-23 21:26:31 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-23 21:26:31 +0200 |
commit | b853102a8f1abb846fb865b3d0c19e8f8614bcd9 (patch) | |
tree | 9643f0139fcce0a0e29f945cbeb06fb64dea50df /apps/dav/lib | |
parent | 41fbda00edd42b5d4f6036959064410016d3f226 (diff) | |
parent | 5cfb5ec17613c4804fa83df6005d934222d16c99 (diff) | |
download | nextcloud-server-b853102a8f1abb846fb865b3d0c19e8f8614bcd9.tar.gz nextcloud-server-b853102a8f1abb846fb865b3d0c19e8f8614bcd9.zip |
Merge pull request #11886 from nextcloud/feature/noid/principal_search_displayname
Principal property search for users and groups with {DAV:}display name
Diffstat (limited to 'apps/dav/lib')
-rw-r--r-- | apps/dav/lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php | 12 | ||||
-rw-r--r-- | apps/dav/lib/CalDAV/ResourceBooking/ResourcePrincipalBackend.php | 2 | ||||
-rw-r--r-- | apps/dav/lib/CalDAV/ResourceBooking/RoomPrincipalBackend.php | 2 | ||||
-rw-r--r-- | apps/dav/lib/CalDAV/Schedule/Plugin.php | 25 | ||||
-rw-r--r-- | apps/dav/lib/Connector/Sabre/Principal.php | 24 | ||||
-rw-r--r-- | apps/dav/lib/DAV/GroupPrincipalBackend.php | 141 | ||||
-rw-r--r-- | apps/dav/lib/RootCollection.php | 2 |
7 files changed, 192 insertions, 16 deletions
diff --git a/apps/dav/lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php b/apps/dav/lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php index dcd393b512e..d658c3433f2 100644 --- a/apps/dav/lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php +++ b/apps/dav/lib/CalDAV/ResourceBooking/AbstractPrincipalBackend.php @@ -50,6 +50,9 @@ abstract class AbstractPrincipalBackend implements BackendInterface { /** @var string */ private $dbTableName; + /** @var string */ + private $cuType; + /** * @param IDBConnection $dbConnection * @param IUserSession $userSession @@ -57,18 +60,22 @@ abstract class AbstractPrincipalBackend implements BackendInterface { * @param ILogger $logger * @param string $principalPrefix * @param string $dbPrefix + * @param string $cuType */ public function __construct(IDBConnection $dbConnection, IUserSession $userSession, IGroupManager $groupManager, ILogger $logger, - $principalPrefix, $dbPrefix) { + string $principalPrefix, + string $dbPrefix, + string $cuType) { $this->db = $dbConnection; $this->userSession = $userSession; $this->groupManager = $groupManager; $this->logger = $logger; $this->principalPrefix = $principalPrefix; $this->dbTableName = 'calendar_' . $dbPrefix; + $this->cuType = $cuType; } /** @@ -328,7 +335,8 @@ abstract class AbstractPrincipalBackend implements BackendInterface { return [ 'uri' => $this->principalPrefix . '/' . $row['backend_id'] . '-' . $row['resource_id'], '{DAV:}displayname' => $row['displayname'], - '{http://sabredav.org/ns}email-address' => $row['email'] + '{http://sabredav.org/ns}email-address' => $row['email'], + '{urn:ietf:params:xml:ns:caldav}calendar-user-type' => $this->cuType, ]; } diff --git a/apps/dav/lib/CalDAV/ResourceBooking/ResourcePrincipalBackend.php b/apps/dav/lib/CalDAV/ResourceBooking/ResourcePrincipalBackend.php index a1030376c11..f8f10e78f94 100644 --- a/apps/dav/lib/CalDAV/ResourceBooking/ResourcePrincipalBackend.php +++ b/apps/dav/lib/CalDAV/ResourceBooking/ResourcePrincipalBackend.php @@ -40,6 +40,6 @@ class ResourcePrincipalBackend extends AbstractPrincipalBackend { IGroupManager $groupManager, ILogger $logger) { parent::__construct($dbConnection, $userSession, $groupManager, $logger, - 'principals/calendar-resources', 'resources'); + 'principals/calendar-resources', 'resources', 'RESOURCE'); } } diff --git a/apps/dav/lib/CalDAV/ResourceBooking/RoomPrincipalBackend.php b/apps/dav/lib/CalDAV/ResourceBooking/RoomPrincipalBackend.php index 1d22299515f..3059ed80ea6 100644 --- a/apps/dav/lib/CalDAV/ResourceBooking/RoomPrincipalBackend.php +++ b/apps/dav/lib/CalDAV/ResourceBooking/RoomPrincipalBackend.php @@ -40,6 +40,6 @@ class RoomPrincipalBackend extends AbstractPrincipalBackend { IGroupManager $groupManager, ILogger $logger) { parent::__construct($dbConnection, $userSession, $groupManager, $logger, - 'principals/calendar-rooms', 'rooms'); + 'principals/calendar-rooms', 'rooms', 'ROOM'); } } diff --git a/apps/dav/lib/CalDAV/Schedule/Plugin.php b/apps/dav/lib/CalDAV/Schedule/Plugin.php index b3f7232c2fe..227a1c11eda 100644 --- a/apps/dav/lib/CalDAV/Schedule/Plugin.php +++ b/apps/dav/lib/CalDAV/Schedule/Plugin.php @@ -50,6 +50,31 @@ class Plugin extends \Sabre\CalDAV\Schedule\Plugin { } /** + * This method handler is invoked during fetching of properties. + * + * We use this event to add calendar-auto-schedule-specific properties. + * + * @param PropFind $propFind + * @param INode $node + * @return void + */ + function propFind(PropFind $propFind, INode $node) { + // overwrite Sabre/Dav's implementation + $propFind->handle('{' . self::NS_CALDAV . '}calendar-user-type', function() use ($node) { + $calendarUserType = '{' . self::NS_CALDAV . '}calendar-user-type'; + $props = $node->getProperties([$calendarUserType]); + + if (isset($props[$calendarUserType])) { + return $props[$calendarUserType]; + } + + return 'INDIVIDUAL'; + }); + + parent::propFind($propFind, $node); + } + + /** * Returns a list of addresses that are associated with a principal. * * @param string $principal diff --git a/apps/dav/lib/Connector/Sabre/Principal.php b/apps/dav/lib/Connector/Sabre/Principal.php index cbfa1bc83e0..2574fbcd436 100644 --- a/apps/dav/lib/Connector/Sabre/Principal.php +++ b/apps/dav/lib/Connector/Sabre/Principal.php @@ -1,6 +1,7 @@ <?php /** * @copyright Copyright (c) 2016, ownCloud, Inc. + * @copyright Copyright (c) 2018, Georg Ehrke * * @author Bart Visscher <bartv@thisnet.nl> * @author Jakob Sack <mail@jakobsack.de> @@ -11,6 +12,7 @@ * @author Thomas Müller <thomas.mueller@tmit.eu> * @author Thomas Tanghus <thomas@tanghus.net> * @author Vincent Petry <pvince81@owncloud.com> + * @author Georg Ehrke <oc.list@georgehrke.com> * * @license AGPL-3.0 * @@ -249,6 +251,23 @@ class Principal implements BackendInterface { }, []); break; + case '{DAV:}displayname': + $users = $this->userManager->searchDisplayName($value); + + $results[] = array_reduce($users, function(array $carry, IUser $user) use ($restrictGroups) { + // is sharing restricted to groups only? + if ($restrictGroups !== false) { + $userGroups = $this->groupManager->getUserGroupIds($user); + if (count(array_intersect($userGroups, $restrictGroups)) === 0) { + return $carry; + } + } + + $carry[] = $this->principalPrefix . '/' . $user->getUID(); + return $carry; + }, []); + break; + default: $results[] = []; break; @@ -263,11 +282,11 @@ class Principal implements BackendInterface { 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)); } } @@ -354,6 +373,7 @@ class Principal implements BackendInterface { $principal = [ 'uri' => $this->principalPrefix . '/' . $userId, '{DAV:}displayname' => is_null($displayName) ? $userId : $displayName, + '{urn:ietf:params:xml:ns:caldav}calendar-user-type' => 'INDIVIDUAL', ]; $email = $user->getEMailAddress(); diff --git a/apps/dav/lib/DAV/GroupPrincipalBackend.php b/apps/dav/lib/DAV/GroupPrincipalBackend.php index 1f182445dbd..166af7c6b27 100644 --- a/apps/dav/lib/DAV/GroupPrincipalBackend.php +++ b/apps/dav/lib/DAV/GroupPrincipalBackend.php @@ -1,9 +1,11 @@ <?php /** * @copyright Copyright (c) 2016, ownCloud, Inc. + * @copyright Copyright (c) 2018, Georg Ehrke * * @author Roeland Jago Douma <roeland@famdouma.nl> * @author Thomas Müller <thomas.mueller@tmit.eu> + * @author Georg Ehrke <oc.list@georgehrke.com> * * @license AGPL-3.0 * @@ -24,6 +26,9 @@ namespace OCA\DAV\DAV; use OCP\IGroup; use OCP\IGroupManager; +use OCP\IUserSession; +use OCP\Share\IManager as IShareManager; +use OCP\IL10N; use OCP\IUser; use Sabre\DAV\Exception; use \Sabre\DAV\PropPatch; @@ -36,11 +41,29 @@ class GroupPrincipalBackend implements BackendInterface { /** @var IGroupManager */ private $groupManager; + /** @var IUserSession */ + private $userSession; + + /** @var IShareManager */ + private $shareManager; + + /** @var IL10N */ + private $l10n; + /** * @param IGroupManager $IGroupManager + * @param IUserSession $userSession + * @param IShareManager $shareManager + * @param IL10N $l10n */ - public function __construct(IGroupManager $IGroupManager) { + public function __construct(IGroupManager $IGroupManager, + IUserSession $userSession, + IShareManager $shareManager, + IL10N $l10n) { $this->groupManager = $IGroupManager; + $this->userSession = $userSession; + $this->shareManager = $shareManager; + $this->l10n = $l10n; } /** @@ -161,7 +184,71 @@ class GroupPrincipalBackend implements BackendInterface { * @return array */ function searchPrincipals($prefixPath, array $searchProperties, $test = 'allof') { - return []; + $results = []; + + if (\count($searchProperties) === 0) { + return []; + } + if ($prefixPath !== self::PRINCIPAL_PREFIX) { + return []; + } + // If sharing is disabled, return the empty array + $shareAPIEnabled = $this->shareManager->shareApiEnabled(); + if (!$shareAPIEnabled) { + return []; + } + + // If sharing is restricted to group members only, + // return only members that have groups in common + $restrictGroups = false; + if ($this->shareManager->shareWithGroupMembersOnly()) { + $user = $this->userSession->getUser(); + if (!$user) { + return []; + } + + $restrictGroups = $this->groupManager->getUserGroupIds($user); + } + + foreach ($searchProperties as $prop => $value) { + switch ($prop) { + case '{DAV:}displayname': + $groups = $this->groupManager->search($value); + + $results[] = array_reduce($groups, function(array $carry, IGroup $group) use ($restrictGroups) { + $gid = $group->getGID(); + // is sharing restricted to groups only? + if ($restrictGroups !== false) { + if (!\in_array($gid, $restrictGroups, true)) { + return $carry; + } + } + + $carry[] = self::PRINCIPAL_PREFIX . '/' . $gid; + return $carry; + }, []); + break; + + default: + $results[] = []; + break; + } + } + + // 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[0]; + } + + switch ($test) { + case 'anyof': + return array_values(array_unique(array_merge(...$results))); + + case 'allof': + default: + return array_values(array_intersect(...$results)); + } } /** @@ -170,7 +257,34 @@ class GroupPrincipalBackend implements BackendInterface { * @return string */ function findByUri($uri, $principalPrefix) { - return ''; + // If sharing is disabled, return the empty array + $shareAPIEnabled = $this->shareManager->shareApiEnabled(); + if (!$shareAPIEnabled) { + return null; + } + + // If sharing is restricted to group members only, + // return only members that have groups in common + $restrictGroups = false; + if ($this->shareManager->shareWithGroupMembersOnly()) { + $user = $this->userSession->getUser(); + if (!$user) { + return null; + } + + $restrictGroups = $this->groupManager->getUserGroupIds($user); + } + + if (strpos($uri, 'principal:principals/groups/') === 0) { + $name = urlencode(substr($uri, 28)); + if ($restrictGroups !== false && !\in_array($name, $restrictGroups, true)) { + return null; + } + + return substr($uri, 10); + } + + return null; } /** @@ -179,12 +293,12 @@ class GroupPrincipalBackend implements BackendInterface { */ protected function groupToPrincipal($group) { $groupId = $group->getGID(); - $principal = [ + + return [ 'uri' => 'principals/groups/' . urlencode($groupId), - '{DAV:}displayname' => $groupId, + '{DAV:}displayname' => $this->l10n->t('%s (group)', [$groupId]), + '{urn:ietf:params:xml:ns:caldav}calendar-user-type' => 'GROUP', ]; - - return $principal; } /** @@ -192,11 +306,20 @@ class GroupPrincipalBackend implements BackendInterface { * @return array */ protected function userToPrincipal($user) { + $userId = $user->getUID(); + $displayName = $user->getDisplayName(); + $principal = [ - 'uri' => 'principals/users/' . $user->getUID(), - '{DAV:}displayname' => $user->getDisplayName(), + 'uri' => 'principals/users/' . $userId, + '{DAV:}displayname' => is_null($displayName) ? $userId : $displayName, + '{urn:ietf:params:xml:ns:caldav}calendar-user-type' => 'INDIVIDUAL', ]; + $email = $user->getEMailAddress(); + if (!empty($email)) { + $principal['{http://sabredav.org/ns}email-address'] = $email; + } + return $principal; } } diff --git a/apps/dav/lib/RootCollection.php b/apps/dav/lib/RootCollection.php index 9a3261c388c..a05781a7621 100644 --- a/apps/dav/lib/RootCollection.php +++ b/apps/dav/lib/RootCollection.php @@ -57,7 +57,7 @@ class RootCollection extends SimpleCollection { \OC::$server->getUserSession(), $config ); - $groupPrincipalBackend = new GroupPrincipalBackend($groupManager); + $groupPrincipalBackend = new GroupPrincipalBackend($groupManager, $userSession, $shareManager, $l10n); $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 |