Merge pull request #110 from Zentyal/ejhernandez/sharing-calendar-request
This requires https://github.com/openchange/openchange/pull/244 to work but basically we have modified this backend to store request-related properties in a `MAPIStoreMailMessage` using the versions message from the `MAPIStoreMailFolder` container and fix the setter/getter for the following properties: * PidNameXSharingFlavor * PidLidSharingFlavor * PidNameXSharingCapabilities * PidLidSharingResponseType * PidLidSharingResponseTimepull/65/head
commit
0e5de2df42
1
NEWS
1
NEWS
|
@ -2,6 +2,7 @@ master
|
|||
------
|
||||
|
||||
Enhancements
|
||||
- Sharing request among different Outlook versions
|
||||
- Improve sync speed from Outlook by non-reprocessing already downloaded unread mails
|
||||
|
||||
Bug fixes
|
||||
|
|
|
@ -55,6 +55,11 @@
|
|||
- (NSData *) changeKeyForMessageWithKey: (NSString *) messageKey;
|
||||
- (NSData *) predecessorChangeListForMessageWithKey: (NSString *) messageKey;
|
||||
|
||||
/* Extra properties from mail messages that already hit the server */
|
||||
- (void) setExtraProperties: (NSDictionary *) props
|
||||
forMessage: (NSString *) messageKey;
|
||||
- (NSDictionary *) extraPropertiesForMessage: (NSString *) messageKey;
|
||||
|
||||
@end
|
||||
|
||||
/* MAPIStoreOutboxFolder is a special subclass of MAPIStoreMailFolder where
|
||||
|
|
|
@ -964,6 +964,37 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data)
|
|||
return list;
|
||||
}
|
||||
|
||||
/* Management for extra properties once they already hit the IMAP server */
|
||||
- (void) setExtraProperties: (NSDictionary *) props
|
||||
forMessage: (NSString *) messageKey
|
||||
{
|
||||
NSMutableDictionary *extraProps, *currentProperties;
|
||||
NSString *messageUid;
|
||||
|
||||
messageUid = [self messageUIDFromMessageKey: messageKey];
|
||||
currentProperties = [versionsMessage properties];
|
||||
extraProps = [currentProperties objectForKey: @"ExtraMessagesProperties"];
|
||||
if (!extraProps)
|
||||
{
|
||||
extraProps = [NSMutableDictionary new];
|
||||
[currentProperties setObject: extraProps forKey: @"ExtraMessagesProperties"];
|
||||
[extraProps release];
|
||||
}
|
||||
|
||||
[extraProps setObject: props
|
||||
forKey: messageUid];
|
||||
[versionsMessage save];
|
||||
}
|
||||
|
||||
- (NSDictionary *) extraPropertiesForMessage: (NSString *) messageKey
|
||||
{
|
||||
NSString *messageUid;
|
||||
|
||||
messageUid = [self messageUIDFromMessageKey: messageKey];
|
||||
return [[[versionsMessage properties] objectForKey: @"ExtraMessagesProperties"]
|
||||
objectForKey: messageUid];
|
||||
}
|
||||
|
||||
- (NSArray *) getDeletedKeysFromChangeNumber: (uint64_t) changeNum
|
||||
andCN: (NSNumber **) cnNbr
|
||||
inTableType: (uint8_t) tableType
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSData.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSScanner.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSValue.h>
|
||||
#import <NGExtensions/NGBase64Coding.h>
|
||||
|
@ -541,6 +542,7 @@ FillMessageHeadersFromSharingProperties (NGMutableHashMap *headers, NSDictionary
|
|||
about the properties */
|
||||
|
||||
id value;
|
||||
NSNumber *sharingFlavourNum = nil;
|
||||
|
||||
value = [mailProperties objectForKey: MAPIPropertyKey (PidLidSharingCapabilities)];
|
||||
if (value)
|
||||
|
@ -549,8 +551,32 @@ FillMessageHeadersFromSharingProperties (NGMutableHashMap *headers, NSDictionary
|
|||
|
||||
value = [mailProperties objectForKey: MAPIPropertyKey (PidLidSharingFlavor)];
|
||||
if (value)
|
||||
[headers setObject: value
|
||||
forKey: @"X-MS-Sharing-Flavor"];
|
||||
sharingFlavourNum = (NSNumber *)value;
|
||||
else
|
||||
{
|
||||
value = [mailProperties objectForKey: MAPIPropertyKey (PidNameXSharingFlavor)];
|
||||
if (value)
|
||||
{
|
||||
/* Transform the hex string to unsigned int */
|
||||
NSScanner *scanner;
|
||||
unsigned int sharingFlavour;
|
||||
scanner = [NSScanner scannerWithString:value];
|
||||
if ([scanner scanHexInt:&sharingFlavour])
|
||||
sharingFlavourNum =[NSNumber numberWithUnsignedInt: sharingFlavour];
|
||||
}
|
||||
}
|
||||
if (sharingFlavourNum)
|
||||
{
|
||||
if ([sharingFlavourNum unsignedIntegerValue] == 0x5100)
|
||||
{
|
||||
/* 0x5100 sharing flavour is not in standard but it seems to
|
||||
be a denial of request + invitation message so we store
|
||||
deny sharing flavour */
|
||||
sharingFlavourNum = [NSNumber numberWithUnsignedInt: SHARING_DENY_REQUEST];
|
||||
}
|
||||
[headers setObject: sharingFlavourNum
|
||||
forKey: @"X-MS-Sharing-Flavor"];
|
||||
}
|
||||
|
||||
value = [mailProperties objectForKey: MAPIPropertyKey (PidLidSharingInitiatorEntryId)];
|
||||
if (value)
|
||||
|
|
|
@ -23,8 +23,10 @@
|
|||
#ifndef MAPISTORESHARINGMESSAGE_H
|
||||
#define MAPISTORESHARINGMESSAGE_H
|
||||
|
||||
#import "MAPIStoreMailMessage.h"
|
||||
#import "MAPIStoreObjectProxy.h"
|
||||
|
||||
#define SHARING_SPECIAL_FOLDER 0x40290
|
||||
|
||||
@interface MAPIStoreSharingMessage : MAPIStoreObjectProxy
|
||||
{
|
||||
|
@ -33,7 +35,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 +92,10 @@
|
|||
- (int) getPidNameContentClass: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx;
|
||||
|
||||
/* Save */
|
||||
- (void) saveWithMessage: (MAPIStoreMailMessage *) msg
|
||||
andSOGoObject: (SOGoMailObject *) sogoObject;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* MAPISTORECALENDARWRAPPER_H */
|
||||
|
|
|
@ -22,9 +22,11 @@
|
|||
|
||||
#include <talloc.h>
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSData.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
|
||||
#import <Mailer/SOGoMailObject.h>
|
||||
#import <NGExtensions/NGBase64Coding.h>
|
||||
|
||||
#import "MAPIStoreTypes.h"
|
||||
|
@ -33,9 +35,12 @@
|
|||
#import "NSString+MAPIStore.h"
|
||||
#import "NSValue+MAPIStore.h"
|
||||
|
||||
#import "MAPIStoreMailFolder.h"
|
||||
#import "MAPIStoreSharingMessage.h"
|
||||
|
||||
#include <mapistore/mapistore.h>
|
||||
#include <mapistore/mapistore_errors.h>
|
||||
#include <mapistore/mapistore_nameid.h>
|
||||
|
||||
@implementation MAPIStoreSharingMessage
|
||||
|
||||
|
@ -52,6 +57,7 @@
|
|||
|
||||
- (id) initWithMailHeaders: (NSDictionary *) mailHeaders
|
||||
andConnectionInfo: (struct mapistore_connection_info *) newConnInfo
|
||||
fromMessage: (MAPIStoreMailMessage *) msg
|
||||
{
|
||||
NSEnumerator *enumerator;
|
||||
NSString *key;
|
||||
|
@ -67,6 +73,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;
|
||||
|
@ -123,7 +135,8 @@
|
|||
value = [properties objectForKey: @"x-ms-sharing-capabilities"];
|
||||
if (value)
|
||||
{
|
||||
*data = [[value stringValue] asUnicodeInMemCtx: memCtx];
|
||||
*data = [[NSString stringWithFormat:@"%X", [value intValue]]
|
||||
asUnicodeInMemCtx: memCtx];
|
||||
rc = MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -163,28 +176,28 @@
|
|||
value = [properties objectForKey: @"x-ms-sharing-capabilities"];
|
||||
if (value)
|
||||
{
|
||||
if ([value intValue] == 0x40290) /* Special folder */
|
||||
if ([value intValue] == SHARING_SPECIAL_FOLDER)
|
||||
{
|
||||
value = [properties objectForKey: @"x-ms-sharing-responsetime"];
|
||||
auxValue = [properties objectForKey: @"x-ms-sharing-remotename"];
|
||||
auxValue = [properties objectForKey: @"x-ms-sharing-remoteuid"];
|
||||
if (value) /* A sharing request */
|
||||
{
|
||||
if (auxValue)
|
||||
*data = MAPILongValue (memCtx, 0x20710);
|
||||
*data = MAPILongValue (memCtx, SHARING_INVITATION_REQUEST_FOLDER);
|
||||
else
|
||||
*data = MAPILongValue (memCtx, 0x20500);
|
||||
*data = MAPILongValue (memCtx, SHARING_REQUEST_SPECIAL_FOLDER);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (auxValue) /* It SHOULD be an invitation or response acceptance */
|
||||
*data = MAPILongValue (memCtx, 0x20310);
|
||||
else
|
||||
*data = MAPILongValue (memCtx, 0x23310);
|
||||
if (auxValue) /* It SHOULD be an invitation or response */
|
||||
*data = MAPILongValue (memCtx, SHARING_INVITATION_SPECIAL_FOLDER);
|
||||
else /* No remote info, then denial */
|
||||
*data = MAPILongValue (memCtx, SHARING_DENY_REQUEST);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*data = MAPILongValue (memCtx, 0x310);
|
||||
*data = MAPILongValue (memCtx, SHARING_INVITATION_FOLDER);
|
||||
}
|
||||
rc = MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
@ -202,7 +215,8 @@
|
|||
value = [properties objectForKey: @"x-ms-sharing-flavor"];
|
||||
if (value)
|
||||
{
|
||||
*data = [[value stringValue] asUnicodeInMemCtx: memCtx];
|
||||
*data = [[NSString stringWithFormat:@"%X", [value intValue]]
|
||||
asUnicodeInMemCtx: memCtx];
|
||||
rc = MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -368,7 +382,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 +410,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 +426,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
|
||||
|
|
Loading…
Reference in New Issue