-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CalDavBackend, implement SharingSupport interface. #36766
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -80,13 +80,15 @@ | |
use Sabre\CalDAV\Backend\SchedulingSupport; | ||
use Sabre\CalDAV\Backend\SubscriptionSupport; | ||
use Sabre\CalDAV\Backend\SyncSupport; | ||
use Sabre\CalDAV\Backend\SharingSupport; | ||
use Sabre\CalDAV\Xml\Property\ScheduleCalendarTransp; | ||
use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet; | ||
use Sabre\DAV; | ||
use Sabre\DAV\Exception\BadRequest; | ||
use Sabre\DAV\Exception\Forbidden; | ||
use Sabre\DAV\Exception\NotFound; | ||
use Sabre\DAV\PropPatch; | ||
use Sabre\DAV\Xml\Element\Sharee; | ||
use Sabre\Uri; | ||
use Sabre\VObject\Component; | ||
use Sabre\VObject\Component\VCalendar; | ||
|
@@ -118,7 +120,7 @@ | |
* | ||
* @package OCA\DAV\CalDAV | ||
*/ | ||
class CalDavBackend extends AbstractBackend implements SyncSupport, SubscriptionSupport, SchedulingSupport { | ||
class CalDavBackend extends AbstractBackend implements SyncSupport, SubscriptionSupport, SchedulingSupport, SharingSupport { | ||
use TTransactional; | ||
|
||
public const CALENDAR_TYPE_CALENDAR = 0; | ||
|
@@ -362,6 +364,9 @@ public function getCalendarsForUser($principalUri) { | |
$calendar = $this->addOwnerPrincipalToCalendar($calendar); | ||
$calendar = $this->addResourceTypeToCalendar($row, $calendar); | ||
|
||
$calendar['{DAV:}share-resource-uri'] = '/ns/share/' . $calendar['id']; | ||
$calendar['{DAV:}share-access'] = \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER; | ||
|
||
if (!isset($calendars[$calendar['id']])) { | ||
$calendars[$calendar['id']] = $calendar; | ||
} | ||
|
@@ -436,6 +441,9 @@ public function getCalendarsForUser($principalUri) { | |
$calendar = $this->addOwnerPrincipalToCalendar($calendar); | ||
$calendar = $this->addResourceTypeToCalendar($row, $calendar); | ||
|
||
$calendar['{DAV:}share-resource-uri'] = '/ns/share/' . $calendar['id']; | ||
$calendar['{DAV:}share-access'] = $row['access']; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue (blocking): The |
||
|
||
$calendars[$calendar['id']] = $calendar; | ||
} | ||
$result->closeCursor(); | ||
|
@@ -658,7 +666,7 @@ public function getCalendarByUri($principal, $uri) { | |
} | ||
|
||
/** | ||
* @return array{id: int, uri: string, '{http://calendarserver.org/ns/}getctag': string, '{http://sabredav.org/ns}sync-token': int, '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set': SupportedCalendarComponentSet, '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp': ScheduleCalendarTransp, '{urn:ietf:params:xml:ns:caldav}calendar-timezone': ?string }|null | ||
* @return array{id: int, uri: string, principaluri: string, '{http://calendarserver.org/ns/}getctag': string, '{http://sabredav.org/ns}sync-token': int, '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set': SupportedCalendarComponentSet, '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp': ScheduleCalendarTransp, '{urn:ietf:params:xml:ns:caldav}calendar-timezone': ?string }|null | ||
*/ | ||
public function getCalendarById(int $calendarId): ?array { | ||
$fields = array_column($this->propertyMap, 0); | ||
|
@@ -2823,23 +2831,28 @@ public function getShares(int $resourceId): array { | |
} | ||
|
||
/** | ||
* @param boolean $value | ||
* @param \OCA\DAV\CalDAV\Calendar $calendar | ||
* @return string|null | ||
*/ | ||
public function setPublishStatus($value, $calendar) { | ||
$calendarId = $calendar->getResourceId(); | ||
* Publishes a calendar. | ||
* | ||
* @param mixed $calendarId | ||
* @param bool $value | ||
* @return null|string | ||
*/ | ||
public function setPublishStatus($calendarId, $value) | ||
{ | ||
$calendarData = $this->getCalendarById($calendarId); | ||
if ($calendarData === null) { | ||
return null; | ||
} | ||
|
||
$query = $this->db->getQueryBuilder(); | ||
if ($value) { | ||
$publicUri = $this->random->generate(16, ISecureRandom::CHAR_HUMAN_READABLE); | ||
$query->insert('dav_shares') | ||
->values([ | ||
'principaluri' => $query->createNamedParameter($calendar->getPrincipalURI()), | ||
'principaluri' => $query->createNamedParameter($calendarData['principaluri']), | ||
'type' => $query->createNamedParameter('calendar'), | ||
'access' => $query->createNamedParameter(self::ACCESS_PUBLIC), | ||
'resourceid' => $query->createNamedParameter($calendar->getResourceId()), | ||
'resourceid' => $query->createNamedParameter($calendarId), | ||
'publicuri' => $query->createNamedParameter($publicUri) | ||
]); | ||
$query->executeStatement(); | ||
|
@@ -2848,7 +2861,7 @@ public function setPublishStatus($value, $calendar) { | |
return $publicUri; | ||
} | ||
$query->delete('dav_shares') | ||
->where($query->expr()->eq('resourceid', $query->createNamedParameter($calendar->getResourceId()))) | ||
->where($query->expr()->eq('resourceid', $query->createNamedParameter($calendarId))) | ||
->andWhere($query->expr()->eq('access', $query->createNamedParameter(self::ACCESS_PUBLIC))); | ||
$query->executeStatement(); | ||
|
||
|
@@ -2882,6 +2895,84 @@ public function applyShareAcl(int $resourceId, array $acl): array { | |
return $this->calendarSharingBackend->applyShareAcl($resourceId, $acl); | ||
} | ||
|
||
/** | ||
* Updates the list of shares. | ||
* | ||
* @param mixed $calendarId | ||
* @param \Sabre\DAV\Xml\Element\Sharee[] $sharees | ||
* @return void | ||
*/ | ||
public function updateInvites($calendarId, array $sharees) { | ||
$currentShares = $this->getShares($calendarId); | ||
|
||
$removals = []; | ||
$additions = []; | ||
|
||
foreach ($sharees as $sharee) { | ||
if (\Sabre\DAV\Sharing\Plugin::ACCESS_NOACCESS === $sharee->access) { | ||
// if access was set no NOACCESS, it means access for an | ||
// existing sharee was removed. | ||
$removals[] = $sharee->href; | ||
continue; | ||
} | ||
|
||
if (is_null($sharee->principal)) { | ||
// If the server could not determine the principal automatically, | ||
// we will mark the invite status as invalid. | ||
continue; | ||
} | ||
|
||
$additions[] = [ | ||
'href' => $sharee->href, | ||
'commonName' => $sharee->properties['{DAV:}displayname'] ?? '', | ||
'readOnly' => $sharee->access == \Sabre\DAV\Sharing\Plugin::ACCESS_READ, | ||
]; | ||
} | ||
// updateShares() needs a IShareable, i.e. a Calendar object. This is | ||
// really hacky now ... and inefficient ... | ||
Comment on lines
+2931
to
+2932
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: This restriction and the whole current implementation of Sharing addressbooks would be the only reason to keep it if we have this instead, so if we manage to overcome that, we could refactor the whole thing. |
||
$calendarInfo = $this->getCalendarById($calendarId); | ||
if ($calendarInfo === null) { | ||
return; | ||
} | ||
$principalUri = $calendarInfo['principaluri']; | ||
$calendarUri = $calendarInfo['uri']; | ||
$shareable = new Calendar($this, $calendarInfo, \OCP\Util::getL10N('dav'), $this->config, $this->logger); | ||
$this->updateShares($shareable, $additions, $removals); | ||
Check notice Code scanning / Psalm ArgumentTypeCoercion
Argument 2 of OCA\DAV\CalDAV\CalDavBackend::updateShares expects list<array{commonName: string, href: string, readOnly: bool}>, but parent type list<array{commonName: ""|mixed, href: string, readOnly: bool}> provided
|
||
} | ||
|
||
/** | ||
* Returns the list of people whom this calendar is shared with. | ||
* | ||
* Every item in the returned list must be a Sharee object with at | ||
* least the following properties set: | ||
* $href | ||
* $shareAccess | ||
* $inviteStatus | ||
* | ||
* and optionally: | ||
* $properties | ||
* | ||
* @param mixed $calendarId | ||
* | ||
* @return \Sabre\DAV\Xml\Element\Sharee[] | ||
*/ | ||
public function getInvites($calendarId) { | ||
$shares = $this->getShares($calendarId); | ||
$result = []; | ||
foreach ($shares as $share) { | ||
$result[] = new Sharee([ | ||
'href' => $share['href'], | ||
'access' => $share['readOnly'] ? \Sabre\DAV\Sharing\Plugin::ACCESS_READ : \Sabre\DAV\Sharing\Plugin::ACCESS_READWRITE, | ||
'inviteStatus' => \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thought: This makes me want invite support. :D |
||
'properties' => !empty($share['commonName']) | ||
? [ '{DAV:}displayname' => $share['commonName'] ] | ||
: [], | ||
'principal' => $share['{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}principal'], | ||
]); | ||
} | ||
return $result; | ||
} | ||
|
||
/** | ||
* update properties table | ||
* | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thought: Not a fan of this. The PDO backend does the exact same, but is this form even a valid URI?