Projects
Kolab:16:Testing
kolab-syncroton
Log In
Username
Password
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 68
View file
kolab-syncroton.spec
Changed
@@ -43,7 +43,7 @@ %global upstream_version 2.4.2 Name: kolab-syncroton -Version: 2.4.2.41 +Version: 2.4.2.42 Release: 1%{?dist} Summary: ActiveSync for Kolab Groupware
View file
debian.changelog
Changed
@@ -1,4 +1,4 @@ -kolab-syncroton (2.4.2.41-0~kolab1) unstable; urgency=low +kolab-syncroton (2.4.2.42-0~kolab1) unstable; urgency=low * Release version 2.4.2
View file
kolab-syncroton-2.4.2.tar.gz/bin/analyzelogs.php
Changed
@@ -45,7 +45,7 @@ $content = file_get_contents($filename); // Split up the log files into chunks that hopefully match the commands -$parts = preg_split("/\.*\: " . preg_quote("DEBUG Syncroton_Server::handle::65 REQUEST METHOD: POST", '/') . "/", $content, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); +$parts = preg_split("/\.*\: " . preg_quote("DEBUG", '/') . " Syncroton_Server::handle::\d+ REQUEST METHOD: POST/", $content, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); function getStatusConstants($classname) {
View file
kolab-syncroton-2.4.2.tar.gz/config/config.inc.php.dist
Changed
@@ -119,3 +119,8 @@ // 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' = false; + +// Force a subscription state per folder +// The following configuration is recommended for Outlook. +// States can be: 0 => not subscribed, 1 => subscribed, 2 => subscribed with alarm +$config'activesync_force_subscription_state' = 'INBOX' => 1, 'Sent' => 1, 'Trash' => 1, 'Calendar' => 1, 'Contacts' => 1, 'Tasks' => 1;
View file
kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Command/Ping.php
Changed
@@ -37,6 +37,23 @@ protected $_changesDetected = false; protected $_foldersWithChanges = ; + private function goToSleep($sleepInterval) { + // take a break to save battery lifetime + call_user_func(Syncroton_Registry::getSleepCallback()); + sleep($sleepInterval); + + // make sure the connection is still alive, abort otherwise + if (connection_aborted()) { + if ($this->_logger instanceof Zend_Log) { + $this->_logger->debug(__METHOD__ . '::' . __LINE__ . " Exiting on aborted connection"); + } + exit; + } + + // reconnect external connections, etc. + call_user_func(Syncroton_Registry::getWakeupCallback()); + } + /** * process the XML file and add, change, delete or fetches data * @@ -48,6 +65,7 @@ $intervalStart = time(); $status = self::STATUS_NO_CHANGES_FOUND; + $pingTimeout = Syncroton_Registry::getPingTimeout(); // the client does not send a wbxml document, if the Ping parameters did not change compared with the last request if ($this->_requestBody instanceof DOMDocument) { $xml = simplexml_import_dom($this->_requestBody); @@ -55,6 +73,11 @@ if (isset($xml->HeartbeatInterval)) { $this->_device->pinglifetime = (int)$xml->HeartbeatInterval; + // Magic value for testing + if ($this->_device->pinglifetime == 9999) { + $pingTimeout = 1; + $this->_device->pinglifetime = 900; + } } if (isset($xml->Folders->Folder)) { @@ -110,7 +133,6 @@ } $intervalEnd = $intervalStart + $lifeTime; - $secondsLeft = $intervalEnd; $folders = $this->_device->pingfolder ? unserialize($this->_device->pingfolder) : ; @@ -123,29 +145,7 @@ } if ($status === self::STATUS_NO_CHANGES_FOUND) { - $sleepCallback = Syncroton_Registry::getSleepCallback(); - $wakeupCallback = Syncroton_Registry::getWakeupCallback(); - do { - // take a break to save battery lifetime - call_user_func($sleepCallback); - sleep(min(Syncroton_Registry::getPingTimeout(), $lifeTime)); - - // make sure the connection is still alive, abort otherwise - if (connection_aborted()) { - if ($this->_logger instanceof Zend_Log) { - $this->_logger->debug(__METHOD__ . '::' . __LINE__ . " Exiting on aborted connection"); - } - exit; - } - - // 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 { /** @var Syncroton_Model_Device $device */ $device = $this->_deviceBackend->get($this->_device->id); @@ -259,7 +259,6 @@ break; } - // Update secondsLeft (again) $secondsLeft = $intervalEnd - time(); if ($this->_logger instanceof Zend_Log) { @@ -271,9 +270,16 @@ // break if there are less than PingTimeout + 10 seconds left for the next loop // otherwise the response will be returned after the client has finished his Ping // request already maybe - } while (Syncroton_Server::validateSession() && $secondsLeft > (Syncroton_Registry::getPingTimeout() + 10)); + if ($secondsLeft < ($pingTimeout + 10)) { + break; + } else { + $this->goToSleep($pingTimeout); + } + + } while (Syncroton_Server::validateSession()); } + $secondsLeft = $intervalEnd - time(); if ($this->_logger instanceof Zend_Log) { $this->_logger->info(__METHOD__ . '::' . __LINE__ . " DeviceId: " . $this->_device->deviceid . " Lifetime: $lifeTime SecondsLeft: $secondsLeft Status: $status)"); }
View file
kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Model/IContent.php
Changed
@@ -22,6 +22,8 @@ * @property DateTime $creation_time * @property string $creation_synckey * @property string $is_deleted + * + * @phpstan-require-extends Syncroton_Model_Content */ interface Syncroton_Model_IContent {
View file
kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Model/IDevice.php
Changed
@@ -38,6 +38,8 @@ * @property string $emailfilter_id * @property string $lastsynccollection * @property DateTime $lastping + * + * @phpstan-require-extends Syncroton_Model_Device */ interface Syncroton_Model_IDevice extends Syncroton_Model_IEntry {
View file
kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Model/IFolder.php
Changed
@@ -25,6 +25,8 @@ * @property int $creationSynckey * @property int $lastfiltertype * @property int $type + * + * @phpstan-require-extends Syncroton_Model_Folder */ interface Syncroton_Model_IFolder {
View file
kolab-syncroton-2.4.2.tar.gz/lib/ext/Syncroton/Model/ISyncState.php
Changed
@@ -23,6 +23,8 @@ * @property ?array $pendingdata * @property string $clientIdMap JSON-encoded array * @property string $extraData JSON-encoded array + * + * @phpstan-require-extends Syncroton_Model_SyncState */ interface Syncroton_Model_ISyncState {
View file
kolab-syncroton-2.4.2.tar.gz/lib/kolab_sync_backend_folder.php
Changed
@@ -144,8 +144,12 @@ Syncroton_Data_Factory::CLASS_TASKS, ; - // Reset imap cache so we work with up-to-date folders list + // Reset imap cache, metadata cache and the folder list cache so we work with up-to-date folders lists rcube::get_instance()->get_storage()->clear_cache('mailboxes', true); + kolab_sync::storage()->reset(); + foreach ($folder_classes as $class) { + Syncroton_Data_Factory::factory($class, $device, $timestamp)->clearCache(); + } // Retrieve all folders already sent to the client $select = $this->db->query("SELECT * FROM `{$this->table_name}` WHERE `device_id` = ?", $device->id);
View file
kolab-syncroton-2.4.2.tar.gz/lib/kolab_sync_data.php
Changed
@@ -748,6 +748,14 @@ } /** + * Clear the internal folder list cache + */ + public function clearCache() + { + $this->folders = ; + } + + /** * List of all IMAP folders (or subtree) * * @param string $parentid Parent folder identifier
View file
kolab-syncroton-2.4.2.tar.gz/lib/kolab_sync_storage.php
Changed
@@ -59,6 +59,7 @@ protected $relationSupport = self::MODEL_TASKS, self::MODEL_NOTES, self::MODEL_EMAIL; protected $tag_rts = ; private $modseq = ; + private $protectedFolders = null; protected static $instance; @@ -124,6 +125,7 @@ public function reset() { $this->folders = ; + $this->folder_meta = null; } /** @@ -174,9 +176,7 @@ // check if folders are "subscribed" for activesync foreach ($folderdata as $folder => $meta) { - if (empty($meta'FOLDER') || empty($meta'FOLDER'$deviceid) - || empty($meta'FOLDER'$deviceid'S') - ) { + if (!$this->is_subscribed($deviceid, $folder, $meta)) { continue; } @@ -1871,6 +1871,27 @@ return $this->folder_uids$name = $uid; } + private function is_protected($folder) + { + if ($this->protectedFolders === null) { + $this->protectedFolders = rcube::get_instance()->config->get('activesync_force_subscription_state', ); + } + return array_key_exists($folder, $this->protectedFolders); + } + + protected function is_subscribed($deviceid, $folder, $meta) + { + if ($this->is_protected($folder)) { + return true; + } + if (empty($meta'FOLDER') || empty($meta'FOLDER'$deviceid) + || empty($meta'FOLDER'$deviceid'S') + ) { + return false; + } + return true; + } + /** * Returns IMAP folder name * @@ -1914,9 +1935,7 @@ // check if folders are "subscribed" for activesync foreach ($folderdata as $folder => $meta) { - if (empty($meta'FOLDER') || empty($meta'FOLDER'$deviceid) - || empty($meta'FOLDER'$deviceid'S') - ) { + if (!$this->is_subscribed($deviceid, $folder, $meta)) { continue; }
View file
kolab-syncroton-2.4.2.tar.gz/lib/kolab_sync_storage_kolab4.php
Changed
@@ -111,9 +111,7 @@ // Get the folders "subscribed" for activesync foreach ($folderdata as $folder => $meta) { - if (empty($meta'FOLDER') || empty($meta'FOLDER'$deviceid) - || empty($meta'FOLDER'$deviceid'S') - ) { + if (!$this->is_subscribed($deviceid, $folder, $meta)) { continue; } @@ -448,9 +446,7 @@ // check if folders are "subscribed" for activesync foreach ($folderdata as $folder => $meta) { - if (empty($meta'FOLDER') || empty($meta'FOLDER'$deviceid) - || empty($meta'FOLDER'$deviceid'S') - ) { + if (!$this->is_subscribed($deviceid, $folder, $meta)) { continue; }
View file
kolab-syncroton-2.4.2.tar.gz/tests/Sync/FoldersTest.php
Changed
@@ -15,6 +15,14 @@ $this->deleteTestFolder('Test Folder New', 'mail'); $this->deleteTestFolder('Test Contacts Folder', 'contact'); $this->deleteTestFolder('Test Contacts New', 'contact'); + // Make sure the default folders exist + if (!$this->isStorageDriver('kolab4')) { + $this->createTestFolder("Calendar", "event.default"); + $this->createTestFolder("Contacts", "contact.default"); + $this->createTestFolder("Tasks", "task.default"); + $this->createTestFolder("Notes", "note.default"); + } + //TODO: handle kolab4 case? } /** @@ -375,6 +383,7 @@ $dom = $this->fromWbxml($response->getBody()); $xpath = $this->xpath($dom); + // This depends on multifolder blacklists to be configured (otherwise we get no "collective" folders) $deleted = $this->isStorageDriver('kolab4') ? 3 : 4; // No Notes folder in Kolab4 $syncKey = 2;
View file
kolab-syncroton-2.4.2.tar.gz/tests/Sync/PingTest.php
Changed
@@ -28,11 +28,11 @@ $dom = $this->fromWbxml($response->getBody()); $xpath = $this->xpath($dom); - //Initially we know no folders + // Initially we know no folders $this->assertSame('7', $xpath->query("//ns:Ping/ns:Status")->item(0)->nodeValue); - //We discover folders with a foldersync + // We discover folders with a foldersync $request = <<<EOF <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/"> @@ -44,7 +44,7 @@ $response = $this->request($request, 'FolderSync'); $this->assertEquals(200, $response->getStatusCode()); - //Now we get to the actual ping + // Now we get to the actual ping $request = <<<EOF <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/"> @@ -63,12 +63,61 @@ $this->assertEquals(200, $response->getStatusCode()); $dom = $this->fromWbxml($response->getBody()); $xpath = $this->xpath($dom); - // Initially we know no folders + // We don't find the folder state because it was never synced $this->assertSame('2', $xpath->query("//ns:Ping/ns:Status")->item(0)->nodeValue); + + // Sync inbox + $request = <<<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"> + <Collections> + <Collection> + <SyncKey>0</SyncKey> + <CollectionId>38b950ebd62cd9a66929c89615d0fc04</CollectionId> + <DeletesAsMoves>1</DeletesAsMoves> + <GetChanges>1</GetChanges> + <Options> + <FilterType>0</FilterType> + <Conflict>1</Conflict> + <BodyPreference xmlns="uri:AirSyncBase"> + <Type>2</Type> + <TruncationSize>51200</TruncationSize> + <AllOrNone>0</AllOrNone> + </BodyPreference> + </Options> + </Collection> + </Collections> + </Sync> + EOF; + + $response = $this->request($request, 'Sync'); + $this->assertEquals(200, $response->getStatusCode()); + + // Now we should get no change + $request = <<<EOF + <?xml version="1.0" encoding="utf-8"?> + <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/"> + <Ping xmlns="uri:Ping"> + <HeartbeatInterval>0</HeartbeatInterval> + <Folders> + <Folder> + <Id>38b950ebd62cd9a66929c89615d0fc04</Id> + <Class>Email</Class> + </Folder> + </Folders> + </Ping> + EOF; + + $response = $this->request($request, 'Ping'); + $this->assertEquals(200, $response->getStatusCode()); + $dom = $this->fromWbxml($response->getBody()); + $xpath = $this->xpath($dom); + $this->assertSame('1', $xpath->query("//ns:Ping/ns:Status")->item(0)->nodeValue); } /** - * Test Ping command + * Test Unknown Folder */ public function testUnknownFolder() { @@ -95,4 +144,148 @@ $this->assertSame('7', $xpath->query("//ns:Ping/ns:Status")->item(0)->nodeValue); } + + /** + * Test New Folder + */ + public function testNewFolder() + { + // Initialize the folder state + $request = <<<EOF + <?xml version="1.0" encoding="utf-8"?> + <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/"> + <FolderSync xmlns="uri:FolderHierarchy"> + <SyncKey>0</SyncKey> + </FolderSync> + EOF; + + $response = $this->request($request, 'FolderSync'); + $this->assertEquals(200, $response->getStatusCode()); + + $this->createTestFolder("NewFolder", "mail"); + $request = <<<EOF + <?xml version="1.0" encoding="utf-8"?> + <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/"> + <Ping xmlns="uri:Ping"> + <HeartbeatInterval>900</HeartbeatInterval> + <Folders> + <Folder> + <Id>38b950ebd62cd9a66929c89615d0fc04</Id> + <Class>Email</Class> + </Folder> + </Folders> + </Ping> + EOF; + + $response = $this->request($request, 'Ping'); + + $this->assertEquals(200, $response->getStatusCode()); + + $dom = $this->fromWbxml($response->getBody()); + $xpath = $this->xpath($dom); + + $this->assertSame('7', $xpath->query("//ns:Ping/ns:Status")->item(0)->nodeValue); + } + + /** + * Test Changed Subscription Folder + */ + public function testNewFolderSubscriptionState() + { + // Initialize the folder state + $request = <<<EOF + <?xml version="1.0" encoding="utf-8"?> + <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/"> + <FolderSync xmlns="uri:FolderHierarchy"> + <SyncKey>0</SyncKey> + </FolderSync> + EOF; + + $response = $this->request($request, 'FolderSync'); + $this->assertEquals(200, $response->getStatusCode()); + + $this->setSubscriptionState("NewFolder", null); + $request = <<<EOF + <?xml version="1.0" encoding="utf-8"?> + <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/"> + <Ping xmlns="uri:Ping"> + <HeartbeatInterval>900</HeartbeatInterval> + <Folders> + <Folder> + <Id>38b950ebd62cd9a66929c89615d0fc04</Id> + <Class>Email</Class> + </Folder> + </Folders> + </Ping> + EOF; + + $response = $this->request($request, 'Ping'); + + $this->assertEquals(200, $response->getStatusCode()); + + $dom = $this->fromWbxml($response->getBody()); + $xpath = $this->xpath($dom); + + $this->assertSame('7', $xpath->query("//ns:Ping/ns:Status")->item(0)->nodeValue); + } + + /** + * Test changed subscription while ping is running + */ + public function testNewFolderSubscriptionStateDuringPing() + { + // Initialize the folder state + $request = <<<EOF + <?xml version="1.0" encoding="utf-8"?> + <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/"> + <FolderSync xmlns="uri:FolderHierarchy"> + <SyncKey>0</SyncKey> + </FolderSync> + EOF; + + $response = $this->request($request, 'FolderSync'); + $this->assertEquals(200, $response->getStatusCode()); + + $request = <<<EOF + <?xml version="1.0" encoding="utf-8"?> + <!DOCTYPE AirSync PUBLIC "-//AIRSYNC//DTD AirSync//EN" "http://www.microsoft.com/"> + <FolderSync xmlns="uri:FolderHierarchy"> + <SyncKey>1</SyncKey> + </FolderSync> + EOF;
View file
kolab-syncroton-2.4.2.tar.gz/tests/SyncTestCase.php
Changed
@@ -224,22 +224,33 @@ /** * Create a folder */ - protected function createTestFolder($name, $type) + protected function createTestFolder($name, $type, $subscriptionState = '1') { // Create IMAP folders if ($type == 'mail' || $this->isStorageDriver('kolab')) { $imap = $this->getImapStorage(); - //TODO set type if not mail $imap->create_folder($name, true); + if ($type != "mail") { + $imap->set_metadata($name, '/private/vendor/kolab/folder-type' => $type); + } + $this->setSubscriptionState($name, $subscriptionState); + } + } + /** + * Subscribe test folder + */ + protected function setSubscriptionState($name, $subscriptionState) + { + $metadata = null; + if ($subscriptionState) { $metadata = ; $metadata'FOLDER' = ; $metadata'FOLDER'self::$deviceId = ; - $metadata'FOLDER'self::$deviceId'S' = '1'; - $imap->set_metadata($name, '/private/vendor/kolab/activesync' => json_encode($metadata)); - - return; + $metadata'FOLDER'self::$deviceId'S' = $subscriptionState; + $metadata = json_encode($metadata); } + $this->getImapStorage()->set_metadata($name, '/private/vendor/kolab/activesync' => $metadata); } /**
View file
kolab-syncroton-2.4.2.tar.gz/tests/setmetadata.php
Added
@@ -0,0 +1,21 @@ +<?php + +define('TESTS_DIR', dirname(__FILE__) . '/'); +require_once(TESTS_DIR . '/../lib/init.php'); + +sleep(5); + +$deviceid=$argv1 ; +$folderName=$argv2 ; + +$metadata = ; +$metadata'FOLDER' = ; +$metadata'FOLDER'$deviceid = ; +$metadata'FOLDER'$deviceid'S' = '1'; +$metadata = json_encode($metadata); +\kolab_sync::get_instance()->authenticate($argv3, $argv4); +if (\kolab_sync::get_instance()->get_storage()->set_metadata($folderName, '/private/vendor/kolab/activesync' => $metadata)) { + print("Set metdata on $deviceid on $folderName"); +} else { + print("Failed to set metdata on $deviceid on $folderName"); +}
View file
kolab-syncroton.dsc
Changed
@@ -2,7 +2,7 @@ Source: kolab-syncroton Binary: kolab-syncroton Architecture: all -Version: 1:2.4.2.41-1~kolab1 +Version: 1:2.4.2.42-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
.