From 514b1c03be190f065f45e5e205e2efd0a2d241d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20J=2E=20Hern=C3=A1ndez=20Blasco?= Date: Wed, 18 Mar 2015 23:57:33 +0100 Subject: [PATCH] oc-mail: Store request properties Save them in extra properties from folder container. This is required because the client once a request is accepted or denied sets these two properties and save the message again. As we cannot modify an IMAP message, we use this utility. See [MS-OXSHARE] Section 3.1.4.3 for details. --- OpenChange/MAPIStoreMailMessage.m | 26 +++++++++++- OpenChange/MAPIStoreSharingMessage.h | 9 +++- OpenChange/MAPIStoreSharingMessage.m | 63 ++++++++++++++++++++++++++-- 3 files changed, 90 insertions(+), 8 deletions(-) diff --git a/OpenChange/MAPIStoreMailMessage.m b/OpenChange/MAPIStoreMailMessage.m index 8c35f4265..c0ca8f9b6 100644 --- a/OpenChange/MAPIStoreMailMessage.m +++ b/OpenChange/MAPIStoreMailMessage.m @@ -65,7 +65,7 @@ @class iCalCalendar, iCalEvent; -static Class NSExceptionK; +static Class NSExceptionK, MAPIStoreSharingMessageK; @interface NSString (MAPIStoreMIME) @@ -108,6 +108,7 @@ static Class NSExceptionK; + (void) initialize { NSExceptionK = [NSException class]; + MAPIStoreSharingMessageK = [MAPIStoreSharingMessage class]; } - (id) init @@ -267,7 +268,8 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data) a sharing object is a proxy in a mail message */ sharingMessage = [[MAPIStoreSharingMessage alloc] initWithMailHeaders: [sogoObject mailHeaders] - andConnectionInfo: [[self context] connectionInfo]]; + andConnectionInfo: [[self context] connectionInfo] + fromMessage: self]; [self addProxy: sharingMessage]; [sharingMessage release]; } @@ -1641,6 +1643,21 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data) bodySetup = YES; } +- (MAPIStoreSharingMessage *) _sharingObject +{ + /* Get the sharing object if available */ + NSUInteger i, max; + id proxy; + + max = [proxies count]; + for (i = 0; i < max; i++) { + proxy = [proxies objectAtIndex: i]; + if ([proxy isKindOfClass: MAPIStoreSharingMessageK]) + return proxy; + } + return nil; +} + - (void) save: (TALLOC_CTX *) memCtx { NSNumber *value; @@ -1654,6 +1671,11 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data) else /* 0: unflagged, 1: follow up complete */ [sogoObject removeFlags: @"\\Flagged"]; } + + if (mailIsSharingObject) + [[self _sharingObject] saveWithMessage: self + andSOGoObject: sogoObject]; + } @end diff --git a/OpenChange/MAPIStoreSharingMessage.h b/OpenChange/MAPIStoreSharingMessage.h index 9b62389a0..c3ca14feb 100644 --- a/OpenChange/MAPIStoreSharingMessage.h +++ b/OpenChange/MAPIStoreSharingMessage.h @@ -23,9 +23,9 @@ #ifndef MAPISTORESHARINGMESSAGE_H #define MAPISTORESHARINGMESSAGE_H +#import "MAPIStoreMailMessage.h" #import "MAPIStoreObjectProxy.h" - @interface MAPIStoreSharingMessage : MAPIStoreObjectProxy { struct mapistore_connection_info *connInfo; @@ -33,7 +33,8 @@ } - (id) initWithMailHeaders: (NSDictionary *) mailHeaders - andConnectionInfo: (struct mapistore_connection_info *) newConnInfo; + andConnectionInfo: (struct mapistore_connection_info *) newConnInfo + fromMessage: (MAPIStoreMailMessage *) msg; /* getters */ - (int) getPidLidSharingCapabilities: (void **) data @@ -89,6 +90,10 @@ - (int) getPidNameContentClass: (void **) data inMemCtx: (TALLOC_CTX *) memCtx; +/* Save */ +- (void) saveWithMessage: (MAPIStoreMailMessage *) msg + andSOGoObject: (SOGoMailObject *) sogoObject; + @end #endif /* MAPISTORECALENDARWRAPPER_H */ diff --git a/OpenChange/MAPIStoreSharingMessage.m b/OpenChange/MAPIStoreSharingMessage.m index 594863e0e..339ca0750 100644 --- a/OpenChange/MAPIStoreSharingMessage.m +++ b/OpenChange/MAPIStoreSharingMessage.m @@ -22,9 +22,11 @@ #include +#import #import #import +#import #import #import "MAPIStoreTypes.h" @@ -33,9 +35,11 @@ #import "NSString+MAPIStore.h" #import "NSValue+MAPIStore.h" +#import "MAPIStoreMailFolder.h" #import "MAPIStoreSharingMessage.h" #include +#include @implementation MAPIStoreSharingMessage @@ -52,6 +56,7 @@ - (id) initWithMailHeaders: (NSDictionary *) mailHeaders andConnectionInfo: (struct mapistore_connection_info *) newConnInfo + fromMessage: (MAPIStoreMailMessage *) msg { NSEnumerator *enumerator; NSString *key; @@ -67,6 +72,12 @@ [properties setObject: [mailHeaders objectForKey: key] forKey: key]; } + + /* Set request properties from container folder */ + NSDictionary *requestProps = [(MAPIStoreMailFolder *)[msg container] + extraPropertiesForMessage: [msg nameInContainer]]; + if (requestProps) + [properties addEntriesFromDictionary: requestProps]; } return self; @@ -368,7 +379,18 @@ enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; id value; - value = [properties objectForKey: @"x-ms-sharing-responsetime"]; + value = [properties objectForKey: MAPIPropertyKey (PidLidSharingResponseTime)]; + if (!value) + { + value = [properties objectForKey: @"x-ms-sharing-responsetime"]; + if (value) + { + /* Here the value is a GSCBufferString */ + NSString * responseTime = [NSString stringWithUTF8String: [value UTF8String]]; + value = [NSDate dateWithString: responseTime]; + } + } + if (value) { *data = [value asFileTimeInMemCtx: memCtx]; @@ -385,7 +407,10 @@ enum mapistore_error rc = MAPISTORE_ERR_NOT_FOUND; id value; - value = [properties objectForKey: @"x-ms-sharing-responsetype"]; + value = [properties objectForKey: MAPIPropertyKey (PidLidSharingResponseType)]; + if (!value) + value = [properties objectForKey: @"x-ms-sharing-responsetype"]; + if (value) { *data = MAPILongValue (memCtx, [value intValue]); @@ -398,8 +423,38 @@ - (int) getPidNameContentClass: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { - *data = talloc_strdup (memCtx, "Sharing"); - return MAPISTORE_SUCCESS; + *data = talloc_strdup (memCtx, "Sharing"); + return MAPISTORE_SUCCESS; +} + +- (void) saveWithMessage: (MAPIStoreMailMessage *) msg + andSOGoObject: (SOGoMailObject *) sogoObject +{ + /* Store PidLidSharingResponseType and PidLidSharingResponseTime if + required in versions message from the container as I don't see + other straightforward place to put that information */ + id response; + NSDictionary *propsToStore; + + response = [[msg properties] objectForKey: MAPIPropertyKey (PidLidSharingResponseType)]; + if (response) + { + /* FIXME: Is there any better way to increase the modseq? */ + [sogoObject addFlags: @"\\Draft"]; + [sogoObject removeFlags: @"\\Draft"]; + + /* Store this modification in container folder along the property values */ + propsToStore = [NSDictionary dictionaryWithObjects: + [NSArray arrayWithObjects: response, + [[msg properties] objectForKey: MAPIPropertyKey (PidLidSharingResponseTime)], + nil] + forKeys: + [NSArray arrayWithObjects: MAPIPropertyKey (PidLidSharingResponseType), + MAPIPropertyKey (PidLidSharingResponseTime), nil]]; + + [(MAPIStoreMailFolder *)[msg container] setExtraProperties: propsToStore + forMessage: [msg nameInContainer]]; + } } @end