From 663c4a44a282abe24f0cf39a23b4cfdbbde61eb9 Mon Sep 17 00:00:00 2001 From: Ludovic Marcotte Date: Mon, 28 Mar 2016 11:13:41 -0400 Subject: [PATCH] (fix) handle Dovecot's mail_shared_explicit_inbox when using EAS Conflicts: ActiveSync/SOGoActiveSyncDispatcher.m SoObjects/Mailer/SOGoMailAccount.m --- ActiveSync/SOGoActiveSyncDispatcher.m | 22 +++++++++- SoObjects/Mailer/SOGoMailAccount.m | 61 ++++++++++++++------------- 2 files changed, 53 insertions(+), 30 deletions(-) diff --git a/ActiveSync/SOGoActiveSyncDispatcher.m b/ActiveSync/SOGoActiveSyncDispatcher.m index a75317007..abb17894d 100644 --- a/ActiveSync/SOGoActiveSyncDispatcher.m +++ b/ActiveSync/SOGoActiveSyncDispatcher.m @@ -172,6 +172,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [super dealloc]; } +- (void) _ensureFolder: (SOGoMailFolder *) mailFolder +{ + BOOL rc; + + if (![mailFolder isKindOfClass: [NSException class]]) + { + rc = [mailFolder exists]; + if (!rc) + rc = [mailFolder create]; + } +} + - (void) _setFolderSyncKey: (NSString *) theSyncKey { SOGoCacheGCSObject *o; @@ -773,7 +785,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. accountsFolder = [userFolder lookupName: @"Mail" inContext: context acquire: NO]; accountFolder = [accountsFolder lookupName: @"0" inContext: context acquire: NO]; - allFoldersMetadata = [accountFolder allFoldersMetadata]; + if (first_sync) + { + [self _ensureFolder: (SOGoMailFolder *)[accountFolder draftsFolderInContext: context]]; + [self _ensureFolder: [accountFolder sentFolderInContext: context]]; + [self _ensureFolder: (SOGoMailFolder *)[accountFolder trashFolderInContext: context]]; + } + + allFoldersMetadata = [NSMutableArray array]; + [self _flattenFolders: [accountFolder allFoldersMetadata] into: allFoldersMetadata parent: nil]; // Get GUIDs of folder (IMAP) // e.g. {folderINBOX = folder6b93c528176f1151c7260000aef6df92} diff --git a/SoObjects/Mailer/SOGoMailAccount.m b/SoObjects/Mailer/SOGoMailAccount.m index 8eb5147ed..bc5c73b66 100644 --- a/SoObjects/Mailer/SOGoMailAccount.m +++ b/SoObjects/Mailer/SOGoMailAccount.m @@ -680,14 +680,14 @@ static NSString *inboxFolderName = @"INBOX"; - (NSDictionary *) imapFolderGUIDs { - NSDictionary *result, *nresult, *namespaceDict; + NSDictionary *result, *nresult; NSMutableDictionary *folders; NGImap4Client *client; SOGoUserDefaults *ud; NSArray *folderList; NSEnumerator *e; NSString *guid; - id object; + id currentFolder; BOOL hasAnnotatemore; @@ -707,7 +707,6 @@ static NSString *inboxFolderName = @"INBOX"; folders = [NSMutableDictionary dictionary]; client = [[self imap4Connection] client]; - namespaceDict = [client namespace]; hasAnnotatemore = [self hasCapability: @"annotatemore"]; if (hasAnnotatemore) @@ -716,43 +715,47 @@ static NSString *inboxFolderName = @"INBOX"; result = [client lstatus: @"*" flags: [NSArray arrayWithObjects: @"x-guid", nil]]; e = [folderList objectEnumerator]; - - while ((object = [e nextObject])) + + while ((currentFolder = [[e nextObject] substringFromIndex: 1])) { if (hasAnnotatemore) - guid = [[[[result objectForKey: @"FolderList"] objectForKey: [object substringFromIndex: 1]] objectForKey: @"/comment"] objectForKey: @"value.priv"]; + guid = [[[[result objectForKey: @"FolderList"] objectForKey: currentFolder] objectForKey: @"/comment"] objectForKey: @"value.priv"]; else - guid = [[[result objectForKey: @"status"] objectForKey: [object substringFromIndex: 1]] objectForKey: @"x-guid"]; + guid = [[[result objectForKey: @"status"] objectForKey: currentFolder] objectForKey: @"x-guid"]; if (!guid) { // Don't generate a GUID for "Other users" and "Shared" namespace folders - user foldername instead - if ([[object substringFromIndex: 1] isEqualToString: [[[[namespaceDict objectForKey: @"other users"] lastObject] objectForKey: @"prefix"] substringFromIndex: 1]] || - [[object substringFromIndex: 1] isEqualToString: [[[[namespaceDict objectForKey: @"shared"] lastObject] objectForKey: @"prefix"] substringFromIndex: 1]]) + if ((otherUsersFolderName && [currentFolder isEqualToString: otherUsersFolderName]) || + (sharedFoldersName && [currentFolder isEqualToString: sharedFoldersName])) + guid = [NSString stringWithFormat: @"%@", currentFolder]; + // If Dovecot is used with mail_shared_explicit_inbox = yes we have to generate a guid for "shared/user". + // * LIST (\NonExistent \HasChildren) "/" shared + // * LIST (\NonExistent \HasChildren) "/" shared/jdoe@example.com + // * LIST (\HasNoChildren) "/" shared/jdoe@example.com/INBOX + else if (([[[result objectForKey: @"list"] objectForKey: currentFolder] indexOfObject: @"nonexistent"] != NSNotFound && + [[[result objectForKey: @"list"] objectForKey: currentFolder] indexOfObject: @"haschildren"] != NSNotFound)) + guid = [NSString stringWithFormat: @"%@", currentFolder]; + else { - [folders setObject: [NSString stringWithFormat: @"folder%@", [object substringFromIndex: 1]] forKey: [NSString stringWithFormat: @"folder%@", [object substringFromIndex: 1]]]; - continue; + // If folder doesn't exists - ignore it. + nresult = [client status: currentFolder + flags: [NSArray arrayWithObject: @"UIDVALIDITY"]]; + if (![[nresult valueForKey: @"result"] boolValue]) + continue; + else if (hasAnnotatemore) + { + guid = [[NSProcessInfo processInfo] globallyUniqueString]; + nresult = [client annotation: currentFolder entryName: @"/comment" attributeName: @"value.priv" attributeValue: guid]; + } + + // setannotation failed or annotatemore is not available + if ((hasAnnotatemore && ![[nresult objectForKey: @"result"] boolValue]) || !hasAnnotatemore) + guid = [NSString stringWithFormat: @"%@", currentFolder]; } - - // if folder doesn't exists - ignore it - nresult = [client status: [object substringFromIndex: 1] - flags: [NSArray arrayWithObject: @"UIDVALIDITY"]]; - if (![[nresult valueForKey: @"result"] boolValue]) - continue; - - if (hasAnnotatemore) - { - guid = [[NSProcessInfo processInfo] globallyUniqueString]; - nresult = [client annotation: [object substringFromIndex: 1] entryName: @"/comment" attributeName: @"value.priv" attributeValue: guid]; - } - - // setannotation failed or annotatemore is not available - if (![[nresult objectForKey: @"result"] boolValue] || !hasAnnotatemore) - guid = [NSString stringWithFormat: @"%@", [object substringFromIndex: 1]]; } - [folders setObject: [NSString stringWithFormat: @"folder%@", guid] forKey: [NSString stringWithFormat: @"folder%@", [object substringFromIndex: 1]]]; - + [folders setObject: [NSString stringWithFormat: @"folder%@", guid] forKey: [NSString stringWithFormat: @"folder%@", currentFolder]]; } return folders;