From 2c337344c04866266e4cf980b5e08541432a5a4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Lehrke?= Date: Fri, 21 May 2010 18:27:39 +0000 Subject: [PATCH] Backport of CalDAV improvements --- calendar/inc/class.calendar_bo.inc.php | 11 ++++- calendar/inc/class.calendar_groupdav.inc.php | 43 ++++++++++++++++---- 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/calendar/inc/class.calendar_bo.inc.php b/calendar/inc/class.calendar_bo.inc.php index 9f92d4c3a2..6a45e46206 100644 --- a/calendar/inc/class.calendar_bo.inc.php +++ b/calendar/inc/class.calendar_bo.inc.php @@ -599,6 +599,11 @@ class calendar_bo 'end' => $event['end'], 'tzid' => $event['tzid'], 'title' => lang('private'), + 'modified' => $event['modified'], + 'owner' => $event['owner'], + 'recur_type' => MCAL_RECUR_NONE, + 'etag' => $event['etag'], + 'max_user_modified' => $event['max_user_modified'], 'participants' => array_intersect_key($event['participants'],array_flip($allowed_participants)), 'public'=> 0, 'category' => $event['category'], // category is visible anyway, eg. by using planner by cat @@ -1007,7 +1012,7 @@ class calendar_bo $private = !$event['public']; } $grants = $this->grants[$owner]; - if (is_array($event) && $needed == EGW_ACL_READ) + if (is_array($event) && ($needed == EGW_ACL_READ || $needed == EGW_ACL_FREEBUSY)) { // Check if the $user is one of the participants or has a read-grant from one of them // in that case he has an implicite READ grant for that event @@ -1018,6 +1023,7 @@ class calendar_bo { if ($uid == $this->user || $uid < 0 && in_array($this->user,$GLOBALS['egw']->accounts->members($uid,true))) { + $grants |= EGW_ACL_FREEBUSY; // if we are a participant, we have an implicite READ and PRIVAT grant // exept the group gives its members only EGW_ACL_FREEBUSY and the participant is not the current user if ($this->grants[$uid] == EGW_ACL_FREEBUSY && $uid != $this->user) continue; @@ -1048,7 +1054,8 @@ class calendar_bo } else { - $access = $this->user == $owner || $grants & $needed && (!$private || $grants & EGW_ACL_PRIVATE); + $access = $this->user == $owner || $grants & $needed + && ($needed == EGW_ACL_FREEBUSY || !$private || $grants & EGW_ACL_PRIVATE); } if ($this->debug && ($this->debug > 2 || $this->debug == 'check_perms')) { diff --git a/calendar/inc/class.calendar_groupdav.inc.php b/calendar/inc/class.calendar_groupdav.inc.php index 4eeace38e4..a15d3f1c0d 100644 --- a/calendar/inc/class.calendar_groupdav.inc.php +++ b/calendar/inc/class.calendar_groupdav.inc.php @@ -114,7 +114,14 @@ class calendar_groupdav extends groupdav_handler 'date_format' => 'server', ); - if ($path == '/calendar/') $filter['filter'] = 'owner'; + if ($path == '/calendar/') + { + $filter['filter'] = 'owner'; + } + else + { + $filter['filter'] = 'default'; // not rejected + } // process REPORT filters or multiget href's if (($id || $options['root']['name'] != 'propfind') && !$this->_report_filters($options,$filter,$id)) @@ -417,6 +424,7 @@ error_log(__METHOD__."($path,,".array2string($start).") filter=".array2string($f $events =& $bo->search(array( 'query' => array('cal_uid' => $uid), + 'filter' => 'owner', // return all possible entries 'daywise' => false, 'date_format' => 'server', )); @@ -608,13 +616,13 @@ error_log(__METHOD__."($path,,".array2string($start).") filter=".array2string($f $org_recurrence = $org_recurrences[$recurrence['recurrence']]; if (isset($org_recurrence)) // already existing recurrence { - error_log(__METHOD__.'() setting id #'.$org_recurrence['id']).' for '.$recurrence['recurrence'].' = '.date('Y-m-d H:i:s',$recurrence['recurrence']); + //error_log(__METHOD__.'() setting id #'.$org_recurrence['id']).' for '.$recurrence['recurrence'].' = '.date('Y-m-d H:i:s',$recurrence['recurrence']); $recurrence['id'] = $org_recurrence['id']; // re-add (non-virtual) exceptions to master's recur_exception if ($recurrence['id'] != $master['id']) { - error_log(__METHOD__.'() re-adding recur_exception '.$recurrence['recurrence'].' = '.date('Y-m-d H:i:s',$recurrence['recurrence'])); + //error_log(__METHOD__.'() re-adding recur_exception '.$recurrence['recurrence'].' = '.date('Y-m-d H:i:s',$recurrence['recurrence'])); $exceptions[] = $recurrence['recurrence']; } // remove recurrence to be able to detect deleted exceptions @@ -633,7 +641,7 @@ error_log(__METHOD__."($path,,".array2string($start).") filter=".array2string($f } else // virtual recurrence { - //error_log(__METHOD__.'() ToDO: delete virtual exception '.$org_recurrence['recurrence'].' = '.date('Y-m-d H:i:s',$org_recurrence['recurrence'])); + //error_log(__METHOD__.'() delete virtual exception '.$org_recurrence['recurrence'].' = '.date('Y-m-d H:i:s',$org_recurrence['recurrence'])); $bo->update_status($master, $org_recurrence, $org_recurrence['recurrence']); } } @@ -692,6 +700,8 @@ error_log(__METHOD__."($path,,".array2string($start).") filter=".array2string($f */ public function getctag($path,$user) { + if ($this->debug > 1) error_log(__FILE__.'['.__LINE__.'] '.__METHOD__. "($path)[$user]"); + $filter = array( 'users' => $user, 'start' => time()-100*24*3600, // default one month back -30 breaks all sync recurrences @@ -699,12 +709,19 @@ error_log(__METHOD__."($path,,".array2string($start).") filter=".array2string($f 'enum_recuring' => false, 'daywise' => false, 'date_format' => 'server', - 'order' => 'cal_modified DESC', + 'order' => 'cal_modified DESC,cal_etag DESC', 'offset' => 0, 'num_rows' => 1, ); - if ($path == '/calendar/') $filter['filter'] = 'owner'; + if (strpos($path, '/calendar') === 0) + { + $filter['filter'] = 'owner'; + } + else + { + $filter['filter'] = 'default'; // not rejected + } $result =& $this->bo->search($filter); @@ -723,25 +740,28 @@ error_log(__METHOD__."($path,,".array2string($start).") filter=".array2string($f { if (!is_array($entry)) { - $entry = $this->read($entry); + if (!$this->bo->check_perms(EGW_ACL_FREEBUSY, $entry, 0, 'server')) return false; + $entry = $this->read($entry, null, true, 'server'); } $etag = $entry['id'].':'.$entry['etag']; // use new MAX(modification date) of egw_cal_user table (deals with virtual exceptions too) if (isset($entry['max_user_modified'])) { - $etag .= ':'.$entry['max_user_modified']; + $modified = max($entry['max_user_modified'], $entry['modified']); } else { - $etag .= ':'.$this->bo->so->max_user_modified($entry['id']); + $modified = max($this->bo->so->max_user_modified($entry['id']), $entry['modified']); } + $etag .= ':' . $modified; // include exception etags into our own etag, if exceptions are included if ($this->client_shared_uid_exceptions && !empty($entry['uid']) && $entry['recur_type'] != MCAL_RECUR_NONE && $entry['recur_exception']) { $events =& $this->bo->search(array( 'query' => array('cal_uid' => $entry['uid']), + 'filter' => 'owner', // return all possible entries 'daywise' => false, 'enum_recuring' => false, 'date_format' => 'server', @@ -767,6 +787,11 @@ error_log(__METHOD__."($path,,".array2string($start).") filter=".array2string($f */ function check_access($acl,$event) { + if ($acl == EGW_ACL_READ) + { + // we need at least EGW_ACL_FREEBUSY to get some information + $acl = EGW_ACL_FREEBUSY; + } return $this->bo->check_perms($acl,$event,0,'server'); }