* CalDAV: CalDAVSynchronizer: only allow owner/organizer to update or delete an event (not users with edit/delete rights)

This commit is contained in:
Ralf Becker 2018-10-09 13:14:36 +02:00
parent 985879b56c
commit cc22e89242
5 changed files with 24 additions and 23 deletions

View File

@ -935,10 +935,13 @@ class addressbook_groupdav extends Api\CalDAV\Handler
* *
* @param array &$options * @param array &$options
* @param int $id * @param int $id
* @param int $user account_id of collection owner
* @return mixed boolean true on success, false on failure or string with http status (eg. '404 Not Found') * @return mixed boolean true on success, false on failure or string with http status (eg. '404 Not Found')
*/ */
function delete(&$options,$id) function delete(&$options,$id,$user)
{ {
unset($user); // not used, but required by function signature
if (!is_array($contact = $this->_common_get_put_delete('DELETE',$options,$id))) if (!is_array($contact = $this->_common_get_put_delete('DELETE',$options,$id)))
{ {
return $contact; return $contact;

View File

@ -1774,7 +1774,7 @@ class CalDAV extends HTTP_WebDAV_Server
} }
if (($handler = self::app_handler($app))) if (($handler = self::app_handler($app)))
{ {
$status = $handler->delete($options,$id); $status = $handler->delete($options,$id,$user);
// set default stati: true --> 204 No Content, false --> should be already handled // set default stati: true --> 204 No Content, false --> should be already handled
if (is_bool($status)) $status = $status ? '204 No Content' : '400 Something went wrong'; if (is_bool($status)) $status = $status ? '204 No Content' : '400 Something went wrong';
return $status; return $status;

View File

@ -184,9 +184,10 @@ abstract class Handler
* *
* @param array &$options * @param array &$options
* @param int $id * @param int $id
* @param int $user account_id of collection owner
* @return mixed boolean true on success, false on failure or string with http status (eg. '404 Not Found') * @return mixed boolean true on success, false on failure or string with http status (eg. '404 Not Found')
*/ */
abstract function delete(&$options,$id); abstract function delete(&$options,$id,$user);
/** /**
* Read an entry * Read an entry

View File

@ -98,21 +98,6 @@ class calendar_groupdav extends Api\CalDAV\Handler
$this->bo = new calendar_boupdate(); $this->bo = new calendar_boupdate();
$this->vCalendar = new Horde_Icalendar; $this->vCalendar = new Horde_Icalendar;
if (self::get_agent() == 'caldavsynchronizer')
{
// Work around problems with Outlook CalDAV Synchroniser (https://caldavsynchronizer.org/)
// - sends a DELETE to reject a meeting request --> deletes event for all participants, if user has delete rights on the calendar
// - always sends all participants back with status NEEDS-ACTION --> resets status of all participant, if user has edit rights
// --> remove all add, edit, delete rights from other users
foreach($this->bo->grants as $user => &$grant)
{
if ($user != $this->bo->user)
{
$grant &= ~(Api\Acl::ADD | Api\Acl::EDIT | Api\Acl::DELETE);
}
}
}
// since 1.9.003 we allow clients to specify the URL when creating a new event, as specified by CalDAV // since 1.9.003 we allow clients to specify the URL when creating a new event, as specified by CalDAV
if (version_compare($GLOBALS['egw_info']['apps']['calendar']['version'], '1.9.003', '>=')) if (version_compare($GLOBALS['egw_info']['apps']['calendar']['version'], '1.9.003', '>='))
{ {
@ -930,7 +915,11 @@ class calendar_groupdav extends Api\CalDAV\Handler
} }
} }
// if no edit-rights (aka no organizer), update only attendee stuff: status and alarms // if no edit-rights (aka no organizer), update only attendee stuff: status and alarms
if (!$this->check_access(Acl::EDIT, $oldEvent)) if (!$this->check_access(Acl::EDIT, $oldEvent) ||
// Work around problems with Outlook CalDAV Synchroniser (https://caldavsynchronizer.org/)
// - always sends all participants back with status NEEDS-ACTION --> resets status of all participant, if user has edit rights
// --> allow full updates only for organizer
self::get_agent() == 'caldavsynchronizer' && $oldEvent['owner'] != $user)
{ {
$user_and_memberships = $GLOBALS['egw']->accounts->memberships($user, true); $user_and_memberships = $GLOBALS['egw']->accounts->memberships($user, true);
$user_and_memberships[] = $user; $user_and_memberships[] = $user;
@ -1362,18 +1351,23 @@ class calendar_groupdav extends Api\CalDAV\Handler
* @todo remove (non-virtual) exceptions, if series master gets deleted * @todo remove (non-virtual) exceptions, if series master gets deleted
* @param array &$options * @param array &$options
* @param int $id * @param int $id
* @param int $user account_id of collection owner
* @return mixed boolean true on success, false on failure or string with http status (eg. '404 Not Found') * @return mixed boolean true on success, false on failure or string with http status (eg. '404 Not Found')
*/ */
function delete(&$options,$id) function delete(&$options,$id,$user)
{ {
if (strpos($options['path'], '/inbox/') !== false) if (strpos($options['path'], '/inbox/') !== false)
{ {
return true; // simply ignore DELETE in inbox for now return true; // simply ignore DELETE in inbox for now
} }
$return_no_access = true; // to allow to check if current use is a participant and reject the event for him $return_no_access = true; // to allow to check if current use is a participant and reject the event for him
if (!is_array($event = $this->_common_get_put_delete('DELETE',$options,$id,$return_no_access)) || !$return_no_access) if (!is_array($event = $this->_common_get_put_delete('DELETE',$options,$id,$return_no_access)) || !$return_no_access ||
// Work around problems with Outlook CalDAV Synchroniser (https://caldavsynchronizer.org/)
// - sends a DELETE to reject a meeting request --> deletes event for all participants, if user has delete rights on the calendar
// --> only set status for everyone else but the organizer
self::get_agent() == 'caldavsynchronizer' && $event['owner'] != $user)
{ {
if (!$return_no_access) if (!$return_no_access || $event['owner'] != $user)
{ {
// check if user is a participant or one of the groups he is a member of --> reject the meeting request // check if user is a participant or one of the groups he is a member of --> reject the meeting request
$ret = '403 Forbidden'; $ret = '403 Forbidden';

View File

@ -693,10 +693,13 @@ class infolog_groupdav extends Api\CalDAV\Handler
* *
* @param array &$options * @param array &$options
* @param int $id * @param int $id
* @param int $user account_id of collection owner
* @return mixed boolean true on success, false on failure or string with http status (eg. '404 Not Found') * @return mixed boolean true on success, false on failure or string with http status (eg. '404 Not Found')
*/ */
function delete(&$options,$id) function delete(&$options,$id,$user)
{ {
unset($user); // not used, but required by function signature
if (!is_array($task = $this->_common_get_put_delete('DELETE',$options,$id))) if (!is_array($task = $this->_common_get_put_delete('DELETE',$options,$id)))
{ {
return $task; return $task;