Projects
Kolab:Winterfell
kolab-syncroton
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 26
View file
kolab-syncroton.spec
Changed
@@ -37,7 +37,7 @@ Name: kolab-syncroton Version: 2.3.6 -Release: 1%{?dist} +Release: 2%{?dist} Summary: ActiveSync for Kolab Groupware Group: Applications/Internet @@ -47,6 +47,12 @@ Source0: https://mirror.kolabenterprise.com/pub/releases/%{name}-%{version}.tar.gz Source1: kolab-syncroton.logrotate +Patch0001: 0001-Add-ready-hook-for-Kolab-plugins-Bifrost-T36327.patch +Patch0002: 0002-Fix-LDAP-connection-errors-in-Ping-when-using-active.patch +Patch0003: 0003-Bump-SEQUENCE-number-on-update-Outlook-only.patch +Patch0004: 0004-Return-Invalid-item-6-status-on-SMS-entries-instead-.patch +Patch0005: 0005-implement-setAttendeeStatus.patch + BuildArch: noarch # Use this build requirement to make sure we are using @@ -224,6 +230,9 @@ %attr(0770,%{httpd_user},%{httpd_group}) %{_var}/log/%{name} %changelog +* Fri Aug 18 2017 Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> - 2.3.6-2 +- Patch setAttendeeStatus for increased Outlook compatibility + * Wed Jul 19 2017 Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> - 2.3.6-1 - Release 2.3.6
View file
0001-Add-ready-hook-for-Kolab-plugins-Bifrost-T36327.patch
Added
@@ -0,0 +1,25 @@ +From 945eeaf741bd6b94840adc81acc0281912919a16 Mon Sep 17 00:00:00 2001 +From: Aleksander Machniak <machniak@kolabsys.com> +Date: Tue, 1 Aug 2017 13:13:15 +0200 +Subject: [PATCH 01/15] Add 'ready' hook for Kolab plugins (Bifrost#T36327) + +--- + lib/kolab_sync.php | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/lib/kolab_sync.php b/lib/kolab_sync.php +index 6d3838a..5e9d262 100644 +--- a/lib/kolab_sync.php ++++ b/lib/kolab_sync.php +@@ -139,6 +139,8 @@ class kolab_sync extends rcube + exit; + } + ++ $this->plugins->exec_hook('ready', array('task' => 'syncroton')); ++ + // Set log directory per-user + $this->set_log_dir($this->username ?: $_SERVER['PHP_AUTH_USER']); + +-- +2.13.2 +
View file
0002-Fix-LDAP-connection-errors-in-Ping-when-using-active.patch
Added
@@ -0,0 +1,59 @@ +From ca089e32a5de5eea7766ec6ba69e037242f80f89 Mon Sep 17 00:00:00 2001 +From: Aleksander Machniak <machniak@kolabsys.com> +Date: Wed, 2 Aug 2017 14:07:00 +0200 +Subject: [PATCH 02/15] Fix LDAP connection errors in Ping when using + activesync_gal_sync + +When the LDAP addressbook is used for syncronization we have to +deal with closing and re-creating LDAP connections on sleep(). +--- + lib/kolab_sync.php | 21 +++++++++++++++++++++ + lib/kolab_sync_data_gal.php | 2 +- + 2 files changed, 22 insertions(+), 1 deletion(-) + +diff --git a/lib/kolab_sync.php b/lib/kolab_sync.php +index 5e9d262..c6cb192 100644 +--- a/lib/kolab_sync.php ++++ b/lib/kolab_sync.php +@@ -492,4 +492,25 @@ class kolab_sync extends rcube + self::console($log); + } + } ++ ++ /** ++ * When you're going to sleep the script execution for a longer time ++ * it is good to close all external connections (sql, memcache, SMTP, IMAP). ++ * ++ * No action is required on wake up, all connections will be ++ * re-established automatically. ++ */ ++ public function sleep() ++ { ++ parent::sleep(); ++ ++ // We'll have LDAP addressbooks here if using activesync_gal_sync ++ if ($this->config->get('activesync_gal_sync')) { ++ foreach (kolab_sync_data_gal::$address_books as $book) { ++ $book->close(); ++ } ++ ++ kolab_sync_data_gal::$address_books = array(); ++ } ++ } + } +diff --git a/lib/kolab_sync_data_gal.php b/lib/kolab_sync_data_gal.php +index 95894e7..09238f4 100644 +--- a/lib/kolab_sync_data_gal.php ++++ b/lib/kolab_sync_data_gal.php +@@ -42,7 +42,7 @@ class kolab_sync_data_gal extends kolab_sync_data implements Syncroton_Data_IDat + * + * @var array + */ +- protected static $address_books = array(); ++ public static $address_books = array(); + + /** + * Mapping from ActiveSync Contacts namespace fields +-- +2.13.2 +
View file
0003-Bump-SEQUENCE-number-on-update-Outlook-only.patch
Added
@@ -0,0 +1,43 @@ +From a68e0428fdb0b34cdc7de673e2d0737fddf0d355 Mon Sep 17 00:00:00 2001 +From: Aleksander Machniak <machniak@kolabsys.com> +Date: Fri, 4 Aug 2017 12:10:30 +0200 +Subject: [PATCH 03/15] Bump SEQUENCE number on update (Outlook only). + +It's been confirmed that any change of the event that has attendees specified +bumps SEQUENCE number of the event (we can see this in sent iTips). +--- + lib/kolab_sync_data_calendar.php | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/lib/kolab_sync_data_calendar.php b/lib/kolab_sync_data_calendar.php +index 946538a..8fab24d 100644 +--- a/lib/kolab_sync_data_calendar.php ++++ b/lib/kolab_sync_data_calendar.php +@@ -332,6 +332,7 @@ class kolab_sync_data_calendar extends kolab_sync_data implements Syncroton_Data + $foldername = isset($event['_mailbox']) ? $event['_mailbox'] : $this->getFolderName($folderid); + $config = $this->getFolderConfig($foldername); + $is_exception = $data instanceof Syncroton_Model_EventException; ++ $last_update = $event['changed']; + + $event['allday'] = 0; + +@@ -483,6 +484,16 @@ class kolab_sync_data_calendar extends kolab_sync_data implements Syncroton_Data + $event['recurrence'] = $this->recurrence_to_kolab($data, $folderid, $timezone); + } + ++ // Bump SEQUENCE number on update (Outlook only). ++ // It's been confirmed that any change of the event that has attendees specified ++ // bumps SEQUENCE number of the event (we can see this in sent iTips). ++ if (!empty($entry) && !$is_exception && !empty($data->attendees) ++ && $data->dtStamp && $last_update && $data->dtStamp > $last_update ++ && stripos($this->device->devicetype, 'outlook') !== false ++ ) { ++ $event['sequence'] += 1; ++ } ++ + return $event; + } + +-- +2.13.2 +
View file
0004-Return-Invalid-item-6-status-on-SMS-entries-instead-.patch
Added
@@ -0,0 +1,28 @@ +From d32b2289c65d749e55ea97de87f0563d4f989881 Mon Sep 17 00:00:00 2001 +From: Aleksander Machniak <machniak@kolabsys.com> +Date: Fri, 4 Aug 2017 16:58:13 +0200 +Subject: [PATCH 04/15] Return "Invalid item" (6) status on SMS entries instead + of "Server error" (5) + +"Server error" status may cause client to try again and again, +while "Invalid item" should thell the device to stop. +--- + lib/kolab_sync_data_email.php | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/kolab_sync_data_email.php b/lib/kolab_sync_data_email.php +index e528f9e..8f4d7a4 100644 +--- a/lib/kolab_sync_data_email.php ++++ b/lib/kolab_sync_data_email.php +@@ -570,7 +570,7 @@ class kolab_sync_data_email extends kolab_sync_data implements Syncroton_Data_ID + { + // Throw exception here for better handling of unsupported + // entry creation, it can be object of class Email or SMS here +- throw new Syncroton_Exception_Status_Sync(Syncroton_Exception_Status_Sync::SYNC_SERVER_ERROR); ++ throw new Syncroton_Exception_Status_Sync(Syncroton_Exception_Status_Sync::INVALID_ITEM); + } + + /** +-- +2.13.2 +
View file
0005-implement-setAttendeeStatus.patch
Added
@@ -0,0 +1,389 @@ +diff --git a/lib/kolab_sync.php b/lib/kolab_sync.php +index c6cb192..823d927 100644 +--- a/lib/kolab_sync.php ++++ b/lib/kolab_sync.php +@@ -82,7 +82,7 @@ class kolab_sync extends rcube + // e.g. are not using output or rcmail objects or + // doesn't throw errors when using them + $plugins = (array)$this->config->get('activesync_plugins', array('kolab_auth')); +- $plugins = array_unique(array_merge($plugins, array('libkolab'))); ++ $plugins = array_unique(array_merge($plugins, array('libcalendaring', 'libkolab'))); + + // Initialize/load plugins + $this->plugins = kolab_sync_plugin_api::get_instance(); +diff --git a/lib/kolab_sync_data.php b/lib/kolab_sync_data.php +index 2b91a7d..f1d723e 100644 +--- a/lib/kolab_sync_data.php ++++ b/lib/kolab_sync_data.php +@@ -92,6 +92,11 @@ abstract class kolab_sync_data implements Syncroton_Data_IData + protected $imap_folders = array(); + + /** ++ * Shortcut to logging. ++ */ ++ protected $log; ++ ++ /** + * Timezone + * + * @var string +@@ -186,6 +191,8 @@ abstract class kolab_sync_data implements Syncroton_Data_IData + + $this->defaultRootFolder = $this->defaultFolder . '::Syncroton'; + ++ $this->log = Syncroton_Registry::get('loggerBackend'); ++ + // set internal timezone of kolab_format to user timezone + try { + $this->timezone = rcube::get_instance()->config->get('timezone', 'GMT'); +@@ -954,18 +961,16 @@ abstract class kolab_sync_data implements Syncroton_Data_IData + $crc = $matches[1]; + $uid = $matches[2]; + +- if (strlen($entryid) >= 64) { +- foreach ($folder->select(array(array('uid', '~*', $uid))) as $object) { +- if (($object['uid'] == $uid || strpos($object['uid'], $uid) === 0) +- && $crc == $this->objectCRC($object['uid'], $folder) +- ) { +- $object['_folderid'] = $folderid; +- return $object; +- } ++ foreach ($folder->select(array(array('uid', '~*', $uid))) as $object) { ++ if (($object['uid'] == $uid || strpos($object['uid'], $uid) === 0) ++ && $crc == $this->objectCRC($object['uid'], $folder) ++ ) { ++ $object['_folderid'] = $folderid; ++ return $object; + } +- +- continue; + } ++ ++ continue; + } + + // Or (faster) strict UID matching... +diff --git a/lib/kolab_sync_data_calendar.php b/lib/kolab_sync_data_calendar.php +index 8fab24d..621cb3c 100644 +--- a/lib/kolab_sync_data_calendar.php ++++ b/lib/kolab_sync_data_calendar.php +@@ -180,6 +180,14 @@ class kolab_sync_data_calendar extends kolab_sync_data implements Syncroton_Data + public function getEntry(Syncroton_Model_SyncCollection $collection, $serverId, $as_array = false) + { + $event = is_array($serverId) ? $serverId : $this->getObject($collection->collectionId, $serverId); ++ ++ // If there is no such event, return NULL (otherwise this function ++ // returns a new Syncroton_Model_Event, that is further treated as if ++ // it were a valid, existing entry. ++ if (!$event) { ++ return NULL; ++ } ++ + $config = $this->getFolderConfig($event['_mailbox']); + $result = array(); + +@@ -273,11 +281,11 @@ class kolab_sync_data_calendar extends kolab_sync_data implements Syncroton_Data + if ($name = $attendee['name']) { + $result['organizerName'] = $name; + } ++ + if ($email = $attendee['email']) { + $result['organizerEmail'] = $email; + } + +- unset($event['attendees'][$idx]); + break; + } + } +@@ -286,11 +294,15 @@ class kolab_sync_data_calendar extends kolab_sync_data implements Syncroton_Data + // Attendees + if (!empty($event['attendees'])) { + foreach ($event['attendees'] as $idx => $attendee) { +- $att = array(); ++ if ($attendee['role'] == 'ORGANIZER') ++ continue; ++ ++ $att = Array(); + + if ($name = $attendee['name']) { + $att['name'] = $name; + } ++ + if ($email = $attendee['email']) { + $att['email'] = $email; + } +@@ -450,32 +462,65 @@ class kolab_sync_data_calendar extends kolab_sync_data implements Syncroton_Data + $name = $data->organizerName; + $email = $data->organizerEmail; + if ($name || $email) { +- $event['attendees'][] = array( ++ $_attendee = array( + 'role' => 'ORGANIZER', + 'name' => $name, + 'email' => $email, + ); ++ ++ if ($this->asversion >= 12) { ++ $_attendee['status'] = $data->meetingStatus == 1 ? 'ACCEPTED' : 'DECLINED'; ++ $_attendee['rsvp'] = FALSE; ++ } ++ ++ $event['attendees'][] = $_attendee; + } + } + + // Attendees + if (isset($data->attendees)) { + foreach ($data->attendees as $attendee) { ++ if ($attendee->email == $data->organizerEmail) ++ continue; ++ + $role = false; ++ + if (isset($attendee->attendeeType)) { +- $role = array_search($attendee->attendeeType, $this->attendeeTypeMap); ++ $role = array_search( ++ $attendee->attendeeType, ++ $this->attendeeTypeMap ++ ); ++ + } ++ + if ($role === false) { +- $role = array_search(self::ATTENDEE_TYPE_REQUIRED, $this->attendeeTypeMap); ++ $role = array_search( ++ self::ATTENDEE_TYPE_REQUIRED, ++ $this->attendeeTypeMap ++ ); + } + +- // AttendeeStatus send only on repsonse (?) +- +- $event['attendees'][] = array( +- 'role' => $role, +- 'name' => $attendee->name, +- 'email' => $attendee->email, ++ // AttendeeStatus send only on response (?) ++ $_attendee = array( ++ 'role' => $role, ++ 'name' => $attendee->name, ++ 'email' => $attendee->email, + ); ++ ++ if ($this->asversion >= 12) { ++ if ($status = $attendee->attendeeStatus) { ++ $_attendee['status'] = array_search( ++ $status, ++ $this->attendeeStatusMap ++ ); ++ ++ if ($status == self::ATTENDEE_STATUS_UNKNOWN) { ++ $_attendee['rsvp'] = TRUE; ++ } ++ } ++ } ++ ++ $event['attendees'][] = $_attendee; + } + } + +@@ -506,8 +551,141 @@ class kolab_sync_data_calendar extends kolab_sync_data implements Syncroton_Data + */ + public function setAttendeeStatus(Syncroton_Model_MeetingResponse $request) + { ++ /* ++ * The request actually involves an iTip request. ++ * ++ * - Get to the iTip, ++ * - Extract the event UID, ++ * - If not already an event in the user's calendar(s), create the event, ++ * - If already an event, update that event. ++ */ ++ ++ $object = $this->parseMessageId($request->requestId); ++ $message = new rcube_message($object['uid'], $object['foldername']); ++ ++ // Parse the message ++ $libcal = libcalendaring::get_instance(); ++ $libcal->mail_message_load(array('object' => $message)); ++ $ical_objects = $libcal->get_mail_ical_objects(); ++ ++ $itip = $ical_objects->objects[0]; ++ $uid = $itip['uid']; ++ ++ // Search the user's (event) folders ++ $folders = $this->listFolders(); ++ ++ $serverIds = Array(); ++ foreach ($folders as $folder => $attrs) { ++ $serverIds[] = $this->serverId($uid, $attrs['imap_name']); ++ } ++ ++ // Go search for a match ++ $existing_event = NULL; ++ ++ foreach ($serverIds as $serverId) { ++ foreach ($folders as $_folderid => $attrs) { ++ $collection = new Syncroton_Model_SyncCollection( ++ Array( ++ 'collectionId' => $_folderid ++ ) ++ ); ++ ++ $existing_event = $this->getEntry( ++ $collection, ++ $serverId ++ ); ++ ++ if ($existing_event) { ++ $folderId = $_folderid; ++ break; ++ } ++ } ++ ++ if ($existing_event) { ++ break; ++ } ++ } ++ ++ /* ++ Consider; ++ ++ - $existing_event->sensitivity (private, confidential, public) ++ - $existing_event->attendees[$x]->{role,rsvp,status} ++ - $request->userresponse ++ */ ++ ++ if ($existing_event) { ++ // This is an existing event that needs updating ++ $user_emails = kolab_sync::get_instance()->user->list_emails(); ++ $user_emails = array_map( ++ function($v) { return $v['email']; }, ++ $user_emails ++ ); ++ ++ foreach ($existing_event->attendees as $idx => $attendee) { ++ if (in_array_nocase($attendee->email, $user_emails)) { ++ $this->log->debug("found my record, updating status"); ++ switch ($request->userResponse) { ++ case Syncroton_Model_MeetingResponse::RESPONSE_ACCEPTED: ++ $existing_event->attendees[$idx]->attendeeStatus = self::ATTENDEE_STATUS_ACCEPTED; ++ break; ++ case Syncroton_Model_MeetingResponse::RESPONSE_DECLINED: ++ $existing_event->attendees[$idx]->attendeeStatus = self::ATTENDEE_STATUS_DECLINED; ++ break; ++ case Syncroton_Model_MeetingResponse::RESPONSE_TENTATIVE: ++ $existing_event->attendees[$idx]->attendeeStatus = self::ATTENDEE_STATUS_TENTATIVE; ++ break; ++ } ++ } ++ } ++ ++ $this->updateEntry($folderId, $serverId, $existing_event); ++ ++ } else { ++ // This is a new event ++ $this->log->debug("This is a new event"); ++ $folderId = $this->getDefaultFolder()['realid']; ++ ++ ++ $user_emails = kolab_sync::get_instance()->user->list_emails(); ++ $user_emails = array_map( ++ function($v) { return $v['email']; }, ++ $user_emails ++ ); ++ ++ $attendees = Array(); ++ ++ foreach($itip['attendees'] as $idx => $attendee) { ++ $att = $attendee; ++ ++ if (in_array_nocase($att['email'], $user_emails)) { ++ switch ($request->userResponse) { ++ case Syncroton_Model_MeetingResponse::RESPONSE_ACCEPTED: ++ $att['status'] = 'ACCEPTED'; ++ $att['rsvp'] = FALSE; ++ break; ++ ++ case Syncroton_Model_MeetingResponse::RESPONSE_DECLINED: ++ $att['status'] = 'DECLINED'; ++ $att['rsvp'] = FALSE; ++ break; ++ ++ case Syncroton_Model_MeetingResponse::RESPONSE_TENTATIVE: ++ $att['status'] = 'TENTATIVE'; ++ break; ++ } ++ } ++ ++ $attendees[] = $att; ++ } ++ ++ $itip['attendees'] = $attendees; ++ ++ $data = $this->createObject($folderId, $itip); ++ } ++ + // @TODO: not implemented +- throw new Syncroton_Exception_Status_MeetingResponse(Syncroton_Exception_Status_MeetingResponse::MEETING_ERROR); ++ throw new Syncroton_Exception_Status_MeetingResponse(1); + } + + /** +@@ -562,20 +740,25 @@ class kolab_sync_data_calendar extends kolab_sync_data implements Syncroton_Data + // TODO: Delegation/aliases support + $user_emails = kolab_sync::get_instance()->user->list_emails(); + $user_emails = array_map(function($v) { return $v['email']; }, $user_emails); +- $is_organizer = true; ++ $is_organizer = false; + + foreach ($event['attendees'] as $attendee) { ++ if ($attendee['role'] != 'ORGANIZER') { ++ // Irrelevant, skip ++ continue; ++ } ++ + if (in_array_nocase($attendee['email'], $user_emails)) { +- $is_organizer = false; ++ $is_organizer = true; + break; + } + } + + if ($event['status'] == 'CANCELLED') { +- $status = !empty($is_organizer) ? 5 : 7; ++ $status = $is_organizer ? 5 : 7; + } + else { +- $status = !empty($is_organizer) ? 1 : 3; ++ $status = $is_organizer ? 1 : 3; + } + } + +@@ -698,4 +881,26 @@ class kolab_sync_data_calendar extends kolab_sync_data implements Syncroton_Data + $entry->endTime = $rounded; + } + } ++ ++ private function parseMessageId($entryid) ++ { ++ // replyEmail/forwardEmail ++ if (is_array($entryid)) { ++ $entryid = $entryid['itemId']; ++ } ++ ++ list($folderid, $uid) = explode('::', $entryid); ++ $foldername = $this->backend->folder_id2name($folderid, $this->device->deviceid); ++ ++ if ($foldername === null || $foldername === false) { ++ // @TODO exception? ++ return null; ++ } ++ ++ return array( ++ 'uid' => $uid, ++ 'folderid' => $folderid, ++ 'foldername' => $foldername, ++ ); ++ } + }
View file
debian.changelog
Changed
@@ -1,3 +1,9 @@ +kolab-syncroton (2.3.6-0~kolab2) unstable; urgency=low + + * Patch setAttendeeStatus for increased Outlook compatibility + + -- Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> Fri, 18 Aug 2017 15:13:40 +0200 + kolab-syncroton (2.3.6-0~kolab1) unstable; urgency=low * Release 2.3.6
View file
debian.series
Changed
@@ -0,0 +1,5 @@ +0001-Add-ready-hook-for-Kolab-plugins-Bifrost-T36327.patch -p1 +0002-Fix-LDAP-connection-errors-in-Ping-when-using-active.patch -p1 +0003-Bump-SEQUENCE-number-on-update-Outlook-only.patch -p1 +0004-Return-Invalid-item-6-status-on-SMS-entries-instead-.patch -p1 +0005-implement-setAttendeeStatus.patch -p1
View file
kolab-syncroton.dsc
Changed
@@ -2,7 +2,7 @@ Source: kolab-syncroton Binary: kolab-syncroton Architecture: all -Version: 2.3.6-0~kolab1 +Version: 2.3.6-0~kolab2 Maintainer: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> Uploaders: Paul Klos <kolab@klos2day.nl> Homepage: http://www.kolab.org/
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.