Skip to content

Commit

Permalink
Revert 'Revert "send invitations for shared calendars"'
Browse files Browse the repository at this point in the history
This is basically the original commit, but with the addition that
CalDavBackend::getCalendarObjectByUID() also takes object in writable
shared calendars in to account and adjusts their uri s.t. the Sabre
library can find the returned object uri in the user's calendar
collection.

Signed-off-by: Claus-Justus Heine <himself@claus-justus-heine.de>
  • Loading branch information
rotdrop committed Feb 21, 2023
1 parent 5fcb55a commit d555972
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 6 deletions.
36 changes: 31 additions & 5 deletions apps/dav/lib/CalDAV/CalDavBackend.php
Original file line number Diff line number Diff line change
Expand Up @@ -2146,18 +2146,44 @@ public function searchPrincipalUri(string $principalUri,
* @return string|null
*/
public function getCalendarObjectByUID($principalUri, $uid) {
// query for shared writable calendars
$principals = $this->principalBackend->getGroupMembership($principalUri, true);
$principals = array_merge($principals, $this->principalBackend->getCircleMembership($principalUri));

$query = $this->db->getQueryBuilder();
$query->selectAlias('c.uri', 'calendaruri')->selectAlias('co.uri', 'objecturi')
$query
->selectAlias('c.id', 'calendarid')
->selectAlias('c.principaluri', 'principaluri')
->selectAlias('c.uri', 'calendaruri')
->selectAlias('co.uri', 'objecturi')
->selectAlias('ds.access', 'access')
->from('calendarobjects', 'co')
->leftJoin('co', 'calendars', 'c', $query->expr()->eq('co.calendarid', 'c.id'))
->where($query->expr()->eq('c.principaluri', $query->createNamedParameter($principalUri)))
->andWhere($query->expr()->eq('co.uid', $query->createNamedParameter($uid)))
->andWhere($query->expr()->isNull('co.deleted_at'));
->leftJoin('co', 'dav_shares', 'ds', $query->expr()->eq('co.calendarid', 'ds.resourceid'))
->where($query->expr()->eq('co.uid', $query->createNamedParameter($uid)))
->andWhere($query->expr()->isNull('co.deleted_at'))
->andWhere($query->expr()->orX(
$query->expr()->eq('c.principaluri', $query->createNamedParameter($principalUri)),
$query->expr()->andX(
$query->expr()->in('ds.principaluri', $query->createParameter('shareprincipal')),
$query->expr()->eq('ds.type', $query->createParameter('type')),
$query->expr()->eq('ds.access', $query->createParameter('access')),
)
))
->setParameter('access', Backend::ACCESS_READ_WRITE)
->setParameter('type', 'calendar')
->setParameter('shareprincipal', $principals, \Doctrine\DBAL\Connection::PARAM_STR_ARRAY);
$stmt = $query->executeQuery();
$row = $stmt->fetch();
$stmt->closeCursor();
if ($row) {
return $row['calendaruri'] . '/' . $row['objecturi'];
if ($row['principaluri'] != $principalUri) {
[, $name] = Uri\split($row['principaluri']);
$calendarUri = $row['calendaruri'] . '_shared_by_' . $name;
} else {
$calendarUri = $row['calendaruri'];
}
return $calendarUri . '/' . $row['objecturi'];
}

return null;
Expand Down
48 changes: 47 additions & 1 deletion apps/dav/lib/CalDAV/Schedule/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,53 @@ public function calendarObjectChange(RequestInterface $request, ResponseInterfac
$this->pathOfCalendarObjectChange = $request->getPath();
}

parent::calendarObjectChange($request, $response, $vCal, $calendarPath, $modified, $isNew);
//parent::calendarObjectChange($request, $response, $vCal, $calendarPath, $modified, $isNew);

if (!$this->scheduleReply($this->server->httpRequest)) {
return;
}

$calendarNode = $this->server->tree->getNodeForPath($calendarPath);

// Original code in parent class:
//
// $addresses = $this->getAddressesForPrincipal(
// $calendarNode->getOwner()
// );

// Allow also writable shared calendars:
$addresses = $this->getAddressesForPrincipal(
$calendarNode->getPrincipalURI()
);

if (!$isNew) {
$node = $this->server->tree->getNodeForPath($request->getPath());
$oldObj = Reader::read($node->get());
} else {
$oldObj = null;
}

$this->processICalendarChange($oldObj, $vCal, $addresses, [], $modified);

if ($oldObj) {
// Destroy circular references so PHP will GC the object.
$oldObj->destroy();
}
}

/**
* This method checks the 'Schedule-Reply' header
* and returns false if it's 'F', otherwise true.
*
* Copied from Sabre/DAV's Schedule plugin, because it's
* private for whatever reason
*
* @param RequestInterface $request
* @return bool
*/
private function scheduleReply(RequestInterface $request) {
$scheduleReply = $request->getHeader('Schedule-Reply');
return $scheduleReply !== 'F';
}

/**
Expand Down

0 comments on commit d555972

Please sign in to comment.