Backport of CalDAV improvements

This commit is contained in:
Jörg Lehrke 2010-05-21 18:27:39 +00:00
parent 4dd5efd3d6
commit 2c337344c0
2 changed files with 43 additions and 11 deletions

View File

@ -599,6 +599,11 @@ class calendar_bo
'end' => $event['end'], 'end' => $event['end'],
'tzid' => $event['tzid'], 'tzid' => $event['tzid'],
'title' => lang('private'), '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)), 'participants' => array_intersect_key($event['participants'],array_flip($allowed_participants)),
'public'=> 0, 'public'=> 0,
'category' => $event['category'], // category is visible anyway, eg. by using planner by cat 'category' => $event['category'], // category is visible anyway, eg. by using planner by cat
@ -1007,7 +1012,7 @@ class calendar_bo
$private = !$event['public']; $private = !$event['public'];
} }
$grants = $this->grants[$owner]; $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 // 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 // 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))) 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 // 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 // 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; if ($this->grants[$uid] == EGW_ACL_FREEBUSY && $uid != $this->user) continue;
@ -1048,7 +1054,8 @@ class calendar_bo
} }
else 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')) if ($this->debug && ($this->debug > 2 || $this->debug == 'check_perms'))
{ {

View File

@ -114,7 +114,14 @@ class calendar_groupdav extends groupdav_handler
'date_format' => 'server', '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 // process REPORT filters or multiget href's
if (($id || $options['root']['name'] != 'propfind') && !$this->_report_filters($options,$filter,$id)) 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( $events =& $bo->search(array(
'query' => array('cal_uid' => $uid), 'query' => array('cal_uid' => $uid),
'filter' => 'owner', // return all possible entries
'daywise' => false, 'daywise' => false,
'date_format' => 'server', 'date_format' => 'server',
)); ));
@ -608,13 +616,13 @@ error_log(__METHOD__."($path,,".array2string($start).") filter=".array2string($f
$org_recurrence = $org_recurrences[$recurrence['recurrence']]; $org_recurrence = $org_recurrences[$recurrence['recurrence']];
if (isset($org_recurrence)) // already existing 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']; $recurrence['id'] = $org_recurrence['id'];
// re-add (non-virtual) exceptions to master's recur_exception // re-add (non-virtual) exceptions to master's recur_exception
if ($recurrence['id'] != $master['id']) 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']; $exceptions[] = $recurrence['recurrence'];
} }
// remove recurrence to be able to detect deleted exceptions // 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 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']); $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) public function getctag($path,$user)
{ {
if ($this->debug > 1) error_log(__FILE__.'['.__LINE__.'] '.__METHOD__. "($path)[$user]");
$filter = array( $filter = array(
'users' => $user, 'users' => $user,
'start' => time()-100*24*3600, // default one month back -30 breaks all sync recurrences '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, 'enum_recuring' => false,
'daywise' => false, 'daywise' => false,
'date_format' => 'server', 'date_format' => 'server',
'order' => 'cal_modified DESC', 'order' => 'cal_modified DESC,cal_etag DESC',
'offset' => 0, 'offset' => 0,
'num_rows' => 1, '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); $result =& $this->bo->search($filter);
@ -723,25 +740,28 @@ error_log(__METHOD__."($path,,".array2string($start).") filter=".array2string($f
{ {
if (!is_array($entry)) 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']; $etag = $entry['id'].':'.$entry['etag'];
// use new MAX(modification date) of egw_cal_user table (deals with virtual exceptions too) // use new MAX(modification date) of egw_cal_user table (deals with virtual exceptions too)
if (isset($entry['max_user_modified'])) if (isset($entry['max_user_modified']))
{ {
$etag .= ':'.$entry['max_user_modified']; $modified = max($entry['max_user_modified'], $entry['modified']);
} }
else 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 // include exception etags into our own etag, if exceptions are included
if ($this->client_shared_uid_exceptions && !empty($entry['uid']) && if ($this->client_shared_uid_exceptions && !empty($entry['uid']) &&
$entry['recur_type'] != MCAL_RECUR_NONE && $entry['recur_exception']) $entry['recur_type'] != MCAL_RECUR_NONE && $entry['recur_exception'])
{ {
$events =& $this->bo->search(array( $events =& $this->bo->search(array(
'query' => array('cal_uid' => $entry['uid']), 'query' => array('cal_uid' => $entry['uid']),
'filter' => 'owner', // return all possible entries
'daywise' => false, 'daywise' => false,
'enum_recuring' => false, 'enum_recuring' => false,
'date_format' => 'server', 'date_format' => 'server',
@ -767,6 +787,11 @@ error_log(__METHOD__."($path,,".array2string($start).") filter=".array2string($f
*/ */
function check_access($acl,$event) 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'); return $this->bo->check_perms($acl,$event,0,'server');
} }