From 1ee47b1ee233a1e5218441ccae777a769932ffd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20J=2E=20Hern=C3=A1ndez=20Blasco?= Date: Fri, 27 Mar 2015 10:27:16 +0100 Subject: [PATCH 1/7] oc: return last modified messages when sorted by PidMessageTagDeliveryTime This change is required as oxcfxics is asking for sorting using this property. We fake this property on GCS folders (Tasks, Calendar, Contacts) using c_lastmodified column. --- OpenChange/MAPIStoreCalendarMessageTable.m | 3 +++ OpenChange/MAPIStoreContactsMessageTable.m | 3 +++ OpenChange/MAPIStoreTasksMessageTable.m | 3 +++ 3 files changed, 9 insertions(+) diff --git a/OpenChange/MAPIStoreCalendarMessageTable.m b/OpenChange/MAPIStoreCalendarMessageTable.m index 6844d8433..bbf05274f 100644 --- a/OpenChange/MAPIStoreCalendarMessageTable.m +++ b/OpenChange/MAPIStoreCalendarMessageTable.m @@ -182,6 +182,9 @@ static Class MAPIStoreCalendarMessageK = Nil; forKey: MAPIPropertyKey (PR_CREATION_TIME)]; [knownProperties setObject: @"c_uid" forKey: MAPIPropertyKey (PR_OWNER_APPT_ID)]; + /* Use by oxcfxics to sort the latest first */ + [knownProperties setObject: @"c_lastmodified" + forKey: MAPIPropertyKey (PidTagMessageDeliveryTime)]; } return [knownProperties objectForKey: MAPIPropertyKey (property)]; diff --git a/OpenChange/MAPIStoreContactsMessageTable.m b/OpenChange/MAPIStoreContactsMessageTable.m index 524ed06c3..b88158a26 100644 --- a/OpenChange/MAPIStoreContactsMessageTable.m +++ b/OpenChange/MAPIStoreContactsMessageTable.m @@ -220,6 +220,9 @@ static Class MAPIStoreContactsMessageK, NGMailAddressK, NSDataK, NSStringK; forKey: MAPIPropertyKey (PidTagSubject)]; [knownProperties setObject: @"c_cn" forKey: MAPIPropertyKey (PidTagNormalizedSubject)]; + /* Use by oxcfxics to sort the latest first */ + [knownProperties setObject: @"c_lastmodified" + forKey: MAPIPropertyKey (PidTagMessageDeliveryTime)]; } return [knownProperties objectForKey: MAPIPropertyKey (property)]; diff --git a/OpenChange/MAPIStoreTasksMessageTable.m b/OpenChange/MAPIStoreTasksMessageTable.m index 2948177b0..b0f39341c 100644 --- a/OpenChange/MAPIStoreTasksMessageTable.m +++ b/OpenChange/MAPIStoreTasksMessageTable.m @@ -157,6 +157,9 @@ static Class MAPIStoreTasksMessageK = Nil; forKey: MAPIPropertyKey (PidLidTaskDueDate)]; [knownProperties setObject: @"c_creationdate" forKey: MAPIPropertyKey (PidLidTaskOrdinal)]; + /* Use by oxcfxics to sort the latest first */ + [knownProperties setObject: @"c_lastmodified" + forKey: MAPIPropertyKey (PidTagMessageDeliveryTime)]; } return [knownProperties objectForKey: MAPIPropertyKey (property)]; From fa23b574eb7f58cc8fdc679dd6c2e47a5f7090da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20J=2E=20Hern=C3=A1ndez=20Blasco?= Date: Mon, 13 Apr 2015 11:37:48 +0200 Subject: [PATCH 2/7] oc: Search for properties in a SOGoMAPIDB object now works sogo-openchange library stores the properties as NSString keys and the search function casts the values to NSNumber, which it may be valid for other parts but not for this library. The real fix would be to store the property keys as NSNumbers as they are uint32_t at the end. However, this may lead to a great refactor in the library. With this fix, we can match the search for a property in a MAPIStoreFallback folder, such as Notes or Deleted Items, or MAPIStoreFolder properties (ie: search for a subfolder) or for MAPIStoreFAIMessages in a folder. --- SoObjects/SOGo/EOQualifier+SOGoCacheObject.m | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/SoObjects/SOGo/EOQualifier+SOGoCacheObject.m b/SoObjects/SOGo/EOQualifier+SOGoCacheObject.m index f86f2a11c..f21e9c7d6 100644 --- a/SoObjects/SOGo/EOQualifier+SOGoCacheObject.m +++ b/SoObjects/SOGo/EOQualifier+SOGoCacheObject.m @@ -125,6 +125,11 @@ typedef BOOL (*EOComparator) (id, SEL, id); finalKey = @""; propValue = [properties objectForKey: finalKey]; + /* sogo-openchange library stores the properties as NSString keys + and we have to check if the property exists using the NSString */ + if (!propValue && [key isKindOfClass: [NSString class]]) + propValue = [properties objectForKey: key]; + comparator = (EOComparator) [propValue methodForSelector: operator]; return (comparator ? comparator (propValue, operator, value) : NO); From bddd67fb9317c03fcf17e384ee4785050885136a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20J=2E=20Hern=C3=A1ndez=20Blasco?= Date: Mon, 13 Apr 2015 11:48:42 +0200 Subject: [PATCH 3/7] oc: Enforce the folder creation mapping when the FID exists We believe the folder ID OpenChange is sending us is new and we keep the indexing database properly updated. Although the solution is not elegant, this could avoid inconsistencies between what the client stores and the relation in the MAPIStore backend. --- OpenChange/MAPIStoreFolder.m | 10 ++++++++-- OpenChange/MAPIStoreMapping.h | 2 ++ OpenChange/MAPIStoreMapping.m | 25 ++++++++++++++++++++++--- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/OpenChange/MAPIStoreFolder.m b/OpenChange/MAPIStoreFolder.m index 0d862b85e..824c15578 100644 --- a/OpenChange/MAPIStoreFolder.m +++ b/OpenChange/MAPIStoreFolder.m @@ -402,7 +402,8 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe withRow: (struct SRow *) aRow andFID: (uint64_t) fid { - int rc = MAPISTORE_SUCCESS; + BOOL mapped; + enum mapistore_error rc = MAPISTORE_SUCCESS; MAPIStoreMapping *mapping; NSString *baseURL, *childURL, *folderKey; MAPIStoreFolder *childFolder; @@ -430,7 +431,12 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe childURL = [NSString stringWithFormat: @"%@%@/", baseURL, [folderKey stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]]; - [mapping registerURL: childURL withID: fid]; + + mapped = [mapping registerURL: childURL withID: fid]; + if (!mapped) + /* Enforce the creation if the backend does know the fid */ + [mapping updateURL: childURL withID: fid]; + childFolder = [self lookupFolder: folderKey]; if (childFolder) { diff --git a/OpenChange/MAPIStoreMapping.h b/OpenChange/MAPIStoreMapping.h index 827cddf38..55c2e944a 100644 --- a/OpenChange/MAPIStoreMapping.h +++ b/OpenChange/MAPIStoreMapping.h @@ -60,6 +60,8 @@ andFlags: (uint8_t) flags; - (void) updateID: (uint64_t) idNbr withURL: (NSString *) urlString; +- (BOOL) updateURL: (NSString *) urlString + withID: (uint64_t) idNbr; @end diff --git a/OpenChange/MAPIStoreMapping.m b/OpenChange/MAPIStoreMapping.m index 6a910ea4c..b7d303ed6 100644 --- a/OpenChange/MAPIStoreMapping.m +++ b/OpenChange/MAPIStoreMapping.m @@ -227,12 +227,32 @@ MAPIStoreMappingKeyFromId (uint64_t idNbr) } } +- (BOOL) updateURL: (NSString *) urlString + withID: (uint64_t) idNbr +{ + BOOL rc = NO; + uint64_t oldIDNbr; + + oldIDNbr = [self idFromURL: urlString]; + if (oldIDNbr) + { + [self logWithFormat: @"Updating URL: %@ with id %.16"PRIx64" from old id %.16"PRIx64, + urlString, idNbr, oldIDNbr]; + [self unregisterURLWithID: oldIDNbr]; + [self registerURL: urlString + withID: idNbr]; + rc = YES; + } + + return rc; +} + - (BOOL) registerURL: (NSString *) urlString withID: (uint64_t) idNbr { NSString *oldURL; uint64_t oldIdNbr; - bool rc, softDeleted; + bool softDeleted; oldURL = [self urlFromID: idNbr]; if (oldURL != NULL) @@ -257,7 +277,6 @@ MAPIStoreMappingKeyFromId (uint64_t idNbr) } else { - rc = YES; // [self logWithFormat: @"registered url '%@' with id %lld (0x%.16"PRIx64")", // urlString, idNbr, idNbr]; @@ -266,7 +285,7 @@ MAPIStoreMappingKeyFromId (uint64_t idNbr) idNbr, [urlString UTF8String]); } - return rc; + return YES; } - (void) registerURLs: (NSArray *) urlStrings From a8e8ec535af3d1674d261df0e39e1bd5ce3bc954 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julio=20Garc=C3=ADa?= Date: Wed, 15 Apr 2015 16:10:03 +0200 Subject: [PATCH 4/7] Prepare for 2.2.17a-zentyal1 --- NEWS | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/NEWS b/NEWS index 2a8958ee1..b37f43aff 100644 --- a/NEWS +++ b/NEWS @@ -1,24 +1,8 @@ -2.2.15-zentyal3 (2015-04-14) ------- - -New features - - Internet headers are now shown in Outlook - -Enhancements - - Sharing request among different Outlook versions - - Improve sync speed from Outlook by non-reprocessing already downloaded unread mails +2.2.17a-zentyal1 (2014-04-15) +-------------------- Bug fixes - - Sent mails are not longer in Drafts folder using Outlook - - Deleted mails are properly synced between Outlook profiles from the same account - - Does not create a mail folder in other user's mailbox - - Fix server-side crash with invalid events - - Fix setting permissions for a folder with several users - - Fix reception of calendar event invitations on optional attendees - - Fix server side crash parsing rtf without color table - - Weekly recurring events created in SOGo web interface are now shown in Outlook - - Fix exception modifications import in recurrence series - - Fix server side crash parsing rtf emails with images (with word97 format) + - Do not share Outlook metadata between users with the same name and different domain 2.2.17a (2014-03-15) -------------------- @@ -79,6 +63,28 @@ Bug fixes - fixed plain/text mails showing on one line on Android/EAS (#3055) - fixed exception in sogo-tool when parsing arguments of a set operation +2.2.15-zentyal3 (2015-04-14) +------ + +New features + - Internet headers are now shown in Outlook + +Enhancements + - Sharing request among different Outlook versions + - Improve sync speed from Outlook by non-reprocessing already downloaded unread mails + +Bug fixes + - Sent mails are not longer in Drafts folder using Outlook + - Deleted mails are properly synced between Outlook profiles from the same account + - Does not create a mail folder in other user's mailbox + - Fix server-side crash with invalid events + - Fix setting permissions for a folder with several users + - Fix reception of calendar event invitations on optional attendees + - Fix server side crash parsing rtf without color table + - Weekly recurring events created in SOGo web interface are now shown in Outlook + - Fix exception modifications import in recurrence series + - Fix server side crash parsing rtf emails with images (with word97 format) + 2.2.15-zentyal2 (2015-03-16) ---------------------------- From 0f432b654f708ab96c79c5197d67e8cd8980951a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Garc=C3=ADa=20S=C3=A1ez?= Date: Wed, 15 Apr 2015 18:52:55 +0200 Subject: [PATCH 5/7] oc: Fix internal EntryIds properties on multidomain PidTag*EntryId properties were not being generated (which contain the email address and so on). Functionality on Outlook clients like "Reply All" were not working because of this (probably a lot more stuff related with email addresses). With multidomain support enabled outlook clients will use full email address (e.g. user@domain.com) as login. This change is needed because we were performing ldap queries on samdb using (sAMAccountName=UIDFieldName), being UIDFieldName the parameter configured in sogo.conf for that source. In multidomain environment this field could be `sAMAccountName` but it could not. Actually the more logical scenario will be to use `uid` field here (which will be just `user`, without the `@domain.com` part). SOGoUserManager will return `sAMAccountName` if the contact has it (in Outlook environment that means always) so it can (and must) be used to query samdb in MAPIStoreSamDBUtils properly. TL;DR: use sAMAccoutName instead of uid to query samdb --- OpenChange/MAPIStoreAppointmentWrapper.m | 6 +- OpenChange/MAPIStoreMailMessage.m | 6 +- OpenChange/MAPIStoreMailVolatileMessage.m | 2 +- OpenChange/MAPIStoreSamDBUtils.m | 7 ++- SoObjects/SOGo/SOGoUserManager.m | 70 ++++++++++++----------- 5 files changed, 49 insertions(+), 42 deletions(-) diff --git a/OpenChange/MAPIStoreAppointmentWrapper.m b/OpenChange/MAPIStoreAppointmentWrapper.m index 7fa60c5c5..889c6c430 100644 --- a/OpenChange/MAPIStoreAppointmentWrapper.m +++ b/OpenChange/MAPIStoreAppointmentWrapper.m @@ -264,7 +264,7 @@ static NSCharacterSet *hexCharacterSet = nil; if (contactInfos) { - username = [contactInfos objectForKey: @"c_uid"]; + username = [contactInfos objectForKey: @"sAMAccountName"]; recipient->username = [username asUnicodeInMemCtx: msgData]; entryId = MAPIStoreInternalEntryId (connInfo->sam_ctx, username); } @@ -365,7 +365,7 @@ static NSCharacterSet *hexCharacterSet = nil; if (contactInfos) { - username = [contactInfos objectForKey: @"c_uid"]; + username = [contactInfos objectForKey: @"sAMAccountName"]; recipient->username = [username asUnicodeInMemCtx: msgData]; entryId = MAPIStoreInternalEntryId (connInfo->sam_ctx, username); } @@ -931,7 +931,7 @@ static NSCharacterSet *hexCharacterSet = nil; contactInfos = [mgr contactInfosForUserWithUIDorEmail: email]; if (contactInfos) { - username = [contactInfos objectForKey: @"c_uid"]; + username = [contactInfos objectForKey: @"sAMAccountName"]; entryId = MAPIStoreInternalEntryId (connInfo->sam_ctx, username); } else diff --git a/OpenChange/MAPIStoreMailMessage.m b/OpenChange/MAPIStoreMailMessage.m index 11eb24d03..9d7342272 100644 --- a/OpenChange/MAPIStoreMailMessage.m +++ b/OpenChange/MAPIStoreMailMessage.m @@ -803,7 +803,7 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data) contactInfos = [mgr contactInfosForUserWithUIDorEmail: email]; if (contactInfos) { - username = [contactInfos objectForKey: @"c_uid"]; + username = [contactInfos objectForKey: @"sAMAccountName"]; samCtx = [[self context] connectionInfo]->sam_ctx; entryId = MAPIStoreInternalEntryId (samCtx, username); } @@ -1501,10 +1501,10 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data) if ([cn length] == 0) cn = email; contactInfos = [mgr contactInfosForUserWithUIDorEmail: email]; - + if (contactInfos) { - username = [contactInfos objectForKey: @"c_uid"]; + username = [contactInfos objectForKey: @"sAMAccountName"]; recipient->username = [username asUnicodeInMemCtx: msgData]; entryId = MAPIStoreInternalEntryId (samCtx, username); } diff --git a/OpenChange/MAPIStoreMailVolatileMessage.m b/OpenChange/MAPIStoreMailVolatileMessage.m index b5239f193..33c803173 100644 --- a/OpenChange/MAPIStoreMailVolatileMessage.m +++ b/OpenChange/MAPIStoreMailVolatileMessage.m @@ -386,7 +386,7 @@ static NSString *recTypes[] = { @"orig", @"to", @"cc", @"bcc" }; contactInfos = [mgr contactInfosForUserWithUIDorEmail: email]; if (contactInfos) { - username = [contactInfos objectForKey: @"c_uid"]; + username = [contactInfos objectForKey: @"sAMAccountName"]; recipient->username = [username asUnicodeInMemCtx: msgData]; entryId = MAPIStoreInternalEntryId (samCtx, username); } diff --git a/OpenChange/MAPIStoreSamDBUtils.m b/OpenChange/MAPIStoreSamDBUtils.m index e1f3fff44..c210deb64 100644 --- a/OpenChange/MAPIStoreSamDBUtils.m +++ b/OpenChange/MAPIStoreSamDBUtils.m @@ -96,8 +96,11 @@ MAPIStoreInternalEntryId (struct ldb_context *samCtx, NSString *username) [entryId appendUInt8: 0]; // end of string } else - entryId = nil; - + { + NSLog (@"Error trying to generate EntryId for `%@`", username); + entryId = nil; + } + return entryId; } diff --git a/SoObjects/SOGo/SOGoUserManager.m b/SoObjects/SOGo/SOGoUserManager.m index 99e9995b2..125ca3fcc 100644 --- a/SoObjects/SOGo/SOGoUserManager.m +++ b/SoObjects/SOGo/SOGoUserManager.m @@ -664,7 +664,7 @@ static Class NSNullK; // // - (void) _fillContactInfosForUser: (NSMutableDictionary *) currentUser - withUIDorEmail: (NSString *) uid + withUIDorEmail: (NSString *) uid inDomain: (NSString *) domain { NSString *sourceID, *cn, *c_domain, *c_uid, *c_imaphostname, *c_imaplogin, *c_sievehostname; @@ -685,12 +685,11 @@ static Class NSNullK; c_sievehostname = nil; [currentUser setObject: [NSNumber numberWithBool: YES] - forKey: @"CalendarAccess"]; + forKey: @"CalendarAccess"]; [currentUser setObject: [NSNumber numberWithBool: YES] - forKey: @"MailAccess"]; + forKey: @"MailAccess"]; - sogoSources = [[self authenticationSourceIDsInDomain: domain] - objectEnumerator]; + sogoSources = [[self authenticationSourceIDsInDomain: domain] objectEnumerator]; userEntry = nil; while (!userEntry && (sourceID = [sogoSources nextObject])) { @@ -698,44 +697,49 @@ static Class NSNullK; userEntry = [currentSource lookupContactEntryWithUIDorEmail: uid inDomain: domain]; if (userEntry) - { + { [currentUser setObject: sourceID forKey: @"SOGoSource"]; - if (!cn) - cn = [userEntry objectForKey: @"c_cn"]; - if (!c_uid) - c_uid = [userEntry objectForKey: @"c_uid"]; + if (!cn) + cn = [userEntry objectForKey: @"c_cn"]; + if (!c_uid) + c_uid = [userEntry objectForKey: @"c_uid"]; if (!c_domain) c_domain = [userEntry objectForKey: @"c_domain"]; - c_emails = [userEntry objectForKey: @"c_emails"]; - if ([c_emails count]) - [emails addObjectsFromArray: c_emails]; - if (!c_imaphostname) - c_imaphostname = [userEntry objectForKey: @"c_imaphostname"]; + c_emails = [userEntry objectForKey: @"c_emails"]; + if ([c_emails count]) + [emails addObjectsFromArray: c_emails]; + if (!c_imaphostname) + c_imaphostname = [userEntry objectForKey: @"c_imaphostname"]; if (!c_imaplogin) c_imaplogin = [userEntry objectForKey: @"c_imaplogin"]; if (!c_sievehostname) c_sievehostname = [userEntry objectForKey: @"c_sievehostname"]; - access = [[userEntry objectForKey: @"CalendarAccess"] boolValue]; - if (!access) - [currentUser setObject: [NSNumber numberWithBool: NO] - forKey: @"CalendarAccess"]; - access = [[userEntry objectForKey: @"MailAccess"] boolValue]; - if (!access) - [currentUser setObject: [NSNumber numberWithBool: NO] - forKey: @"MailAccess"]; - - // We check if it's a group + access = [[userEntry objectForKey: @"CalendarAccess"] boolValue]; + if (!access) + [currentUser setObject: [NSNumber numberWithBool: NO] + forKey: @"CalendarAccess"]; + access = [[userEntry objectForKey: @"MailAccess"] boolValue]; + if (!access) + [currentUser setObject: [NSNumber numberWithBool: NO] + forKey: @"MailAccess"]; + + // We check if it's a group isGroup = [userEntry objectForKey: @"isGroup"]; if (isGroup) [currentUser setObject: isGroup forKey: @"isGroup"]; - // We also fill the resource attributes, if any - if ([userEntry objectForKey: @"isResource"]) - [currentUser setObject: [userEntry objectForKey: @"isResource"] - forKey: @"isResource"]; - if ([userEntry objectForKey: @"numberOfSimultaneousBookings"]) - [currentUser setObject: [userEntry objectForKey: @"numberOfSimultaneousBookings"] - forKey: @"numberOfSimultaneousBookings"]; + // We also fill the resource attributes, if any + if ([userEntry objectForKey: @"isResource"]) + [currentUser setObject: [userEntry objectForKey: @"isResource"] + forKey: @"isResource"]; + if ([userEntry objectForKey: @"numberOfSimultaneousBookings"]) + [currentUser setObject: [userEntry objectForKey: @"numberOfSimultaneousBookings"] + forKey: @"numberOfSimultaneousBookings"]; + + // This is Active Directory specific attribute (needed on OpenChange/* layer) + if ([userEntry objectForKey: @"samaccountname"]) + [currentUser setObject: [userEntry objectForKey: @"samaccountname"] + forKey: @"sAMAccountName"]; } } @@ -745,7 +749,7 @@ static Class NSNullK; c_uid = @""; if (!c_domain) c_domain = @""; - + if (c_imaphostname) [currentUser setObject: c_imaphostname forKey: @"c_imaphostname"]; if (c_imaplogin) From d4930a7960e0cd3c8891d2695d8f957b3471e69d Mon Sep 17 00:00:00 2001 From: Julien Kerihuel Date: Mon, 30 Mar 2015 04:42:13 +0200 Subject: [PATCH 6/7] oc: Remove deprecated notification code. --- OpenChange/MAPIStoreFolder.h | 6 -- OpenChange/MAPIStoreFolder.m | 159 ----------------------------- OpenChange/MAPIStoreMailFolder.m | 7 -- OpenChange/MAPIStoreMessage.m | 44 -------- OpenChange/MAPIStoreMessageTable.m | 51 --------- 5 files changed, 267 deletions(-) diff --git a/OpenChange/MAPIStoreFolder.h b/OpenChange/MAPIStoreFolder.h index e5440bd95..b16e4b91f 100644 --- a/OpenChange/MAPIStoreFolder.h +++ b/OpenChange/MAPIStoreFolder.h @@ -185,12 +185,6 @@ /* subclass helpers */ - (void) setupVersionsMessage; - (void) ensureIDsForChildKeys: (NSArray *) keys; -- (void) postNotificationsForMoveCopyMessagesWithMIDs: (uint64_t *) srcMids - andMessageURLs: (NSArray *) oldMessageURLs - andCount: (uint32_t) midCount - fromFolder: (MAPIStoreFolder *) sourceFolder - withMIDs: (uint64_t *) targetMids - wantCopy: (uint8_t) wantCopy; @end diff --git a/OpenChange/MAPIStoreFolder.m b/OpenChange/MAPIStoreFolder.m index 0d862b85e..6e50248df 100644 --- a/OpenChange/MAPIStoreFolder.m +++ b/OpenChange/MAPIStoreFolder.m @@ -581,8 +581,6 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe NSUInteger count, max; id msgObject; SOGoUser *ownerUser; - struct mapistore_connection_info *connInfo; - struct mapistore_object_notification_parameters *notif_parameters; int rc; /* flags that control the behaviour of the operation @@ -621,49 +619,6 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe } else { - if (![message isNew]) - { - /* folder notification */ - notif_parameters - = talloc_zero(NULL, - struct mapistore_object_notification_parameters); - notif_parameters->object_id = [self objectId]; - notif_parameters->tag_count = 5; - notif_parameters->tags = talloc_array (notif_parameters, - enum MAPITAGS, 5); - notif_parameters->tags[0] = PR_CONTENT_COUNT; - notif_parameters->tags[1] = PR_DELETED_COUNT_TOTAL; - notif_parameters->tags[2] = PR_MESSAGE_SIZE; - notif_parameters->tags[3] = PR_NORMAL_MESSAGE_SIZE; - notif_parameters->tags[4] = PR_DELETED_MSG_COUNT; - notif_parameters->new_message_count = true; - notif_parameters->message_count = [[self messageKeys] - count] - 1; - connInfo = [[self context] connectionInfo]; - mapistore_push_notification (connInfo->mstore_ctx, - MAPISTORE_FOLDER, - MAPISTORE_OBJECT_MODIFIED, - notif_parameters); - talloc_free(notif_parameters); - - /* message notification */ - notif_parameters - = talloc_zero(NULL, - struct mapistore_object_notification_parameters); - notif_parameters->object_id = mid; - notif_parameters->folder_id = [self objectId]; - /* Exchange sends a fnevObjectCreated!! */ - mapistore_push_notification (connInfo->mstore_ctx, - MAPISTORE_MESSAGE, - MAPISTORE_OBJECT_CREATED, - notif_parameters); - talloc_free(notif_parameters); - - /* table notification */ - for (count = 0; count < max; count++) - [[activeTables objectAtIndex: count] - notifyChangesForChild: message]; - } [self logWithFormat: @"successfully deleted object at URL: %@", childURL]; /* Ensure we are respecting flags parameter */ [mapping unregisterURLWithID: mid andFlags: flags]; @@ -790,13 +745,6 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe /* Notifications */ if (rc == MAPISTORE_SUCCESS) { - [self postNotificationsForMoveCopyMessagesWithMIDs: srcMids - andMessageURLs: oldMessageURLs - andCount: midCount - fromFolder: sourceFolder - withMIDs: targetMids - wantCopy: wantCopy]; - // We cleanup cache of our source and destination folders [self cleanupCaches]; [sourceFolder cleanupCaches]; @@ -998,113 +946,6 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe withIDs: newIDs]; } -- (void) postNotificationsForMoveCopyMessagesWithMIDs: (uint64_t *) srcMids - andMessageURLs: (NSArray *) oldMessageURLs - andCount: (uint32_t) midCount - fromFolder: (MAPIStoreFolder *) sourceFolder - withMIDs: (uint64_t *) targetMids - wantCopy: (uint8_t) wantCopy -{ - NSArray *activeTables; - NSUInteger count, tableCount, max; - MAPIStoreMessage *message; - NSString *messageURL; - MAPIStoreMapping *mapping; - struct mapistore_object_notification_parameters *notif_parameters; - struct mapistore_connection_info *connInfo; - - connInfo = [[self context] connectionInfo]; - - // For the "source folder, we ensure the table caches are loaded so - // that old and new state can be compared - activeTables = [sourceFolder activeMessageTables]; - max = [activeTables count]; - for (count = 0; count < max; count++) - [[activeTables objectAtIndex: count] restrictedChildKeys]; - - if (!wantCopy) - { - // We notify the client. We start with the source folder. - notif_parameters = talloc_zero(NULL, struct mapistore_object_notification_parameters); - notif_parameters->object_id = [sourceFolder objectId]; - notif_parameters->tag_count = 5; - notif_parameters->tags = talloc_array (notif_parameters, enum MAPITAGS, 5); - notif_parameters->tags[0] = PR_CONTENT_COUNT; - notif_parameters->tags[1] = PR_DELETED_COUNT_TOTAL; - notif_parameters->tags[2] = PR_MESSAGE_SIZE; - notif_parameters->tags[3] = PR_NORMAL_MESSAGE_SIZE; - notif_parameters->tags[4] = PR_RECIPIENT_ON_NORMAL_MSG_COUNT; - notif_parameters->new_message_count = true; - notif_parameters->message_count = [[sourceFolder messageKeys] count] - midCount; - mapistore_push_notification (connInfo->mstore_ctx, - MAPISTORE_FOLDER, - MAPISTORE_OBJECT_MODIFIED, - notif_parameters); - talloc_free(notif_parameters); - } - - // move/copy notification of the copied/moved message - for (count = 0; count < midCount; count++) - { - notif_parameters = talloc_zero (NULL, struct mapistore_object_notification_parameters); - notif_parameters->tag_count = 0; - notif_parameters->new_message_count = true; - notif_parameters->message_count = 0; - notif_parameters->object_id = targetMids[count]; - notif_parameters->folder_id = [self objectId]; - notif_parameters->old_object_id = srcMids[count]; - notif_parameters->old_folder_id = [sourceFolder objectId]; - - mapistore_push_notification (connInfo->mstore_ctx, - MAPISTORE_MESSAGE, - (wantCopy ? MAPISTORE_OBJECT_COPIED : MAPISTORE_OBJECT_MOVED), - notif_parameters); - talloc_free (notif_parameters); - - message = [sourceFolder lookupMessageByURL: [oldMessageURLs objectAtIndex: count]]; - // table notification - for (tableCount = 0; tableCount < max; tableCount++) - [[activeTables objectAtIndex: tableCount] - notifyChangesForChild: message]; - } - - // For the "destination folder, we ensure the table caches are loaded so - // that old and new state can be compared - activeTables = [self activeMessageTables]; - max = [activeTables count]; - for (count = 0; count < max; count++) - [[activeTables objectAtIndex: count] restrictedChildKeys]; - - notif_parameters = talloc_zero(NULL, struct mapistore_object_notification_parameters); - notif_parameters->object_id = [self objectId]; - notif_parameters->tag_count = 5; - notif_parameters->tags = talloc_array (notif_parameters, enum MAPITAGS, 5); - notif_parameters->tags[0] = PR_CONTENT_COUNT; - notif_parameters->tags[1] = PR_DELETED_COUNT_TOTAL; - notif_parameters->tags[2] = PR_MESSAGE_SIZE; - notif_parameters->tags[3] = PR_NORMAL_MESSAGE_SIZE; - notif_parameters->tags[4] = PR_RECIPIENT_ON_NORMAL_MSG_COUNT; - notif_parameters->new_message_count = true; - notif_parameters->message_count = [[self messageKeys] count] + midCount; - connInfo = [[self context] connectionInfo]; - mapistore_push_notification (connInfo->mstore_ctx, - MAPISTORE_FOLDER, - MAPISTORE_OBJECT_MODIFIED, - notif_parameters); - talloc_free(notif_parameters); - - // table notification - mapping = [self mapping]; - for (count = 0; count < midCount; count++) - { - messageURL = [mapping urlFromID: targetMids[count]]; - message = [self lookupMessageByURL: messageURL]; - for (tableCount = 0; tableCount < max; tableCount++) - [[activeTables objectAtIndex: tableCount] - notifyChangesForChild: message]; - } -} - - (int) getDeletedFMIDs: (struct UI8Array_r **) fmidsPtr andCN: (uint64_t *) cnPtr fromChangeNumber: (uint64_t) changeNum diff --git a/OpenChange/MAPIStoreMailFolder.m b/OpenChange/MAPIStoreMailFolder.m index 07d1debe2..d2036454a 100644 --- a/OpenChange/MAPIStoreMailFolder.m +++ b/OpenChange/MAPIStoreMailFolder.m @@ -1295,13 +1295,6 @@ _parseCOPYUID (NSString *line, NSArray **destUIDsP) } } - [self postNotificationsForMoveCopyMessagesWithMIDs: srcMids - andMessageURLs: oldMessageURLs - andCount: midCount - fromFolder: sourceFolder - withMIDs: targetMids - wantCopy: wantCopy]; - // We cleanup cache of our source and destination folders [self cleanupCaches]; [sourceFolder cleanupCaches]; diff --git a/OpenChange/MAPIStoreMessage.m b/OpenChange/MAPIStoreMessage.m index e922d4a18..5d5e03dac 100644 --- a/OpenChange/MAPIStoreMessage.m +++ b/OpenChange/MAPIStoreMessage.m @@ -465,9 +465,6 @@ rtf2html (NSData *compressedRTF) enum mapistore_error rc; NSArray *containerTables; NSUInteger count, max; - struct mapistore_object_notification_parameters *notif_parameters; - uint64_t folderId; - struct mapistore_context *mstoreCtx; MAPIStoreContext *context; SOGoUser *ownerUser; BOOL userIsOwner; @@ -498,47 +495,6 @@ rtf2html (NSData *compressedRTF) /* notifications */ if ([container isKindOfClass: MAPIStoreFolderK]) { - folderId = [(MAPIStoreFolder *) container objectId]; - mstoreCtx = [[self context] connectionInfo]->mstore_ctx; - - /* folder modified */ - notif_parameters - = talloc_zero(memCtx, struct mapistore_object_notification_parameters); - notif_parameters->object_id = folderId; - if (isNew) - { - notif_parameters->tag_count = 3; - notif_parameters->tags = talloc_array (notif_parameters, - enum MAPITAGS, 3); - notif_parameters->tags[0] = PR_CONTENT_COUNT; - notif_parameters->tags[1] = PR_MESSAGE_SIZE; - notif_parameters->tags[2] = PR_NORMAL_MESSAGE_SIZE; - notif_parameters->new_message_count = true; - notif_parameters->message_count - = [[(MAPIStoreFolder *) container messageKeys] count] + 1; - } - mapistore_push_notification (mstoreCtx, - MAPISTORE_FOLDER, - MAPISTORE_OBJECT_MODIFIED, - notif_parameters); - talloc_free (notif_parameters); - - /* message created */ - if (isNew) - { - notif_parameters - = talloc_zero(memCtx, - struct mapistore_object_notification_parameters); - notif_parameters->object_id = [self objectId]; - notif_parameters->folder_id = folderId; - - notif_parameters->tag_count = 0xffff; - mapistore_push_notification (mstoreCtx, - MAPISTORE_MESSAGE, MAPISTORE_OBJECT_CREATED, - notif_parameters); - talloc_free (notif_parameters); - } - /* we ensure the table caches are loaded so that old and new state can be compared */ containerTables = [self activeContainerMessageTables]; diff --git a/OpenChange/MAPIStoreMessageTable.m b/OpenChange/MAPIStoreMessageTable.m index 75d5adab9..f978a5ea6 100644 --- a/OpenChange/MAPIStoreMessageTable.m +++ b/OpenChange/MAPIStoreMessageTable.m @@ -87,58 +87,7 @@ - (void) notifyChangesForChild: (MAPIStoreMessage *) child { - NSUInteger currentChildRow, newChildRow; - NSArray *list; - NSString *childName; - struct mapistore_table_notification_parameters notif_parameters; - struct mapistore_context *mstoreCtx; - mstoreCtx = [[(MAPIStoreFolder *) container context] - connectionInfo]->mstore_ctx; - - notif_parameters.table_type = tableType; - notif_parameters.handle = handleId; - notif_parameters.folder_id = [(MAPIStoreFolder *) container objectId]; - notif_parameters.object_id = [child objectId]; - notif_parameters.instance_id = 0; /* TODO: always 0 ? */ - - childName = [child nameInContainer]; - list = [self restrictedChildKeys]; - currentChildRow = [list indexOfObject: childName]; - notif_parameters.row_id = currentChildRow; - - [self cleanupCaches]; - list = [self restrictedChildKeys]; - newChildRow = [list indexOfObject: childName]; - - if (currentChildRow == NSNotFound) - { - if (newChildRow != NSNotFound) - { - notif_parameters.row_id = newChildRow; - mapistore_push_notification (mstoreCtx, - MAPISTORE_TABLE, - MAPISTORE_OBJECT_CREATED, - ¬if_parameters); - } - } - else - { - if (newChildRow == NSNotFound) - mapistore_push_notification (mstoreCtx, - MAPISTORE_TABLE, - MAPISTORE_OBJECT_DELETED, - ¬if_parameters); - else - { - /* the fact that the row order has changed has no impact here */ - notif_parameters.row_id = newChildRow; - mapistore_push_notification (mstoreCtx, - MAPISTORE_TABLE, - MAPISTORE_OBJECT_MODIFIED, - ¬if_parameters); - } - } } @end From 539060d25271cc5e5ba0a28d34522f806ff4025b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Antonio=20Calvo?= Date: Thu, 16 Apr 2015 09:34:43 +0200 Subject: [PATCH 7/7] oc-calendar: Fix recipient type for invitations Take into account optional attendees setting the recipient type to MAPI_CC when they have the iCal role set to OPT-PARTICIPANT instead of harding always MAPI_TO (required) as was done before. This is a complementary fix for: https://github.com/Zentyal/sogo/pull/108 --- OpenChange/MAPIStoreAppointmentWrapper.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenChange/MAPIStoreAppointmentWrapper.m b/OpenChange/MAPIStoreAppointmentWrapper.m index 7fa60c5c5..07996572b 100644 --- a/OpenChange/MAPIStoreAppointmentWrapper.m +++ b/OpenChange/MAPIStoreAppointmentWrapper.m @@ -273,7 +273,7 @@ static NSCharacterSet *hexCharacterSet = nil; recipient->username = NULL; entryId = MAPIStoreExternalEntryId (cn, email); } - recipient->type = MAPI_TO; + recipient->type = [[person role] isEqualToString: @"OPT-PARTICIPANT"] ? MAPI_CC : MAPI_TO; /* properties */ p = 0; @@ -283,7 +283,7 @@ static NSCharacterSet *hexCharacterSet = nil; // PR_OBJECT_TYPE = MAPI_MAILUSER (see MAPI_OBJTYPE) recipient->data[p] = MAPILongValue (msgData, MAPI_MAILUSER); p++; - + // PR_DISPLAY_TYPE = DT_MAILUSER (see MS-NSPI) recipient->data[p] = MAPILongValue (msgData, 0); p++; @@ -383,7 +383,7 @@ static NSCharacterSet *hexCharacterSet = nil; // PR_OBJECT_TYPE = MAPI_MAILUSER (see MAPI_OBJTYPE) recipient->data[p] = MAPILongValue (msgData, MAPI_MAILUSER); p++; - + // PR_DISPLAY_TYPE = DT_MAILUSER (see MS-NSPI) recipient->data[p] = MAPILongValue (msgData, 0); p++;