Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117915023
D473.1775404444.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
7 KB
Referenced Files
None
Subscribers
None
D473.1775404444.diff
View Options
diff --git a/lib/kolab_sync_data.php b/lib/kolab_sync_data.php
--- a/lib/kolab_sync_data.php
+++ b/lib/kolab_sync_data.php
@@ -484,7 +484,7 @@
throw new Syncroton_Exception_Status_Sync(Syncroton_Exception_Status_Sync::SYNC_SERVER_ERROR);
}
- return $entry['uid'];
+ return $entry['_serverId'];
}
/**
@@ -505,13 +505,13 @@
}
$entry = $this->toKolab($entry, $folderId, $oldEntry);
- $entry = $this->updateObject($folderId, $serverId, $entry);
+ $entry = $this->updateObject($folderId, $serverId, $entry);
if (empty($entry)) {
throw new Syncroton_Exception_Status_Sync(Syncroton_Exception_Status_Sync::SYNC_SERVER_ERROR);
}
- return $entry['uid'];
+ return $entry['_serverId'];
}
/**
@@ -602,8 +602,8 @@
if (!is_array($uids)) {
$error = true;
}
- else {
- $result = array_merge($result, $uids);
+ else if (!empty($uids)) {
+ $result = array_merge($result, $this->applyServerId($uids, $folder));
}
break;
}
@@ -641,8 +641,8 @@
case self::RESULT_UID:
$uids = $folder->get_uids($tag_filter);
- if (is_array($uids)) {
- $result = array_unique(array_merge($result, $uids));
+ if (is_array($uids) && !empty($uids)) {
+ $result = array_unique(array_merge($result, $this->applyServerId($uids, $folder)));
}
break;
@@ -944,10 +944,37 @@
$foldername = $this->backend->folder_id2name($folderid, $this->device->deviceid);
$folder = $this->getFolderObject($foldername);
- if ($folder && $folder->valid && ($object = $folder->get_object($entryid))) {
- $object['_folderid'] = $folderid;
+ if ($folder && $folder->valid) {
+ $crc = null;
+ $uid = $entryid;
+
+ // See self::serverId() for full explanation
+ // Use (slower) UID prefix matching...
+ if (preg_match('/^CRC([0-9A-Fa-f]{8})(.+)$/', $uid, $matches)) {
+ $crc = $matches[1];
+ $uid = $matches[2];
+
+ if (strlen($entryid) >= 64) {
+ foreach ($folder->select(array(array('uid', '~*', $uid))) as $object) {
+ if (($object['uid'] == $uid || strpos($object['uid'], $uid) === 0)
+ && $crc == $this->objectCRC($object['uid'], $folder)
+ ) {
+ $object['_folderid'] = $folderid;
+ return $object;
+ }
+ }
+
+ continue;
+ }
+ }
- return $object;
+ // Or (faster) strict UID matching...
+ if (($object = $folder->get_object($uid))
+ && ($crc === null || $crc == $this->objectCRC($object['uid'], $folder))
+ ) {
+ $object['_folderid'] = $folderid;
+ return $object;
+ }
}
}
}
@@ -981,6 +1008,8 @@
$this->setKolabTags($data['uid'], $tags);
}
+ $data['_serverId'] = $this->serverId($data['uid'], $folder);
+
return $data;
}
}
@@ -1006,6 +1035,8 @@
$this->setKolabTags($data['uid'], $tags);
}
+ $data['_serverId'] = $this->serverId($object['uid'], $folder);
+
return $data;
}
}
@@ -1021,7 +1052,7 @@
if ($object) {
$folder = $this->getFolderObject($object['_mailbox']);
- if ($folder && $folder->valid && $folder->delete($entryid)) {
+ if ($folder && $folder->valid && $folder->delete($object['uid'])) {
if ($this->tag_categories) {
$this->setKolabTags($object['uid'], null);
}
@@ -1848,4 +1879,65 @@
return false;
}
+
+ /**
+ * Generate CRC-based ServerId from object UID
+ */
+ protected function serverId($uid, $folder)
+ {
+ if ($this->modelName == 'mail') {
+ return $uid;
+ }
+
+ // When ActiveSync communicates with the client, it refers to objects with a ServerId
+ // We can't use object UID for ServerId because:
+ // - ServerId is limited to 64 chars,
+ // - there can be multiple calendars with a copy of the same event.
+ //
+ // The solution is to; Take the original UID, and regardless of its length, execute the following:
+ // - Hash the UID concatenated with the Folder ID using CRC32b,
+ // - Prefix the UID with 'CRC' and the hash string,
+ // - Tryncate the result to 64 characters.
+ //
+ // Searching for the server-side copy of the object now follows the logic;
+ // - If the ServerId is prefixed with 'CRC', strip off the first 11 characters
+ // and we search for the UID using the remainder;
+ // - if the UID is shorter than 53 characters, it'll be the complete UID,
+ // - if the UID is longer than 53 characters, it'll be the truncated UID,
+ // and we search for a wildcard match of <uid>*
+ // When multiple copies of the same event are found, the same CRC32b hash can be used
+ // on the events metadata (i.e. the copy's UID and Folder ID), and compared with the CRC from the ServerId.
+
+ // ServerId is max. 64 characters, below we generate a string of max. 64 chars
+ // Note: crc32b is always 8 characters
+ return 'CRC' . $this->objectCRC($uid, $folder) . substr($uid, 0, 53);
+ }
+
+ /**
+ * Calculate checksum on object UID and folder UID
+ */
+ protected function objectCRC($uid, $folder)
+ {
+ if (!is_object($folder)) {
+ $folder = $this->getFolderObject($folder);
+ }
+
+ $folder_uid = $folder->get_uid();
+
+ return strtoupper(hash('crc32b', $folder_uid . $uid)); // always 8 chars
+ }
+
+ /**
+ * Apply serverId() on a set of uids
+ */
+ protected function applyServerId($uids, $folder)
+ {
+ if (!empty($uids) && $this->modelName != 'mail') {
+ $self = $this;
+ $func = function($uid) use ($self, $folder) { return $self->serverId($uid, $folder); };
+ $uids = array_map($func, $uids);
+ }
+
+ return $uids;
+ }
}
diff --git a/lib/kolab_sync_data_calendar.php b/lib/kolab_sync_data_calendar.php
--- a/lib/kolab_sync_data_calendar.php
+++ b/lib/kolab_sync_data_calendar.php
@@ -413,14 +413,6 @@
continue 2;
}
break;
-
- case 'uid':
- // If UID is too long, use auto-generated UID (#1034)
- // It's because UID is used as ServerId which cannot be longer than 64 chars
- if (strlen($value) > 64) {
- $value = null;
- }
- break;
}
$this->setKolabDataItem($event, $name, $value);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Apr 5, 3:54 PM (5 d, 13 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18833841
Default Alt Text
D473.1775404444.diff (7 KB)
Attached To
Mode
D473: Bifrost#T36198: Create non-conflicting ServerId for objects with non-unique or long UID
Attached
Detach File
Event Timeline