Fix handling iTip replies with different address in From: and the iTip (Bifrost#T84315)

This commit is contained in:
Aleksander Machniak 2018-04-06 10:20:43 +02:00
parent f422aa853f
commit fdc0fbe4db
3 changed files with 53 additions and 14 deletions

View file

@ -3063,14 +3063,17 @@ class calendar extends rcube_plugin
// try to identify the attendee using the email sender address // try to identify the attendee using the email sender address
$existing_attendee = -1; $existing_attendee = -1;
$existing_attendee_emails = array(); $existing_attendee_emails = array();
foreach ($existing['attendees'] as $i => $attendee) { foreach ($existing['attendees'] as $i => $attendee) {
$existing_attendee_emails[] = $attendee['email']; $existing_attendee_emails[] = $attendee['email'];
if ($this->itip->compare_email($attendee['email'], $event['_sender'], $event['_sender_utf'])) { if ($this->itip->compare_email($attendee['email'], $event['_sender'], $event['_sender_utf'])) {
$existing_attendee = $i; $existing_attendee = $i;
} }
} }
$event_attendee = null; $event_attendee = null;
$update_attendees = array(); $update_attendees = array();
foreach ($event['attendees'] as $attendee) { foreach ($event['attendees'] as $attendee) {
if ($this->itip->compare_email($attendee['email'], $event['_sender'], $event['_sender_utf'])) { if ($this->itip->compare_email($attendee['email'], $event['_sender'], $event['_sender_utf'])) {
$event_attendee = $attendee; $event_attendee = $attendee;
@ -3078,6 +3081,7 @@ class calendar extends rcube_plugin
$metadata['fallback'] = $attendee['status']; $metadata['fallback'] = $attendee['status'];
$metadata['attendee'] = $attendee['email']; $metadata['attendee'] = $attendee['email'];
$metadata['rsvp'] = $attendee['rsvp'] || $attendee['role'] != 'NON-PARTICIPANT'; $metadata['rsvp'] = $attendee['rsvp'] || $attendee['role'] != 'NON-PARTICIPANT';
if ($attendee['status'] != 'DELEGATED') { if ($attendee['status'] != 'DELEGATED') {
break; break;
} }
@ -3103,6 +3107,23 @@ class calendar extends rcube_plugin
} }
} }
// Accept sender as a new participant (different email in From: and the iTip)
// Use ATTENDEE entry from the iTip with replaced email address
if (!$event_attendee) {
// remove the organizer
$itip_attendees = array_filter($event['attendees'], function($item) { return $item['role'] != 'ORGANIZER'; });
// there must be only one attendee
if (is_array($itip_attendees) && count($itip_attendees) == 1) {
$event_attendee = $itip_attendees[key($itip_attendees)];
$event_attendee['email'] = $event['_sender'];
$update_attendees[] = $event_attendee;
$metadata['fallback'] = $event_attendee['status'];
$metadata['attendee'] = $event_attendee['email'];
$metadata['rsvp'] = $event_attendee['rsvp'] || $event_attendee['role'] != 'NON-PARTICIPANT';
}
}
// found matching attendee entry in both existing and new events // found matching attendee entry in both existing and new events
if ($existing_attendee >= 0 && $event_attendee) { if ($existing_attendee >= 0 && $event_attendee) {
$existing['attendees'][$existing_attendee] = $event_attendee; $existing['attendees'][$existing_attendee] = $event_attendee;
@ -3113,6 +3134,9 @@ class calendar extends rcube_plugin
$existing['attendees'][] = $event_attendee; $existing['attendees'][] = $event_attendee;
$success = $this->driver->update_attendees($existing, $update_attendees); $success = $this->driver->update_attendees($existing, $update_attendees);
} }
else if (!$event_attendee) {
$error_msg = $this->gettext('errorunknownattendee');
}
else { else {
$error_msg = $this->gettext('newerversionexists'); $error_msg = $this->gettext('newerversionexists');
} }

View file

@ -249,6 +249,7 @@ $labels['nowritecalendarfound'] = 'No calendar found to save the event';
$labels['importedsuccessfully'] = 'The event was successfully added to \'$calendar\''; $labels['importedsuccessfully'] = 'The event was successfully added to \'$calendar\'';
$labels['updatedsuccessfully'] = 'The event was successfully updated in \'$calendar\''; $labels['updatedsuccessfully'] = 'The event was successfully updated in \'$calendar\'';
$labels['attendeupdateesuccess'] = 'Successfully updated the participant\'s status'; $labels['attendeupdateesuccess'] = 'Successfully updated the participant\'s status';
$labels['errorunknownattendee'] = 'Failed to find the participant information.';
$labels['itipsendsuccess'] = 'Invitation sent to participants.'; $labels['itipsendsuccess'] = 'Invitation sent to participants.';
$labels['itipresponseerror'] = 'Failed to send the response to this event invitation'; $labels['itipresponseerror'] = 'Failed to send the response to this event invitation';
$labels['itipinvalidrequest'] = 'This invitation is no longer valid'; $labels['itipinvalidrequest'] = 'This invitation is no longer valid';

View file

@ -613,6 +613,20 @@ class libcalendaring_itip
} }
} }
// It may happen that sender's address is different in From: and the attached iTip
// In such case use the ATTENDEE entry with the address from From: header
if (empty($metadata['attendee']) && !empty($event['_sender'])) {
// remove the organizer
$itip_attendees = array_filter($event['attendees'], function($item) { return $item['role'] != 'ORGANIZER'; });
// there must be only one attendee
if (is_array($itip_attendees) && count($itip_attendees) == 1) {
$event_attendee = $itip_attendees[key($itip_attendees)];
$metadata['attendee'] = $event['_sender'];
$rsvp_status = strtoupper($event_attendee['status']);
}
}
// 1. update the attendee status on our copy // 1. update the attendee status on our copy
$update_button = html::tag('input', array( $update_button = html::tag('input', array(
'type' => 'button', 'type' => 'button',