Projects
Kolab:16
kolab-syncroton
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 70
View file
kolab-syncroton.spec
Changed
@@ -17,6 +17,12 @@ %{!?php_inidir: %global php_inidir %{_sysconfdir}/php.d} +%if 0%{?suse_version} < 1 && 0%{?fedora} < 1 && 0%{?rhel} < 7 +%global with_systemd 0 +%else +%global with_systemd 1 +%endif + %if 0%{?suse_version} %global httpd_group www %global httpd_name apache2 @@ -37,7 +43,7 @@ %global upstream_version 2.4.2 Name: kolab-syncroton -Version: 2.4.2.28 +Version: 2.4.2.31 Release: 1%{?dist} Summary: ActiveSync for Kolab Groupware @@ -165,7 +171,7 @@ %post if -f "%{php_inidir}/apc.ini" -o -f "%{php_inidir}/apcu.ini" ; then if ! -z "`grep ^apc.enabled=1 %{php_inidir}/apc{,u}.ini 2>/dev/null`" ; then -%if 0%{?fedora} > 15 +%if 0%{?with_systemd} /bin/systemctl condrestart %{httpd_name}.service %else /sbin/service %{httpd_name} condrestart @@ -177,6 +183,27 @@ /bin/systemctl reload php-fpm.service || : fi +if -f "/usr/lib/systemd/system/plesk-php74-fpm.service" ; then + /bin/systemctl reload plesk-php74-fpm.service || : +fi + +if -f "/usr/lib/systemd/system/plesk-php80-fpm.service" ; then + /bin/systemctl reload plesk-php80-fpm.service || : +fi + +if -f "/usr/lib/systemd/system/plesk-php81-fpm.service" ; then + /bin/systemctl reload plesk-php81-fpm.service || : +fi + +if -f "/usr/lib/systemd/system/plesk-php82-fpm.service" ; then + /bin/systemctl reload plesk-php82-fpm.service || : +fi + +if -f "/usr/lib/systemd/system/plesk-php83-fpm.service" ; then + /bin/systemctl reload plesk-php83-fpm.service || : +fi + + %if 0%{?plesk} > 0 && 0%{?rhel} == 7 php="/opt/plesk/php/7.4/bin/php"
View file
debian.changelog
Changed
@@ -1,4 +1,4 @@ -kolab-syncroton (2.4.2.28-0~kolab1) unstable; urgency=low +kolab-syncroton (2.4.2.31-0~kolab1) unstable; urgency=low * Release version 2.4.2
View file
kolab-syncroton-2.4.2.tar.gz/bin/delete-device.php
Added
@@ -0,0 +1,97 @@ +#!/usr/bin/env php +<?php +/* + +--------------------------------------------------------------------------+ + | Kolab Sync (ActiveSync for Kolab) | + | | + | Copyright (C) 2024, Apheleia IT AG <contact@apheleia-it.ch> | + | | + | This program is free software: you can redistribute it and/or modify | + | it under the terms of the GNU Affero General Public License as published | + | by the Free Software Foundation, either version 3 of the License, or | + | (at your option) any later version. | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU Affero General Public License for more details. | + | | + | You should have received a copy of the GNU Affero General Public License | + | along with this program. If not, see <http://www.gnu.org/licenses/> | + +--------------------------------------------------------------------------+ + | Author: Christian Mollekopf <mollekopf@apheleia-it.ch> | + +--------------------------------------------------------------------------+ +*/ + + +define('RCUBE_INSTALL_PATH', realpath(dirname(__FILE__) . '/../') . '/'); +define('RCUBE_PLUGINS_DIR', RCUBE_INSTALL_PATH . 'lib/plugins/'); + +// Define include path +$include_path = RCUBE_INSTALL_PATH . 'lib' . PATH_SEPARATOR; +$include_path .= RCUBE_INSTALL_PATH . 'lib/ext' . PATH_SEPARATOR; +$include_path .= ini_get('include_path'); +set_include_path($include_path); + +// include composer autoloader (if available) +if (@file_exists(RCUBE_INSTALL_PATH . 'vendor/autoload.php')) { + require RCUBE_INSTALL_PATH . 'vendor/autoload.php'; +} + +// include global functions from Roundcube Framework +require_once 'Roundcube/bootstrap.php'; + +$opts = rcube_utils::get_opt( + 's' => 'since', // Deletes *all* devices that haven't been used since the given timestamp. Doesn't take owner and device id into account. Timestamp format e.g.: "2024-11-01" + 'o' => 'owner', + 'd' => 'deviceid', +); + +$rcube = \rcube::get_instance(); +$db = $rcube->get_dbh(); + +if (!empty($opts'since')) { + $since = $opts'since'; + $since = new DateTime($since); + print("Removing all devices that haven't been used since: " . $since->format('Y-m-d H:i:s') . "\n"); + + $db->query( + "DELETE FROM `syncroton_device`" + . " WHERE `lastping` < ? OR `lastping` = NULL", + $since->format('Y-m-d H:i:s') + ); + return; +} + +if (empty($opts'deviceid')) { + rcube::raise_error("Device id not specified (--deviceid).", false, true); +} +$device = $opts'deviceid'; + +if (empty($opts'owner')) { + rcube::raise_error("owner not specified (--owner).", false, true); +} +$owner = $opts'owner'; + +$select = $db->query( + "SELECT `user_id` FROM `users`" + . " WHERE `username` = ?" + . " ORDER BY `user_id` DESC", + \strtolower($owner) +); + +if ($data = $db->fetch_assoc($select)) { + $userid = $data'user_id'; +} else { + rcube::raise_error("User not found in roundcube database, aborting: $email.", false, true); +} + +print("Found the user with id: $userid\n"); + +$db->query( + "DELETE FROM syncroton_device WHERE owner_id = ? AND deviceid = ?", + $userid, + $device +); + +print("Deleted the device with the deviceid: $deviceid\n");
View file
kolab-syncroton-2.4.2.tar.gz/bin/inspect.php
Changed
@@ -51,18 +51,27 @@ rcube::raise_error("Email address not specified (--email).", false, true); } $email = $opts'email'; -if (empty($opts'adminpassword')) { - rcube::raise_error("Admin password not specified (--adminpassword).", false, true); + +$proxyAuth = false; +if ($password = $opts'adminpassword') { + $proxyAuth = true; + $user = "cyrus-admin"; +} else { + $password = $opts'password'; +} + +if (empty($password)) { + rcube::raise_error("Password not specified (--adminpassword/--password).", false, true); } -$password = $opts'adminpassword'; $rcube = rcube::get_instance(); $default_port = $rcube->config->get('default_port', 143); $default_host = $rcube->config->get('default_host'); -$user = "cyrus-admin"; $imap = new \rcube_imap_generic(); -$options'auth_cid' = $user; -$options'auth_pw' = $password; +if ($proxyAuth) { + $options'auth_cid' = $user; + $options'auth_pw' = $password; +} $options'auth_type' = 'PLAIN'; $options'port' = $default_port; $options'socket_options' = @@ -96,7 +105,7 @@ if ($data = $db->fetch_assoc($select)) { $userid = $data'user_id'; } else { - rcube::raise_error("User not found: $email.", false, true); + rcube::raise_error("User not found in roundcube database (only available after first login): $email.", false, true); } print("Found the user with id: $userid\n"); @@ -217,7 +226,7 @@ foreach ($values'folders' ?? as $folderId => $folder) { println(" " . $folder'name' . " ($folderId)"); $messageCount = $folder'contentCount'; - $totalCount = $folder'imapMessagecount'; + $totalCount = $folder'imapMessagecount' ?? "unknown"; $modseq = $folder'modseq' ?? "none"; $imapModseq = $folder'imapModseq'; // We're not using modseq for groupware folders
View file
kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Server.php
Changed
@@ -52,7 +52,10 @@ $this->_request = $request instanceof Zend_Controller_Request_Http ? $request : new Zend_Controller_Request_Http(); $this->_body = $body !== null ? $body : fopen('php://input', 'r'); - $this->_deviceBackend = Syncroton_Registry::getDeviceBackend(); + // Not available on unauthenticated OPTIONS request + if (!empty($this->_userId)) { + $this->_deviceBackend = Syncroton_Registry::getDeviceBackend(); + } } @@ -62,6 +65,13 @@ $this->_logger->debug(__METHOD__ . '::' . __LINE__ . ' REQUEST METHOD: ' . $this->_request->getMethod()); } + if ($this->_request->getMethod() != "OPTIONS" && empty($this->_userId)) { + $this->_logger->warn(__METHOD__ . '::' . __LINE__ . ' Not authenticated'); + header('WWW-Authenticate: Basic realm="ActiveSync for Kolab"'); + header('HTTP/1.1 401 Unauthorized'); + exit; + } + switch($this->_request->getMethod()) { case 'OPTIONS': $this->_handleOptions();
View file
kolab-syncroton-2.4.2.tar.gz/lib/kolab_sync.php
Changed
@@ -135,12 +135,6 @@ $userid = $this->authenticate($_SERVER'PHP_AUTH_USER', $_SERVER'PHP_AUTH_PW'); } - if (empty($userid)) { - header('WWW-Authenticate: Basic realm="' . $this->app_name . '"'); - header('HTTP/1.1 401 Unauthorized'); - exit; - } - $this->plugins->exec_hook('ready', 'task' => 'syncroton'); // Set log directory per-user (again, in case the username changed above) @@ -153,12 +147,15 @@ Syncroton_Registry::set(Syncroton_Registry::LOGGERBACKEND, $this->logger); Syncroton_Registry::set(Syncroton_Registry::DATABASE, $this->get_dbh()); Syncroton_Registry::set(Syncroton_Registry::TRANSACTIONMANAGER, kolab_sync_transaction_manager::getInstance()); - Syncroton_Registry::set(Syncroton_Registry::DEVICEBACKEND, new kolab_sync_backend_device()); - Syncroton_Registry::set(Syncroton_Registry::FOLDERBACKEND, new kolab_sync_backend_folder()); - Syncroton_Registry::set(Syncroton_Registry::SYNCSTATEBACKEND, new kolab_sync_backend_state()); - Syncroton_Registry::set(Syncroton_Registry::CONTENTSTATEBACKEND, new kolab_sync_backend_content()); - Syncroton_Registry::set(Syncroton_Registry::POLICYBACKEND, new kolab_sync_backend_policy()); - Syncroton_Registry::set(Syncroton_Registry::SLEEP_CALLBACK, $this, 'sleep'); + // The unauthenticated OPTIONS request doesn't require these backends and we can't instantiate them without credentials for the underlying storage backend + if (!empty($userid)) { + Syncroton_Registry::set(Syncroton_Registry::DEVICEBACKEND, new kolab_sync_backend_device()); + Syncroton_Registry::set(Syncroton_Registry::FOLDERBACKEND, new kolab_sync_backend_folder()); + Syncroton_Registry::set(Syncroton_Registry::SYNCSTATEBACKEND, new kolab_sync_backend_state()); + Syncroton_Registry::set(Syncroton_Registry::CONTENTSTATEBACKEND, new kolab_sync_backend_content()); + Syncroton_Registry::set(Syncroton_Registry::POLICYBACKEND, new kolab_sync_backend_policy()); + Syncroton_Registry::set(Syncroton_Registry::SLEEP_CALLBACK, $this, 'sleep'); + } Syncroton_Registry::setContactsDataClass('kolab_sync_data_contacts'); Syncroton_Registry::setCalendarDataClass('kolab_sync_data_calendar');
View file
kolab-syncroton-2.4.2.tar.gz/lib/kolab_sync_storage.php
Changed
@@ -1572,7 +1572,7 @@ // FIXME: The one caveat is that we will still update the database and thus overwrite the old entry. // That means if we rerun the same request, the changes will not be detected // => We should not be dealing with timestamps really. - $this->relations$folderid$sinceFormatted . "-1" = $this->relations$folderid$sinceFormatted; + $this->relations$folderid$sinceFormatted . "-1" = $this->relations$folderid$sinceFormatted ?? null; $this->relations$folderid$sinceFormatted = null; } @@ -1968,7 +1968,7 @@ $db->limitquery( "SELECT `data`, `synctime` FROM `syncroton_relations_state`" - . " WHERE `device_id` = ? AND `folder_id` = ? AND `synctime` <= ?" + . " WHERE `device_id` = ? AND `folder_id` = ? AND `synctime` < ?" . " ORDER BY `synctime` DESC", 0, 1, @@ -1986,9 +1986,13 @@ // Cleanup: remove all records older than the current one. // We must use the row's synctime, otherwise we would delete the record we just loaded + // We must delete all entries that are before the synctime to clean up old entries, + // but we must also delete all entries that are more recent in case the sync gets rerun + // with the same timestamp (e.g. when rerunning the same sync request). + // Otherwise the number of entries will start to grow with every sync. $db->query( "DELETE FROM `syncroton_relations_state`" - . " WHERE `device_id` = ? AND `folder_id` = ? AND `synctime` < ?", + . " WHERE `device_id` = ? AND `folder_id` = ? AND `synctime` <> ?", $device_key, $folderid, $row'synctime'
View file
kolab-syncroton-2.4.2.tar.gz/tests/Sync/OptionsTest.php
Changed
@@ -7,7 +7,7 @@ */ public function testOptions() { - $response = self::$client->request('OPTIONS', ''); + $response = self::$client->request('OPTIONS', '', 'auth' => null); $this->assertEquals(200, $response->getStatusCode()); $this->assertStringContainsString('14', $response->getHeader('MS-Server-ActiveSync')0); $this->assertStringContainsString('14.1', $response->getHeader('MS-ASProtocolVersions')0);
View file
kolab-syncroton-2.4.2.tar.gz/tests/Sync/Sync/RelationsTest.php
Changed
@@ -125,35 +125,45 @@ //FIXME not sure what I'm doing wrong, but the xml looks ok $this->assertSame("test1test2", $xpath->query("{$root}/ns:ApplicationData/Email:Categories")->item(0)->nodeValue); - //Rerun the same command and make sure we get the same result + $retries = 2; $syncKey--; - $root = "//ns:Sync/ns:Collections/ns:Collection"; - $this->assertSame('1', $xpath->query("{$root}/ns:Status")->item(0)->nodeValue); - $this->assertSame(strval(++$syncKey), $xpath->query("{$root}/ns:SyncKey")->item(0)->nodeValue); - $this->assertSame($folderId, $xpath->query("{$root}/ns:CollectionId")->item(0)->nodeValue); - $this->assertSame(0, $xpath->query("{$root}/ns:Commands/ns:Add")->count()); - $this->assertSame(1, $xpath->query("{$root}/ns:Commands/ns:Change")->count()); - $root .= "/ns:Commands/ns:Change"; - $this->assertSame(1, $xpath->query("{$root}/ns:ApplicationData/Email:Categories")->count()); - //FIXME not sure what I'm doing wrong, but the xml looks ok - $this->assertSame("test1test2", $xpath->query("{$root}/ns:ApplicationData/Email:Categories")->item(0)->nodeValue); - - - // Assert the db state - $rcube = \rcube::get_instance(); - $db = $rcube->get_dbh(); - $result = $db->query( - "SELECT `data`, `synctime` FROM `syncroton_relations_state`" - . " WHERE `device_id` = ? AND `folder_id` = ?" - . " ORDER BY `synctime` DESC", - $device'ID', - $folderId - ); - $data = ; - while ($state = $db->fetch_assoc($result)) { - $data = $state; + // Rerun the same command and make sure we get the same result + for ($i = 0; $i < $retries; $i++) { + $response = $this->syncRequest($syncKey, $folderId, 10); + $this->assertEquals(200, $response->getStatusCode()); + $dom = $this->fromWbxml($response->getBody()); + $xpath = $this->xpath($dom); + + $root = "//ns:Sync/ns:Collections/ns:Collection"; + $this->assertSame('1', $xpath->query("{$root}/ns:Status")->item(0)->nodeValue); + $this->assertSame($folderId, $xpath->query("{$root}/ns:CollectionId")->item(0)->nodeValue); + $this->assertSame(0, $xpath->query("{$root}/ns:Commands/ns:Add")->count()); + $this->assertSame(1, $xpath->query("{$root}/ns:Commands/ns:Change")->count()); + $root .= "/ns:Commands/ns:Change"; + $this->assertSame(1, $xpath->query("{$root}/ns:ApplicationData/Email:Categories")->count()); + //FIXME not sure what I'm doing wrong, but the xml looks ok + $this->assertSame("test1test2", $xpath->query("{$root}/ns:ApplicationData/Email:Categories")->item(0)->nodeValue); + + // Assert the db state + $rcube = \rcube::get_instance(); + $db = $rcube->get_dbh(); + $result = $db->query( + "SELECT `data`, `synctime` FROM `syncroton_relations_state`" + . " WHERE `device_id` = ? AND `folder_id` = ?" + . " ORDER BY `synctime` DESC", + $device'ID', + $folderId + ); + $data = ; + while ($state = $db->fetch_assoc($result)) { + $data = $state; + } + $this->assertSame(2, count($data)); + // Make sure we have a new timestamp after the first iteration. + // This way we can potentially catch errors when we end up using the same or a different timestamp. + sleep(1); } - $this->assertSame(2, count($data)); + $syncKey += ($retries + 1); // Reset to no tags $sync->storage()->updateItem($folderId, $device'ID', \kolab_sync_storage::MODEL_EMAIL, $uid1, null, 'categories' => );
View file
kolab-syncroton.dsc
Changed
@@ -2,7 +2,7 @@ Source: kolab-syncroton Binary: kolab-syncroton Architecture: all -Version: 1:2.4.2.28-1~kolab1 +Version: 1:2.4.2.31-1~kolab1 Maintainer: Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> Uploaders: Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> Homepage: http://www.kolab.org/
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.