[Tickets #13664] accept event to Horde CalDAV calendar from Thunderbird Lightning parses Attendees

noreply at bugs.horde.org noreply at bugs.horde.org
Wed Nov 5 09:32:32 UTC 2014


DO NOT REPLY TO THIS MESSAGE. THIS EMAIL ADDRESS IS NOT MONITORED.

Ticket URL: https://bugs.horde.org/ticket/13664
------------------------------------------------------------------------------
  Ticket             | 13664
  Created By         | willem.verbruggen at anagky.be
  Summary            | accept event to Horde CalDAV calendar from Thunderbird
                     | Lightning parses Attendees
  Queue              | Kronolith
  Version            | 4.2.2
  Type               | Bug
  State              | Unconfirmed
  Priority           | 2. Medium
  Milestone          |
  Patch              |
  Owners             |
------------------------------------------------------------------------------


willem.verbruggen at anagky.be (2014-11-05 09:32) wrote:

Dear,

A meeting request arrives by e-mail in Thunderbird 31.2.0 with  
Lightning 3.3.1 installed from an external calendar application.  On  
accepting the meeting request putting it into a Kronolith calendar  
installed/connected from Lightning using CalDAV, Horde parses the  
attendees and puts them into the newly created request.

As a result Kronolith:
-> sends notifications to all the attendees from the organizers  
meeting as it is seen as a new meeting in Horde, effectively  
duplicating and hijacking someone else's meeting.
-> this happens for everyone accepting, and possibly also accepting  
the wrongly newly created meeting, with a mailing spree through the  
organization and towards the external partner as a result.
-> Horde treats accepting requests from Thunderbird differently than  
from within IMP with totally different meetings in Kronolith as a  
result, not working consistently.
-> Ligthing cannot be used as a mail client for accepting invites.

Thunderbird/Ligthning adds a header X-MOZ-RECEIVED-SEQUENCE to a  
meeting request being an accept on a received invite compared to a new  
meeting request created in LIghtning directly.

We could get a working, yes ugly but still a solution, patched up  
Kronolith with the following code changes whereby we check for the  
X-MOZ-RECEIVED-SEQUENCE header.  Hope it is any help to you.

vi /var/www/horde/kronolith/lib/Event.php

  363     /**
  364      * The cached event duration, split up in time units.
  365      *
  366      * @see getDuration()
  367      * @var stdClass
  368      */
  369     protected $_duration;
  370
   371     //OpenOutsourcing added properties
   372     //public $organizer;
   373     public $x_moz_received_sequence;
   374     public $x_moz_received_attendees = array();
  375
  376     /**
  377      * Constructor.
  378      *
  379      * @param Kronolith_Driver $driver  The backend driver that  
this event is
  380      *                                  stored in.
  381      * @param mixed $eventObject        Backend specific event object
  382      *                                  that this will represent.
  383      */
  384     public function __construct(Kronolith_Driver $driver,  
$eventObject = null)

1052     /**
1053      * Updates the properties of this event from a Horde_Icalendar_Vevent
1054      * object.
1055      *
1056      * @param Horde_Icalendar_Vevent $vEvent  The iCalendar data  
to update
1057      *                                        from.
1058      * @param boolean $parseAttendees         Parse attendees too?
1059      *                                        @since Kronolith 4.2
1060      */
1061     public function fromiCalendar($vEvent, $parseAttendees = false)
1062     {
1063
  1064         // OpenOutsourcing
  1065         // Add X-MOZ-RECEIVED-SEQUENCE to object
  1066         try {
  1067             $this->x_moz_received_sequence = False;
  1068             // This call throws exception when attribute does not exist
  1069             $moz_received =  
$vEvent->getAttribute('X-MOZ-RECEIVED-SEQUENCE');
  1070             $this->x_moz_received_sequence = True;
  1071         } catch (Horde_Icalendar_Exception $e) {}

2659     public function addAttendee($email, $attendance, $response,  
$name = null)
2660     {
2661         if ($attendance == Kronolith::PART_IGNORE) {
2662             if (isset($this->attendees[$email])) {
2663                 $attendance = $this->attendees[$email]['attendance'];
2664             } else {
2665                 $attendance = Kronolith::PART_REQUIRED;
2666             }
2667         }
2668         if (empty($name) && isset($this->attendees[$email]) &&
2669             !empty($this->attendees[$email]['name'])) {
2670             $name = $this->attendees[$email]['name'];
2671         }
2672
  2673         // OpenOutsourcing
  2674         // Add IF and wrap existing code into ELSE
  2675         if ($this->x_moz_received_sequence == True) {
  2676             $this->x_moz_received_attendees[$email] = array(
  2677                 'attendance' => $attendance,
  2678                 'response' => $response,
  2679                 'name' => $name
  2680             );
  2681         }
  2682         else {
  2683             $this->attendees[$email] = array(
  2684                 'attendance' => $attendance,
  2685                 'response' => $response,
  2686                 'name' => $name
  2687             );
  2688         }
2689     }

vi /var/www/horde/kronolith/lib/Application.php
800     public function davPutObject($collection, $object, $data)
...
854             // Save entry.
855             $id = $event->save();
856
857             if (!$existing_event) {
858                 $dav->addObjectMap($id, $object, $internal);
859             }
860
  861             // OpenOutsourcing
  862             // Send ACCEPT and DECLINE messages on  
X-MOZ-RECEIVED-SEQUENCE
  863             if($event->x_moz_received_sequence == True) {
  864
  865                 $ident_user =  
$GLOBALS['injector']->getInstance('Horde_Core_Factory_Identity')-  
 >create($event->creator);
  866                 $reply_to = $ident_user->getValue('from_addr');
  867
  868                 /** Invitation responses */
  869                 $RESPONSE_NONE      = 1;
  870                 $RESPONSE_ACCEPTED  = 2;
  871                 $RESPONSE_DECLINED  = 3;
  872                 $RESPONSE_TENTATIVE = 4;
  873
  874                 $response = $RESPONSE_NONE;
  875                 foreach ($event->x_moz_received_attendees as  
$email => $status) {
  876                     if ($email == $reply_to) {
  877                         $response = $status['response'];
  878                     }
  879                 }
  880
  881                 $resource = new Horde_Itip_Resource_Identity(
  882                     $GLOBALS['injector']->getInstance('IMP_Identity'),
  883                     $content->getAttribute('ATTENDEE'),
  884                     $reply_to
  885                 );
  886
  887                 switch ($response) {
  888                     case $RESPONSE_ACCEPTED:
  889                         $type = new  
Horde_Itip_Response_Type_Accept($resource);
  890                         break;
  891                     case $RESPONSE_TENTATIVE:
  892                         $type = new  
Horde_Itip_Response_Type_Tentative($resource);
  893                         break;
  894                     case $RESPONSE_DECLINED:
  895                         $type = new  
Horde_Itip_Response_Type_Decline($resource);
  896                         break;
  897                     default:
  898                         $type = new  
Horde_Itip_Response_Type_Accept($resource);
  899                         break;
  900                 }
  901
  902                 try {
  903                     Horde_Itip::factory($content,  
$resource)->sendMultiPartResponse(
  904                         $type,
  905                         new Horde_Itip_Response_Options_Horde(
  906                             'UTF-8',
  907                             array(
  908                                 'dns' =>  
$GLOBALS['injector']->getInstance('Net_DNS2_Resolver'),
  909                                 'server' =>  
$GLOBALS['conf']['server']['name']
  910                             )
  911                         ),
  912                         $GLOBALS['injector']->getInstance('IMP_Mail')
  913                     );
  914                 } catch (Horde_Itip_Exception $e) {
  915                     system("echo SENT ERROR >> /tmp/willem");
  916                 }
  917                 //$type = new  
Horde_Itip_Response_Type_Decline($resource);
  918             }
919
920             // Send iTip messages.

KR,

Willem





More information about the bugs mailing list