Projects
home:sicherha:branches:Kolab:16
kolab-syncroton
Log In
Username
Password
Problem getting expanded diff: bad link: conflict in file debian.control
×
We truncated the diff of some files because they were too big. If you want to see the full diff for every file,
click here
.
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 3
View file
kolab-syncroton.spec
Changed
@@ -34,9 +34,10 @@ %endif %global _ap_sysconfdir %{_sysconfdir}/%{httpd_name} +%global upstream_version 2.4.2 Name: kolab-syncroton -Version: 2.3.10 +Version: 2.4.2.10 Release: 1%{?dist} Summary: ActiveSync for Kolab Groupware @@ -44,55 +45,46 @@ License: LGPLv2 URL: http://www.syncroton.org -Source0: https://mirror.kolabenterprise.com/pub/releases/%{name}-%{version}.tar.gz +Source0: %{name}-%{upstream_version}.tar.gz Source1: kolab-syncroton.logrotate +Source2: plesk.kolab_syncroton.inc.php BuildArch: noarch -# Use this build requirement to make sure we are using -# up to date vendorized copies of the plugins. -%if 0%{?plesk} < 1 -BuildRequires: roundcubemail-plugin-kolab_auth >= 3.2 -%endif -BuildRequires: roundcubemail-plugin-kolab_folders >= 3.2 -BuildRequires: roundcubemail-plugin-libcalendaring >= 3.2 -BuildRequires: roundcubemail-plugin-libkolab >= 3.2 - +%if 0%{?rhel} < 8 %if 0%{?suse_version} BuildRequires: roundcubemail Requires: php Requires: php-pear-Auth_SASL Requires: php-pear-MDB2_Driver_mysqli -Requires: php-pear-Net_IDNA2 Requires: php-pear-Net_SMTP Requires: php-pear-Net_Socket %else +BuildRequires: roundcubemail >= 1.5 Requires: php-common >= 5.3 Requires: php-pear-Auth-SASL Requires: php-pear-MDB2-Driver-mysqli -Requires: php-pear-Net-IDNA2 Requires: php-pear-Net-SMTP Requires: php-pear-Net-Socket %endif +%endif +Requires: roundcubemail Requires: logrotate -Requires: roundcubemail(core) -%if 0%{?plesk} < 1 -Requires: roundcubemail-plugin-kolab_auth >= 3.2 -%endif -Requires: roundcubemail-plugin-kolab_folders >= 3.2 -Requires: roundcubemail-plugin-libcalendaring >= 3.2 -Requires: roundcubemail-plugin-libkolab >= 3.2 +%if 0%{?rhel} < 8 Requires: php-kolabformat Requires: php-pear-MDB2 Requires: php-ZendFramework +%endif + %description Kolab Groupware provides ActiveSync for Calendars, Address Books and Tasks though this package - based on Syncroton technology. %prep -%setup -q -n %{name}-%{version} +%setup -q -n %{name}-%{upstream_version} +#%patch0 -p1 %build @@ -102,7 +94,7 @@ %if 0%{?plesk} < 1 %{buildroot}/%{_ap_sysconfdir}/conf.d/ \ %endif - %{buildroot}/%{_sysconfdir}/%{name} \ + %{buildroot}/%{_sysconfdir}/roundcubemail/ \ %{buildroot}/%{_var}/log/%{name} mkdir -p %{buildroot}%{_sysconfdir}/logrotate.d @@ -115,6 +107,12 @@ cp -a lib %{buildroot}/%{_datadir}/%{name}/. cp -a index.php %{buildroot}/%{_datadir}/%{name}/. +%if 0%{?plesk} +cp -a %SOURCE2 %{buildroot}/%{_sysconfdir}/roundcubemail/kolab_syncroton.inc.php +%else +cp -a config/config.inc.php.dist %{buildroot}/%{_sysconfdir}/roundcubemail/kolab_syncroton.inc.php +%endif + pushd %{buildroot}/%{_datadir}/%{name} ln -s ../../..%{_sysconfdir}/roundcubemail config ln -s ../../..%{_var}/log/%{name} logs @@ -174,8 +172,12 @@ fi fi +if -f "/usr/lib/systemd/system/php-fpm.service" ; then + /bin/systemctl reload php-fpm.service || : +fi + /usr/share/roundcubemail/bin/updatedb.sh \ - --dir /usr/share/doc/kolab-syncroton-%{version}/SQL/ \ + --dir /usr/share/doc/kolab-syncroton/SQL/ \ --package syncroton \ >/dev/null 2>&1 || : @@ -191,10 +193,53 @@ %config(noreplace) %{_ap_sysconfdir}/conf.d/kolab-syncroton.conf %endif %config(noreplace) %{_sysconfdir}/logrotate.d/%{name} +%config(noreplace) %{_sysconfdir}/roundcubemail/kolab_syncroton.inc.php %{_datadir}/%{name} %attr(0770,%{httpd_user},%{httpd_group}) %{_var}/log/%{name} %changelog +* Thu Jul 27 2023 Christian Mollekopf <mollekopf@apheleia-it.ch> - 2.4.2-1 +- Release version 2.4.2 + +* Mon Jul 17 2023 Christian Mollekopf <mollekopf@apheleia-it.ch> - 2.4.1-1 +- Release version 2.4.1 + +* Wed May 10 2023 Christian Mollekopf <mollekopf@apheleia-it.ch> - 2.4.0-1 +- Release version 2.4.0 + +* Fri Feb 04 2022 Jeroen van Meeuwen <vanmeeuwen@apheleia-it.ch> - 2.3.22-1 +- Release version 2.3.22 + +* Fri Jul 02 2021 Jeroen van Meeuwen <vanmeeuwen@apheleia-it.ch> - 2.3.21-1 +- Release version 2.3.21 + +* Thu Jan 28 2021 Christian Mollekopf <mollekopf@kolabsys.com> - 2.3.19-1 +- Release version 2.3.19 + +* Mon May 4 2020 Christian Mollekopf <mollekopf@kolabsys.com> - 2.3.17-1 +- Release version 2.3.17 + +* Wed Dec 4 2019 Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> - 2.3.16-1 +- Release version 2.3.16 + +* Mon Jul 29 2019 Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> - 2.3.15-3 +- Fix MeetingResponse for Calendar events + +* Thu Apr 11 2019 Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> - 2.3.15-2 +- Update defaults + +* Fri Feb 1 2019 Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> - 2.3.15-1 +- Release 2.3.15 + +* Thu Dec 27 2018 Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> - 2.3.14-1 +- Release 2.3.14 + +* Fri Aug 17 2018 Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> - 2.3.13-1 +- Release 2.3.13 + +* Wed Jun 13 2018 Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> - 2.3.12-1 +- Release 2.3.12 + * Thu Mar 8 2018 Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> - 2.3.10-1 - Release 2.3.10
View file
_link
Changed
@@ -1,4 +1,4 @@ -<link project="Kolab:16" baserev="dd538f7b82bd9c7a957c830645c5ea1b"> +<link project="Kolab:16" baserev="cda5fd56ba5f683501ff6dda3d784c7c"> <patches> <branch/> </patches>
View file
buildtarball.sh
Added
@@ -0,0 +1,22 @@ +#!/bin/bash + +set -e + +VERSION=2.4.2 +GIT_REF=master +NAME=kolab-syncroton-$VERSION + +ROOT_DIR=$(pwd) + +rm -Rf /tmp/$NAME +mkdir /tmp/$NAME +cd /tmp/$NAME + +rm -f $NAME.tar.gz + -d "$NAME" && rm -rf "$NAME" +git clone --branch master ssh://git@git.kolab.org/diffusion/S/syncroton.git $NAME +pushd $NAME +git reset --hard $GIT_REF +git archive --prefix=$NAME/ -o "$ROOT_DIR/$NAME.tar.gz" HEAD + +cd "$PWD"
View file
debian.changelog
Changed
@@ -1,3 +1,123 @@ +kolab-syncroton (2.4.2.10-0~kolab1) unstable; urgency=low + + * Release version 2.4.2 + + -- Christian Mollekopf <mollekopf@apheleia-it.ch> Thu, 27 July 2023 15:13:40 +0200 + +kolab-syncroton (2.4.1-0~kolab1) unstable; urgency=low + + * Release version 2.4.1 + + -- Christian Mollekopf <mollekopf@apheleia-it.ch> Mon, 17 July 2023 15:13:40 +0200 + +kolab-syncroton (2.4.0-0~kolab1) unstable; urgency=low + + * Release version 2.4.0 + + -- Christian Mollekopf <mollekopf@apheleia-it.ch> Wed, 10 May 2023 15:13:40 +0200 + +kolab-syncroton (2.3.23-0~kolab1) unstable; urgency=low + + * Release version 2.3.23 + + -- Christian Mollekopf <mollekopf@apheleia-it.ch> Wed, 19 Apr 2023 15:13:40 +0200 + +kolab-syncroton (2.3.22-1~kolab1) unstable; urgency=low + + * Fixed timezone issue + + -- Christian Mollekopf <mollekopf@apheleia-it.ch> Mon, 19 Dec 2022 15:13:40 +0200 + +kolab-syncroton (2.3.22-0~kolab1) unstable; urgency=low + + * Release version 2.3.22 + + -- Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> Fri, 4 Feb 2022 15:13:40 +0200 + +kolab-syncroton (2.3.21-0~kolab1) unstable; urgency=low + + * Release version 2.3.21 + + -- Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> Fri, 2 Jul 2021 15:13:40 +0200 + +kolab-syncroton (2.3.19-0~kolab1) unstable; urgency=low + + * Release version 2.3.19 + + -- Christian Mollekopf <mollekopf@kolabsys.com> Thu, 28 Jan 2021 15:13:40 +0200 + +kolab-syncroton (2.3.18-0~kolab2) unstable; urgency=low + + * Release version 2.3.18 + + -- Christian Mollekopf <mollekopf@kolabsys.com> Wed, 16 Dec 2020 15:13:40 +0200 + +kolab-syncroton (2.3.17-1~kolab3) unstable; urgency=low + + * Adjusted kolab-syncroton.logrotate according to new filenames + + -- Christian Mollekopf <mollekopf@kolabsys.com> Wed, 20 May 2020 15:13:40 +0200 + +kolab-syncroton (2.3.17-0~kolab2) unstable; urgency=low + + * Release version 2.3.17 + + -- Christian Mollekopf <mollekopf@kolabsys.com> Mon, 4 May 2020 15:13:40 +0200 + +kolab-syncroton (2.3.16-0~kolab2) unstable; urgency=low + + * Release version 2.3.16 + + -- Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> Wed, 4 Dec 2019 15:13:40 +0200 + +kolab-syncroton (2.3.15-0~kolab6) unstable; urgency=low + + * Fix MeetingResponse parsing for Calendar events + + -- Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> Mon, 29 Jul 2019 15:13:40 +0200 + +kolab-syncroton (2.3.15-0~kolab5) unstable; urgency=low + + * Correctly clause dependency on kolab-auth + + -- Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> Wed, 17 Apr 2019 15:13:40 +0200 + +kolab-syncroton (2.3.15-0~kolab3) unstable; urgency=low + + * Adjusted kolab-syncroton.logrotate according to new filenames + + -- Christian Mollekopf (Kolab Systems) <mollekopf@kolabys.com> Mon, 15 Apr 2019 12:12:12 +0100 + +kolab-syncroton (2.3.15-0~kolab2) unstable; urgency=low + + * Update defaults + + -- Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> Thu, 11 Apr 2019 15:13:40 +0200 + +kolab-syncroton (2.3.15-0~kolab1) unstable; urgency=low + + * Release 2.3.15 + + -- Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> Fri, 1 Feb 2019 15:13:40 +0200 + +kolab-syncroton (2.3.14-0~kolab1) unstable; urgency=low + + * Release 2.3.14 + + -- Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> Thu, 27 Dec 2018 15:13:40 +0200 + +kolab-syncroton (2.3.13-0~kolab1) unstable; urgency=low + + * Release 2.3.13 + + -- Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> Fri, 17 Aug 2018 15:13:40 +0200 + +kolab-syncroton (2.3.12-0~kolab1) unstable; urgency=low + + * Release 2.3.12 + + -- Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> Wed, 13 Jun 2018 15:13:40 +0200 + kolab-syncroton (2.3.10-0~kolab1) unstable; urgency=low * Release 2.3.10
View file
debian.control
Changed
@@ -3,26 +3,14 @@ Priority: extra Maintainer: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> Uploaders: Paul Klos <kolab@klos2day.nl> -Build-Depends: debhelper (>= 8), po-debconf +Build-Depends: debhelper (>= 8), po-debconf, psa | bash Homepage: http://www.kolab.org/ Standards-Version: 3.9.3 Vcs-Git: http://git.kolab.org/kolab-syncroton Package: kolab-syncroton Architecture: all -Depends: php-auth-sasl, - php-mail-mime, - php-mdb2 (>= 2.5.0), - php-net-idna2, - php-net-smtp, - php-net-socket, - php-cli | php5-cli, - php-mysql | php5-mysql, - roundcubemail-core, - roundcubemail-plugin-kolab-folders (>= 3.1.12), - roundcubemail-plugin-libcalendaring (>= 3.1.12), - roundcubemail-plugin-libkolab (>= 3.1.12), - zendframework | zend-framework, +Depends: roundcubemail-core, ${misc:Depends} Description: ActiveSync for Kolab Groupware Kolab Groupware provides ActiveSync for Calendars,
View file
debian.rules
Changed
@@ -21,7 +21,11 @@ mkdir -p debian/tmp dh_install --list-missing -XLICENSE + mkdir -p $(CURDIR)/debian/kolab-syncroton/etc/roundcubemail + cp -a config/config.inc.php.dist $(CURDIR)/debian/kolab-syncroton/etc/roundcubemail/kolab_syncroton.inc.php + if ! -f "/etc/plesk-release" ; then \ + cp -v ../SOURCES/plesk.kolab_syncroton.inc.php $(CURDIR)/debian/kolab-syncroton/etc/roundcubemail/kolab_syncroton.inc.php; \ mkdir -p $(CURDIR)/debian/kolab-syncroton/etc/apache2/sites-available ; \ install -pm 644 $(CURDIR)/docs/kolab-syncroton.conf \ $(CURDIR)/debian/kolab-syncroton/etc/apache2/sites-available/kolab-syncroton.conf ; \
View file
debian.tar.gz/kolab-syncroton.logrotate
Changed
@@ -1,4 +1,4 @@ -/var/log/kolab-syncroton/console /var/log/kolab-syncroton/errors /var/log/kolab-syncroton/imap /var/log/kolab-syncroton/ldap /var/log/kolab-syncroton/sendmail /var/log/kolab-syncroton/sieve /var/log/kolab-syncroton/smtp /var/log/kolab-syncroton/sql /var/log/kolab-syncroton/userlogins { +/var/log/kolab-syncroton/*.log { missingok compress notifempty
View file
kolab-syncroton-2.3.10.tar.gz/composer.json-dist -> kolab-syncroton-2.4.2.tar.gz/composer.json-dist
Changed
@@ -19,9 +19,10 @@ "pear/net_ldap2": "~2.2.0", "pear/net_sieve": "~1.4.0", "kolab/net_ldap3": "dev-master", - "zf1/zend-log": "~1.12.11" + "zf1s/zend-json": "~1.12.20", + "zf1s/zend-log": "~1.12.20" }, "require-dev": { - "phpunit/phpunit": "~4.4.0" + "phpunit/phpunit": "^4.8 || ^5.7 || ^6 || ^7 || ^9" } }
View file
kolab-syncroton-2.3.10.tar.gz/config/config.inc.php.dist -> kolab-syncroton-2.4.2.tar.gz/config/config.inc.php.dist
Changed
@@ -5,9 +5,6 @@ // Enables ActiveSync protocol debuging $config'activesync_debug' = true; -// Enables logging to a separate directory for every user/device -$config'activesync_user_log' = false; - // If specified all ActiveSync-related logs will be saved to this file // Note: This doesn't change Roundcube Framework log locations $config'activesync_log_file' = null; @@ -70,7 +67,10 @@ // List of Roundcube plugins // WARNING: Not all plugins used in Roundcube can be listed here -$config'activesync_plugins' = array(); +$config'activesync_plugins' = array( + 'libcalendaring', + 'libkolab' +); // Defines for how many seconds we'll sleep between every // action for detecting changes in folders. Default: 60 @@ -100,13 +100,13 @@ // 8 - all folders in other users namespace // 16 - all subscribed folders in shared namespace // 32 - all folders in shared namespace -$config'activesync_init_subscriptions' = 0; +$config'activesync_init_subscriptions' = 21; // Defines blacklist of devices (device type strings) that do not support folder hierarchies. // When set to an array folder hierarchies are used on all devices not listed here. // When set to null an old whitelist approach will be used where we do opposite // action and enable folder hierarchies only on device types known to support it. -$config'activesync_multifolder_blacklist' = null; +$config'activesync_multifolder_blacklist' = array(); // Blacklist overwrites for specified object type. If set to an array // it will have a precedence over 'activesync_multifolder_blacklist' list only for that type. @@ -114,7 +114,7 @@ // in that case use $config'activesync_multifolder_blacklist_contact' = array('windowsoutlook'); $config'activesync_multifolder_blacklist_mail' = null; $config'activesync_multifolder_blacklist_event' = null; -$config'activesync_multifolder_blacklist_contact' = null; +$config'activesync_multifolder_blacklist_contact' = array('windowsoutlook'); $config'activesync_multifolder_blacklist_note' = null; $config'activesync_multifolder_blacklist_task' = null;
View file
kolab-syncroton-2.4.2.tar.gz/docs/SQL/mysql/2023100500.sql
Added
@@ -0,0 +1,2 @@ + +ALTER TABLE `syncroton_synckey` ADD `client_id_map` longblob DEFAULT NULL;
View file
kolab-syncroton-2.3.10.tar.gz/lib/ext/Syncroton/Backend/ABackend.php -> kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Backend/ABackend.php
Changed
@@ -128,7 +128,7 @@ unset($data$key); if (!empty($value) && preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/', $value)) { # 2012-08-12 07:43:26 - $value = new DateTime($value, new DateTimeZone('utc')); + $value = new DateTime($value, new DateTimeZone('UTC')); } $data$this->_toCamelCase($key, false) = $value;
View file
kolab-syncroton-2.3.10.tar.gz/lib/ext/Syncroton/Command/FolderCreate.php -> kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Command/FolderCreate.php
Changed
@@ -98,16 +98,31 @@ $this->_folder->deviceId = $this->_device; $this->_folder->creationTime = $this->_syncTimeStamp; - $this->_folderBackend->create($this->_folder); + // Check if the folder already exists to avoid a duplicate insert attempt in db + try { + $this->_folderBackend->getFolder($this->_device, $this->_folder->serverId); + + if ($this->_logger instanceof Zend_Log) + $this->_logger->info(__METHOD__ . '::' . __LINE__ . " Attempted to create a folder that already exists. parentId: {$folder->parentId} displayName: {$folder->displayName}"); + + // The folder already exists + $this->_status = Syncroton_Command_FolderSync::STATUS_FOLDER_EXISTS; + } catch (Syncroton_Exception_NotFound $e) { + // This is the normal case + if ($this->_logger instanceof Zend_Log) + $this->_logger->debug(__METHOD__ . '::' . __LINE__ . " " . $e->getMessage()); + + $this->_folderBackend->create($this->_folder); + } } } catch (Syncroton_Exception_Status $e) { if ($this->_logger instanceof Zend_Log) - $this->_logger->debug(__METHOD__ . '::' . __LINE__ . " " . $e->getMessage()); + $this->_logger->warn(__METHOD__ . '::' . __LINE__ . " " . $e->getMessage()); $this->_status = $e->getCode(); } catch (Exception $e) { if ($this->_logger instanceof Zend_Log) - $this->_logger->debug(__METHOD__ . '::' . __LINE__ . " " . $e->getMessage()); + $this->_logger->warn(__METHOD__ . '::' . __LINE__ . " " . $e->getMessage()); $this->_status = Syncroton_Command_FolderSync::STATUS_UNKNOWN_ERROR; }
View file
kolab-syncroton-2.3.10.tar.gz/lib/ext/Syncroton/Command/GetAttachment.php -> kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Command/GetAttachment.php
Changed
@@ -49,7 +49,7 @@ if (PHP_SAPI !== 'cli') { // cache for 3600 seconds $maxAge = 3600; - $now = new DateTime(null, new DateTimeZone('UTC')); + $now = new DateTime('now', new DateTimeZone('UTC')); header('Cache-Control: private, max-age=' . $maxAge); header("Expires: " . gmdate('D, d M Y H:i:s', $now->modify("+{$maxAge} sec")->getTimestamp()) . " GMT");
View file
kolab-syncroton-2.3.10.tar.gz/lib/ext/Syncroton/Command/ItemOperations.php -> kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Command/ItemOperations.php
Changed
@@ -59,9 +59,6 @@ $this->_emptyFolderContents = $this->_handleEmptyFolderContents($emptyFolderContents); } } - - if ($this->_logger instanceof Zend_Log) - $this->_logger->debug(__METHOD__ . '::' . __LINE__ . " fetches: " . print_r($this->_fetches, true)); } /** @@ -118,7 +115,7 @@ $fileReference = $dataController->getFileReference($fetch'fileReference'); // unset data field and move content to stream - if ($this->_requestParameters'acceptMultipart' == true) { + if (!empty($this->_requestParameters'acceptMultipart')) { $this->_headers'Content-Type' = 'application/vnd.ms-sync.multipart'; $partStream = fopen("php://temp", 'r+'); @@ -252,12 +249,13 @@ } } - if (isset($fetch->Options->MIMESupport)){ - $fetchArray'options''mimeSupport' = (int) $fetch->Options->MIMESupport; + $airSync = $fetch->Options->children('uri:AirSync'); + if (isset($airSync->MIMESupport)) { + $fetchArray'options''mimeSupport' = (int) $airSync->MIMESupport; } - if (isset($airSyncBase->Range)) { - $fetchArray'options''range' = (string) $airSyncBase->Range; + if (isset($fetch->Options->Range)) { + $fetchArray'options''range' = (string) $fetch->Options->Range; } }
View file
kolab-syncroton-2.3.10.tar.gz/lib/ext/Syncroton/Command/MeetingResponse.php -> kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Command/MeetingResponse.php
Changed
@@ -50,9 +50,6 @@ ); } } - - if ($this->_logger instanceof Zend_Log) - $this->_logger->debug(__METHOD__ . '::' . __LINE__ . " results: " . print_r($this->_results, true)); } /**
View file
kolab-syncroton-2.3.10.tar.gz/lib/ext/Syncroton/Command/MoveItems.php -> kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Command/MoveItems.php
Changed
@@ -46,9 +46,6 @@ 'dstFldId' => (string)$move->DstFldId ); } - - if ($this->_logger instanceof Zend_Log) - $this->_logger->debug(__METHOD__ . '::' . __LINE__ . " moves: " . print_r($this->_moves, true)); } /** @@ -82,9 +79,12 @@ $dataController = Syncroton_Data_Factory::factory($sourceFolder->class, $this->_device, $this->_syncTimeStamp); $newId = $dataController->moveItem($move'srcFldId', $move'srcMsgId', $move'dstFldId'); + if (!$newId) { + throw new Syncroton_Exception_Status_MoveItems(Syncroton_Exception_Status_MoveItems::INVALID_SOURCE); + } + $response->appendChild($this->_outputDom->createElementNS('uri:Move', 'Status', Syncroton_Command_MoveItems::STATUS_SUCCESS)); - if ($newId) - $response->appendChild($this->_outputDom->createElementNS('uri:Move', 'DstMsgId', $newId)); + $response->appendChild($this->_outputDom->createElementNS('uri:Move', 'DstMsgId', $newId)); } catch (Syncroton_Exception_Status $e) { $response->appendChild($this->_outputDom->createElementNS('uri:Move', 'Status', $e->getCode())); } catch (Exception $e) {
View file
kolab-syncroton-2.3.10.tar.gz/lib/ext/Syncroton/Command/Ping.php -> kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Command/Ping.php
Changed
@@ -90,7 +90,7 @@ } } - $this->_device->lastping = new DateTime('now', new DateTimeZone('utc')); + $this->_device->lastping = new DateTime('now', new DateTimeZone('UTC')); if ($status == self::STATUS_NO_CHANGES_FOUND) { $this->_device = $this->_deviceBackend->update($this->_device); @@ -113,7 +113,7 @@ $intervalEnd = $intervalStart + $lifeTime; $secondsLeft = $intervalEnd; - $folders = unserialize($this->_device->pingfolder); + $folders = $this->_device->pingfolder ? unserialize($this->_device->pingfolder) : array(); if ($status === self::STATUS_NO_CHANGES_FOUND && (!is_array($folders) || count($folders) == 0)) { $status = self::STATUS_MISSING_PARAMETERS; @@ -141,6 +141,10 @@ // reconnect external connections, etc. call_user_func($wakeupCallback); + // Calculate secondsLeft before any loop break just to have a correct value + // for logging purposes in case we breaked from the loop early + $secondsLeft = $intervalEnd - time(); + try { $device = $this->_deviceBackend->get($this->_device->id); } catch (Syncroton_Exception_NotFound $e) { @@ -181,7 +185,7 @@ continue; } - $now = new DateTime('now', new DateTimeZone('utc')); + $now = new DateTime('now', new DateTimeZone('UTC')); foreach ($folders as $folderId) { try { @@ -237,7 +241,8 @@ if ($status != self::STATUS_NO_CHANGES_FOUND) { break; } - + + // Update secondsLeft (again) $secondsLeft = $intervalEnd - time(); if ($this->_logger instanceof Zend_Log)
View file
kolab-syncroton-2.3.10.tar.gz/lib/ext/Syncroton/Command/Search.php -> kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Command/Search.php
Changed
@@ -33,15 +33,18 @@ /** * parse search command request * + * @throws Syncroton_Exception_UnexpectedValue */ public function handle() { + if (! $this->_requestBody instanceof DOMDocument) { + throw new Syncroton_Exception_UnexpectedValue( + 'request body is no DOMDocument. got: ' . print_r($this->_requestBody, true)); + } + $xml = simplexml_import_dom($this->_requestBody); $this->_store = new Syncroton_Model_StoreRequest($xml->Store); - - if ($this->_logger instanceof Zend_Log) - $this->_logger->debug(__METHOD__ . '::' . __LINE__ . " stores: " . print_r($this->_store, true)); } /**
View file
kolab-syncroton-2.3.10.tar.gz/lib/ext/Syncroton/Command/SendMail.php -> kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Command/SendMail.php
Changed
@@ -32,7 +32,8 @@ */ public function handle() { - if ($this->_requestParameters'contentType' == 'message/rfc822') { + if (isset($this->_requestParameters'contentType') && + $this->_requestParameters'contentType' === 'message/rfc822') { $this->_mime = $this->_requestBody; $this->_saveInSent = $this->_requestParameters'saveInSent'; $this->_replaceMime = false;
View file
kolab-syncroton-2.3.10.tar.gz/lib/ext/Syncroton/Command/Settings.php -> kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Command/Settings.php
Changed
@@ -110,8 +110,10 @@ // Out-of-Office if (!empty($this->_OofGet)) { + $OofGet = null; try { $OofGet = $this->_deviceBackend->getOOF($this->_OofGet); + $OofStatus = self::STATUS_SUCCESS; } catch (Exception $e) { if ($e instanceof Syncroton_Exception_Status) { $OofStatus = $e->getCode();
View file
kolab-syncroton-2.3.10.tar.gz/lib/ext/Syncroton/Command/Sync.php -> kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Command/Sync.php
Changed
@@ -243,7 +243,12 @@ continue; } - // check for invalid sycnkey + $syncKeyReused = $this->_syncStateBackend->haveNext($this->_device, $collectionData->folder, $collectionData->syncKey); + if ($syncKeyReused) { + if ($this->_logger instanceof Zend_Log) + $this->_logger->warn(__METHOD__ . '::' . __LINE__ . " already known synckey {$collectionData->syncKey} provided"); + } + // check for invalid synckey if(($collectionData->syncState = $this->_syncStateBackend->validate($this->_device, $collectionData->folder, $collectionData->syncKey)) === false) { if ($this->_logger instanceof Zend_Log) $this->_logger->warn(__METHOD__ . '::' . __LINE__ . " invalid synckey {$collectionData->syncKey} provided"); @@ -301,6 +306,11 @@ if ($this->_logger instanceof Zend_Log) $this->_logger->info(__METHOD__ . '::' . __LINE__ . " found " . count($adds) . " entries to be added to server"); + $clientIdMap = ; + if ($syncKeyReused && $collectionData->syncState->clientIdMap) { + $clientIdMap = Zend_Json::decode($collectionData->syncState->clientIdMap); + } + foreach ($adds as $add) { if ($this->_logger instanceof Zend_Log) $this->_logger->debug(__METHOD__ . '::' . __LINE__ . " add entry with clientId " . (string) $add->ClientId); @@ -309,20 +319,35 @@ if ($this->_logger instanceof Zend_Log) $this->_logger->info(__METHOD__ . '::' . __LINE__ . " adding entry as new"); - $serverId = $dataController->createEntry($collectionData->collectionId, new $dataClass($add->ApplicationData)); - - $clientModifications'added'$serverId = array( - 'clientId' => (string)$add->ClientId, - 'serverId' => $serverId, - 'status' => self::STATUS_SUCCESS, - 'contentState' => $this->_contentStateBackend->create(new Syncroton_Model_Content(array( - 'device_id' => $this->_device, - 'folder_id' => $collectionData->folder, - 'contentid' => $serverId, - 'creation_time' => $this->_syncTimeStamp, - 'creation_synckey' => $collectionData->syncKey + 1 - ))) - ); + $clientId = (string)$add->ClientId; + // If the sync key was reused, but we don't have a $clientId mapping, + // this means the client sent a new item with the same sync_key. + if ($syncKeyReused && array_key_exists($clientId, $clientIdMap)) { + // We don't normally store the clientId, so if a command with Add's is resent, + // we have to look-up the corresponding serverId using a cached clientId => serverId mapping, + // otherwise we would duplicate all added items on resend. + $serverId = $clientIdMap$clientId; + $clientModifications'added'$serverId = array( + 'clientId' => (string)$add->ClientId, + 'serverId' => $serverId, + 'status' => self::STATUS_SUCCESS, + 'contentState' => null + ); + } else { + $serverId = $dataController->createEntry($collectionData->collectionId, new $dataClass($add->ApplicationData)); + $clientModifications'added'$serverId = array( + 'clientId' => (string)$add->ClientId, + 'serverId' => $serverId, + 'status' => self::STATUS_SUCCESS, + 'contentState' => $this->_contentStateBackend->create(new Syncroton_Model_Content(array( + 'device_id' => $this->_device, + 'folder_id' => $collectionData->folder, + 'contentid' => $serverId, + 'creation_time' => $this->_syncTimeStamp, + 'creation_synckey' => $collectionData->syncKey + 1 + ))) + ); + } } catch (Exception $e) { if ($this->_logger instanceof Zend_Log) @@ -336,7 +361,7 @@ } // handle changes, but only if not first sync - if($collectionData->syncKey > 1 && $collectionData->hasClientChanges()) { + if(!$syncKeyReused && $collectionData->syncKey > 1 && $collectionData->hasClientChanges()) { $changes = $collectionData->getClientChanges(); if ($this->_logger instanceof Zend_Log) @@ -367,7 +392,7 @@ } // handle deletes, but only if not first sync - if($collectionData->hasClientDeletes()) { + if(!$syncKeyReused && $collectionData->hasClientDeletes()) { $deletes = $collectionData->getClientDeletes(); if ($this->_logger instanceof Zend_Log) $this->_logger->info(__METHOD__ . '::' . __LINE__ . " found " . count($deletes) . " entries to be deleted on server"); @@ -414,7 +439,7 @@ if ($this->_logger instanceof Zend_Log) $this->_logger->info(__METHOD__ . '::' . __LINE__ . " found " . count($fetches) . " entries to be fetched from server"); - $toBeFecthed = array(); + $toBeFetched = array(); foreach ($fetches as $fetch) { $serverId = (string)$fetch->ServerId; @@ -465,7 +490,7 @@ $wakeupCallback(); - $now = new DateTime(null, new DateTimeZone('utc')); + $now = new DateTime('now', new DateTimeZone('UTC')); foreach($this->_collections as $collectionData) { // continue immediately if folder does not exist @@ -548,6 +573,10 @@ // First check for folders hierarchy changes foreach ($this->_collections as $collectionData) { if (! ($collectionData->folder instanceof Syncroton_Model_IFolder)) { + + if ($this->_logger instanceof Zend_Log) + $this->_logger->warn(__METHOD__ . '::' . __LINE__ . " Detected a folder hierarchy change on {$collectionData->collectionId}."); + $sync->appendChild($this->_outputDom->createElementNS('uri:AirSync', 'Status', self::STATUS_FOLDER_HIERARCHY_HAS_CHANGED)); return $this->_outputDom; } @@ -629,13 +658,14 @@ if ($hasChanges) { // update _syncTimeStamp as $dataController->hasChanges might have spent some time - $this->_syncTimeStamp = new DateTime(null, new DateTimeZone('utc')); + $this->_syncTimeStamp = new DateTime('now', new DateTimeZone('UTC')); try { // fetch entries added since last sync $allClientEntries = $this->_contentStateBackend->getFolderState( $this->_device, - $collectionData->folder + $collectionData->folder, + $collectionData->syncState->counter ); // fetch entries changed since last sync @@ -666,8 +696,8 @@ if ($this->_logger instanceof Zend_Log) $this->_logger->info(__METHOD__ . '::' . __LINE__ . " skipped added entry: " . $serverId); unset($serverModifications'added'$id); - } } + } // entries to be deleted $serverModifications'deleted' = array_diff($allClientEntries, $allServerEntries); @@ -727,7 +757,7 @@ foreach($clientModifications'added' as $entryData) { $add = $responses->appendChild($this->_outputDom->createElementNS('uri:AirSync', 'Add')); $add->appendChild($this->_outputDom->createElementNS('uri:AirSync', 'ClientId', $entryData'clientId')); - // we have no serverId is the add failed + // we have no serverId if the add failed if(isset($entryData'serverId')) { $add->appendChild($this->_outputDom->createElementNS('uri:AirSync', 'ServerId', $entryData'serverId')); } @@ -826,6 +856,14 @@ $commands->appendChild($add); + $newContentStates = new Syncroton_Model_Content(array( + 'device_id' => $this->_device, + 'folder_id' => $collectionData->folder, + 'contentid' => $serverId, + 'creation_time' => $this->_syncTimeStamp, + 'creation_synckey' => $collectionData->syncState->counter + 1 + )); + $collectionChanges++; } catch (Syncroton_Exception_MemoryExhausted $seme) { // continue to next entry, as there is not enough memory left for the current entry @@ -833,23 +871,18 @@ if ($this->_logger instanceof Zend_Log) $this->_logger->warn(__METHOD__ . '::' . __LINE__ . " memory exhausted for entry: " . $serverId); - continue; + break; } catch (Exception $e) { if ($this->_logger instanceof Zend_Log) $this->_logger->warn(__METHOD__ . '::' . __LINE__ . " unable to convert entry to xml: " . $e->getMessage()); if ($this->_logger instanceof Zend_Log) $this->_logger->debug(__METHOD__ . '::' . __LINE__ . " unable to convert entry to xml: " . $e->getTraceAsString()); + // We bump collectionChanges anyways to make sure the windowSize still applies. + $collectionChanges++; } // mark as sent to the client, even the conversion to xml might have failed - $newContentStates = new Syncroton_Model_Content(array( - 'device_id' => $this->_device, - 'folder_id' => $collectionData->folder, - 'contentid' => $serverId, - 'creation_time' => $this->_syncTimeStamp, - 'creation_synckey' => $collectionData->syncState->counter + 1 - )); unset($serverModifications'added'$id); }
View file
kolab-syncroton-2.3.10.tar.gz/lib/ext/Syncroton/Command/Wbxml.php -> kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Command/Wbxml.php
Changed
@@ -143,8 +143,8 @@ $this->_requestBody = $requestBody; $this->_device = $device; $this->_requestParameters = $requestParameters; - $this->_policyKey = $requestParameters'policyKey'; - + $this->_policyKey = isset($requestParameters'policyKey') ? $requestParameters'policyKey' : null; + $this->_deviceBackend = Syncroton_Registry::getDeviceBackend(); $this->_folderBackend = Syncroton_Registry::getFolderBackend(); $this->_syncStateBackend = Syncroton_Registry::getSyncStateBackend(); @@ -154,7 +154,7 @@ $this->_logger = Syncroton_Registry::get('loggerBackend'); } - $this->_syncTimeStamp = new DateTime(null, new DateTimeZone('UTC')); + $this->_syncTimeStamp = new DateTime('now', new DateTimeZone('UTC')); // set default content type $this->_headers'Content-Type' = 'application/vnd.ms-sync.wbxml'; @@ -181,12 +181,12 @@ $policy = $this->_policyBackend->get($this->_device->policyId); if((int)$policy->policyKey != (int)$this->_policyKey) { - $this->_outputDom->documentElement->appendChild($this->_outputDom->createElementNS($this->_defaultNameSpace, 'Status', 142)); - - $sepn = new Syncroton_Exception_ProvisioningNeeded(); - $sepn->domDocument = $this->_outputDom; - - throw $sepn; + $this->_outputDom->documentElement->appendChild($this->_outputDom->createElementNS($this->_defaultNameSpace, 'Status', 142)); + + $sepn = new Syncroton_Exception_ProvisioningNeeded(); + $sepn->domDocument = $this->_outputDom; + + throw $sepn; } // should we wipe the mobile phone?
View file
kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Exception/DeadlockDetected.php
Added
@@ -0,0 +1,20 @@ +<?php +/** + * Syncroton + * + * @package Syncroton + * @subpackage Exception + * @license http://www.tine20.org/licenses/lgpl.html LGPL Version 3 + * @copyright Copyright (c) 2013-2013 Metaways Infosystems GmbH (http://www.metaways.de) + * @author Lars Kneschke <l.kneschke@metaways.de> + */ + +/** + * exception for database deadlocks + * + * @package Syncroton + * @subpackage Exception + */ +class Syncroton_Exception_DeadlockDetected extends Syncroton_Exception +{ +}
View file
kolab-syncroton-2.3.10.tar.gz/lib/ext/Syncroton/Exception/Status/Settings.php -> kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Exception/Status/Settings.php
Changed
@@ -32,11 +32,11 @@ * @var array */ protected $_errorMessages = array( - self::PROTOCOL_ERROR => "Protocol error"; - self::ACCESS_DENIED => "Access denied"; - self::SERVICE_UNAVAILABLE => "Server unavailable"; - self::INVALID_ARGUMENTS => "Invalid arguments"; - self::CONFLICTING_ARGUMENTS => "Conflicting arguments"; - self::DENIED_BY_POLICY => "Denied by policy. Disabled by administrator"; + self::PROTOCOL_ERROR => "Protocol error", + self::ACCESS_DENIED => "Access denied", + self::SERVICE_UNAVAILABLE => "Server unavailable", + self::INVALID_ARGUMENTS => "Invalid arguments", + self::CONFLICTING_ARGUMENTS => "Conflicting arguments", + self::DENIED_BY_POLICY => "Denied by policy. Disabled by administrator", ); }
View file
kolab-syncroton-2.3.10.tar.gz/lib/ext/Syncroton/Model/AEntry.php -> kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Model/AEntry.php
Changed
@@ -40,6 +40,7 @@ * (non-PHPdoc) * @see Countable::count() */ + #\ReturnTypeWillChange public function count() { return count($this->_elements); @@ -49,6 +50,7 @@ * (non-PHPdoc) * @see IteratorAggregate::getIterator() */ + #\ReturnTypeWillChange public function getIterator() { return new ArrayIterator($this->_elements);
View file
kolab-syncroton-2.3.10.tar.gz/lib/ext/Syncroton/Model/AXMLEntry.php -> kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Model/AXMLEntry.php
Changed
@@ -174,7 +174,7 @@ $element->appendChild($element->ownerDocument->createCDATASection(base64_encode($value))); } else { // strip off any non printable control characters - if (!ctype_print($value)) { + if (!ctype_print((string)$value)) { $value = $this->_removeControlChars($value); }
View file
kolab-syncroton-2.3.10.tar.gz/lib/ext/Syncroton/Model/EmailMeetingRequest.php -> kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Model/EmailMeetingRequest.php
Changed
@@ -68,8 +68,6 @@ const MESSAGE_TYPE_COPY = 5; const MESSAGE_TYPE_DELEGATED = 6; - protected $_dateTimeFormat = "Ymd\THis\Z"; - protected $_xmlBaseElement = 'MeetingRequest'; protected $_properties = array( @@ -80,7 +78,7 @@ 'dtStamp' => array('type' => 'datetime'), 'endTime' => array('type' => 'datetime'), 'globalObjId' => array('type' => 'string'), - 'instanceType' => array('type' => 'datetime'), + 'instanceType' => array('type' => 'number'), 'location' => array('type' => 'string'), 'organizer' => array('type' => 'string'), //e-mail address 'recurrenceId' => array('type' => 'datetime'),
View file
kolab-syncroton-2.3.10.tar.gz/lib/ext/Syncroton/Model/ISyncState.php -> kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Model/ISyncState.php
Changed
@@ -19,6 +19,7 @@ * @property string counter * @property DateTime lastsync * @property string pendingdata + * @property string client_id_map */ interface Syncroton_Model_ISyncState {
View file
kolab-syncroton-2.3.10.tar.gz/lib/ext/Syncroton/Model/StoreRequest.php -> kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Model/StoreRequest.php
Changed
@@ -178,12 +178,12 @@ switch ($this->_store'name') { case 'DocumentLibrary': case 'Document Library': //? - '0-999'; + $this->_store'options''range' = '0-999'; break; case 'Mailbox': case 'GAL': default: - '0-99'; + $this->_store'options''range' = '0-99'; break; } }
View file
kolab-syncroton-2.3.10.tar.gz/lib/ext/Syncroton/Registry.php -> kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Registry.php
Changed
@@ -517,16 +517,4 @@ { parent::__construct($array, $flags); } - - /** - * @param string $index - * @returns mixed - * - * Workaround for http://bugs.php.net/bug.php?id=40442 (ZF-960). - */ - public function offsetExists($index) - { - return array_key_exists($index, $this); - } - }
View file
kolab-syncroton-2.3.10.tar.gz/lib/ext/Syncroton/Server.php -> kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Server.php
Changed
@@ -105,9 +105,9 @@ $className = 'Syncroton_Command_' . $requestParameters'command'; - if(!class_exists($className)) { + if (!class_exists($className)) { if ($this->_logger instanceof Zend_Log) - $this->_logger->crit(__METHOD__ . '::' . __LINE__ . " command not supported: " . $requestParameters'command'); + $this->_logger->notice(__METHOD__ . '::' . __LINE__ . " command not supported: " . $requestParameters'command'); header("HTTP/1.1 501 not implemented"); @@ -123,10 +123,11 @@ $decoder = new Syncroton_Wbxml_Decoder($this->_body); $requestBody = $decoder->decode(); if ($this->_logger instanceof Zend_Log) { - $requestBody->formatOutput = true; - $this->_logger->debug(__METHOD__ . '::' . __LINE__ . " xml request:\n" . $requestBody->saveXML()); + $this->_logDomDocument($requestBody, 'request', __METHOD__, __LINE__); } } catch(Syncroton_Wbxml_Exception_UnexpectedEndOfFile $e) { + if ($this->_logger instanceof Zend_Log) + $this->_logger->warn(__METHOD__ . '::' . __LINE__ . " unexpected end of file."); $requestBody = NULL; } } else { @@ -161,11 +162,11 @@ } catch (Exception $e) { if ($this->_logger instanceof Zend_Log) - $this->_logger->crit(__METHOD__ . '::' . __LINE__ . " unexpected exception occured: " . get_class($e)); + $this->_logger->err(__METHOD__ . '::' . __LINE__ . " unexpected exception occured: " . get_class($e)); if ($this->_logger instanceof Zend_Log) - $this->_logger->crit(__METHOD__ . '::' . __LINE__ . " exception message: " . $e->getMessage()); + $this->_logger->err(__METHOD__ . '::' . __LINE__ . " exception message: " . $e->getMessage()); if ($this->_logger instanceof Zend_Log) - $this->_logger->crit(__METHOD__ . '::' . __LINE__ . " " . $e->getTraceAsString()); + $this->_logger->err(__METHOD__ . '::' . __LINE__ . " " . $e->getTraceAsString()); header("HTTP/1.1 500 Internal server error"); @@ -174,7 +175,7 @@ if ($response instanceof DOMDocument) { if ($this->_logger instanceof Zend_Log) { - $this->_logDomDocument(Zend_Log::DEBUG, $response, __METHOD__, __LINE__); + $this->_logDomDocument($response, 'response', __METHOD__, __LINE__); } if (isset($command) && $command instanceof Syncroton_Command_ICommand) { @@ -190,7 +191,6 @@ } catch (Syncroton_Wbxml_Exception $swe) { if ($this->_logger instanceof Zend_Log) { $this->_logger->err(__METHOD__ . '::' . __LINE__ . " Could not encode output: " . $swe); - $this->_logDomDocument(Zend_Log::WARN, $response, __METHOD__, __LINE__); } header("HTTP/1.1 500 Internal server error"); @@ -245,27 +245,31 @@ /** * write (possible big) DOMDocument in smaller chunks to log file * - * @param unknown $priority * @param DOMDocument $dom + * @param string $action * @param string $method * @param int $line */ - protected function _logDomDocument($priority, DOMDocument $dom, $method, $line) + protected function _logDomDocument(DOMDocument $dom, $action, $method, $line) { - $loops = 0; + if (method_exists($this->_logger, 'hasDebug') && !$this->_logger->hasDebug()) { + return; + } + + $tempStream = tmpfile(); + + $meta_data = stream_get_meta_data($tempStream); + $filename = $meta_data"uri"; - $tempStream = fopen('php://temp/maxmemory:5242880', 'r+'); - $dom->formatOutput = true; - fwrite($tempStream, $dom->saveXML()); + $dom->save($filename); $dom->formatOutput = false; rewind($tempStream); - - // log data in 1MByte chunks + + $loops = 0; while (!feof($tempStream)) { - $this->_logger->log($method . '::' . $line . " xml response($loops):\n" . fread($tempStream, 1048576), $priority); - + $this->_logger->debug("{$method}::{$line} xml {$action} ({$loops}):\n" . fread($tempStream, 1048576)); $loops++; } @@ -343,6 +347,11 @@ $tag = ord(fread($stream, 1)); $length = ord(fread($stream, 1)); + // If the stream is at the end we'll get a 0-length + if (!$length) { + continue; + } + switch ($tag) { case self::PARAMETER_ATTACHMENTNAME: $unpacked = unpack('A' . $length . 'string', fread($stream, $length));
View file
kolab-syncroton-2.3.10.tar.gz/lib/ext/Syncroton/Wbxml/Encoder.php -> kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Wbxml/Encoder.php
Changed
@@ -20,27 +20,6 @@ class Syncroton_Wbxml_Encoder extends Syncroton_Wbxml_Abstract { /** - * stack of dtd objects - * - * @var array - */ - protected $_dtdStack = array(); - - /** - * stack of stream resources - * - * @var array - */ - protected $_streamStack = array(); - - /** - * stack of levels when to pop data from the other stacks - * - * @var array - */ - protected $_popStack = array(); - - /** * count level of tags * * @var string @@ -48,27 +27,6 @@ protected $_level = 0; /** - * when to take data next time from the different stacks - * - * @var unknown_type - */ - protected $_nextStackPop = NULL; - - /** - * collect data trough different calls to _handleCharacters - * - * @var string - */ - protected $_currentTagData = NULL; - - /** - * the current tag as read by the parser - * - * @var string - */ - protected $_currentTag = NULL; - - /** * the constructor * * @param resource $_stream @@ -151,64 +109,66 @@ { $_dom->formatOutput = false; - $tempStream = fopen('php://temp/maxmemory:5242880', 'r+'); - fwrite($tempStream, $_dom->saveXML()); - rewind($tempStream); - $this->_initialize($_dom); - - $parser = xml_parser_create_ns($this->_charSet, ';'); - xml_set_object($parser, $this); - xml_set_element_handler($parser, '_handleStartTag', '_handleEndTag'); - xml_set_character_data_handler($parser, '_handleCharacters'); - xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); - - while (!feof($tempStream)) { - if (!xml_parse($parser, fread($tempStream, 1048576), feof($tempStream))) { - // uncomment to write xml document to file - #rewind($tempStream); - #$xmlStream = fopen(tempnam(sys_get_temp_dir(), "xmlerrors"), 'r+'); - #stream_copy_to_stream($tempStream, $xmlStream); - #fclose($xmlStream); - - throw new Syncroton_Wbxml_Exception(sprintf('XML error: %s at line %d', - xml_error_string(xml_get_error_code($parser)), - xml_get_current_line_number($parser) - )); + $this->_traverseDom($_dom); + } + + private function getAttributes($node) + { + $attributes = array(); + if ($node->attributes) { + for ($i = 0; $i < $node->attributes->length; ++$i) { + $attributes$node->attributes->item($i)->name = $node->attributes->item($i)->value; } } + return $attributes; + } - fclose($tempStream); - xml_parser_free($parser); + private function writeNode($node, $withContent = false, $data = null) { + if($this->_codePage->getNameSpace() != $node->namespaceURI) { + $this->_switchCodePage($node->namespaceURI); + } + $this->_writeTag($node->localName, $this->getAttributes($node), $withContent, $data); } - /** - * get's called by xml parser when tag starts - * - * @param resource $_parser - * @param string $_tag current tag prefixed with namespace - * @param array $_attributes list of tag attributes - */ - protected function _handleStartTag($_parser, $_tag, $_attributes) + protected function _traverseDom($_dom) { - $this->_level++; - $this->_currentTagData = null; - - // write data for previous tag happens whith <tag1><tag2> - if($this->_currentTag !== NULL) { - $this->_writeTag($this->_currentTag, $this->_attributes, true); + if ($_dom->childNodes->length == 0) { + return false; } - - list($nameSpace, $this->_currentTag) = explode(';', $_tag); - - if($this->_codePage->getNameSpace() != $nameSpace) { - $this->_switchCodePage($nameSpace); + // print(str_pad("", $this->_level, " ") . "traversing {$_dom->nodeName}" . "\n"); + $this->_level++; + $prevNode = $_dom; + $foundElementNode = false; + foreach ($_dom->childNodes as $node) { + if ($node->nodeType == XML_ELEMENT_NODE) { + $foundElementNode = true; + if ($prevNode && $this->_level > 1) { + // print(str_pad("", $this->_level, " ") . "{$node->nodeName} creating parent {$prevNode->nodeName}" . "\n"); + $this->writeNode($prevNode, true); + $prevNode = null; + } + if (!$this->_traverseDom($node)) { + // print(str_pad("", $this->_level, " ") . "{$node->nodeName} content {$node->nodeValue}" . "\n"); + $data = $node->nodeValue; + if (strlen($data) == 0) { + $this->writeNode($node); + } else { + $this->writeNode($node, true, $data); + $this->_writeByte(Syncroton_Wbxml_Abstract::END); + // print("Closing tag after writing tag\n"); + } + } else { + $this->_writeByte(Syncroton_Wbxml_Abstract::END); + // print("Closing tag\n"); + } + } } + $this->_level--; - $this->_attributes = $_attributes; - + return $foundElementNode; } - + /** * strip uri: from nameSpace * @@ -221,73 +181,6 @@ } /** - * get's called by xml parser when tag ends - * - * @param resource $_parser - * @param string $_tag current tag prefixed with namespace - */ - protected function _handleEndTag($_parser, $_tag) - { - #echo "$_tag Level: $this->_level == $this->_nextStackPop \n"; - - if($this->_nextStackPop !== NULL && $this->_nextStackPop == $this->_level) { - #echo "TAG: $_tag\n"; - $this->_writeByte(Syncroton_Wbxml_Abstract::END); - - $subStream = $this->_stream; - $subStreamLength = ftell($subStream); - - $this->_dtd = array_pop($this->_dtdStack); - $this->_stream = array_pop($this->_streamStack); - $this->_nextStackPop = array_pop($this->_popStack); - $this->_codePage = $this->_dtd->getCurrentCodePage(); - - rewind($subStream); - #while (!feof($subStream)) {$buffer = fgets($subStream, 4096);echo $buffer;} - $this->_writeByte(Syncroton_Wbxml_Abstract::OPAQUE); - $this->_writeMultibyteUInt($subStreamLength); -
View file
kolab-syncroton-2.3.10.tar.gz/lib/ext/Syncroton/Wbxml/Exception/UnexpectedEndOfFile.php -> kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Wbxml/Exception/UnexpectedEndOfFile.php
Changed
@@ -19,5 +19,5 @@ class Syncroton_Wbxml_Exception_UnexpectedEndOfFile extends Syncroton_Wbxml_Exception { - protected $message = 'unexpcted end of file detected'; -} \ No newline at end of file + protected $message = 'unexpected end of file detected'; +}
View file
kolab-syncroton-2.3.10.tar.gz/lib/ext/rtf.php -> kolab-syncroton-2.4.2.tar.gz/lib/ext/rtf.php
Changed
@@ -101,6 +101,7 @@ var $cfirst; // could this be the first character ? so watch out for control symbols var $flags = array(); // parser flags + var $fonttable = array(); var $queue; // every character which is no sepcial char, not belongs to a control word/symbol; is generally considered being 'plain' @@ -214,20 +215,20 @@ $flagCount = 0; $flags = 0; while ($out<$oblen) { - $flags = ($flagCount++ % 8 == 0) ? ord($src{$in++}) : $flags >> 1; + $flags = ($flagCount++ % 8 == 0) ? ord($src$in++) : $flags >> 1; if (($flags & 1) == 1) { - $offset = ord($src{$in++}); - $length = ord($src{$in++}); + $offset = ord($src$in++); + $length = ord($src$in++); $offset = ($offset << 4) | ($length >> 4); $length = ($length & 0xF) + 2; $offset = (int)($out / 4096) * 4096 + $offset; if ($offset >= $out) $offset -= 4096; $end = $offset + $length; while ($offset < $end) { - $dst{$out++} = $dst{$offset++}; + $dst$out++ = $dst$offset++; }; } else { - $dst{$out++} = $src{$in++}; + $dst$out++ = $src$in++; } } $src = $dst; @@ -249,7 +250,7 @@ $c=0; $end = $off + $len; for($i=$off;$i < $end;$i++) { - $c=$this->CRC32_TABLE($c ^ ord($buf{$i})) & 0xFF ^ (($c >> 8) & 0x00ffffff); + $c=$this->CRC32_TABLE($c ^ ord($buf$i)) & 0xFF ^ (($c >> 8) & 0x00ffffff); } return $c; } @@ -399,7 +400,6 @@ $this->out.="<group>"; } if($state == "close") { /* pop from the stack */ - $this->last_flags = $this->flags; $this->flags = array_pop($this->stack); $this->flags"fonttbl_current_write" = ""; // on group close, no more fontdefinition will be written to this id
View file
kolab-syncroton-2.3.10.tar.gz/lib/kolab_sync.php -> kolab-syncroton-2.4.2.tar.gz/lib/kolab_sync.php
Changed
@@ -45,8 +45,11 @@ public $username; public $password; + public $task = null; + protected $per_user_log_dir; + const CHARSET = 'UTF-8'; - const VERSION = "2.3.10"; + const VERSION = "2.4.2"; /** @@ -207,7 +210,7 @@ } // LDAP server failure... send 503 error - if ($auth'kolab_ldap_error') { + if ($auth'kolab_ldap_error' ?? null) { self::server_error(); } @@ -222,8 +225,10 @@ $auth'pass' = $password; } + $err = null; + // Authenticate - get Roundcube user ID - if (!$auth'abort' && ($userid = $this->login($auth'user', $auth'pass', $auth'host', $err))) { + if (!($auth'abort' ?? false) && ($userid = $this->login($auth'user', $auth'pass', $auth'host', $err))) { // set real username $this->username = $auth'user'; return $userid; @@ -232,7 +237,9 @@ $err_str = $this->get_storage()->get_error_str(); } - kolab_auth::log_login_error($auth'user', $err_str ?: $err); + if (class_exists('kolab_auth', false)) { + kolab_auth::log_login_error($auth'user', !empty($err_str) ? $err_str : $err); + } $this->plugins->exec_hook('login_failed', array( 'host' => $auth'host', @@ -296,7 +303,9 @@ // parse $host $a_host = parse_url($host); - if ($a_host'host') { + $port = null; + $ssl = null; + if (!empty($a_host'host')) { $host = $a_host'host'; $ssl = (isset($a_host'scheme') && in_array($a_host'scheme', array('ssl','imaps','tls'))) ? $a_host'scheme' : null; if (!empty($a_host'port')) { @@ -392,48 +401,63 @@ $this->logger->set_username($this->username); - $user_debug = $this->config->get('per_user_logging'); - $user_log = $user_debug || $this->config->get('activesync_user_log'); + $user_debug = (bool) $this->config->get('per_user_logging'); - if (!$user_log) { + if (!$user_debug) { return; } $log_dir = $this->config->get('log_dir'); $log_dir .= DIRECTORY_SEPARATOR . $this->username; - if (!$user_debug && !is_dir($log_dir)) { - if (!mkdir($log_dir, 0770)) { - return; - } + // No automatically creating any log directories + if (!is_dir($log_dir)) { + $this->logger->set_log_dir(null); + return; } + $deviceId = null; + if (!empty($_GET'DeviceId')) { - $log_dir .= DIRECTORY_SEPARATOR . $_GET'DeviceId'; + $deviceId = $_GET'DeviceId'; } - - if (!is_dir($log_dir)) { - if (!mkdir($log_dir, 0770)) { - return; + else if ( + !empty($_SERVER'QUERY_STRING') + && strpos($_SERVER'QUERY_STRING', '&') == false + && ($query = base64_decode($_SERVER'QUERY_STRING')) + && strlen($query) > 8 + ) { + // unpack the first 5 bytes, the last one is a length of the device id + $unpacked = unpack('Cversion/Ccommand/vlocale/Clength', substr($query, 0, 5)); + + // unpack the deviceId, with some input sanity checks + if ( + !empty($unpacked'version') + && !empty($unpacked'length') + && $unpacked'version' >= 121 + && ($length = $unpacked'length') > 0 && $length <= 32 + ) { + $unpacked = unpack("H" . ($length * 2) . "string", $query, 5); + $deviceId = $unpacked'string'; } } - if ($user_debug) { - $this->per_user_log_dir = $log_dir; - } - else { - $this->config->set('log_dir', $log_dir); - } + if (!empty($deviceId)) { + $dev_dir = $log_dir . DIRECTORY_SEPARATOR . $deviceId; - // re-set PHP error logging - if (($this->config->get('debug_level') & 1) && $this->config->get('log_driver') != 'syslog') { - ini_set('error_log', $log_dir . '/errors'); + if (is_dir($dev_dir) || mkdir($dev_dir, 0770)) { + $log_dir = $dev_dir; + } } + + $this->per_user_log_dir = $log_dir; + $this->logger->set_log_dir($log_dir); + $this->config->set('log_dir', $log_dir); } /** - * Get the per-user log directory - */ + * Get the per-user log directory + */ public function get_user_log_dir() { return $this->per_user_log_dir; @@ -464,13 +488,16 @@ // write performance stats to logs/console if ($this->config->get('devel_mode') || $this->config->get('performance_stats')) { + // we have to disable per_user_logging to make sure stats end up in the main console log + $this->config->set('per_user_logging', false); + // make sure logged numbers use unified format setlocale(LC_NUMERIC, 'en_US.utf8', 'en_US.UTF-8', 'en_US', 'C'); if (function_exists('memory_get_usage')) - $mem = sprintf('%.1f', memory_get_usage() / 1048576); + $mem = round(memory_get_usage() / 1048576, 1); if (function_exists('memory_get_peak_usage')) - $mem .= '/' . sprintf('%.1f', memory_get_peak_usage() / 1048576); + $mem .= '/' . round(memory_get_peak_usage() / 1048576, 1); $query = $_SERVER'QUERY_STRING'; $log = $query . ($mem ? ($query ? ' ' : '') . "$mem" : '');
View file
kolab-syncroton-2.3.10.tar.gz/lib/kolab_sync_backend.php -> kolab-syncroton-2.4.2.tar.gz/lib/kolab_sync_backend.php
Changed
@@ -149,7 +149,7 @@ public function folders_list($deviceid, $type, $flat_mode = false) { // get all folders of specified type - $folders = (array) kolab_storage::list_folders('', '*', $type, false, $typedata); + $folders = kolab_storage::list_folders('', '*', $type, false, $typedata); // get folders activesync config $folderdata = $this->folder_meta(); @@ -176,7 +176,7 @@ } // Activesync folder identifier (serverId) - $folder_type = $typedata$folder ?: 'mail'; + $folder_type = !empty($typedata$folder) ? $typedata$folder : 'mail'; $folder_id = self::folder_id($folder, $folder_type); $folders_list$folder_id = $this->folder_data($folder, $folder_type); @@ -215,8 +215,8 @@ while (count($items) > 0) { array_pop($items); - $parent_name = implode($items, $delim); - $parent_type = $typedata$parent_name ?: 'mail'; + $parent_name = implode($delim, $items); + $parent_type = !empty($typedata$parent_name) ? $typedata$parent_name : 'mail'; $parent_id = self::folder_id($parent_name, $parent_type); if (isset($folders$parent_id)) { @@ -253,14 +253,15 @@ public function folder_meta() { if (!isset($this->folder_meta)) { - $this->folder_meta = array(); // get folders activesync config $folderdata = $this->storage->get_metadata("*", self::ASYNC_KEY); if (!is_array($folderdata)) { - return false; + return $this->folder_meta = false; } + $this->folder_meta = array(); + foreach ($folderdata as $folder => $meta) { if ($asyncdata = $metaself::ASYNC_KEY) { if ($metadata = $this->unserialize_metadata($asyncdata)) { @@ -364,7 +365,7 @@ return false; } - $metadata = $metadata$name; + $metadata = isset($metadata$name) ? $metadata$name : array(); if ($flag) { if (empty($metadata)) { @@ -384,8 +385,7 @@ // 2 - synchronize with alarms $metadata'FOLDER'$deviceid'S' = $flag; } - - if (!$flag) { + else { unset($metadata'FOLDER'$deviceid'S'); if (empty($metadata'FOLDER'$deviceid)) { @@ -402,7 +402,7 @@ } // Return if nothing's been changed - if (!self::data_array_diff($this->folder_meta$name, $metadata)) { + if (!self::data_array_diff(isset($this->folder_meta$name) ? $this->folder_meta$name : null, $metadata)) { return true; } @@ -416,10 +416,7 @@ public function device_get($id) { $devices_list = $this->devices_list(); - - $result = $devices_list$id; - - return $result; + return $devices_list$id ?? null; } /** @@ -589,7 +586,11 @@ 'event', 'contact', 'note', - 'task' + 'task', + 'event.confidential', + 'event.private', + 'task.confidential', + 'task.private', ); // This default set can be extended by adding following values: @@ -665,7 +666,7 @@ continue; } - $type = $foldertypes$folder ?: 'mail'; + $type = ($foldertypes$folder ?? null) ?: 'mail'; if ($type == 'mail' && isset($special_folders$folder)) { $type = $special_folders$folder; } @@ -736,6 +737,8 @@ */ public static function type_kolab2activesync($type) { + $type = preg_replace('/\.(confidential|private)$/i', '', $type); + if ($key = array_search($type, self::$types)) { return $key; } @@ -769,11 +772,18 @@ $folder_id = $this->folder_id($folder, $type); // Folder type - $type = self::type_kolab2activesync($type); - // fix type, if there's no type annotation it's detected as UNKNOWN - // we'll use 'mail' (12) or 'mail.inbox' (2) - if ($type == 1) { - $type = $folder == 'INBOX' ? 2 : 12; + if (strcasecmp($folder, 'INBOX') === 0) { + // INBOX is always inbox, prevent from issues related with a change of + // folder type annotation (it can be initially unset). + $type = 2; + } + else { + $type = self::type_kolab2activesync($type); + + // fix type, if there's no type annotation it's detected as UNKNOWN we'll use 'mail' (12) + if ($type == 1) { + $type = 12; + } } // Syncroton folder data array @@ -818,8 +828,23 @@ return $this->folder_uids$name = $uid; } */ + if (strcasecmp($name, 'INBOX') === 0) { + // INBOX is always inbox, prevent from issues related with a change of + // folder type annotation (it can be initially unset). + $type = 'mail.inbox'; + } + else { + if ($type === null) { + $type = kolab_storage::folder_type($name); + } + + if ($type != null) { + $type = preg_replace('/\.(confidential|private)$/i', '', $type); + } + } + // Add type to folder UID hash, so type change can be detected by Syncroton - $uid = $name . '!!' . ($type !== null ? $type : kolab_storage::folder_type($name)); + $uid = $name . '!!' . $type; $uid = md5($uid); return $this->folder_uids$name = $uid; @@ -892,7 +917,7 @@ $synctime = $synctime->format('Y-m-d H:i:s'); $rcube = rcube::get_instance(); $db = $rcube->get_dbh(); - $old_data = $this->modseq$folderid$synctime; + $old_data = $this->modseq$folderid$synctime ?? null; if (empty($old_data)) { $this->modseq$folderid$synctime = $data; @@ -944,7 +969,7 @@ $synctime = $synctime->format('Y-m-d H:i:s'); $rcube = rcube::get_instance(); $db = $rcube->get_dbh(); - $old_data = $this->relations$folderid$synctime; + $old_data = $this->relations$folderid$synctime ?? null; if (empty($old_data)) { $this->relations$folderid$synctime = $relations;
View file
kolab-syncroton-2.3.10.tar.gz/lib/kolab_sync_backend_common.php -> kolab-syncroton-2.4.2.tar.gz/lib/kolab_sync_backend_common.php
Changed
@@ -81,8 +81,8 @@ * * @param Syncroton_Model_* $object Object * - * @throws InvalidArgumentException * @return Syncroton_Model_* Object + * @throws InvalidArgumentException|Syncroton_Exception_DeadlockDetected|Exception */ public function create($object) { @@ -104,8 +104,13 @@ array_values($data) ); - if ($this->db->is_error($result)) { - throw new Exception('Failed to save instance of ' . $this->interface_name); + if ($err = $this->db->is_error($result)) { + $err = "Failed to save instance of {$this->interface_name}: {$err}"; + if ($this->db->error_info()0 == '40001') { + throw new Syncroton_Exception_DeadlockDetected($err); + } else { + throw new Exception($err); + } } return $object; @@ -140,6 +145,7 @@ * @param string|Syncroton_Model_* $id Object or identifier * * @return bool True on success, False on failure + * @throws Syncroton_Exception_DeadlockDetected|Exception */ public function delete($id) { @@ -151,6 +157,15 @@ $result = $this->db->query('DELETE FROM `' . $this->table_name .'` WHERE `id` = ?', array($id)); + if ($err = $this->db->is_error($result)) { + $err = "Failed to delete instance of {$this->interface_name}: {$err}"; + if ($this->db->error_info()0 == '40001') { + throw new Syncroton_Exception_DeadlockDetected($err); + } else { + throw new Exception($rr); + } + } + return (bool) $this->db->affected_rows($result); } @@ -159,8 +174,8 @@ * * @param Syncroton_Model_* $object * - * @throws InvalidArgumentException * @return Syncroton_Model_* Object + * @throws InvalidArgumentException|Syncroton_Exception_DeadlockDetected|Exception */ public function update($object) { @@ -175,9 +190,18 @@ $set = $this->db->quote_identifier($key) . ' = ?'; } - $this->db->query('UPDATE `' . $this->table_name . '` SET ' . implode(', ', $set) + $result = $this->db->query('UPDATE `' . $this->table_name . '` SET ' . implode(', ', $set) . ' WHERE `id` = ' . $this->db->quote($object->id), array_values($data)); + if ($err = $this->db->is_error($result)) { + $err = "Failed to update instance of {$this->interface_name}: {$err}"; + if ($this->db->error_info()0 == '40001') { + throw new Syncroton_Exception_DeadlockDetected($err); + } else { + throw new Exception($err); + } + } + return $object; }
View file
kolab-syncroton-2.3.10.tar.gz/lib/kolab_sync_backend_content.php -> kolab-syncroton-2.4.2.tar.gz/lib/kolab_sync_backend_content.php
Changed
@@ -55,6 +55,7 @@ * @param Syncroton_Model_IDevice|string $_deviceId * @param Syncroton_Model_IFolder|string $_folderId * @param string $_contentId + * * @return Syncroton_Model_IContent */ public function getContentState($_deviceId, $_folderId, $_contentId) @@ -82,13 +83,15 @@ * * @param Syncroton_Model_IDevice|string $_deviceId * @param Syncroton_Model_IFolder|string $_folderId + * @param int $syncKey + * * @return array */ - public function getFolderState($_deviceId, $_folderId) + public function getFolderState($_deviceId, $_folderId, $syncKey = null) { $deviceId = $_deviceId instanceof Syncroton_Model_IDevice ? $_deviceId->id : $_deviceId; $folderId = $_folderId instanceof Syncroton_Model_IFolder ? $_folderId->id : $_folderId; - $cachekey = $deviceId . ':' . $folderId; + $cachekey = $deviceId . ':' . $folderId . ':' . ($syncKey ?: '*'); // in Sync request we call this function twice in case when // folder state changed - use cache to skip at least one SELECT query @@ -99,6 +102,9 @@ $where = $this->db->quote_identifier('device_id') . ' = ' . $this->db->quote($deviceId); $where = $this->db->quote_identifier('folder_id') . ' = ' . $this->db->quote($folderId); $where = $this->db->quote_identifier('is_deleted') . ' = 0'; + if ($syncKey) { + $where = $this->db->quote_identifier('creation_synckey') . ' < ' . $this->db->quote($syncKey + 1); + } $select = $this->db->query("SELECT `contentid` FROM `{$this->table_name}` WHERE " . implode(' AND ', $where)); $result = array(); @@ -120,9 +126,8 @@ { $deviceId = $_deviceId instanceof Syncroton_Model_IDevice ? $_deviceId->id : $_deviceId; $folderId = $_folderId instanceof Syncroton_Model_IFolder ? $_folderId->id : $_folderId; - $cachekey = $deviceId . ':' . $folderId; - unset($this->cache'content_folderstate'$cachekey); + unset($this->cache'content_folderstate'); $where = $this->db->quote_identifier('device_id') . ' = ' . $this->db->quote($deviceId); $where = $this->db->quote_identifier('folder_id') . ' = ' . $this->db->quote($folderId);
View file
kolab-syncroton-2.3.10.tar.gz/lib/kolab_sync_backend_device.php -> kolab-syncroton-2.4.2.tar.gz/lib/kolab_sync_backend_device.php
Changed
@@ -207,7 +207,11 @@ $status = Syncroton_Model_Oof::STATUS_GLOBAL; } + $message = null; + if ($vacation'message') { + $message = array(); + // convert message format, Roundcube supports plain text only if ($request'bodyType' == 'HTML') { $text2html = new rcube_text2html($vacation'message');
View file
kolab-syncroton-2.3.10.tar.gz/lib/kolab_sync_backend_state.php -> kolab-syncroton-2.4.2.tar.gz/lib/kolab_sync_backend_state.php
Changed
@@ -72,7 +72,7 @@ $data = parent::object_to_array($object); if (is_array($object->pendingdata)) { - $data'pendingdata' = json_encode($object->pendingdata); + $data'pendingdata' = gzdeflate(json_encode($object->pendingdata)); } return $data; @@ -86,7 +86,10 @@ $object = parent::get_object($data); if ($object->pendingdata) { - $object->pendingdata = json_decode($object->pendingdata, true); + $inflated = gzinflate($object->pendingdata); + // Inflation may fail for backward compatiblity + $data = $inflated ? $inflated : $object->pendingdata; + $object->pendingdata = json_decode($data, true); } return $object; @@ -177,21 +180,28 @@ $where'folder_id' = $this->db->quote_identifier('folder_id') . ' = ' . $this->db->quote($folder_id); $where'is_deleted' = $this->db->quote_identifier('is_deleted') . ' = 1'; - // found more recent synckey => the last sync response got not received by the client + // found more recent synckey => the last sync response was not received by the client if ($next > $sync_key) { - $where'synckey' = $this->db->quote_identifier('creation_synckey') . ' = ' . $this->db->quote($state->counter); - // undelete entries marked as deleted in syncroton_content table - $this->db->query("UPDATE `syncroton_content` SET `is_deleted` = 0 WHERE " . implode(' AND ', $where)); - - // remove entries added during latest sync in syncroton_content table - unset($where'is_deleted'); - $where'synckey' = $this->db->quote_identifier('creation_synckey') . ' > ' . $this->db->quote($state->counter); - - $this->db->query("DELETE FROM `syncroton_content` WHERE " . implode(' AND ', $where)); + // We store the clientIdMap with the "next" sync state, so we need to copy it back. + $state->clientIdMap = $states$next->clientIdMap; } else { - // finaly delete all entries marked for removal in syncroton_content table - $this->db->query("DELETE FROM `syncroton_content` WHERE " . implode(' AND ', $where)); + // finally delete all entries marked for removal in syncroton_content table + $retryCounter = 0; + while(True) { + $result = $this->db->query("DELETE FROM `syncroton_content` WHERE " . implode(' AND ', $where)); + if ($this->db->is_error($result)) { + $retryCounter++; + // Retry on deadlock + if ($this->db->error_info()0 != '40001' || $retryCounter > 60) { + throw new Exception('Failed to delete entries in sync_key check'); + } + } else { + break; + } + //Give the other transactions some time before we try again + sleep(1); + } } // remove all other synckeys @@ -201,4 +211,18 @@ return $state; } + + public function haveNext($deviceid, $folderid, $sync_key) + { + $device_id = $deviceid instanceof Syncroton_Model_IDevice ? $deviceid->id : $deviceid; + $folder_id = $folderid instanceof Syncroton_Model_IFolder ? $folderid->id : $folderid; + + $where'device_id' = $this->db->quote_identifier('device_id') . ' = ' . $this->db->quote($device_id); + $where'type' = $this->db->quote_identifier('type') . ' = ' . $this->db->quote($folder_id); + $where'counter' = $this->db->quote_identifier('counter') . ' > ' . $this->db->quote($sync_key); + + $select = $this->db->query("SELECT id FROM `{$this->table_name}` WHERE " . implode(' AND ', $where)); + return $this->db->num_rows($select) > 0; + } + }
View file
kolab-syncroton-2.3.10.tar.gz/lib/kolab_sync_data.php -> kolab-syncroton-2.4.2.tar.gz/lib/kolab_sync_data.php
Changed
@@ -311,6 +311,7 @@ $parentid = $folder->parentId; $type = $folder->type; $display_name = $folder->displayName; + $parent = null; if ($parentid) { $parent = $this->backend->folder_id2name($parentid, $this->device->deviceid); @@ -428,6 +429,11 @@ // Remove subfolders if (!empty($options'deleteSubFolders')) { $list = $this->listFolders($folderid); + + if (!is_array($list)) { + throw new Syncroton_Exception_Status_ItemOperations(Syncroton_Exception_Status_ItemOperations::ITEM_SERVER_ERROR); + } + foreach ($list as $folderid => $folder) { $foldername = $this->backend->folder_id2name($folderid, $this->device->deviceid); $folder = $this->getFolderObject($foldername); @@ -508,7 +514,7 @@ $oldEntry = $this->getObject($folderId, $serverId); if (empty($oldEntry)) { - throw new Syncroton_Exception_NotFound('id not found'); + throw new Syncroton_Exception_NotFound('entry not found'); } $entry = $this->toKolab($entry, $folderId, $oldEntry); @@ -670,7 +676,7 @@ */ protected function getChangesByRelations($folderid, $filter) { - if (!$this->tag_categories) { + if (isset($this->tag_categories) && !$this->tag_categories) { return; } @@ -897,7 +903,7 @@ */ public function getCountOfChanges(Syncroton_Backend_IContent $contentBackend, Syncroton_Model_IFolder $folder, Syncroton_Model_ISyncState $syncState) { - $allClientEntries = $contentBackend->getFolderState($this->device, $folder); + $allClientEntries = $contentBackend->getFolderState($this->device, $folder, $syncState->counter); $allServerEntries = $this->getServerEntries($folder->serverId, $folder->lastfiltertype); $changedEntries = $this->getChangedEntriesCount($folder->serverId, $syncState->lastsync, null, $folder->lastfiltertype); $addedEntries = array_diff($allServerEntries, $allClientEntries); @@ -922,7 +928,7 @@ return true; } - $allClientEntries = $contentBackend->getFolderState($this->device, $folder); + $allClientEntries = $contentBackend->getFolderState($this->device, $folder, $syncState->counter); // @TODO: Consider looping over all folders here, not in getServerEntries() and // getChangedEntriesCount(). This way we could break the loop and not check all folders @@ -947,6 +953,10 @@ { $folders = $this->extractFolders($folderid); + if (empty($folders)) { + return null; + } + foreach ($folders as $folderid) { $foldername = $this->backend->folder_id2name($folderid, $this->device->deviceid); $folder = $this->getFolderObject($foldername); @@ -1002,7 +1012,7 @@ } // convert categories into tags, save them after creating an object - if ($this->tag_categories) { + if (!empty($data'categories') && isset($this->tag_categories) && $this->tag_categories) { $tags = $data'categories'; unset($data'categories'); } @@ -1010,6 +1020,10 @@ $foldername = $this->backend->folder_id2name($folderid, $this->device->deviceid); $folder = $this->getFolderObject($foldername); + // Set User-Agent for saved objects + $app = kolab_sync::get_instance(); + $app->config->set('useragent', $app->app_name . ' ' . kolab_sync::VERSION); + if ($folder && $folder->valid && $folder->save($data)) { if (!empty($tags)) { $this->setKolabTags($data'uid', $tags); @@ -1032,11 +1046,15 @@ $folder = $this->getFolderObject($object'_mailbox'); // convert categories into tags, save them after updating an object - if ($this->tag_categories && array_key_exists('categories', $data)) { + if (isset($this->tag_categories) && $this->tag_categories && array_key_exists('categories', $data)) { $tags = (array) $data'categories'; unset($data'categories'); } + // Set User-Agent for saved objects + $app = kolab_sync::get_instance(); + $app->config->set('useragent', $app->app_name . ' ' . kolab_sync::VERSION); + if ($folder && $folder->valid && $folder->save($data)) { if (isset($tags)) { $this->setKolabTags($data'uid', $tags); @@ -1060,7 +1078,7 @@ $folder = $this->getFolderObject($object'_mailbox'); if ($folder && $folder->valid && $folder->delete($object'uid')) { - if ($this->tag_categories) { + if (isset($this->tag_categories) && $this->tag_categories) { $this->setKolabTags($object'uid', null); } @@ -1117,7 +1135,7 @@ $this->device->deviceid, $this->modelName, $this->isMultiFolder()); } - if ($parentid === null) { + if ($parentid === null || !is_array($this->imap_folders)) { return $this->imap_folders; } @@ -1247,10 +1265,12 @@ if ($count == 2 && $name_items0 == 'x-custom') { $value = null; - foreach ((array) $data'x-custom' as $val) { - if (is_array($val) && $val0 == $name_items1) { - $value = $val1; - break; + if (!empty($data'x-custom') && is_array($data'x-custom')) { + foreach ($data'x-custom' as $val) { + if (is_array($val) && $val0 == $name_items1) { + $value = $val1; + break; + } } } @@ -1314,7 +1334,8 @@ // custom properties if ($count == 2 && $name_items0 == 'x-custom') { - foreach ((array) $data'x-custom' as $idx => $val) { + $data'x-custom' = isset($data'x-custom') ? ((array) $data'x-custom') : array(); + foreach ($data'x-custom' as $idx => $val) { if (is_array($val) && $val0 == $name_items1) { $data'x-custom'$idx1 = $value; return; @@ -1445,16 +1466,17 @@ * @param int $type Result data type (to which the body will be converted, if specified). * One or array of Syncroton_Model_EmailBody constants. * - * @return string Body value + * @return string|null Body value */ protected function getBody($body, $type = null) { + $data = null; if ($body && $body->data) { $data = $body->data; } if (!$data || empty($type)) { - return; + return null; } $type = (array) $type; @@ -1505,7 +1527,7 @@ $real_length = $body_length = strlen($body); // truncate the body if needed - if (($truncateAt = $prefs$type'truncationSize') && $body_length > $truncateAt) { + if (isset($prefs$type'truncationSize') && ($truncateAt = $prefs$type'truncationSize') && $body_length > $truncateAt) { $body = mb_strcut($body, 0, $truncateAt); $body_length = strlen($body); @@ -1667,8 +1689,14 @@ */ protected function recurrence_to_kolab($data, $folderid, $timezone = null) { - if (!($data->recurrence instanceof Syncroton_Model_EventRecurrence) || !isset($data->recurrence->type)) { - return null; + if (!($data->recurrence instanceof Syncroton_Model_EventRecurrence) + && !($data->recurrence instanceof Syncroton_Model_TaskRecurrence) + ) { + return; + } + + if (!isset($data->recurrence->type)) { + return; } $recurrence = $data->recurrence; @@ -1745,35 +1773,39 @@ $ex_list = array(); // exceptions (modified occurences) - foreach ((array)$data'recurrence''EXCEPTIONS' as $exception) {
View file
kolab-syncroton-2.3.10.tar.gz/lib/kolab_sync_data_calendar.php -> kolab-syncroton-2.4.2.tar.gz/lib/kolab_sync_data_calendar.php
Changed
@@ -116,6 +116,9 @@ const SENSITIVITY_PRIVATE = 2; const SENSITIVITY_CONFIDENTIAL = 3; + const KEY_DTSTAMP = 'x-custom.X-ACTIVESYNC-DTSTAMP'; + const KEY_REPLYTIME = 'x-custom.X-ACTIVESYNC-REPLYTIME'; + /** * Mapping of attendee status * @@ -181,21 +184,12 @@ $event = is_array($serverId) ? $serverId : $this->getObject($collection->collectionId, $serverId); $config = $this->getFolderConfig($event'_mailbox'); $result = array(); + $is_outlook = stripos($this->device->devicetype, 'outlook') !== false; + $is_android = stripos($this->device->devicetype, 'android') !== false; - // Timezone // Kolab Format 3.0 and xCal does support timezone per-date, but ActiveSync allows // only one timezone per-event. We'll use timezone of the start date - if ($event'start' instanceof DateTime) { - $timezone = $event'start'->getTimezone(); - - if ($timezone && ($tz_name = $timezone->getName()) != 'UTC') { - $tzc = kolab_sync_timezone_converter::getInstance(); - - if ($tz_name = $tzc->encodeTimezone($tz_name)) { - $result'timezone' = $tz_name; - } - } - } + $result'timezone' = kolab_sync_timezone_converter::encodeTimezoneFromDate($event'start'); // Calendar namespace fields foreach ($this->mapping as $key => $name) { @@ -233,11 +227,15 @@ break; case 'sensitivity': - $value = intval($this->sensitivityMap$value); + if (!empty($value)) { + $value = intval($this->sensitivityMap$value); + } break; case 'free_busy': - $value = $this->busyStatusMap$value; + if (!empty($value)) { + $value = $this->busyStatusMap$value; + } break; case 'description': @@ -283,27 +281,51 @@ } } + $resp_type = self::ATTENDEE_STATUS_UNKNOWN; + $user_rsvp = false; + // Attendees if (!empty($event'attendees')) { - foreach ($event'attendees' as $idx => $attendee) { - $att = array(); + $user_emails = $this->user_emails(); - if ($email = $attendee'email') { - $att'email' = $email; - } - else { + foreach ($event'attendees' as $idx => $attendee) { + if (empty($attendee'email')) { // In Activesync email is required continue; } - $att'name' = $attendee'name' ?: $email; + $email = $attendee'email'; + + $att = + 'email' => $email, + 'name' => !empty($attendee'name') ? $attendee'name' : $email, + ; + + $type = isset($attendee'role') ? $this->attendeeTypeMap$attendee'role' : null; + $status = isset($attendee'status') ? $this->attendeeStatusMap$attendee'status' : null; if ($this->asversion >= 12) { - $type = isset($attendee'role') ? $this->attendeeTypeMap$attendee'role' : null; - $status = isset($attendee'status') ? $this->attendeeStatusMap$attendee'status' : null; + if (isset($attendee'cutype') && strtolower($attendee'cutype') == 'resource') { + $att'attendeeType' = self::ATTENDEE_TYPE_RESOURCE; + } else { + $att'attendeeType' = $type ?: self::ATTENDEE_TYPE_REQUIRED; + } + $att'attendeeStatus' = $status ?: self::ATTENDEE_STATUS_UNKNOWN; + } - $att'attendeeType' = $type ? $type : self::ATTENDEE_TYPE_REQUIRED; - $att'attendeeStatus' = $status ? $status : self::ATTENDEE_STATUS_UNKNOWN; + if ($email && in_array_nocase($email, $user_emails)) { + $user_rsvp = !empty($attendee'rsvp'); + $resp_type = $status ?: self::ATTENDEE_STATUS_UNKNOWN; + + // Synchronize the attendee status to the event status to get the same behaviour as outlook. + if (($is_outlook || $is_android )&& isset($attendee'status')) { + if ($attendee'status' == 'ACCEPTED') { + $result'busyStatus' = self::BUSY_STATUS_BUSY; + } + if ($attendee'status' == 'TENTATIVE') { + $result'busyStatus' = self::BUSY_STATUS_TENTATIVE; + } + } } $result'attendees' = new Syncroton_Model_EventAttendee($att); @@ -311,11 +333,26 @@ } // Event meeting status - $this->meeting_status_from_kolab($collection, $event, $result); + $this->meeting_status_from_kolab($event, $result); // Recurrence (and exceptions) $this->recurrence_from_kolab($collection, $event, $result); + // RSVP status + $result'responseRequested' = $result'meetingStatus' == 3 && $user_rsvp ? 1 : 0; + $result'responseType' = $result'meetingStatus' == 3 ? $resp_type : null; + + // Appointment Reply Time (without it Outlook displays e.g. "Accepted on None") + if ($resp_type != self::ATTENDEE_STATUS_UNKNOWN) { + if ($reply_time = $this->getKolabDataItem($event, self::KEY_REPLYTIME)) { + $result'appointmentReplyTime' = new DateTime($reply_time, new DateTimeZone('UTC')); + } elseif (!empty($event'changed')) { + $reply_time = clone $event'changed'; + $reply_time->setTimezone(new DateTimeZone('UTC')); + $result'appointmentReplyTime' = $reply_time; + } + } + return $as_array ? $result : new Syncroton_Model_Event($result); } @@ -331,15 +368,33 @@ */ public function toKolab(Syncroton_Model_IEntry $data, $folderid, $entry = null, $timezone = null) { + $foldername = isset($entry'_mailbox') ? $entry'_mailbox' : $this->getFolderName($folderid); + if (empty($entry)) { + // If we don't have an existing event (not a modification) we nevertheless check for conflicts. + // This is necessary so we don't overwrite the server-side copy in case the client did not have it available + // when generating an Add command. + try { + $folder = $this->getFolderObject($foldername); + $entry = $folder->get_object($data->uID); + + if ($entry) { + $this->logger->debug('Found and existing event for UID: ' . $data->uID); + } + } catch (Exception $e) { + // uID is not available on exceptions, so we guard for that and silently ignore. + } + } $event = !empty($entry) ? $entry : array(); - $foldername = isset($event'_mailbox') ? $event'_mailbox' : $this->getFolderName($folderid); $config = $this->getFolderConfig($foldername); $is_exception = $data instanceof Syncroton_Model_EventException; $dummy_tz = str_repeat('A', 230) . '=='; $is_outlook = stripos($this->device->devicetype, 'outlook') !== false; + $is_android = stripos($this->device->devicetype, 'android') !== false; - // check data validity - $this->check_event($data); + // check data validity (of a new event) + if (empty($event)) { + $this->check_event($data); + } if (!empty($event'start') && ($event'start' instanceof DateTime)) { $old_timezone = $event'start'->getTimezone(); @@ -348,19 +403,20 @@ // Timezone if (!$timezone && isset($data->timezone) && $data->timezone != $dummy_tz) { $tzc = kolab_sync_timezone_converter::getInstance(); - $expected = $old_timezone ?: kolab_format::$timezone; + $expected = !empty($old_timezone) ? $old_timezone : kolab_format::$timezone; try { $timezone = $tzc->getTimezone($data->timezone, $expected->getName()); $timezone = new DateTimeZone($timezone); } catch (Exception $e) { + $this->logger->warn('Failed to convert the timezone information. UID: ' . $event'uid' . 'Timezone: ' . $data->timezone); $timezone = null; } } if (empty($timezone)) { - $timezone = $old_timezone ?: new DateTimeZone('UTC');
View file
kolab-syncroton-2.3.10.tar.gz/lib/kolab_sync_data_contacts.php -> kolab-syncroton-2.4.2.tar.gz/lib/kolab_sync_data_contacts.php
Changed
@@ -168,7 +168,7 @@ if ($value) { // ActiveSync limits photo size to 48KB (of base64 encoded string) if (strlen($value) * 1.33 > 48 * 1024) { - continue; + continue 2; } } break; @@ -192,7 +192,8 @@ // email address(es): email1Address, email2Address, email3Address for ($x=0; $x<3; $x++) { - if ($email = $data'email'$x) { + if (!empty($data'email'$x)) { + $email = $data'email'$x; if (is_array($email)) { $email = $email'address'; }
View file
kolab-syncroton-2.3.10.tar.gz/lib/kolab_sync_data_email.php -> kolab-syncroton-2.4.2.tar.gz/lib/kolab_sync_data_email.php
Changed
@@ -50,6 +50,8 @@ 'to' => 'to', ); + static $memory_accumulated = 0; + /** * Special folder type/name map * @@ -91,6 +93,9 @@ */ protected $folderType = Syncroton_Command_FolderSync::FOLDERTYPE_MAIL_USER_CREATED; + private $lastsync_folder = null; + private $lastsync_time = null; + /** * the constructor @@ -113,6 +118,52 @@ } /** + * Encode a globalObjId according to https://interoperability.blob.core.windows.net/files/MS-ASEMAIL/%5bMS-ASEMAIL%5d-150526.pdf 2.2.2.3 + * + * @param array $data An array with the data to encode + * + * @return string the encoded globalObjId + */ + public static function encodeGlobalObjId(array $data): string + { + $classid = "040000008200e00074c5b7101a82e008"; + if (!empty($data'data')) { + $payload = $data'data'; + } else { + $uid = $data'uid'; + $payload = "vCal-Uid\1\0\0\0{$uid}\0"; + } + + $packed = pack( + "H32nCCPx8Va*", + $classid, + $data'year' ?? 0, + $data'month' ?? 0, + $data'day' ?? 0, + $data'now' ?? 0, + strlen($payload), + $payload + ); + + return base64_encode($packed); + } + + /** + * Decode a globalObjId according to https://interoperability.blob.core.windows.net/files/MS-ASEMAIL/%5bMS-ASEMAIL%5d-150526.pdf 2.2.2.3 + * + * @param string the encoded globalObjId + * + * @return array An array with the decoded data + */ + public static function decodeGlobalObjId(string $globalObjId): array + { + $unpackString = 'H32classid/nyear/Cmonth/Cday/Pnow/x8/Vbytecount/a*data'; + $decoded = unpack($unpackString, base64_decode($globalObjId)); + $decoded'uid' = substr($decoded'data', strlen("vCal-Uid\1\0\0\0"), -1); + return $decoded; + } + + /** * Creates model object * * @param Syncroton_Model_SyncCollection $collection Collection data @@ -131,6 +182,10 @@ $headers = $message->headers; // rcube_message_header + $this->storage->set_folder($message->folder); + + $this->logger->debug(sprintf("Processing message %s (size: %.2f MB)", $serverId, $headers->size / 1024 / 1024)); + // Calendar namespace fields foreach ($this->mapping as $key => $name) { $value = null; @@ -187,6 +242,8 @@ 'flagType' => 'FollowUp', 'status' => Syncroton_Model_EmailFlag::STATUS_ACTIVE, )); + } else { + $result'flag' = new Syncroton_Model_EmailFlag(); } // Importance/Priority @@ -258,7 +315,7 @@ $truncateAt = $prefs$type'truncationSize'; } - $preview = (int) $prefs$type'preview'; + $preview = (int) (isset($prefs$type'preview') ? $prefs$type'preview' : 0); $airSyncBaseType = $type; break; @@ -272,17 +329,26 @@ // In Sync examples there's one in which bodyPreferences is not defined // in such case Truncated=1 and there's no body sent to the client // only it's estimated size + $isTruncated = 0; if (empty($prefs)) { $messageBody = ''; - $real_length = $message->size; + $real_length = $headers->size; $truncateAt = 0; $body_length = 0; $isTruncated = 1; } else if ($airSyncBaseType == Syncroton_Command_Sync::BODY_TYPE_MIME) { - $messageBody = $this->storage->get_raw_body($message->uid); + // Check if we have enough memory to handle the message + $messageBody = $this->message_mem_check($message, $headers->size); + static::$memory_accumulated += $headers->size; + + if (empty($messageBody)) { + $messageBody = $this->storage->get_raw_body($message->uid); + } + // make the source safe (Bug #2715, #2757) $messageBody = kolab_sync_message::recode_message($messageBody); + // strip out any non utf-8 characters $messageBody = rcube_charset::clean($messageBody); $real_length = $body_length = strlen($messageBody); @@ -319,26 +385,91 @@ $result'nativeBodyType' = $message->has_html_part() ? 2 : 1; // Message class + $result'messageClass' = 'IPM.Note'; + $result'contentClass' = 'urn:content-classes:message'; + if ($headers->ctype == 'multipart/signed' - && count($message->attachments) == 1 && $message->attachments0->mimetype == 'application/pkcs7-signature' + && !empty($message->parts1) + && $message->parts1->mimetype == 'application/pkcs7-signature' ) { $result'messageClass' = 'IPM.Note.SMIME.MultipartSigned'; } else if ($headers->ctype == 'application/pkcs7-mime' || $headers->ctype == 'application/x-pkcs7-mime') { $result'messageClass' = 'IPM.Note.SMIME'; } - else { - $result'messageClass' = 'IPM.Note'; - } + // FIXME disabled for now because it results in broken invitations on android (gmail client) and ios + // else if ($event = $this->get_invitation_event_from_message($message)) { + else if (false) { + $result'messageClass' = 'IPM.Schedule.Meeting.Request'; + $result'contentClass' = 'urn:content-classes:calendarmessage'; + + $meeting = array(); + + $meeting'allDayEvent' = $event'allday' ?? null ? 1 : 0; + $meeting'startTime' = self::date_from_kolab($event'start'); + $meeting'dtStamp' = self::date_from_kolab($event'dtstamp' ?? null); + $meeting'endTime' = self::date_from_kolab($event'end' ?? null); + $meeting'location' = $event'location' ?? null; + $meeting'instanceType' = Syncroton_Model_EmailMeetingRequest::TYPE_NORMAL; + + if (!empty($event'recurrence_date')) { + $meeting'recurrenceId' = self::date_from_kolab($event'recurrence_date'); + if (!empty($event'status') && $event'status' == 'CANCELLED') { + $meeting'instanceType' = Syncroton_Model_EmailMeetingRequest::TYPE_RECURRING_EXCEPTION; + } else { + $meeting'instanceType' = Syncroton_Model_EmailMeetingRequest::TYPE_RECURRING_SINGLE; + } + } else if (!empty($event'recurrence')) { + $meeting'instanceType' = Syncroton_Model_EmailMeetingRequest::TYPE_RECURRING_MASTER; + // TODO: MeetingRequest recurrence is different that the one in Calendar + // $this->recurrence_from_kolab($collection, $event, $meeting); + } - $result'contentClass' = 'urn:content-classes:message'; + // Organizer + if (!empty($event'attendees')) { + foreach ($event'attendees' as $idx => $attendee) { + if (!empty($attendee'role') && $attendee'role' == 'ORGANIZER' && !empty($attendee'email')) { + $meeting'organizer' = $attendee'email'; + break; + } + } + } + + $fileTime = ($event'start'->getTimestamp() + 11644473600) * 10000000; // 1.1.1600 - 1.1.1970 difference in seconds. Converted to microseconds + + // Kolab Format 3.0 and xCal does support timezone per-date, but ActiveSync allows + // only one timezone per-event. We'll use timezone of the start date + $meeting'timeZone' = kolab_sync_timezone_converter::encodeTimezoneFromDate($event'start'); + $meeting'globalObjId' = self::encodeGlobalObjId( + 'uid' => $event'uid', + 'year' => intval($event'start'->format('Y')), + 'month' => intval($event'start'->format('n')), + 'day' => intval($event'start'->format('j')), + 'now' => $fileTime,
View file
kolab-syncroton-2.3.10.tar.gz/lib/kolab_sync_data_gal.php -> kolab-syncroton-2.4.2.tar.gz/lib/kolab_sync_data_gal.php
Changed
@@ -153,7 +153,7 @@ } if (strlen($value) > $maxsize) { - continue; + continue 2; } $value = new Syncroton_Model_GALPicture(array(
View file
kolab-syncroton-2.3.10.tar.gz/lib/kolab_sync_data_tasks.php -> kolab-syncroton-2.4.2.tar.gz/lib/kolab_sync_data_tasks.php
Changed
@@ -117,7 +117,7 @@ $result = array(); // Completion status (required) - $result'complete' = intval($task'status' == 'COMPLETED' || $task'complete' == 100); + $result'complete' = intval($task'status' ?? null == 'COMPLETED' || $task'complete' ?? null == 100); // Calendar namespace fields foreach ($this->mapping as $key => $name) { @@ -140,7 +140,9 @@ break; case 'sensitivity': - $value = intval($this->sensitivityMap$value); + if (!empty($value)) { + $value = intval($this->sensitivityMap$value); + } break; case 'priority': @@ -156,7 +158,9 @@ } // convert kolab tags into categories - $result'categories' = $this->getKolabTags($task'uid', $result'categories'); + if (!empty($result'categories')) { + $result'categories' = $this->getKolabTags($task'uid', $result'categories'); + } // Recurrence $this->recurrence_from_kolab($collection, $task, $result, 'Task'); @@ -164,6 +168,23 @@ return $as_array ? $result : new Syncroton_Model_Task($result); } + + + /** + * Apply a timezone matching the utc offset. + */ + private static function applyTimezone($value, $utcValue) + { + $tzc = kolab_sync_timezone_converter::getInstance(); + $tz = $tzc->getOffsetTimezone($value, $utcValue); + if ($tz) { + //Setting the timezone will change the time, so we set it on the utc variant instead to end up with the same time in the new timezone. + $value = $utcValue; + $value->setTimezone($tz); + } + return $value; + } + /** * convert contact from xml to libkolab array * @@ -186,9 +207,26 @@ $value = $data->$key; switch ($name) { + + case 'due': + case 'start': + // We expect to always get regular and utc variants, so we only need to take one into account. + if ($key == 'utcStartDate' || $key == 'utcDueDate') { + continue 2; + } + if ($value) { + if ($name =='due' && $data->utcDueDate) { + $value = static::applyTimezone($value, $data->utcDueDate); + } + if ($name =='start' && $data->utcStartDate) { + $value = static::applyTimezone($value, $data->utcStartDate); + } + } + break; + case 'sensitivity': $map = array_flip($this->sensitivityMap); - $value = $map$value; + $value = $map$value ?? 'none' ?? self::SENSITIVITY_NORMAL; break; case 'description': @@ -211,9 +249,13 @@ $task'status' = 'COMPLETED'; $task'complete' = 100; } - else if (isset($data->complete) && ($task'status' == 'COMPLETED' || $task'complete' == 100)) { - $task'status' = ''; - $task'complete' = 0; + else if (isset($data->complete)) { + if ((!empty($task'status') && $task'status' == 'COMPLETED') + || (!empty($task'complete') && $task'complete' == 100) + ) { + $task'status' = ''; + $task'complete' = 0; + } } // recurrence
View file
kolab-syncroton-2.3.10.tar.gz/lib/kolab_sync_logger.php -> kolab-syncroton-2.4.2.tar.gz/lib/kolab_sync_logger.php
Changed
@@ -29,12 +29,22 @@ { public $mode; + protected $logfile; + protected $format; + protected $log_dir; + protected $username; + /** * Constructor */ function __construct($mode = null) { - $this->mode = intval($mode); + $rcube = rcube::get_instance(); + + $this->mode = intval($mode); + $this->logfile = $rcube->config->get('activesync_log_file'); + $this->format = $rcube->config->get('log_date_format', 'd-M-Y H:i:s O'); + $this->log_dir = $rcube->config->get('log_dir'); $r = new ReflectionClass($this); $this->_priorities = $r->getConstants(); @@ -49,6 +59,17 @@ } /** + * Check whether debug logging is enabled + * + * @return bool + */ + public function hasDebug() + { + // This is what we check in self::log() below + return !empty($this->log_dir) && $this->mode >= self::NOTICE; + } + + /** * Message logger * * @param string $message Log message @@ -56,11 +77,6 @@ */ public function log($message, $method, $extras = null) { - $rcube = rcube::get_instance(); - $logfile = $rcube->config->get('activesync_log_file'); - $format = $rcube->config->get('log_date_format', 'd-M-Y H:i:s O'); - $log_dir = $rcube->get_user_log_dir() ?: $rcube->config->get('log_dir'); - if (is_numeric($method)) { $mode = $method; $method = array_search($method, $this->_priorities); @@ -69,10 +85,20 @@ $mode = $this->_priorities$method; } + // Don't log messages with lower prio than the configured one if ($mode > $this->mode) { return; } + // Don't log debug messages if it's disabled e.g. by per_user_logging + if (empty($this->log_dir) && $mode >= self::NOTICE) { + return; + } + + $rcube = rcube::get_instance(); + $log_dir = $this->log_dir ?: $rcube->config->get('log_dir'); + $logfile = $this->logfile; + // if log_file is configured all logs will go to it // otherwise use separate file for info/debug and warning/error if (!$logfile) { @@ -121,7 +147,7 @@ } } - $date = rcube_utils::date_format($format); + $date = rcube_utils::date_format($this->format); $logline = sprintf("%s: %s %s\n", $date, $method, $message); if ($fp = @fopen($logfile, 'a')) { @@ -144,4 +170,12 @@ { $this->username = $username; } + + /** + * Set log directory + */ + public function set_log_dir($dir) + { + $this->log_dir = $dir; + } }
View file
kolab-syncroton-2.3.10.tar.gz/lib/kolab_sync_message.php -> kolab-syncroton-2.4.2.tar.gz/lib/kolab_sync_message.php
Changed
@@ -161,7 +161,7 @@ $headers = $this->headers; $mailto = $headers'To'; - $headers'User-Agent' .= $rcube->app_name . ' ' . kolab_sync::VERSION; + $headers'User-Agent' = $rcube->app_name . ' ' . kolab_sync::VERSION; if ($agent = $rcube->config->get('useragent')) { $headers'User-Agent' .= '/' . $agent; } @@ -193,75 +193,39 @@ // remove empty headers $headers = array_filter($headers); - // send thru SMTP server using custom SMTP library - if ($rcube->config->get('smtp_server')) { - $smtp_headers = $headers; - // generate list of recipients - $recipients = array(); - - if (!empty($headers'To')) - $recipients = $headers'To'; - if (!empty($headers'Cc')) - $recipients = $headers'Cc'; - if (!empty($headers'Bcc')) - $recipients = $headers'Bcc'; - - // remove Bcc header - unset($smtp_headers'Bcc'); - - // send message - if (!is_object($rcube->smtp)) { - $rcube->smtp_init(true); - } + $smtp_headers = $headers; - $sent = $rcube->smtp->send_mail($headers'From', $recipients, $smtp_headers, $this->body, $smtp_opts); - $smtp_response = $rcube->smtp->get_response(); - $smtp_error = $rcube->smtp->get_error(); + // generate list of recipients + $recipients = array(); - // log error - if (!$sent) { - rcube::raise_error(array('code' => 800, 'type' => 'smtp', - 'line' => __LINE__, 'file' => __FILE__, - 'message' => "SMTP error: ".join("\n", $smtp_response)), true, false); - } + if (!empty($headers'To')) + $recipients = $headers'To'; + if (!empty($headers'Cc')) + $recipients = $headers'Cc'; + if (!empty($headers'Bcc')) + $recipients = $headers'Bcc'; + + if (empty($headers'To') && empty($headers'Cc')) { + $headers'To' = 'undisclosed-recipients:;'; } - // send mail using PHP's mail() function - else { - $mail_headers = $headers; - $delim = $rcube->config->header_delimiter(); - $subject = $headers'Subject'; - $to = $headers'To'; - - // unset some headers because they will be added by the mail() function - unset($mail_headers'To', $mail_headers'Subject'); - - // #1485779 - if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { - if (preg_match_all('/<(^@+@^>+)>/', $to, $m)) { - $to = implode(', ', $m1); - } - } - foreach ($mail_headers as $header => $header_value) { - $mail_headers$header = $header . ': ' . $header_value; - } - $header_str = rtrim(implode("\r\n", $mail_headers)); + // remove Bcc header + unset($smtp_headers'Bcc'); - if ($delim != "\r\n") { - $header_str = str_replace("\r\n", $delim, $header_str); - $msg_body = str_replace("\r\n", $delim, $this->body); - $to = str_replace("\r\n", $delim, $to); - $subject = str_replace("\r\n", $delim, $subject); - } + // send message + if (!is_object($rcube->smtp)) { + $rcube->smtp_init(true); + } - if (ini_get('safe_mode')) { - $sent = mail($to, $subject, $msg_body, $header_str); - } - else { - $from = rcube_mime::decode_address_list($headers'From', 1, false, null, true); - $from = $from0; - $sent = mail($to, $subject, $msg_body, $header_str, "-f$from"); - } + $sent = $rcube->smtp->send_mail($headers'From', $recipients, $smtp_headers, $this->body, $smtp_opts); + $smtp_response = $rcube->smtp->get_response(); + $smtp_error = $rcube->smtp->get_error(); + + // log error + if (!$sent) { + rcube::raise_error(array('code' => 800, 'type' => 'smtp', + 'line' => __LINE__, 'file' => __FILE__, + 'message' => "SMTP error: ".join("\n", $smtp_response)), true, false); } if ($sent) { @@ -270,25 +234,20 @@ // remove MDN headers after sending unset($headers'Return-Receipt-To', $headers'Disposition-Notification-To'); - // get all recipients - if ($headers'Cc') - $mailto .= ' ' . $headers'Cc'; - if ($headers'Bcc') - $mailto .= ' ' . $headers'Bcc'; - if (preg_match_all('/<(^@+@^>+)>/', $mailto, $m)) - $mailto = implode(', ', array_unique($m1)); - if ($rcube->config->get('smtp_log')) { - rcube::write_log('sendmail', sprintf("User %s %s; Message for %s; %s", + // get all recipient addresses + $mailto = rcube_mime::decode_address_list(implode(',', $recipients), null, false, null, true); + + rcube::write_log('sendmail', sprintf("User %s %s; Message %s for %s; %s", $rcube->get_user_name(), - $_SERVER'REMOTE_ADDR', - $mailto, - !empty($smtp_response) ? join('; ', $smtp_response) : '')); + rcube_utils::remote_addr(), + $headers'Message-ID', + implode(', ', $mailto), + !empty($smtp_response) ? implode('; ', $smtp_response) : '') + ); } } - unset($headers'Bcc'); - $this->headers = $headers; return $sent; @@ -310,12 +269,12 @@ $message = stream_get_contents($message); } - list($headers, $message) = preg_split('/\r?\n\r?\n/', $message, 2, PREG_SPLIT_NO_EMPTY); + list($headers, $message) = array_pad(preg_split('/\r?\n\r?\n/', $message, 2, PREG_SPLIT_NO_EMPTY), 2, ''); $hdrs = self::parse_headers($headers); // multipart message - if (preg_match('/boundary="?(a-z0-9-\'\(\)+_\,\.\/:=\? +)"?/i', $hdrs'Content-Type', $matches)) { + if (preg_match('/boundary="?(a-z0-9-\'\(\)+_\,\.\/:=\? +)"?/i', $hdrs'Content-Type' ?? '', $matches)) { $boundary = '--' . $matches1; $message = explode($boundary, $message); @@ -327,7 +286,7 @@ } // single part - $enc = strtolower($hdrs'Content-Transfer-Encoding'); + $enc = !empty($hdrs'Content-Transfer-Encoding') ? strtolower($hdrs'Content-Transfer-Encoding') : null; // do nothing if already encoded if ($enc != 'quoted-printable' && $enc != 'base64') { @@ -347,6 +306,29 @@ } /** + * Creates a fake plain text message source with predefined headers and body + * + * @param string $headers Message headers + * @param string $body Plain text body + * + * @return string Message source + */ + public static function fake_message($headers, $body = '') + { + $hdrs = self::parse_headers($headers); + $result = ''; + + $hdrs'Content-Type' = 'text/plain; charset=UTF-8'; + $hdrs'Content-Transfer-Encoding' = 'quoted-printable'; + + foreach ($hdrs as $header => $header_value) { + $result .= $header . ': ' . $header_value . "\r\n"; + } + + return $result . "\r\n" . self::encode($body, 'quoted-printable'); + } + + /** * MIME message parser *
View file
kolab-syncroton-2.3.10.tar.gz/lib/kolab_sync_timezone_converter.php -> kolab-syncroton-2.4.2.tar.gz/lib/kolab_sync_timezone_converter.php
Changed
@@ -57,6 +57,14 @@ ) ); + + protected $_legacyTimezones = array( + // This is an outdated timezone that outlook keeps sending because of an outdate timezone database on windows + 'Lv///0kAcgBhAG4AIABTAHQAYQBuAGQAYQByAGQAIABUAGkAbQBlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkABAADABcAOwA7AOcDAAAAAEkAcgBhAG4AIABEAGEAeQBsAGkAZwBoAHQAIABUAGkAbQBlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAwAEAAAAAAAAAAAAxP///w==' => array( + 'Asia/Tehran' => '+0330' + ) + ); + /** * don't use the constructor. Use the singleton. * @@ -87,6 +95,43 @@ return self::$_instance; } + + /** + * Returns a timezone with an offset matching the time difference + * of $dt from $referenceDt. + * + * If set and matching the offset, kolab_format::$timezone is preferred. + * + * @param DateTime $dt The date time value for which we + * calculate the offset. + * @param DateTime $referenceDt The reference value, for instance in UTC. + * + * @return DateTimeZone|null + */ + public function getOffsetTimezone($dt, $referenceDt) + { + $interval = $referenceDt->diff($dt); + $tz = new DateTimeZone($interval->format('%R%H%I')); //e.g. +0200 + $utcOffset = $tz->getOffset($dt); + + //Prefer the configured timezone if it matches the offset. + if (kolab_format::$timezone) { + if (kolab_format::$timezone->getOffset($dt) == $utcOffset) { + return kolab_format::$timezone; + } + } + + //Look for any timezone with a matching offset. + foreach (DateTimeZone::listIdentifiers() as $timezoneIdentifier) { + $timezone = new DateTimeZone($timezoneIdentifier); + if ($timezone->getOffset($dt) == $utcOffset) { + return $timezone; + } + } + return null; + } + + /** * Returns a list of timezones that match to the {@param $_offsets} * @@ -103,6 +148,9 @@ if (is_string($_offsets) && isset($this->_knownTimezones$_offsets)) { $timezones = $this->_knownTimezones$_offsets; } + elseif (is_string($_offsets) && isset($this->_legacyTimezones$_offsets)) { + $timezones = $this->_legacyTimezones$_offsets; + } else { if (is_string($_offsets)) { // unpack timezone info to array @@ -114,18 +162,12 @@ } $this->_setDefaultStartDateIfEmpty($_offsets); - $cacheId = $this->_getCacheId('timezones', $_offsets); - $timezones = $this->_loadFromCache($cacheId); - - if (!is_array($timezones)) { - $timezones = array(); - foreach (DateTimeZone::listIdentifiers() as $timezoneIdentifier) { - $timezone = new DateTimeZone($timezoneIdentifier); - if (false !== ($matchingTransition = $this->_checkTimezone($timezone, $_offsets))) { - $timezones$timezoneIdentifier = $matchingTransition'abbr'; - } + $timezones = array(); + foreach (DateTimeZone::listIdentifiers() as $timezoneIdentifier) { + $timezone = new DateTimeZone($timezoneIdentifier); + if (false !== ($matchingTransition = $this->_checkTimezone($timezone, $_offsets))) { + $timezones$timezoneIdentifier = $matchingTransition'abbr'; } - $this->_saveInCache($timezones, $cacheId); } } @@ -175,6 +217,29 @@ return $this->_packTimezoneInfo($offsets); } + + /** + * Returns an encoded timezone representation from $date + * + * @param DateTime $date The date with the timezone to encode + * + * @return string encoded timezone + */ + public static function encodeTimezoneFromDate($date) + { + if ($date instanceof DateTime) { + $timezone = $date->getTimezone(); + + if ($timezone && ($tz_name = $timezone->getName()) != 'UTC') { + $tzc = self::getInstance(); + if ($tz_name = $tzc->encodeTimezone($tz_name, $date->format('Y-m-d'))) { + return $tz_name; + } + } + } + return null; + } + /** * Get offsets for given timezone * @@ -187,36 +252,30 @@ { $this->_setStartDate($_startDate); - $cacheId = $this->_getCacheId('offsets', array($_timezone)); - - if (false === ($offsets = $this->_loadFromCache($cacheId))) { - $offsets = $this->_getOffsetsTemplate(); + $offsets = $this->_getOffsetsTemplate(); - try { - $timezone = new DateTimeZone($_timezone); - } - catch (Exception $e) { - return null; - } + try { + $timezone = new DateTimeZone($_timezone); + } + catch (Exception $e) { + return null; + } - list($standardTransition, $daylightTransition) = $this->_getTransitionsForTimezoneAndYear($timezone, $this->_startDate'year'); + list($standardTransition, $daylightTransition) = $this->_getTransitionsForTimezoneAndYear($timezone, $this->_startDate'year'); - if ($standardTransition) { - $offsets'bias' = $standardTransition'offset'/60*-1; - if ($daylightTransition) { - $offsets = $this->_generateOffsetsForTransition($offsets, $standardTransition, 'standard'); - $offsets = $this->_generateOffsetsForTransition($offsets, $daylightTransition, 'daylight'); + if ($standardTransition) { + $offsets'bias' = $standardTransition'offset'/60*-1; + if ($daylightTransition) { + $offsets = $this->_generateOffsetsForTransition($offsets, $standardTransition, 'standard', $timezone); + $offsets = $this->_generateOffsetsForTransition($offsets, $daylightTransition, 'daylight', $timezone); - //@todo how do we get the standardBias (is usually 0)? - //$offsets'standardBias' = ... + //@todo how do we get the standardBias (is usually 0)? + //$offsets'standardBias' = ... - $offsets'daylightBias' = ($daylightTransition'offset' - $standardTransition'offset')/60*-1; - $offsets'standardHour' -= $offsets'daylightBias' / 60; - $offsets'daylightHour' += $offsets'daylightBias' / 60; - } + $offsets'daylightBias' = ($daylightTransition'offset' - $standardTransition'offset')/60*-1; + $offsets'standardHour' -= $offsets'daylightBias' / 60; + $offsets'daylightHour' += $offsets'daylightBias' / 60; } - - $this->_saveInCache($offsets, $cacheId); } return $offsets; @@ -225,28 +284,29 @@ /** * Get offsets for timezone transition * - * @param array $_offsets Timezone offsets - * @param array $_transition Timezone transition information - * @param string $_type 'standard' or 'daylight' + * @param array $_offsets Timezone offsets + * @param array $_transition Timezone transition information + * @param string $_type Transition type: 'standard' or 'daylight' + * @param DateTimeZone $_timezone Timezone of the transition * * @return array */ - protected function _generateOffsetsForTransition(array $_offsets, array $_transition, $_type) + protected function _generateOffsetsForTransition(array $_offsets, array $_transition, $_type, $_timezone) { - $transitionDateParsed = new DateTime($_transition'time'); + $transitionDate = new DateTime($_transition'time', $_timezone); if ($_transition'offset') { - $transitionDateParsed->modify($_transition'offset' . ' seconds');
View file
kolab-syncroton-2.3.10.tar.gz/tests/body_converter.php -> kolab-syncroton-2.4.2.tar.gz/tests/body_converter.php
Changed
@@ -1,12 +1,7 @@ <?php -class body_converter extends PHPUnit_Framework_TestCase +class body_converter extends PHPUnit\Framework\TestCase { - function setUp() - { - } - - function data_html_to_text() { return array(
View file
kolab-syncroton-2.3.10.tar.gz/tests/data.php -> kolab-syncroton-2.4.2.tar.gz/tests/data.php
Changed
@@ -1,6 +1,6 @@ <?php -class data extends PHPUnit_Framework_TestCase +class data extends PHPUnit\Framework\TestCase { /** * Test for kolab_sync_data::recurrence_to_kolab()
View file
kolab-syncroton-2.3.10.tar.gz/tests/data_calendar.php -> kolab-syncroton-2.4.2.tar.gz/tests/data_calendar.php
Changed
@@ -1,6 +1,6 @@ <?php -class data_calendar extends PHPUnit_Framework_TestCase +class data_calendar extends PHPUnit\Framework\TestCase { /** * Test for kolab_sync_data_calendar::from_kolab_alarm()
View file
kolab-syncroton-2.3.10.tar.gz/tests/data_tasks.php -> kolab-syncroton-2.4.2.tar.gz/tests/data_tasks.php
Changed
@@ -1,6 +1,6 @@ <?php -class data_tasks extends PHPUnit_Framework_TestCase +class data_tasks extends PHPUnit\Framework\TestCase { function data_prio() {
View file
kolab-syncroton-2.4.2.tar.gz/tests/globalid_converter.php
Added
@@ -0,0 +1,37 @@ +<?php + +class globalid_converter extends PHPUnit\Framework\TestCase +{ + /** + * Test GlobalObjId encoding/decoding + */ + function test_globalobjid() + { + // https://learn.microsoft.com/en-us/openspecs/exchange_server_protocols/ms-asemail/e7424ddc-dd10-431e-a0b7-5c794863370e + $input = 'BAAAAIIA4AB0xbcQGoLgCAAAAAAAAAAAAAAAAAAAAAAAAAAAMwAAAHZDYWwtVWlkAQAAAHs4MTQxMkQzQy0yQTI0LTRFOUQtQjIwRS0xMUY3QkJFOTI3OTl9AA=='; + $output = kolab_sync_data_email::decodeGlobalObjId($input); + + $this->assertSame(51, $output'bytecount'); + $this->assertSame('{81412D3C-2A24-4E9D-B20E-11F7BBE92799}', $output'uid'); + + $encoded = kolab_sync_data_email::encodeGlobalObjId($output); + $this->assertSame($encoded, $input); + + $input = 'BAAAAIIA4AB0xbcQGoLgCAfUCRDgQMnBJoXEAQAAAAAAAAAAEAAAAAvw7UtuTulOnjnjhns3jvM='; + $output = kolab_sync_data_email::decodeGlobalObjId($input); + + $this->assertSame(16, $output'bytecount'); + $this->assertSame(2004, $output'year'); + $this->assertSame(9, $output'month'); + $this->assertSame(16, $output'day'); + $this->assertSame(127373090979660000, $output'now'); + + // This is how the "now" value is interpreted + // $winSecs = (int)($output'now' / 10000000); // convert microseconds to seconds + // $unixTimestamp = ($winSecs - 11644473600); // subtract 1.1.1600 - 1.1.1970 difference in seconds + // print(date(DateTime::RFC822, $unixTimestamp)); + + $encoded = kolab_sync_data_email::encodeGlobalObjId($output); + $this->assertSame($encoded, $input); + } +}
View file
kolab-syncroton-2.3.10.tar.gz/tests/message.php -> kolab-syncroton-2.4.2.tar.gz/tests/message.php
Changed
@@ -1,12 +1,7 @@ <?php -class message extends PHPUnit_Framework_TestCase +class message extends PHPUnit\Framework\TestCase { - function setUp() - { - } - - /** * Test message parsing and headers setting */
View file
kolab-syncroton-2.3.10.tar.gz/tests/phpunit.xml -> kolab-syncroton-2.4.2.tar.gz/tests/phpunit.xml
Changed
@@ -7,8 +7,10 @@ <file>data.php</file> <file>data_calendar.php</file> <file>data_tasks.php</file> + <file>globalid_converter.php</file> <file>message.php</file> <file>timezone_converter.php</file> + <file>wbxml.php</file> </testsuite> </testsuites> </phpunit>
View file
kolab-syncroton-2.3.10.tar.gz/tests/timezone_converter.php -> kolab-syncroton-2.4.2.tar.gz/tests/timezone_converter.php
Changed
@@ -1,47 +1,75 @@ <?php -class timezone_converter extends PHPUnit_Framework_TestCase +class timezone_converter extends PHPUnit\Framework\TestCase { - function setUp() + function test_list_timezones() { - } +// date_default_timezone_set('America/Los_Angeles'); + $converter = kolab_sync_timezone_converter::getInstance(); + $output = $converter->getListOfTimezones('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAEAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAFAAEAAAAAAAAAxP///w=='); - function test_list_timezones() - { - $converter = timezone_converter_test::getInstance(); + $this->assertTrue(is_array($output)); + $this->assertSame(array(), $output); - $input = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAEAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAFAAEAAAAAAAAAxP///w=='; - $output = $converter->getListOfTimezones($input); + $converter = kolab_sync_timezone_converter::getInstance(); + $output = $converter->getListOfTimezones('xP///0MAZQBuAHQAcgBhAGwAIABFAHUAcgBvAHAAZQAgAFMAdABhAG4AZABhAHIAZAAgAFQAaQBtAGUAAAAAAAAAAAAAAAoAAAAFAAMAAAAAAAAAAAAAAEMAZQBuAHQAcgBhAGwAIABFAHUAcgBvAHAAZQAgAEQAYQB5AGwAaQBnAGgAdAAgAFQAaQBtAGUAAAAAAAAAAAAAAAMAAAAFAAIAAAAAAAAAxP///w=='); $this->assertTrue(is_array($output)); - } + $this->assertTrue(isset($output'Europe/Warsaw')); - function test_get_timezone() - { - $converter = timezone_converter_test::getInstance(); - $datetime = new DateTime('2017-01-01T12:00:00Z'); + $converter = kolab_sync_timezone_converter::getInstance(); + $output = $converter->getListOfTimezones('4AEAAFAAYQBjAGkAZgBpAGMAIABTAHQAYQBuAGQAYQByAGQAIABUAGkAbQBlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAABAAIAAAAAAAAAAAAAAFAAYQBjAGkAZgBpAGMAIABEAGEAeQBsAGkAZwBoAHQAIABUAGkAbQBlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAACAAIAAAAAAAAAxP///w=='); + + $this->assertTrue(is_array($output)); + $this->assertTrue(isset($output'America/Los_Angeles')); + + $converter = kolab_sync_timezone_converter::getInstance(); + $output = $converter->getListOfTimezones('Lv///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=='); - $offsets = $converter->getOffsetsForTimezone('UTC', $datetime); - $output = $converter->getTimezone($offsets, 'UTC'); + $this->assertTrue(is_array($output)); + $this->assertTrue(isset($output'Asia/Tehran')); - $this->assertSame('UTC', $output); + // As seen in outlook + $converter = kolab_sync_timezone_converter::getInstance(); + $output = $converter->getListOfTimezones('Lv///0kAcgBhAG4AIABTAHQAYQBuAGQAYQByAGQAIABUAGkAbQBlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkABAADABcAOwA7AOcDAAAAAEkAcgBhAG4AIABEAGEAeQBsAGkAZwBoAHQAIABUAGkAbQBlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAwAEAAAAAAAAAAAAxP///w=='); - $offsets = $converter->getOffsetsForTimezone('Europe/Warsaw', $datetime); - $output = $converter->getTimezone($offsets, 'Europe/Warsaw'); + $this->assertTrue(is_array($output)); + $this->assertTrue(isset($output'Asia/Tehran')); + } + + function data_get_timezone() + { + return + 'UTC', + 'Europe/Warsaw', + 'Europe/Zurich', + 'America/Los_Angeles', + 'Asia/Tehran', + ; + } - $this->assertSame('Europe/Warsaw', $output); + /** + * @dataProvider data_get_timezone + */ + function test_get_timezone($tzName) + { + date_default_timezone_set('America/Los_Angeles'); - $offsets = $converter->getOffsetsForTimezone('America/Los_angeles', $datetime); - $output = $converter->getTimezone($offsets, 'America/Los_Angeles'); + $converter = kolab_sync_timezone_converter::getInstance(); + $datetime = '2017-01-01T12:00:00Z'; - $this->assertSame('America/Los_Angeles', $output); + $offsets = $converter->getOffsetsForTimezone($tzName, $datetime); + $output = $converter->getTimezone($offsets, $tzName); + $this->assertSame($tzName, $output); } function test_get_offsets_for_timezone() { - $converter = timezone_converter_test::getInstance(); - $datetime = new DateTime('2017-01-01T12:00:00Z'); + date_default_timezone_set('America/Los_Angeles'); + + $converter = kolab_sync_timezone_converter::getInstance(); + $datetime = '2017-01-01T12:00:00Z'; $output = $converter->getOffsetsForTimezone('UTC', $datetime); @@ -55,11 +83,11 @@ $this->assertSame($output'standardBias', 0); $this->assertSame($output'standardMonth', 10); - $this->assertSame($output'standardDay', 5); + $this->assertSame($output'standardWeek', 5); $this->assertSame($output'standardHour', 3); $this->assertSame($output'daylightBias', -60); $this->assertSame($output'daylightMonth', 3); - $this->assertSame($output'daylightDay', 5); + $this->assertSame($output'daylightWeek', 5); $this->assertSame($output'daylightHour', 2); $output = $converter->getOffsetsForTimezone('America/Los_Angeles', $datetime); @@ -67,11 +95,11 @@ $this->assertSame($output'bias', 480); $this->assertSame($output'standardBias', 0); $this->assertSame($output'standardMonth', 11); - $this->assertSame($output'standardDay', 1); + $this->assertSame($output'standardWeek', 1); $this->assertSame($output'standardHour', 2); $this->assertSame($output'daylightBias', -60); $this->assertSame($output'daylightMonth', 3); - $this->assertSame($output'daylightDay', 2); + $this->assertSame($output'daylightWeek', 2); $this->assertSame($output'daylightHour', 2); $output = $converter->getOffsetsForTimezone('Atlantic/Azores', $datetime); @@ -79,20 +107,69 @@ $this->assertSame($output'bias', 60); $this->assertSame($output'standardBias', 0); $this->assertSame($output'standardMonth', 10); - $this->assertSame($output'standardDay', 5); + $this->assertSame($output'standardWeek', 5); $this->assertSame($output'standardHour', 1); $this->assertSame($output'daylightBias', -60); $this->assertSame($output'daylightMonth', 3); - $this->assertSame($output'daylightDay', 5); + $this->assertSame($output'daylightWeek', 5); + $this->assertSame($output'daylightHour', 0); + + //Check before dst change + $output = $converter->getOffsetsForTimezone('Asia/Tehran', $datetime); + + $this->assertSame($output'bias', -210); + $this->assertSame($output'standardBias', 0); + $this->assertSame($output'standardMonth', 9); + $this->assertSame($output'standardWeek', 3); + $this->assertSame($output'standardDayOfWeek', 4); + $this->assertSame($output'standardHour', 24); + $this->assertSame($output'daylightBias', -60); + $this->assertSame($output'daylightMonth', 3); + $this->assertSame($output'daylightWeek', 4); + $this->assertSame($output'daylightDayOfWeek', 3); + $this->assertSame($output'daylightHour', 0); + + //Check after dst change + $output = $converter->getOffsetsForTimezone('Asia/Tehran', '2023-01-01T12:00:00Z'); + + $this->assertSame($output'bias', -210); + $this->assertSame($output'standardBias', 0); + $this->assertSame($output'standardMonth', 0); + $this->assertSame($output'standardWeek', 0); + $this->assertSame($output'standardDayOfWeek', 0); + $this->assertSame($output'standardHour', 0); + $this->assertSame($output'daylightBias', 0); + $this->assertSame($output'daylightMonth', 0); + $this->assertSame($output'daylightWeek', 0); + $this->assertSame($output'daylightDayOfWeek', 0); $this->assertSame($output'daylightHour', 0); } -} -class timezone_converter_test extends kolab_sync_timezone_converter -{ - // disable cache - function getCache() + function data_timezone_conversion() + { + return array( + //Pre dst change + array('Asia/Tehran', 'Lv///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkAAgADABcAOwA7AOcDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAQAEAAAAAAAAAAAAxP///w==', '2021-07-01T12:00:00Z'), + //Post dst change + array('Asia/Tehran', 'Lv///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==', '2023-04-01T12:00:00Z'), + array('Pacific/Pago_Pago', 'lAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==', '2021-07-01T12:00:00Z'), + array('Europe/Warsaw', 'xP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAFAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAFAAIAAAAAAAAAxP///w==', '2021-07-01T12:00:00Z'), + ); + } + + /** + * @dataProvider data_timezone_conversion + */ + function test_timezone_conversion($tz, $expected, $datetime) { - return null; + $converter = kolab_sync_timezone_converter::getInstance(); + $output = $converter->encodeTimezone($tz, $datetime); + + $this->assertSame($expected, $output); +
View file
kolab-syncroton-2.4.2.tar.gz/tests/wbxml.php
Added
@@ -0,0 +1,892 @@ +<?php + +class wbxml extends PHPUnit\Framework\TestCase +{ + //function testDecode() + //{ + // //TODO input some wbxml document + // // + // $dom = new DOMDocument(); + // $dom->loadXML($lastSyncCollection'lastXML'); + // // + // try { + // $decoder = new Syncroton_Wbxml_Decoder($dom); + // $requestBody = $decoder->decode(); + // if ($this->_logger instanceof Zend_Log) { + // $requestBody->formatOutput = true; + // $this->_logger->debug(__METHOD__ . '::' . __LINE__ . " xml request:\n" . $requestBody->saveXML()); + // } + // } catch(Syncroton_Wbxml_Exception_UnexpectedEndOfFile $e) { + // $requestBody = NULL; + // } + // //TODO validate output + //} + + + + public function testEncode() + { + $outputStream = fopen("php://temp", 'r+'); + + $encoder = new Syncroton_Wbxml_Encoder($outputStream, 'UTF-8', 3); + + $xml = <<<EOF + <?xml version="1.0" encoding="utf-8"?> + <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/"> + <Sync xmlns="uri:AirSync" xmlns:AirSyncBase="uri:AirSyncBase" xmlns:Tasks="uri:Tasks"> + <Collections> + <Collection> + <SyncKey>2</SyncKey> + <CollectionId>tasksId</CollectionId> + <Commands> + <Add> + <ClientId>clientId2</ClientId> + <ApplicationData> + <Subject xmlns="uri:Tasks">task2</Subject> + <Complete xmlns="uri:Tasks">0</Complete> + <DueDate xmlns="uri:Tasks">2020-11-04T00:00:00.000Z</DueDate> + <UtcDueDate xmlns="uri:Tasks">2020-11-03T23:00:00.000Z</UtcDueDate> + </ApplicationData> + </Add> + <Add> + <ClientId>clientId3</ClientId> + <ApplicationData> + <Subject xmlns="uri:Tasks">task3</Subject> + <Complete xmlns="uri:Tasks">0</Complete> + <DueDate xmlns="uri:Tasks">2020-11-04T00:00:00.000Z</DueDate> + <UtcDueDate xmlns="uri:Tasks">2020-11-03T23:00:00.000Z</UtcDueDate> + </ApplicationData> + </Add> + </Commands> + </Collection> + </Collections> + <WindowSize>16</WindowSize> + </Sync> + EOF; + + + $dom = new DOMDocument(); + $dom->loadXML($xml); + + $encoder->encode($dom); + + rewind($outputStream); + $output = stream_get_contents($outputStream); + // print("----"); + // print(var_export($output, true)); + // print("----"); + $this->assertEquals( + base64_decode('AwFqAEVcT0sDMgABUgN0YXNrc0lkAAFWR0wDY2xpZW50SWQyAAFdAAlgA3Rhc2syAAFKAzAAAUwDMjAyMC0xMS0wNFQwMDowMDowMC4wMDBaAAFNAzIwMjAtMTEtMDNUMjM6MDA6MDAuMDAwWgABAQEAAEdMA2NsaWVudElkMwABXQAJYAN0YXNrMwABSgMwAAFMAzIwMjAtMTEtMDRUMDA6MDA6MDAuMDAwWgABTQMyMDIwLTExLTAzVDIzOjAwOjAwLjAwMFoAAQEBAQEBAABVAzE2AAEB'), + $output + ); + } + + public function testEncodeFolderSync() + { + $outputStream = fopen("php://temp", 'r+'); + + $encoder = new Syncroton_Wbxml_Encoder($outputStream, 'UTF-8', 3); + + $xml = <<<EOF + <?xml version="1.0" encoding="utf-8"?> + <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/"> + <FolderSync xmlns="uri:FolderHierarchy" xmlns:Syncroton="uri:Syncroton" xmlns:Internal="uri:Internal"> + <Status>1</Status> + <SyncKey>1</SyncKey> + <Changes> + <Count>18</Count> + <Add> + <ServerId>2685b302b79f58d2753199545e3cb8be</ServerId> + <ParentId>0</ParentId> + <DisplayName>Test2</DisplayName> + <Type>13</Type> + </Add> + <Add> + <ServerId>9770b083c68e8584f396d15a116d6608</ServerId> + <ParentId>0</ParentId> + <DisplayName>DavidCalendar</DisplayName> + <Type>13</Type> + </Add> + <Add> + <ServerId>0f66388806743c514b8063bf0dc87486</ServerId> + <ParentId>0</ParentId> + <DisplayName>SergeyCalendar</DisplayName> + <Type>13</Type> + </Add> + <Add> + <ServerId>cca1b81c734abbcd669bea90d23e08ae</ServerId> + <ParentId>0</ParentId> + <DisplayName>Calendar</DisplayName> + <Type>8</Type> + </Add> + <Add> + <ServerId>ab1ddb4ef8e8f8fcc2c9f5a7f9062452</ServerId> + <ParentId>0</ParentId> + <DisplayName>PubCal</DisplayName> + <Type>13</Type> + </Add> + <Add> + <ServerId>d98bd8721371544ed095841ead941893</ServerId> + <ParentId>0</ParentId> + <DisplayName>(david) Test2</DisplayName> + <Type>13</Type> + </Add> + <Add> + <ServerId>9e7b9656ef61d4af2fb2fdcabe600079</ServerId> + <ParentId>0</ParentId> + <DisplayName>(david) DavidCalendar</DisplayName> + <Type>13</Type> + </Add> + <Add> + <ServerId>384cf2d877c39a622fdc2a16898052e2</ServerId> + <ParentId>0</ParentId> + <DisplayName>(david) Calendar</DisplayName> + <Type>13</Type> + </Add> + <Add> + <ServerId>Contacts::Syncroton</ServerId> + <ParentId>0</ParentId> + <DisplayName>Contacts</DisplayName> + <Type>9</Type> + </Add> + <Add> + <ServerId>1bb8c55fe84d52c6968db2571f7dc124</ServerId> + <ParentId>0</ParentId> + <DisplayName>Archive</DisplayName> + <Type>12</Type> + </Add> + <Add> + <ServerId>b51abe73e9e98fe200a4afe409050502</ServerId> + <ParentId>38b950ebd62cd9a66929c89615d0fc04</ParentId> + <DisplayName>Spam</DisplayName> + <Type>12</Type> + </Add> + <Add> + <ServerId>cf529c792fc87d1f207435b3921bb02e</ServerId> + <ParentId>0</ParentId> + <DisplayName>Sent</DisplayName> + <Type>5</Type> + </Add> + <Add> + <ServerId>715ed9ea29b8a5377a69c1f758037c65</ServerId> + <ParentId>0</ParentId> + <DisplayName>Spam</DisplayName> + <Type>12</Type> + </Add> + <Add> + <ServerId>db0d959a3aeb21757f8849a830947a7a</ServerId> + <ParentId>0</ParentId> + <DisplayName>Trash</DisplayName> + <Type>4</Type> + </Add> + <Add> + <ServerId>5ac9ec2e1a9d99e2e10cabe4abf26729</ServerId> + <ParentId>0</ParentId> + <DisplayName>Drafts</DisplayName> + <Type>3</Type> + </Add> + <Add> + <ServerId>38b950ebd62cd9a66929c89615d0fc04</ServerId> + <ParentId>0</ParentId> + <DisplayName>INBOX</DisplayName> + <Type>2</Type> + </Add> + <Add> + <ServerId>fc56f4c7ffe0aefa622db9f8d9186c4a</ServerId> + <ParentId>0</ParentId> + <DisplayName>Notes</DisplayName> + <Type>10</Type> + </Add>
View file
kolab-syncroton.dsc
Changed
@@ -2,15 +2,15 @@ Source: kolab-syncroton Binary: kolab-syncroton Architecture: all -Version: 2.3.10-0~kolab1 -Maintainer: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> -Uploaders: Paul Klos <kolab@klos2day.nl> +Version: 1:2.4.2.10-1~kolab1 +Maintainer: Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> +Uploaders: Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> Homepage: http://www.kolab.org/ Standards-Version: 3.9.3 Vcs-Git: http://git.kolab.org/kolab-syncroton -Build-Depends: debhelper (>= 8), po-debconf +Build-Depends: debhelper (>= 8), po-debconf, psa | bash Package-List: kolab-syncroton deb utils extra Files: - 00000000000000000000000000000000 0 kolab-syncroton-2.3.10.tar.gz + 00000000000000000000000000000000 0 kolab-syncroton-2.4.0.tar.gz 00000000000000000000000000000000 0 debian.tar.gz
View file
kolab-syncroton.logrotate
Changed
@@ -1,4 +1,4 @@ -/var/log/kolab-syncroton/console /var/log/kolab-syncroton/errors /var/log/kolab-syncroton/imap /var/log/kolab-syncroton/ldap /var/log/kolab-syncroton/sendmail /var/log/kolab-syncroton/sieve /var/log/kolab-syncroton/smtp /var/log/kolab-syncroton/sql /var/log/kolab-syncroton/userlogins { +/var/log/kolab-syncroton/*.log { missingok compress notifempty
View file
plesk.kolab_syncroton.inc.php
Added
@@ -0,0 +1,123 @@ +<?php + +// This file lists all ActiveSync-related configuration options + +// Enables ActiveSync protocol debuging +$config'activesync_debug' = false; + +// If specified all ActiveSync-related logs will be saved to this file +// Note: This doesn't change Roundcube Framework log locations +$config'activesync_log_file' = null; + +// Type of ActiveSync cache. Supported values: 'db', 'apc' and 'memcache'. +// Note: This is only for some additional data like timezones mapping. +$config'activesync_cache' = 'db'; + +// lifetime of ActiveSync cache +// possible units: s, m, h, d, w +$config'activesync_cache_ttl' = '1d'; + +// Type of ActiveSync Auth cache. Supported values: 'db', 'apc' and 'memcache'. +// Note: This is only for username canonification map. +$config'activesync_auth_cache' = 'db'; + +// lifetime of ActiveSync Auth cache +// possible units: s, m, h, d, w +$config'activesync_auth_cache_ttl' = '1d'; + +// List of global addressbooks (GAL) +// Note: If empty 'autocomplete_addressbooks' setting will be used +$config'activesync_addressbooks' = array(); + +// ActiveSync => Roundcube contact fields map for GAL search +/* Default: array( + 'alias' => 'nickname', + 'company' => 'organization', + 'displayName' => 'name', + 'emailAddress' => 'email', + 'firstName' => 'firstname', + 'lastName' => 'surname', + 'mobilePhone' => 'phone.mobile', + 'office' => 'office', + 'picture' => 'photo', + 'phone' => 'phone', + 'title' => 'jobtitle', +); +*/ +$config'activesync_gal_fieldmap' = null; + +// List of device types that will sync the LDAP addressbook(s) as a normal folder. +// For devices that do not support GAL searching, e.g. Outlook. +// Note: To make the LDAP addressbook sources working we need two additional +// fields ('uid' and 'changed') specified in the fieldmap array +// of the LDAP configuration ('ldap_public' option). For example: +// 'uid' => 'nsuniqueid', +// 'changed' => 'modifytimestamp', +// Examples: +// array('windowsoutlook') # enable for Oultook only +// true # enable for all +$config'activesync_gal_sync' = false; + +// GAL cache. As reading all contacts from LDAP may be slow, caching is recommended. +$config'activesync_gal_cache' = 'db'; + +// TTL of GAL cache entries. Technically this causes that synchronized +// contacts will not be updated (queried) often than the specified interval. +$config'activesync_gal_cache_ttl' = '1d'; + +// List of Roundcube plugins +// WARNING: Not all plugins used in Roundcube can be listed here +$config'activesync_plugins' = array( + 'libcalendaring', + 'libkolab' +); + +// Defines for how many seconds we'll sleep between every +// action for detecting changes in folders. Default: 60 +$config'activesync_ping_timeout' = 60; + +// Defines maximum Ping interval in seconds. Default: 900 (15 minutes) +$config'activesync_ping_interval' = 900; + +// We start detecting changes n seconds since the last sync of a folder +// Default: 180 +$config'activesync_quiet_time' = 0; + +// Defines maximum number of folders in a single Sync/Ping request. Default: 100. +$config'activesync_max_folders' = 100; + +// When a device is reqistered, by default a set of folders are +// subscribed for syncronization, i.e. INBOX and personal folders with +// defined folder type: +// mail.drafts, mail.wastebasket, mail.sentitems, mail.outbox, +// event, event.default, +// contact, contact.default, +// task, task.default +// This default set can be extended by adding following values: +// 1 - all subscribed folders in personal namespace +// 2 - all folders in personal namespace +// 4 - all subscribed folders in other users namespace +// 8 - all folders in other users namespace +// 16 - all subscribed folders in shared namespace +// 32 - all folders in shared namespace +$config'activesync_init_subscriptions' = 21; + +// Defines blacklist of devices (device type strings) that do not support folder hierarchies. +// When set to an array folder hierarchies are used on all devices not listed here. +// When set to null an old whitelist approach will be used where we do opposite +// action and enable folder hierarchies only on device types known to support it. +$config'activesync_multifolder_blacklist' = array(); + +// Blacklist overwrites for specified object type. If set to an array +// it will have a precedence over 'activesync_multifolder_blacklist' list only for that type. +// Note: Outlook does not support multiple folders for contacts, +// in that case use $config'activesync_multifolder_blacklist_contact' = array('windowsoutlook'); +$config'activesync_multifolder_blacklist_mail' = null; +$config'activesync_multifolder_blacklist_event' = null; +$config'activesync_multifolder_blacklist_contact' = array('windowsoutlook'); +$config'activesync_multifolder_blacklist_note' = null; +$config'activesync_multifolder_blacklist_task' = null; + +// Enables adding sender name in the From: header of send email +// when a device uses email address only (e.g. iOS devices) +$config'activesync_fix_from' = true;
View file
release.sh
Added
@@ -0,0 +1,15 @@ +#!/bin/bash + +./buildtarball.sh + +# Autobump the version +CURRENT_VERSION=$(grep '^Version: ' ./*.spec | sed 's/Version: //') +NEW_VERSION=$(echo "$CURRENT_VERSION" | awk -F. '/0-9+\./{$NF++;print}' OFS=.) +echo "Bumping from $CURRENT_VERSION to $NEW_VERSION" + +sed -i "s/$CURRENT_VERSION/$NEW_VERSION/" debian.changelog +sed -i "s/^Version:.*/Version: 1:$NEW_VERSION-1~kolab1/" ./*.dsc +sed -i "s/^Version:.*/Version: $NEW_VERSION/" ./*.spec + +osc ci -m "New release $NEW_VERSION" +osc sr Kolab:16 --yes -m "New release $NEW_VERSION"
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
.