View Issue Details

IDProjectCategoryView StatusLast Update
0002650SOGoActiveSyncpublic2014-03-19 15:34
Reportertfu Assigned Toludovic  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Platform[Client] MicrosoftOSWindowsOS Version7
Product Version2.2.1 
Target Version2.2.2Fixed in Version2.2.2 
Summary0002650: Outlook 2013 creates duplicates when you move messages from one folder to the other one
Description

The installation guide documents a limitation were Outlook 2013 creates duplicates when you move messages from one folder to the other on.
I found that the problem is that SOGO generates an activesync-add command when syncing the message in the target folder. This is ok for e.g. Android clients but Outlook creates a duplicate message in the target folder.

To change this behavior I tested with a modification which saves the deviceid and the messageid of the moved message in case the move is executed by outlook and then use this info when syncing the message in the target folder to do a change instead of an add.

With the following code Outlook doesn't create duplicates when moving messages. It's just an idea on how to handle this and I know it needs a lot of improvement …

root@sogo:~/SOGo-2.2.0/ActiveSync# diff SOGoActiveSyncDispatcher.m /tmp/SOGo-2.2.0/ActiveSync/SOGoActiveSyncDispatcher.m
117,119d116
< //tfu
< #import <SOGo/SOGoCache.h>
<
930,943d926
<
< //tfu
<
< NSLog(@"tfu MoveItem %@ - %@", [context objectForKey: @"DeviceType"], dstMessageId );
< NSLog(@"tfu MoveItem1 %@ - %@", [context objectForKey: @"DeviceId"], dstMessageId );
< // if move is initiated by an outlook client save the "deviceType+dstMessageId" to use it later to modify the sync-command from add to change (SOGoActiveSyncDispatcher+Sync.m)
< if ([[context objectForKey: @"DeviceType"] isEqualToString: @"WindowsOutlook15" ] ) {
< NSLog(@"tfu MoveItem 2 %@ - %@", [context objectForKey: @"DeviceType"], dstMessageId );
<
< [[SOGoCache sharedCache] setValue: @"MovedItem"
< forKey: [NSString stringWithFormat: @"%@+%@", [context objectForKey: @"DeviceType"], dstMessageId]];
< NSLog(@"tfu MoveItem 3 %@ - %@", [context objectForKey: @"DeviceType"], dstMessageId );
< }
< //tfu

root@sogo:~/SOGo-2.2.0/ActiveSync# diff SOGoActiveSyncDispatcher+Sync.m /tmp/SOGo-2.2.0/ActiveSync/SOGoActiveSyncDispatcher+Sync.m
110,113d109
< //tfu
< #import <SOGo/SOGoCache.h>
<
<
603,618d598
< //tfu
<
<
< NSLog(@"tfu SyncGetChanges cmd %@ - %@", command, uid );
< // if "deviceType+uid" found in cache it was saved by SOGoActiveSyncDispatcher.m (moveitem - outlook client) change the command = 'changed'
< if ([[SOGoCache sharedCache] valueForKey: [NSString stringWithFormat: @"%@+%@", [context objectForKey: @"DeviceType"], uid ]]) {
< NSLog(@"tfu SyncGetChanges 1 %@ - %@", [context objectForKey: @"DeviceType"], uid );
< [[SOGoCache sharedCache] removeValueForKey: [NSString stringWithFormat: @"%@+%@", [context objectForKey: @"DeviceType"], uid ]];
< NSLog(@"tfu SyncGetChanges 2 %@ - %@", [context objectForKey: @"DeviceType"], uid );
< //???
< //continue;
< command = @"changed";
< }
< NSLog(@"tfu SyncGetChanges cmd %@ - %@", command, uid );
<
< //tfu

root@sogo:~/SOGo-2.2.0/ActiveSync# diff NSString+ActiveSync.m /tmp/SOGo-2.2.0/ActiveSync/NSString+ActiveSync.m
156,172d155
< // This method extracts the "DeviceType" from a URI:
< //
< // /SOGo/Microsoft-Server-ActiveSync?Cmd=FolderSync&User=sogo10&DeviceId=SEC17CD1A3E9E3F2&DeviceType=SAMSUNGSGHI317M
< //
< - (NSString ) deviceType
< {
< NSString
s;
<
< s = [self _valueForParameter: @"DEVICETYPE="];
<
< if (!s)
< s = @"Unknown";
<
< return s;
< }
<
< //

TagsNo tags attached.

Activities

ludovic

ludovic

2014-03-10 21:25

administrator   ~0006681

This is indeed an Outlook 2013 bug but your idea is a nice one!

Can you attach your patch as pasting it messed up formatting...

Thanks!

tfu

tfu

2014-03-11 16:43

reporter  

sogo_outlook_dup_msg.txt (2,560 bytes)   
root@sogo:~/SOGo-2.2.0/ActiveSync# diff NSString+ActiveSync.m /tmp/SOGo-2.2.0/ActiveSync/NSString+ActiveSync.m
156,172d155
< // This method extracts the "DeviceType" from a URI:
< //
< // /SOGo/Microsoft-Server-ActiveSync?Cmd=FolderSync&User=sogo10&DeviceId=SEC17CD1A3E9E3F2&DeviceType=SAMSUNGSGHI317M
< //
< - (NSString *) deviceType
< {
<   NSString *s;
<
<   s = [self _valueForParameter: @"DEVICETYPE="];
<
<   if (!s)
<     s = @"Unknown";
<
 <   return s;
< }
<
< //
root@sogo:~/SOGo-2.2.0/ActiveSync#
root@sogo:~/SOGo-2.2.0/ActiveSync# diff SOGoActiveSyncDispatcher+Sync.m /tmp/SOGo-2.2.0/ActiveSync/SOGoActiveSyncDispatcher+Sync.m
110,113d109
< //tfu
< #import <SOGo/SOGoCache.h>
<
<
603,618d598
< //tfu
<
<
<  NSLog(@"tfu SyncGetChanges cmd %@ -  %@", command, uid );
< // if "deviceType+uid" found in cache it was saved by SOGoActiveSyncDispatcher.m (moveitem - outlook client) change the command = 'changed'
< if ([[SOGoCache sharedCache] valueForKey: [NSString stringWithFormat: @"%@+%@", [context objectForKey: @"DeviceType"], uid ]]) {
<  NSLog(@"tfu SyncGetChanges 1 %@ -  %@", [context objectForKey: @"DeviceType"], uid );
< [[SOGoCache sharedCache] removeValueForKey: [NSString stringWithFormat: @"%@+%@", [context objectForKey: @"DeviceType"], uid ]];
<  NSLog(@"tfu SyncGetChanges 2 %@ -  %@", [context objectForKey: @"DeviceType"], uid );
< //???
< //continue;
< command = @"changed";
< }
<  NSLog(@"tfu SyncGetChanges cmd %@ -  %@", command, uid );
<
< //tfu

root@sogo:~/SOGo-2.2.0/ActiveSync# diff SOGoActiveSyncDispatcher.m /tmp/SOGo-2.2.0/ActiveSync/SOGoActiveSyncDispatcher.m
117,119d116
< //tfu
< #import <SOGo/SOGoCache.h>
<
930,943d926
<
< //tfu
<
<  NSLog(@"tfu MoveItem %@ -  %@", [context objectForKey: @"DeviceType"], dstMessageId );
<  NSLog(@"tfu MoveItem1 %@ -  %@", [context objectForKey: @"DeviceId"], dstMessageId );
< // if move is initiated by an outlook client save the "deviceType+dstMessageId" to use it later to modify the sync-command from add to change (SOGoActiveSyncDispatcher+Sync.m)
< if ([[context objectForKey: @"DeviceType"] isEqualToString: @"WindowsOutlook15" ] ) {
<  NSLog(@"tfu MoveItem 2 %@ -  %@", [context objectForKey: @"DeviceType"], dstMessageId );
<
<           [[SOGoCache sharedCache] setValue: @"MovedItem"
<             forKey: [NSString stringWithFormat: @"%@+%@",  [context objectForKey: @"DeviceType"], dstMessageId]];
<  NSLog(@"tfu MoveItem 3 %@ -  %@", [context objectForKey: @"DeviceType"], dstMessageId );
< }
< //tfu
sogo_outlook_dup_msg.txt (2,560 bytes)   
tfu

tfu

2014-03-11 16:46

reporter   ~0006687

Uploaded a file which contains the diff-output - hope that's what you requested.

tfu

tfu

2014-03-11 23:22

reporter  

0001-outlook-moveitems-dup-messages.patch (5,073 bytes)   
From 0c94f9b09d36fde0138a1ba5c6c9de38c2fe4a0f Mon Sep 17 00:00:00 2001
From: root <root@example.com>
Date: Tue, 11 Mar 2014 19:19:00 -0400
Subject: [PATCH] outlook moveitems dup messages

---
 ActiveSync/NSString+ActiveSync.h           |    1 +
 ActiveSync/NSString+ActiveSync.m           |   17 +++++++++++++++++
 ActiveSync/SOGoActiveSyncDispatcher+Sync.m |   18 ++++++++++++++++++
 ActiveSync/SOGoActiveSyncDispatcher.m      |   22 ++++++++++++++++++++++
 4 files changed, 58 insertions(+)

diff --git a/ActiveSync/NSString+ActiveSync.h b/ActiveSync/NSString+ActiveSync.h
index 6f0433d..f3f95b0 100644
--- a/ActiveSync/NSString+ActiveSync.h
+++ b/ActiveSync/NSString+ActiveSync.h
@@ -46,6 +46,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 - (NSString *) realCollectionIdWithFolderType: (SOGoMicrosoftActiveSyncFolderType *) folderType;
 - (NSCalendarDate *) calendarDate;
 - (NSString *) deviceId;
+- (NSString *) deviceType;
 - (NSString *) command;
 - (NSData *) convertHexStringToBytes;
 
diff --git a/ActiveSync/NSString+ActiveSync.m b/ActiveSync/NSString+ActiveSync.m
index 8b09c75..1c7a8ba 100644
--- a/ActiveSync/NSString+ActiveSync.m
+++ b/ActiveSync/NSString+ActiveSync.m
@@ -170,6 +170,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 }
 
 //
+// This method extracts the "DeviceType" from a URI:
+//
+// /SOGo/Microsoft-Server-ActiveSync?Cmd=FolderSync&User=sogo10&DeviceId=SEC17CD1A3E9E3F2&DeviceType=SAMSUNGSGHI317M
+//
+- (NSString *) deviceType
+{
+  NSString *s;
+
+  s = [self _valueForParameter: @"DEVICETYPE="];
+
+  if (!s)
+    s = @"Unknown";
+
+  return s;
+}
+
+//
 //
 //
 - (NSString *) command
diff --git a/ActiveSync/SOGoActiveSyncDispatcher+Sync.m b/ActiveSync/SOGoActiveSyncDispatcher+Sync.m
index b214984..0f9992b 100644
--- a/ActiveSync/SOGoActiveSyncDispatcher+Sync.m
+++ b/ActiveSync/SOGoActiveSyncDispatcher+Sync.m
@@ -103,6 +103,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <unistd.h>
 
+//tfu
+#import <SOGo/SOGoCache.h>
+
+
 @implementation SOGoActiveSyncDispatcher (Sync)
 
 //
@@ -617,6 +621,20 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
             
             uid = [[[aMessage allKeys] lastObject] stringValue];
             command = [[aMessage allValues] lastObject];          
+
+//tfu
+
+
+            // if "deviceType+uid" found in cache it was saved by SOGoActiveSyncDispatcher.m (moveitem - outlook client) change the command = 'changed'
+            if ([[SOGoCache sharedCache] valueForKey: [NSString stringWithFormat: @"%@+%@", [context objectForKey: @"DeviceType"], uid ]]) {
+               NSLog(@"tfu moveMessage %@ - %@", [context objectForKey: @"DeviceType"], uid );
+
+               [[SOGoCache sharedCache] removeValueForKey: [NSString stringWithFormat: @"%@+%@", [context objectForKey: @"DeviceType"], uid ]];
+
+	       command = @"changed";
+            }
+
+//tfu
             
             if ([command isEqualToString: @"added"])
               [s appendString: @"<Add xmlns=\"AirSync:\">"];
diff --git a/ActiveSync/SOGoActiveSyncDispatcher.m b/ActiveSync/SOGoActiveSyncDispatcher.m
index efb2013..9c18471 100644
--- a/ActiveSync/SOGoActiveSyncDispatcher.m
+++ b/ActiveSync/SOGoActiveSyncDispatcher.m
@@ -114,6 +114,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "SOGoActiveSyncConstants.h"
 #include "SOGoMailObject+ActiveSync.h"
 
+//tfu
+#import <SOGo/SOGoCache.h>
+
 #include <unistd.h>
 
 @implementation SOGoActiveSyncDispatcher
@@ -924,6 +927,22 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
         {
           NSMutableString *s;
           NSData *d;
+
+//tfu
+
+          NSLog(@"tfu MoveItem  %@ - %@", [context objectForKey: @"DeviceType"], dstMessageId );
+          NSLog(@"tfu MoveItem1 %@ - %@", [context objectForKey: @"DeviceId"], dstMessageId );
+
+          // if move is initiated by an outlook client save the "deviceType+dstMessageId" to use it later to modify the sync-command from add to change (SOGoActiveSyncDispatcher+Sync.m)
+          if ([[context objectForKey: @"DeviceType"] isEqualToString: @"WindowsOutlook15" ] ) {
+              NSLog(@"tfu MoveItem 2 %@ - %@", [context objectForKey: @"DeviceType"], dstMessageId );
+
+              [[SOGoCache sharedCache] setValue: @"MovedItem" forKey: [NSString stringWithFormat: @"%@+%@",  [context objectForKey: @"DeviceType"], dstMessageId]];
+
+              NSLog(@"tfu MoveItem 3 %@ - %@", [context objectForKey: @"DeviceType"], dstMessageId );
+          }
+//tfu
+
           
           // Everything is alright, lets return the proper response. "Status == 3" means success.
           s = [NSMutableString string];
@@ -1526,6 +1545,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   deviceId = [[theRequest uri] deviceId];
   [context setObject: deviceId  forKey: @"DeviceId"];
 
+//tfu
+  [context setObject:  [[theRequest uri] deviceType]  forKey: @"DeviceType"];
+
   d = [[theRequest content] wbxml2xml];
   documentElement = nil;
 
-- 
1.7.9.5

ludovic

ludovic

2014-03-19 15:34

administrator   ~0006736

Thanks for your idea on this.

I've fixed the code in a slightly more elegant way in order to avoid collisions of messages IDs.

See:

https://github.com/inverse-inc/sogo/commit/35d71f61505309078b3199850fd8ba3f5d176c68

and:

https://github.com/inverse-inc/sogo/commit/83bccda55116bc94e4323aa082cc008c8d3b67c5

Issue History

Date Modified Username Field Change
2014-03-10 21:21 tfu New Issue
2014-03-10 21:25 ludovic Note Added: 0006681
2014-03-11 16:43 tfu File Added: sogo_outlook_dup_msg.txt
2014-03-11 16:46 tfu Note Added: 0006687
2014-03-11 23:22 tfu File Added: 0001-outlook-moveitems-dup-messages.patch
2014-03-19 15:33 ludovic Target Version => 2.2.2
2014-03-19 15:34 ludovic Note Added: 0006736
2014-03-19 15:34 ludovic Status new => closed
2014-03-19 15:34 ludovic Assigned To => ludovic
2014-03-19 15:34 ludovic Resolution open => fixed
2014-03-19 15:34 ludovic Fixed in Version => 2.2.2