mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-10-12 07:17:12 +00:00
Added EAS folder merge support and fixed long GUID issue (fixes #3460)
Conflicts: ActiveSync/SOGoActiveSyncDispatcher+Sync.m
This commit is contained in:
1 parent
4c4d3e4c25
commit
16356aaf36
3 files changed
+842
-92
No files matched your search
@@ -102,6 +102,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#import <SOGo/NSString+Utilities.h>
|
||||
#import <SOGo/WORequest+SOGo.h>
|
||||
#import <SOGo/NSArray+Utilities.h>
|
||||
#import <SOGo/NSString+Utilities.h>
|
||||
|
||||
#import <Appointments/SOGoAppointmentFolder.h>
|
||||
#import <Appointments/SOGoAppointmentFolders.h>
|
||||
@@ -119,6 +120,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#import <Mailer/SOGoMailObject.h>
|
||||
#import <Mailer/SOGoMailObject+Draft.h>
|
||||
#import <Mailer/NSString+Mail.h>
|
||||
#import <Mailer/SOGoSentFolder.h>
|
||||
|
||||
|
||||
#import <Foundation/NSObject.h>
|
||||
@@ -157,6 +159,9 @@ void handle_eas_terminate(int signum)
|
||||
|
||||
- (NSMutableDictionary *) _folderMetadataForKey: (NSString *) theFolderKey;
|
||||
- (void) _setFolderMetadata: (NSDictionary *) theFolderMetadata forKey: (NSString *) theFolderKey;
|
||||
- (void) _setOrUnsetSyncRequest: (BOOL) set
|
||||
collections: (NSArray *) collections;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@@ -853,7 +858,7 @@ void handle_eas_terminate(int signum)
|
||||
if ([key rangeOfString: @"+folder" options: NSCaseInsensitiveSearch].location != NSNotFound)
|
||||
[cachedGUIDs setObject: [NSString stringWithFormat: @"folder%@", [[o properties] objectForKey: @"displayName"]] // e.g. CDB648DDBC5040F8AC90792383DBBBAA+folderINBOX
|
||||
forKey: [key substringFromIndex: [key rangeOfString: @"+"].location+1]];
|
||||
else
|
||||
else
|
||||
[cachedGUIDs setObject: [key substringFromIndex: [key rangeOfString: @"+"].location+1] // e.g. CDB648DDBC5040F8AC90792383DBBBAA+vcard/personal
|
||||
forKey: [key substringFromIndex: [key rangeOfString: @"+"].location+1]];
|
||||
}
|
||||
@@ -896,12 +901,26 @@ void handle_eas_terminate(int signum)
|
||||
if ([cKey rangeOfString: @"/"].location != NSNotFound)
|
||||
currentFolder = [[[[context activeUser] homeFolderInContext: context] lookupName: folderType inContext: context acquire: NO]
|
||||
lookupName: [cKey substringFromIndex: [cKey rangeOfString: @"/"].location+1] inContext: context acquire: NO];
|
||||
else
|
||||
currentFolder = nil;
|
||||
|
||||
// We skip personal GCS folders - we always want to synchronize these
|
||||
if ([currentFolder isKindOfClass: [SOGoGCSFolder class]] &&
|
||||
[[currentFolder nameInContainer] isEqualToString: @"personal"])
|
||||
continue;
|
||||
|
||||
// We remove the folder from device but keep the cache entry,
|
||||
// otherwise the user would see duplication objects, one in personal folder and one in the merged folder.
|
||||
// MergedFolder=1 - Folder need to be removed from device.
|
||||
// MergedFolder=2 - Folder has been removed from device; i.e. <Delete> has been sent already.
|
||||
if ([[[o properties] objectForKey: @"MergedFolder"] isEqualToString: @"1"])
|
||||
{
|
||||
[commands appendFormat: @"<Delete><ServerId>%@</ServerId></Delete>", [cKey stringByEscapingURL] ];
|
||||
command_count++;
|
||||
[[o properties] setObject: @"2" forKey: @"MergedFolder"];
|
||||
[o save];
|
||||
}
|
||||
|
||||
// Remove the folder from device if it doesn't exist, we don't want to sync it, or it doesn't have the proper permissions
|
||||
if (!currentFolder ||
|
||||
![currentFolder synchronize] ||
|
||||
@@ -912,10 +931,16 @@ void handle_eas_terminate(int signum)
|
||||
onObject: currentFolder
|
||||
inContext: context])
|
||||
{
|
||||
[commands appendFormat: @"<Delete><ServerId>%@</ServerId></Delete>", [cKey stringByEscapingURL] ];
|
||||
command_count++;
|
||||
// Don't send a delete when MergedFoler is set, we have done it above.
|
||||
// Windows Phones don't like when a <Delete>-folder is sent twice.
|
||||
if (![[[o properties] objectForKey: @"MergedFolder"] isEqualToString: @"2"])
|
||||
{
|
||||
[commands appendFormat: @"<Delete><ServerId>%@</ServerId></Delete>", [cKey stringByEscapingURL] ];
|
||||
command_count++;
|
||||
}
|
||||
[o destroy];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1004,6 +1029,7 @@ void handle_eas_terminate(int signum)
|
||||
[[o properties] removeObjectForKey: @"SyncKey"];
|
||||
[[o properties] removeObjectForKey: @"SyncCache"];
|
||||
[[o properties] removeObjectForKey: @"DateCache"];
|
||||
[[o properties] removeObjectForKey: @"UidCache"];
|
||||
[[o properties] removeObjectForKey: @"MoreAvailable"];
|
||||
[[o properties] removeObjectForKey: @"BodyPreferenceType"];
|
||||
[[o properties] removeObjectForKey: @"SupportedElements"];
|
||||
@@ -1011,6 +1037,9 @@ void handle_eas_terminate(int signum)
|
||||
[[o properties] removeObjectForKey: @"InitialLoadSequence"];
|
||||
[[o properties] removeObjectForKey: @"FirstIdInCache"];
|
||||
[[o properties] removeObjectForKey: @"LastIdInCache"];
|
||||
[[o properties] removeObjectForKey: @"MergedFoldersSyncKeys"];
|
||||
[[o properties] removeObjectForKey: @"MergedFolder"];
|
||||
[[o properties] removeObjectForKey: @"CleanoutDate"];
|
||||
|
||||
[o save];
|
||||
|
||||
@@ -1069,7 +1098,7 @@ void handle_eas_terminate(int signum)
|
||||
operation = @"Add";
|
||||
else if (![[[o properties ] objectForKey: @"displayName"] isEqualToString: [[folders objectAtIndex:fi] displayName]])
|
||||
operation = @"Update";
|
||||
else
|
||||
else
|
||||
operation = nil;
|
||||
|
||||
if (operation)
|
||||
@@ -1105,6 +1134,7 @@ void handle_eas_terminate(int signum)
|
||||
[[o properties] removeObjectForKey: @"SyncKey"];
|
||||
[[o properties] removeObjectForKey: @"SyncCache"];
|
||||
[[o properties] removeObjectForKey: @"DateCache"];
|
||||
[[o properties] removeObjectForKey: @"UidCache"];
|
||||
[[o properties] removeObjectForKey: @"MoreAvailable"];
|
||||
[[o properties] removeObjectForKey: @"BodyPreferenceType"];
|
||||
[[o properties] removeObjectForKey: @"SupportedElements"];
|
||||
@@ -1112,6 +1142,9 @@ void handle_eas_terminate(int signum)
|
||||
[[o properties] removeObjectForKey: @"InitialLoadSequence"];
|
||||
[[o properties] removeObjectForKey: @"FirstIdInCache"];
|
||||
[[o properties] removeObjectForKey: @"LastIdInCache"];
|
||||
[[o properties] removeObjectForKey: @"MergedFoldersSyncKeys"];
|
||||
[[o properties] removeObjectForKey: @"MergedFolder"];
|
||||
[[o properties] removeObjectForKey: @"CleanoutDate"];
|
||||
}
|
||||
|
||||
[o save];
|
||||
@@ -1132,6 +1165,7 @@ void handle_eas_terminate(int signum)
|
||||
[[o properties] removeObjectForKey: @"SyncKey"];
|
||||
[[o properties] removeObjectForKey: @"SyncCache"];
|
||||
[[o properties] removeObjectForKey: @"DateCache"];
|
||||
[[o properties] removeObjectForKey: @"UidCache"];
|
||||
[[o properties] removeObjectForKey: @"MoreAvailable"];
|
||||
[[o properties] removeObjectForKey: @"BodyPreferenceType"];
|
||||
[[o properties] removeObjectForKey: @"SupportedElements"];
|
||||
@@ -1139,6 +1173,9 @@ void handle_eas_terminate(int signum)
|
||||
[[o properties] removeObjectForKey: @"InitialLoadSequence"];
|
||||
[[o properties] removeObjectForKey: @"FirstIdInCache"];
|
||||
[[o properties] removeObjectForKey: @"LastIdInCache"];
|
||||
[[o properties] removeObjectForKey: @"MergedFoldersSyncKeys"];
|
||||
[[o properties] removeObjectForKey: @"MergedFolder"];
|
||||
[[o properties] removeObjectForKey: @"CleanoutDate"];
|
||||
}
|
||||
|
||||
[o save];
|
||||
@@ -1606,10 +1643,11 @@ void handle_eas_terminate(int signum)
|
||||
- (void) processMeetingResponse: (id <DOMElement>) theDocumentElement
|
||||
inResponse: (WOResponse *) theResponse
|
||||
{
|
||||
NSString *realCollectionId, *requestId, *participationStatus, *calendarId;
|
||||
NSString *realCollectionId, *requestId, *easRequestId, *participationStatus, *calendarId;
|
||||
SOGoAppointmentObject *appointmentObject;
|
||||
SOGoMailObject *mailObject;
|
||||
NSMutableString *s;
|
||||
NSMutableDictionary *uidCache, *folderMetadata;
|
||||
NSMutableString *s, *nameInCache;
|
||||
NSData *d;
|
||||
|
||||
id collection;
|
||||
@@ -1624,7 +1662,7 @@ void handle_eas_terminate(int signum)
|
||||
realCollectionId = [[[(id)[theDocumentElement getElementsByTagName: @"CollectionId"] lastObject] textValue] realCollectionIdWithFolderType: &folderType];
|
||||
realCollectionId = [self globallyUniqueIDToIMAPFolderName: realCollectionId type: folderType];
|
||||
userResponse = [[[(id)[theDocumentElement getElementsByTagName: @"UserResponse"] lastObject] textValue] intValue];
|
||||
requestId = [[(id)[theDocumentElement getElementsByTagName: @"RequestId"] lastObject] textValue];
|
||||
easRequestId = [[(id)[theDocumentElement getElementsByTagName: @"RequestId"] lastObject] textValue];
|
||||
appointmentObject = nil;
|
||||
calendarId = nil;
|
||||
|
||||
@@ -1643,10 +1681,35 @@ void handle_eas_terminate(int signum)
|
||||
if (folderType == ActiveSyncEventFolder)
|
||||
{
|
||||
collection = [[context activeUser] personalCalendarFolderInContext: context];
|
||||
|
||||
nameInCache = [NSString stringWithFormat: @"vevent/%@", [collection nameInContainer]];
|
||||
folderMetadata = [self _folderMetadataForKey: nameInCache];
|
||||
|
||||
uidCache = [folderMetadata objectForKey: @"UidCache"];
|
||||
if (uidCache)
|
||||
{
|
||||
requestId = [[uidCache allKeysForObject: easRequestId] objectAtIndex: 0];
|
||||
|
||||
if (requestId)
|
||||
{
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Found requestId: %@ for easRequestId: %@", requestId, easRequestId];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Use original requestId: %@", easRequestId];
|
||||
|
||||
requestId = easRequestId;
|
||||
}
|
||||
}
|
||||
else
|
||||
requestId = easRequestId;
|
||||
|
||||
appointmentObject = [collection lookupName: [requestId sanitizedServerIdWithType: ActiveSyncEventFolder]
|
||||
inContext: context
|
||||
acquire: NO];
|
||||
calendarId = requestId;
|
||||
calendarId = easRequestId;
|
||||
|
||||
// Object not found, let's fallback on the INBOX folder
|
||||
if ([appointmentObject isKindOfClass: [NSException class]])
|
||||
@@ -1666,7 +1729,7 @@ void handle_eas_terminate(int signum)
|
||||
// We fetch the calendar information based on the email (requestId) in the user's INBOX (or elsewhere)
|
||||
//
|
||||
// FIXME: that won't work too well for external invitations...
|
||||
mailObject = [collection lookupName: requestId
|
||||
mailObject = [collection lookupName: easRequestId
|
||||
inContext: context
|
||||
acquire: 0];
|
||||
|
||||
@@ -1681,6 +1744,12 @@ void handle_eas_terminate(int signum)
|
||||
|
||||
// Fetch the SOGoAppointmentObject
|
||||
collection = [[context activeUser] personalCalendarFolderInContext: context];
|
||||
nameInCache = [NSString stringWithFormat: @"vevent/%@", [collection nameInContainer]];
|
||||
|
||||
[self _setOrUnsetSyncRequest: YES collections: [NSArray arrayWithObject: nameInCache]];
|
||||
folderMetadata = [self _folderMetadataForKey: nameInCache];
|
||||
uidCache = [folderMetadata objectForKey: @"UidCache"];
|
||||
|
||||
appointmentObject = [collection lookupName: [NSString stringWithFormat: @"%@.ics", [event uid]]
|
||||
inContext: context
|
||||
acquire: NO];
|
||||
@@ -1692,6 +1761,27 @@ void handle_eas_terminate(int signum)
|
||||
inContainer: collection];
|
||||
[appointmentObject saveComponent: event];
|
||||
}
|
||||
|
||||
if (uidCache && [calendarId length] > 64)
|
||||
{
|
||||
calendarId = [uidCache objectForKey: [event uid]];
|
||||
|
||||
if (![calendarId length])
|
||||
{
|
||||
calendarId = [collection globallyUniqueObjectId];
|
||||
[uidCache setObject: calendarId forKey: [event uid]];
|
||||
|
||||
[self _setFolderMetadata: folderMetadata forKey: nameInCache];
|
||||
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Generated new calendarId: %@ for serverId: %@", calendarId, [event uid]];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Reuse calendarId: %@ for serverId: %@", calendarId, [event uid]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1715,7 +1805,7 @@ void handle_eas_terminate(int signum)
|
||||
[s appendString: @"<!DOCTYPE ActiveSync PUBLIC \"-//MICROSOFT//DTD ActiveSync//EN\" \"http://www.microsoft.com/\">"];
|
||||
[s appendString: @"<MeetingResponse xmlns=\"MeetingResponse:\">"];
|
||||
[s appendString: @"<Result>"];
|
||||
[s appendFormat: @"<RequestId>%@</RequestId>", requestId];
|
||||
[s appendFormat: @"<RequestId>%@</RequestId>", easRequestId];
|
||||
[s appendFormat: @"<CalendarId>%@</CalendarId>", calendarId];
|
||||
[s appendFormat: @"<Status>%d</Status>", status];
|
||||
[s appendString: @"</Result>"];
|
||||
@@ -1731,7 +1821,7 @@ void handle_eas_terminate(int signum)
|
||||
[s appendString: @"<!DOCTYPE ActiveSync PUBLIC \"-//MICROSOFT//DTD ActiveSync//EN\" \"http://www.microsoft.com/\">"];
|
||||
[s appendString: @"<MeetingResponse xmlns=\"MeetingResponse:\">"];
|
||||
[s appendString: @"<Result>"];
|
||||
[s appendFormat: @"<RequestId>%@</RequestId>", requestId];
|
||||
[s appendFormat: @"<RequestId>%@</RequestId>", easRequestId];
|
||||
[s appendFormat: @"<Status>%d</Status>", 2];
|
||||
[s appendString: @"</Result>"];
|
||||
[s appendString: @"</MeetingResponse>"];
|
||||
@@ -1756,8 +1846,8 @@ void handle_eas_terminate(int signum)
|
||||
- (void) processMoveItems: (id <DOMElement>) theDocumentElement
|
||||
inResponse: (WOResponse *) theResponse
|
||||
{
|
||||
NSString *srcMessageId, *srcFolderId, *dstFolderId, *dstMessageId, *nameInCache, *currentFolder;
|
||||
NSMutableDictionary *folderMetadata, *prevSuccessfulMoveItemsOps, *newSuccessfulMoveItemsOps;
|
||||
NSString *srcMessageId, *srcFolderId, *dstFolderId, *dstMessageId, *srcNameInCache, *dstNameInCache, *currentSrcFolder, *currentDstFolder;
|
||||
NSMutableDictionary *srcFolderMetadata, *dstFolderMetadata, *prevSuccessfulMoveItemsOps, *newSuccessfulMoveItemsOps;
|
||||
SOGoMicrosoftActiveSyncFolderType srcFolderType, dstFolderType;
|
||||
id <DOMElement> aMoveOperation;
|
||||
NSArray *moveOperations;
|
||||
@@ -1766,12 +1856,17 @@ void handle_eas_terminate(int signum)
|
||||
NSData *d;
|
||||
int i;
|
||||
|
||||
currentSrcFolder = nil;
|
||||
currentDstFolder = nil;
|
||||
|
||||
moveOperations = (id)[theDocumentElement getElementsByTagName: @"Move"];
|
||||
|
||||
newSuccessfulMoveItemsOps = [NSMutableDictionary dictionary];
|
||||
prevSuccessfulMoveItemsOps = nil;
|
||||
folderMetadata = nil;
|
||||
currentFolder = nil;
|
||||
srcFolderMetadata = nil;
|
||||
dstFolderMetadata = nil;
|
||||
currentSrcFolder = nil;
|
||||
currentDstFolder = nil;
|
||||
|
||||
s = [NSMutableString string];
|
||||
|
||||
@@ -1787,18 +1882,33 @@ void handle_eas_terminate(int signum)
|
||||
srcFolderId = [[[(id)[aMoveOperation getElementsByTagName: @"SrcFldId"] lastObject] textValue] realCollectionIdWithFolderType: &srcFolderType];
|
||||
dstFolderId = [[[(id)[aMoveOperation getElementsByTagName: @"DstFldId"] lastObject] textValue] realCollectionIdWithFolderType: &dstFolderType];
|
||||
|
||||
[self _setOrUnsetSyncRequest: YES collections: [NSArray arrayWithObjects:
|
||||
[[[(id)[aMoveOperation getElementsByTagName: @"SrcFldId"] lastObject] textValue] stringByUnescapingURL],
|
||||
[[[(id)[aMoveOperation getElementsByTagName: @"DstFldId"] lastObject] textValue] stringByUnescapingURL], nil ]];
|
||||
|
||||
if (srcFolderType == ActiveSyncMailFolder)
|
||||
nameInCache = [NSString stringWithFormat: @"folder%@", [[[[(id)[aMoveOperation getElementsByTagName: @"SrcFldId"] lastObject] textValue] stringByUnescapingURL] substringFromIndex: 5]];
|
||||
srcNameInCache = [NSString stringWithFormat: @"folder%@", [[[[(id)[aMoveOperation getElementsByTagName: @"SrcFldId"] lastObject] textValue] stringByUnescapingURL] substringFromIndex: 5]];
|
||||
else
|
||||
nameInCache = [[[(id)[aMoveOperation getElementsByTagName: @"SrcFldId"] lastObject] textValue] stringByUnescapingURL];
|
||||
srcNameInCache = [[[(id)[aMoveOperation getElementsByTagName: @"SrcFldId"] lastObject] textValue] stringByUnescapingURL];
|
||||
|
||||
if (![nameInCache isEqualToString: currentFolder])
|
||||
if (![srcNameInCache isEqualToString: currentSrcFolder])
|
||||
{
|
||||
folderMetadata = [self _folderMetadataForKey: nameInCache];
|
||||
prevSuccessfulMoveItemsOps = [folderMetadata objectForKey: @"SuccessfulMoveItemsOps"];
|
||||
currentFolder = nameInCache;
|
||||
srcFolderMetadata = [self _folderMetadataForKey: srcNameInCache];
|
||||
prevSuccessfulMoveItemsOps = [srcFolderMetadata objectForKey: @"SuccessfulMoveItemsOps"];
|
||||
currentSrcFolder = srcNameInCache;
|
||||
}
|
||||
|
||||
|
||||
if (dstFolderType == ActiveSyncMailFolder)
|
||||
dstNameInCache = [NSString stringWithFormat: @"folder%@", [[[[(id)[aMoveOperation getElementsByTagName: @"DstFldId"] lastObject] textValue] stringByUnescapingURL] substringFromIndex: 5]];
|
||||
else
|
||||
dstNameInCache = [[[(id)[aMoveOperation getElementsByTagName: @"DstFldId"] lastObject] textValue] stringByUnescapingURL];
|
||||
|
||||
if (![dstNameInCache isEqualToString: currentDstFolder])
|
||||
{
|
||||
dstFolderMetadata = [self _folderMetadataForKey: dstNameInCache];
|
||||
currentDstFolder = dstNameInCache;
|
||||
}
|
||||
|
||||
[s appendString: @"<Response>"];
|
||||
|
||||
if (srcFolderType == ActiveSyncMailFolder && dstFolderType == ActiveSyncMailFolder)
|
||||
@@ -1903,14 +2013,44 @@ void handle_eas_terminate(int signum)
|
||||
{
|
||||
id srcCollection, dstCollection, srcSogoObject, dstSogoObject;
|
||||
NSArray *elements;
|
||||
NSString *newUID;
|
||||
NSString *newUID, *origSrcMessageId;
|
||||
NSMutableDictionary *srcUidCache, *dstUidCache, *dstSyncCache;
|
||||
NSException *ex;
|
||||
|
||||
unsigned int count, max;
|
||||
|
||||
srcCollection = [self collectionFromId: srcFolderId type: srcFolderType];
|
||||
|
||||
if ([srcCollection isKindOfClass: [NSException class]])
|
||||
{
|
||||
[s appendFormat: @"<SrcMsgId>%@</SrcMsgId>", srcMessageId];
|
||||
[s appendFormat: @"<Status>%d</Status>", 1];
|
||||
continue;
|
||||
}
|
||||
|
||||
dstCollection = [self collectionFromId: dstFolderId type: srcFolderType];
|
||||
|
||||
|
||||
if ([dstCollection isKindOfClass: [NSException class]])
|
||||
{
|
||||
[s appendFormat: @"<SrcMsgId>%@</SrcMsgId>", srcMessageId];
|
||||
[s appendFormat: @"<Status>%d</Status>", 2];
|
||||
continue;
|
||||
}
|
||||
|
||||
origSrcMessageId = srcMessageId;
|
||||
srcUidCache = [srcFolderMetadata objectForKey: @"UidCache"];
|
||||
dstUidCache = [dstFolderMetadata objectForKey: @"UidCache"];
|
||||
dstSyncCache = [dstFolderMetadata objectForKey: @"SyncCache"];
|
||||
|
||||
if (srcUidCache)
|
||||
{
|
||||
srcMessageId = [[srcUidCache allKeysForObject: origSrcMessageId] objectAtIndex: 0];
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Found serverId: %@ for easId: %@", srcMessageId, origSrcMessageId];
|
||||
}
|
||||
else
|
||||
srcMessageId = origSrcMessageId;
|
||||
|
||||
srcSogoObject = [srcCollection lookupName: [srcMessageId sanitizedServerIdWithType: srcFolderType]
|
||||
inContext: context
|
||||
acquire: NO];
|
||||
@@ -1918,7 +2058,8 @@ void handle_eas_terminate(int signum)
|
||||
sm = [SoSecurityManager sharedSecurityManager];
|
||||
if (![sm validatePermission: SoPerm_DeleteObjects
|
||||
onObject: srcCollection
|
||||
inContext: context])
|
||||
inContext: context] &&
|
||||
![srcSogoObject isKindOfClass: [NSException class]])
|
||||
{
|
||||
if (![sm validatePermission: SoPerm_AddDocumentsImagesAndFiles
|
||||
onObject: dstCollection
|
||||
@@ -1936,7 +2077,18 @@ void handle_eas_terminate(int signum)
|
||||
if (!ex)
|
||||
{
|
||||
ex = [srcSogoObject delete];
|
||||
[s appendFormat: @"<SrcMsgId>%@</SrcMsgId>", srcMessageId];
|
||||
|
||||
if (dstUidCache)
|
||||
{
|
||||
[dstUidCache setObject: newUID forKey: newUID];
|
||||
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Saved new easId: %@ for serverId: %@", newUID, newUID];
|
||||
}
|
||||
|
||||
[dstSyncCache setObject: [dstFolderMetadata objectForKey: @"SyncKey"] forKey: newUID];
|
||||
|
||||
[s appendFormat: @"<SrcMsgId>%@</SrcMsgId>", origSrcMessageId];
|
||||
[s appendFormat: @"<DstMsgId>%@</DstMsgId>", newUID];
|
||||
[s appendFormat: @"<Status>%d</Status>", 3];
|
||||
|
||||
@@ -1948,36 +2100,45 @@ void handle_eas_terminate(int signum)
|
||||
if ([prevSuccessfulMoveItemsOps objectForKey: srcMessageId])
|
||||
{
|
||||
// Move failed but we can recover the dstMessageId from previous request
|
||||
[s appendFormat: @"<SrcMsgId>%@</SrcMsgId>", srcMessageId];
|
||||
[s appendFormat: @"<SrcMsgId>%@</SrcMsgId>", origSrcMessageId];
|
||||
[s appendFormat: @"<DstMsgId>%@</DstMsgId>", [prevSuccessfulMoveItemsOps objectForKey: srcMessageId] ];
|
||||
[s appendFormat: @"<Status>%d</Status>", 3];
|
||||
[newSuccessfulMoveItemsOps setObject: [prevSuccessfulMoveItemsOps objectForKey: srcMessageId] forKey: srcMessageId];
|
||||
|
||||
if (dstUidCache)
|
||||
{
|
||||
[dstUidCache setObject: newUID forKey: newUID];
|
||||
|
||||
if (debugOn)
|
||||
[self logWithFormat: @"EAS - Saved new easId: %@ for serverId: %@", newUID, newUID];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[s appendFormat: @"<SrcMsgId>%@</SrcMsgId>", srcMessageId];
|
||||
[s appendFormat: @"<SrcMsgId>%@</SrcMsgId>", origSrcMessageId];
|
||||
[s appendFormat: @"<Status>%d</Status>", 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
[s appendFormat: @"<SrcMsgId>%@</SrcMsgId>", srcMessageId];
|
||||
[s appendFormat: @"<SrcMsgId>%@</SrcMsgId>", origSrcMessageId];
|
||||
[s appendFormat: @"<Status>%d</Status>", 2];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[s appendFormat: @"<SrcMsgId>%@</SrcMsgId>", srcMessageId];
|
||||
[s appendFormat: @"<SrcMsgId>%@</SrcMsgId>", origSrcMessageId];
|
||||
[s appendFormat: @"<Status>%d</Status>", 1];
|
||||
}
|
||||
}
|
||||
|
||||
[s appendString: @"</Response>"];
|
||||
|
||||
[folderMetadata removeObjectForKey: @"SuccessfulMoveItemsOps"];
|
||||
[folderMetadata setObject: newSuccessfulMoveItemsOps forKey: @"SuccessfulMoveItemsOps"];
|
||||
[self _setFolderMetadata: folderMetadata forKey: nameInCache];
|
||||
[srcFolderMetadata removeObjectForKey: @"SuccessfulMoveItemsOps"];
|
||||
[srcFolderMetadata setObject: newSuccessfulMoveItemsOps forKey: @"SuccessfulMoveItemsOps"];
|
||||
[self _setFolderMetadata: srcFolderMetadata forKey: srcNameInCache];
|
||||
[self _setFolderMetadata: dstFolderMetadata forKey: dstNameInCache];
|
||||
}
|
||||
|
||||
[s appendString: @"</MoveItems>"];
|
||||
@@ -2155,7 +2316,7 @@ void handle_eas_terminate(int signum)
|
||||
|
||||
if (folderType == ActiveSyncMailFolder)
|
||||
folderMetadata = [self _folderMetadataForKey: [NSString stringWithFormat: @"folder%@", [[collectionId stringByUnescapingURL] substringFromIndex:5]]];
|
||||
else
|
||||
else
|
||||
folderMetadata = [self _folderMetadataForKey: [collectionId stringByUnescapingURL]];
|
||||
|
||||
collection = [self collectionFromId: realCollectionId type: folderType];
|
||||
@@ -3209,7 +3370,7 @@ void handle_eas_terminate(int signum)
|
||||
textPart = apart;
|
||||
}
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
if ([[[part contentType] type] isEqualToString: @"text"] && [[[part contentType] subType] isEqualToString: @"html"])
|
||||
htmlPart = part;
|
||||
@@ -3242,7 +3403,7 @@ void handle_eas_terminate(int signum)
|
||||
charset = [[htmlPart contentType] valueOfParameter: @"charset"];
|
||||
isHTML = YES;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
bodyFromSmartForward = [textPart body];
|
||||
charset = [[textPart contentType] valueOfParameter: @"charset"];
|
||||
@@ -3559,7 +3720,7 @@ void handle_eas_terminate(int signum)
|
||||
if (([cmdName rangeOfString: @"ItemOperations" options: NSCaseInsensitiveSearch].location != NSNotFound) &&
|
||||
([[theRequest headerForKey: @"MS-ASAcceptMultiPart"] isEqualToString:@"T"] || [[theRequest uri] acceptsMultiPart]))
|
||||
[theResponse setHeader: @"application/vnd.ms-sync.multipart" forKey: @"Content-Type"];
|
||||
else
|
||||
else
|
||||
[theResponse setHeader: @"application/vnd.ms-sync.wbxml" forKey: @"Content-Type"];
|
||||
|
||||
[self performSelector: aSelector withObject: documentElement withObject: theResponse];
|
||||
|
||||
Reference in new issue
Block a user