mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-03-03 17:51:54 +01:00
* Calendar/CalDAV: do not allow to resurrect a deleted meeting by accepting it again via CalDAV or meeting-request from mail app
This commit is contained in:
parent
a8222ed710
commit
0846fa78f3
@ -1067,6 +1067,25 @@ class calendar_groupdav extends Api\CalDAV\Handler
|
||||
}
|
||||
}
|
||||
|
||||
// if path not found, check the UID and return "403 Forbidden" if event is deleted or user has not rights to event with same UID
|
||||
if (!isset($oldEvent) && ($events = $handler->icaltoegw($vCalendar)) &&
|
||||
($oldEvents = $this->bo->read(['cal_uid' => $events[0]['uid'], 'cal_reference=0'], null, false, 'server')) !== null)
|
||||
{
|
||||
foreach($oldEvents as $oldEvent)
|
||||
{
|
||||
if (empty($oldEvent['deleted']))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!empty($oldEvent['deleted']))
|
||||
{
|
||||
$this->caldav->log("Event with UID='{$events[0]['uid']}' has already been deleted!");
|
||||
return '403 Forbidden';
|
||||
}
|
||||
// case user has no edit-rights for $oldEvent is handled below
|
||||
}
|
||||
|
||||
if (is_array($oldEvent))
|
||||
{
|
||||
$eventId = $oldEvent['id'];
|
||||
@ -1583,6 +1602,21 @@ class calendar_groupdav extends Api\CalDAV\Handler
|
||||
$return_no_access = true; // to allow to check if current use is a participant and reject the event for him
|
||||
$event = $this->_common_get_put_delete('DELETE',$options,$id,$return_no_access);
|
||||
|
||||
/* user has delete-rights, check if we have an external organizer and more participants
|
||||
if ($event && $return_no_access && count($event['participants']) > 2)
|
||||
{
|
||||
foreach($event['participants'] as $uid => $status)
|
||||
{
|
||||
$quantity = $role = null;
|
||||
calendar_so::split_status($status, $quantity, $role);
|
||||
if (!is_numeric($uid) && $role == 'CHAIR') break;
|
||||
}
|
||||
if (!(!is_numeric($uid) && $role == 'CHAIR'))
|
||||
{
|
||||
$return_no_access = false; // only set status rejected, but do NOT delete the event
|
||||
}
|
||||
}*/
|
||||
|
||||
// no event found --> 404 Not Found
|
||||
if (!is_array($event))
|
||||
{
|
||||
@ -1643,15 +1677,31 @@ class calendar_groupdav extends Api\CalDAV\Handler
|
||||
* the same UID and/or caldav_name as not deleted events and would block access to valid entries
|
||||
*
|
||||
* @param string|id $id
|
||||
* @return array|boolean array with entry, false if no read rights, null if $id does not exist
|
||||
* @return array|boolean array with entry, false if no read rights or deleted, null if $id does not exist
|
||||
*/
|
||||
function read($id)
|
||||
{
|
||||
if (strpos($column=self::$path_attr,'_') === false) $column = 'cal_'.$column;
|
||||
|
||||
$event = $this->bo->read(array($column => $id, 'cal_deleted IS NULL', 'cal_reference=0'), null, true,
|
||||
$event = $this->bo->read(array($column => $id, 'cal_reference=0'), null, true,
|
||||
$date_format = Api\CalDAV::isJSON() ? 'object' : 'server');
|
||||
if ($event) $event = array_shift($event); // read with array as 1. param, returns an array of events!
|
||||
|
||||
// read with array as 1. param, returns an array of events!
|
||||
// as we no longer return only NOT-deleted events, there might be more
|
||||
if ($event)
|
||||
{
|
||||
foreach ($event as $event)
|
||||
{
|
||||
if (empty($event['cal_deleted'])) break;
|
||||
}
|
||||
// the above prefers a NOT deleted event over deleted noes, thought all might be deleted
|
||||
if (!empty($event['cal_deleted']))
|
||||
{
|
||||
$retval = false;
|
||||
if ($this->debug > 0) error_log(__METHOD__."($id) event has been deleted returning ".array2string($retval));
|
||||
return $retval;
|
||||
}
|
||||
}
|
||||
|
||||
if (!($retval = $this->bo->check_perms(calendar_bo::ACL_FREEBUSY,$event, 0, 'server')) &&
|
||||
// above can be true, if current user is not in master but just a recurrence
|
||||
|
@ -2130,8 +2130,7 @@ class calendar_uiforms extends calendar_ui
|
||||
$event['end'] += $diff;
|
||||
}
|
||||
|
||||
if (($existing_event = $this->bo->read($event['uid'], $event['recurrence'], false, 'ts', null, true)) && // true = read the exception
|
||||
!$existing_event['deleted'])
|
||||
if (($existing_event = $this->bo->read($event['uid'], $event['recurrence'], false, 'ts', null, true))) // true = read the exception
|
||||
{
|
||||
// check if mail is from extern organizer
|
||||
$from_extern_organizer = false;
|
||||
@ -2179,7 +2178,7 @@ class calendar_uiforms extends calendar_ui
|
||||
// warn user about party-crashers (non-participants sending a reply)
|
||||
if (!isset($existing_status))
|
||||
{
|
||||
if (!empty($event['sender_warning'])) $event['sender_warning'] .= "\n";
|
||||
if (!empty($event['sender_warning'])) $event['sender_warning'] .= "\n\n";
|
||||
$event['sender_warning'] .= lang('Replying "%1" is NOT a participant of the event! Only continue if you want to add as new participant.', $participant);
|
||||
}
|
||||
calendar_so::split_status($existing_status, $quantity, $role);
|
||||
@ -2255,7 +2254,7 @@ class calendar_uiforms extends calendar_ui
|
||||
$event['recure'] = $this->bo->recure2string($event);
|
||||
$event['all_participants'] = implode(",\n",$this->bo->participants($event, true));
|
||||
|
||||
// EGroupware event has been deleted, dont let user resurect it by accepting again
|
||||
// EGroupware event has been deleted, don't let user resurrect it by accepting again
|
||||
if ($existing_event && $existing_event['deleted'] && strtolower($ical_method) !== 'cancel')
|
||||
{
|
||||
// check if this is an EGroupware event or has an external organizer
|
||||
@ -2265,12 +2264,8 @@ class calendar_uiforms extends calendar_ui
|
||||
calendar_so::split_status($status, $quantity, $role);
|
||||
if (!is_numeric($uid) && $role == 'CHAIR') break;
|
||||
}
|
||||
if (!(!is_numeric($uid) && $role == 'CHAIR'))
|
||||
{
|
||||
$event['error'] = lang('Event has been deleted by organizer!');
|
||||
$readonlys['button[accept]'] = $readonlys['button[tentativ]'] =
|
||||
$readonlys['button[reject]'] = $readonlys['button[cancel]'] = true;
|
||||
}
|
||||
$event['sender_warning'] = lang('Event has been deleted by organizer!').
|
||||
(!empty($event['sender_warning']) ? "\n\n".$event['sender_warning'] : '');
|
||||
}
|
||||
// ignore events in the past (for recurring events check enddate!)
|
||||
elseif ($this->bo->date2ts($event['start']) < $this->bo->now_su &&
|
||||
|
@ -10,7 +10,7 @@
|
||||
</columns>
|
||||
<rows>
|
||||
<row disabled="!@sender_warning">
|
||||
<grid width="100%" class="meetingRequest" span="all">
|
||||
<grid width="100%" class="meetingRequest meetingWarning" span="all">
|
||||
<columns>
|
||||
<column/>
|
||||
</columns>
|
||||
@ -19,35 +19,42 @@
|
||||
<et2-description value="Attention"></et2-description>
|
||||
</row>
|
||||
<row class="row">
|
||||
<et2-description id="sender_warning" class="meetingRequestError"></et2-description>
|
||||
<et2-description id="sender_warning"></et2-description>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</row>
|
||||
<row disabled="!@ics_method=request">
|
||||
<et2-description value="This mail contains a meeting request" class="meetingRequestMessage"></et2-description>
|
||||
<et2-hbox>
|
||||
<et2-button label="Apply" id="button[apply]" class="leftPad5" hideOnReadonly="true"></et2-button>
|
||||
<et2-button label="Accept" id="button[accept]" class="leftPad5" image="calendar/accepted"></et2-button>
|
||||
<et2-button label="Tentative" id="button[tentativ]" class="leftPad5" image="calendar/tentative"></et2-button>
|
||||
<et2-button label="Reject" id="button[reject]" class="leftPad5" image="calendar/rejected"></et2-button>
|
||||
<et2-button statustext="Edit event in calendar" label="Edit" id="button[edit]" image="edit" hideOnReadonly="true" onclick="window.open(egw::link('/index.php','menuaction=calendar.calendar_uiforms.edit&cal_id=$cont[id]'),'_blank','dependent=yes,width=750,height=410,scrollbars=yes,status=yes'); return false;" class="leftPad5" noSubmit="true"></et2-button>
|
||||
</et2-hbox>
|
||||
<et2-description id="error" class="meetingRequestError" align="right"></et2-description>
|
||||
<et2-vbox>
|
||||
<et2-description value="This mail contains a meeting request" class="meetingRequestMessage"></et2-description>
|
||||
<et2-hbox class="buttonRow">
|
||||
<et2-button label="Apply" id="button[apply]" hideOnReadonly="true"></et2-button>
|
||||
<et2-button label="Accept" id="button[accept]" image="calendar/accepted"></et2-button>
|
||||
<et2-button label="Tentative" id="button[tentativ]" image="calendar/tentative"></et2-button>
|
||||
<et2-button label="Reject" id="button[reject]" image="calendar/rejected"></et2-button>
|
||||
<et2-button statustext="Edit event in calendar" label="Edit" id="button[edit]" image="edit" hideOnReadonly="true"
|
||||
onclick="window.open(egw::link('/index.php','menuaction=calendar.calendar_uiforms.edit&cal_id=$cont[id]'),'_blank','dependent=yes,width=750,height=410,scrollbars=yes,status=yes'); return false;" noSubmit="true"></et2-button>
|
||||
</et2-hbox>
|
||||
</et2-vbox>
|
||||
</row>
|
||||
<row disabled="!@ics_method=reply">
|
||||
<et2-description value="This mail contains a reply to a meeting request" class="meetingRequestMessage"></et2-description>
|
||||
<et2-button label="Apply" id="button[apply]" class="leftPad5"></et2-button>
|
||||
<et2-description id="error" class="meetingRequestError" align="right"></et2-description>
|
||||
<et2-vbox>
|
||||
<et2-description value="This mail contains a reply to a meeting request" class="meetingRequestMessage"></et2-description>
|
||||
<et2-hbox class="buttonRow">
|
||||
<et2-button label="Apply" id="button[apply]"></et2-button>
|
||||
</et2-hbox>
|
||||
</et2-vbox>
|
||||
</row>
|
||||
<row disabled="!@ics_method=cancel">
|
||||
<et2-description value="This mail cancels a meeting" class="meetingRequestMessage"></et2-description>
|
||||
<et2-hbox>
|
||||
<et2-button label="Apply" statustext="Removes the event from my calendar" id="button[cancel]" class="leftPad5"></et2-button>
|
||||
<et2-button label="Delete" statustext="Delete this meeting for all participants" id="button[delete]" class="leftPad5" onclick="et2_dialog.confirm(widget,'Delete this meeting for all participants','Delete')"></et2-button>
|
||||
<et2-button statustext="Edit event in calendar" label="Edit" id="button[edit]" image="edit" onclick="window.open(egw::link('/index.php','menuaction=calendar.calendar_uiforms.edit&cal_id=$cont[id]'),'_blank','dependent=yes,width=750,height=410,scrollbars=yes,status=yes'); return false;" class="leftPad5"></et2-button>
|
||||
</et2-hbox>
|
||||
<et2-description id="error" class="meetingRequestError" align="right"></et2-description>
|
||||
<et2-vbox>
|
||||
<et2-description value="This mail cancels a meeting" class="meetingRequestMessage"></et2-description>
|
||||
<et2-hbox class="buttonRow">
|
||||
<et2-button label="Apply" statustext="Removes the event from my calendar" id="button[cancel]"></et2-button>
|
||||
<et2-button label="Delete" statustext="Delete this meeting for all participants" id="button[delete]" onclick="et2_dialog.confirm(widget,'Delete this meeting for all participants','Delete')"></et2-button>
|
||||
<et2-button statustext="Edit event in calendar" label="Edit" id="button[edit]" image="edit"
|
||||
onclick="window.open(egw::link('/index.php','menuaction=calendar.calendar_uiforms.edit&cal_id=$cont[id]'),'_blank','dependent=yes,width=750,height=410,scrollbars=yes,status=yes'); return false;"></et2-button>
|
||||
</et2-hbox>
|
||||
</et2-vbox>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
@ -61,6 +68,9 @@
|
||||
<row class="th">
|
||||
<et2-description id="ics_method_label" span="all"></et2-description>
|
||||
</row>
|
||||
<row class="row">
|
||||
<et2-description id="error" class="meetingRequestError" span="all"></et2-description>
|
||||
</row>
|
||||
<row class="row">
|
||||
<et2-description value="Title"></et2-description>
|
||||
<et2-description id="title" noLang="1"></et2-description>
|
||||
@ -75,9 +85,9 @@
|
||||
</row>
|
||||
<row class="row">
|
||||
<et2-description value="Date"></et2-description>
|
||||
<et2-hbox>
|
||||
<et2-hbox class="dates">
|
||||
<et2-date-time id="start" readonly="true"></et2-date-time>
|
||||
<et2-date-time label="-" id="end" readonly="true" class="leftPad5"></et2-date-time>
|
||||
<et2-date-time label="-" id="end" readonly="true"></et2-date-time>
|
||||
</et2-hbox>
|
||||
</row>
|
||||
<row class="row" disabled="!@recure">
|
||||
@ -107,7 +117,7 @@
|
||||
overflow-y: auto;
|
||||
}
|
||||
.meetingRequestMessage {
|
||||
font-size: 120%;
|
||||
font-size: 150%;
|
||||
}
|
||||
|
||||
table.meetingRequest {
|
||||
@ -123,6 +133,7 @@
|
||||
}
|
||||
.meetingRequest td {
|
||||
padding: 3px;
|
||||
padding-left: 0;
|
||||
}
|
||||
.meetingRequest a {
|
||||
display: inline-block;
|
||||
@ -130,11 +141,22 @@
|
||||
overflow-wrap: break-word;
|
||||
vertical-align: text-top;
|
||||
}
|
||||
|
||||
et2-hbox.dates {
|
||||
padding-left: 5px;
|
||||
}
|
||||
.meetingWarning tr.th {
|
||||
background-color: #dc2625;
|
||||
}
|
||||
.meetingWarning tr.row td {
|
||||
font-size: 120% !important;
|
||||
}
|
||||
.meetingRequestError {
|
||||
color: red;
|
||||
font-style: italic;
|
||||
font-size: 120%;
|
||||
color: red;
|
||||
}
|
||||
.buttonRow {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
</styles>
|
||||
</template>
|
||||
|
Loading…
Reference in New Issue
Block a user