mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-07-15 05:14:53 +00:00
(feat) first pas at EAS v16 support and save in drafts
Conflicts: ActiveSync/SOGoMailObject+ActiveSync.m
This commit is contained in:
@@ -366,8 +366,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
// the case, let's just update it. This can happen if for example, an iOS based device receives the
|
||||
// invitation email and choses "Add to calendar" BEFORE actually syncing the calendar. That would
|
||||
// create a duplicate on the server.
|
||||
if ([allValues objectForKey: @"UID"])
|
||||
serverId = [allValues objectForKey: @"UID"];
|
||||
if ([allValues objectForKey: ([[context objectForKey: @"ASProtocolVersion"] floatValue] >= 16.0) ? @"ClientUid" : @"UID"])
|
||||
serverId = [allValues objectForKey: ([[context objectForKey: @"ASProtocolVersion"] floatValue] >= 16.0) ? @"ClientUid" : @"UID"];
|
||||
else
|
||||
serverId = [theCollection globallyUniqueObjectId];
|
||||
|
||||
@@ -402,9 +402,33 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
case ActiveSyncMailFolder:
|
||||
default:
|
||||
{
|
||||
// FIXME - what to do?
|
||||
[self errorWithFormat: @"Fatal error occured - tried to call -processSyncAddCommand: ... on a mail folder. We abort."];
|
||||
abort();
|
||||
// Support SMS to Exchange eMail sync.
|
||||
NSString *serverId;
|
||||
sogoObject = [SOGoMailObject objectWithName: @"Mail" inContainer: theCollection];
|
||||
serverId = [sogoObject storeMail: allValues inContext: context];
|
||||
if (serverId)
|
||||
{
|
||||
// Everything is fine, lets generate our response
|
||||
// serverId = clientId - There is no furhter processing after adding the SMS to the inbox.
|
||||
[theBuffer appendString: @"<Add>"];
|
||||
[theBuffer appendFormat: @"<ClientId>%@</ClientId>", clientId];
|
||||
[theBuffer appendFormat: @"<ServerId>%@</ServerId>", serverId];
|
||||
[theBuffer appendFormat: @"<Status>%d</Status>", 1];
|
||||
[theBuffer appendString: @"</Add>"];
|
||||
|
||||
folderMetadata = [self _folderMetadataForKey: [self _getNameInCache: theCollection withType: theFolderType]];
|
||||
syncCache = [folderMetadata objectForKey: @"SyncCache"];
|
||||
[syncCache setObject: @"0" forKey: serverId];
|
||||
[self _setFolderMetadata: folderMetadata forKey: [self _getNameInCache: theCollection withType: theFolderType]];
|
||||
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME - what to do?
|
||||
[self errorWithFormat: @"Fatal error occured - tried to call -processSyncAddCommand: ... on a mail folder. We abort."];
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4151,7 +4151,7 @@ void handle_eas_terminate(int signum)
|
||||
return_response:
|
||||
[theResponse setHeader: @"14.1" forKey: @"MS-Server-ActiveSync"];
|
||||
[theResponse setHeader: @"Sync,SendMail,SmartForward,SmartReply,GetAttachment,GetHierarchy,CreateCollection,DeleteCollection,MoveCollection,FolderSync,FolderCreate,FolderDelete,FolderUpdate,MoveItems,GetItemEstimate,MeetingResponse,Search,Settings,Ping,ItemOperations,ResolveRecipients,ValidateCert" forKey: @"MS-ASProtocolCommands"];
|
||||
[theResponse setHeader: @"2.5,12.0,12.1,14.0,14.1" forKey: @"MS-ASProtocolVersions"];
|
||||
[theResponse setHeader: @"2.5,12.0,12.1,14.0,14.1,16.0" forKey: @"MS-ASProtocolVersions"];
|
||||
|
||||
if (debugOn && [[theResponse headerForKey: @"Content-Type"] isEqualToString:@"application/vnd.ms-sync.wbxml"] && [[theResponse content] length] && !([(WOResponse *)theResponse status] == 500))
|
||||
[self logWithFormat: @"EAS - response for device %@: %@", [context objectForKey: @"DeviceId"], [[[NSString alloc] initWithData: [[theResponse content] wbxml2xml] encoding: NSUTF8StringEncoding] autorelease]];
|
||||
|
||||
@@ -42,6 +42,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
- (NSString *) activeSyncRepresentationInContext: (WOContext *) context;
|
||||
- (void) takeActiveSyncValues: (NSDictionary *) theValues
|
||||
inContext: (WOContext *) context;
|
||||
- (NSString *) storeMail: (NSDictionary *) theValues
|
||||
inContext: (WOContext *) _context;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#import <Foundation/NSException.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSCharacterSet.h>
|
||||
#import <Foundation/NSTimeZone.h>
|
||||
|
||||
#import <NGCards/iCalCalendar.h>
|
||||
#import <NGCards/iCalDateTime.h>
|
||||
@@ -46,9 +47,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#import <NGExtensions/NGQuotedPrintableCoding.h>
|
||||
#import <NGExtensions/NSString+misc.h>
|
||||
#import <NGExtensions/NSString+Encoding.h>
|
||||
#import <NGExtensions/NGHashMap.h>
|
||||
#import <NGImap4/NGImap4Envelope.h>
|
||||
#import <NGImap4/NGImap4EnvelopeAddress.h>
|
||||
#import <NGImap4/NSString+Imap4.h>
|
||||
#import <NGImap4/NGImap4Connection.h>
|
||||
#import <NGImap4/NGImap4Client.h>
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#import <NGObjWeb/WOApplication.h>
|
||||
|
||||
@@ -63,6 +67,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#import <Mailer/SOGoMailLabel.h>
|
||||
|
||||
#import <SOGo/SOGoUserDefaults.h>
|
||||
#import <SOGo/SOGoUserFolder.h>
|
||||
|
||||
#include "iCalTimeZone+ActiveSync.h"
|
||||
#include "NSData+ActiveSync.h"
|
||||
@@ -73,6 +78,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <Appointments/iCalPerson+SOGo.h>
|
||||
#include <Mailer/NSString+Mail.h>
|
||||
#include <Mailer/SOGoMailBodyPart.h>
|
||||
#import <Mailer/SOGoMailLabel.h>
|
||||
#import <Mailer/SOGoMailFolder.h>
|
||||
#import <Mailer/SOGoMailObject.h>
|
||||
#import <Mailer/SOGoMailAccount.h>
|
||||
#import <Mailer/SOGoMailAccounts.h>
|
||||
|
||||
#include <SOGo/SOGoUser.h>
|
||||
#include <SOGo/NSString+Utilities.h>
|
||||
|
||||
@@ -962,7 +973,12 @@ struct GlobalObjectId {
|
||||
|
||||
// Location
|
||||
if ([[event location] length])
|
||||
[s appendFormat: @"<Location xmlns=\"Email:\">%@</Location>", [[event location] activeSyncRepresentationInContext: context]];
|
||||
{
|
||||
if ([[context objectForKey: @"ASProtocolVersion"] floatValue] >= 16.0)
|
||||
[s appendFormat: @"<Location xmlns=\"AirSyncBase:\"><DisplayName>%@</DisplayName></Location>", [[event location] activeSyncRepresentationInContext: context]];
|
||||
else
|
||||
[s appendFormat: @"<Location xmlns=\"Email:\">%@</Location>", [[event location] activeSyncRepresentationInContext: context]];
|
||||
}
|
||||
|
||||
[s appendFormat: @"<Organizer xmlns=\"Email:\">%@</Organizer>", [[[event organizer] mailAddress] activeSyncRepresentationInContext: context]];
|
||||
|
||||
@@ -1422,4 +1438,96 @@ struct GlobalObjectId {
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *) storeMail: (NSDictionary *) theValues
|
||||
inContext: (WOContext *) _context
|
||||
{
|
||||
int bodyType;
|
||||
NGImap4Client *client;
|
||||
NSData *message_data;
|
||||
NSString *folder, *s;
|
||||
id o, result;
|
||||
NSDictionary *identity;
|
||||
NGMutableHashMap *map;
|
||||
NGMimeMessage *bounceMessage;
|
||||
NGMimeMessageGenerator *generator;
|
||||
NSString *email, *dateReceived;
|
||||
|
||||
identity = [[context activeUser] primaryIdentity];
|
||||
email = [identity objectForKey: @"email"];
|
||||
|
||||
|
||||
bodyType = 1;
|
||||
|
||||
if ((o = [[theValues objectForKey: @"Body"] objectForKey: @"Type"]))
|
||||
{
|
||||
bodyType = [o intValue];
|
||||
}
|
||||
|
||||
if (bodyType == 4)
|
||||
{
|
||||
s = [[theValues objectForKey: @"Body"] objectForKey: @"Data"];
|
||||
message_data = [ s dataUsingEncoding: NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
if (bodyType == 1)
|
||||
{
|
||||
map = [[[NGMutableHashMap alloc] initWithCapacity: 1] autorelease];
|
||||
|
||||
[map setObject: [NSString stringWithFormat: @"%@ <%@>", [theValues objectForKey: @"From"], email] forKey: @"from"];
|
||||
[map setObject: [NSString stringWithFormat: @"%@ <%@>", [theValues objectForKey: @"To"], email] forKey: @"to"];
|
||||
[map setObject: [NSString stringWithFormat: @"SMS: %@", [theValues objectForKey: @"From"]] forKey: @"subject"];
|
||||
|
||||
|
||||
#if GNUSTEP_BASE_MINOR_VERSION < 21
|
||||
dateReceived = [[[theValues objectForKey: @"DateReceived"] calendarDate] descriptionWithCalendarFormat: @"%a, %d %b %Y %H:%M:%S %z"
|
||||
timeZone: [NSTimeZone timeZoneWithName: @"GMT"]
|
||||
locale: nil];
|
||||
#else
|
||||
dateReceived = [[[theValues objectForKey: @"DateReceived"] calendarDate] descriptionWithCalendarFormat: @"%a, %d %b %Y %H:%M:%S %z"
|
||||
timeZone: [NSTimeZone timeZoneWithName: @"GMT"]
|
||||
locale: [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSArray arrayWithObjects: @"Jan", @"Feb", @"Mar", @"Apr",
|
||||
@"May", @"Jun", @"Jul", @"Aug",
|
||||
@"Sep", @"Oct", @"Nov", @"Dec", nil],
|
||||
@"NSShortMonthNameArray",
|
||||
[NSArray arrayWithObjects: @"Sun", @"Mon", @"Tue", @"Wed", @"Thu",
|
||||
@"Fri", @"Sat", nil],
|
||||
@"NSShortWeekDayNameArray",
|
||||
nil]];
|
||||
#endif
|
||||
|
||||
[map setObject: dateReceived forKey: @"date"];
|
||||
[map setObject: [NSString generateMessageID] forKey: @"message-id"];
|
||||
[map setObject: @"text/plain; charset=utf-8" forKey: @"content-type"];
|
||||
[map setObject: @"quoted-printable" forKey: @"content-transfer-encoding"];
|
||||
|
||||
bounceMessage = [[[NGMimeMessage alloc] initWithHeader: map] autorelease];
|
||||
|
||||
[bounceMessage setBody: [[NSString stringWithFormat: @"%@", [[theValues objectForKey: @"Body"] objectForKey: @"Data"] ] dataUsingEncoding: NSUTF8StringEncoding]];
|
||||
|
||||
generator = [[[NGMimeMessageGenerator alloc] init] autorelease];
|
||||
message_data = [generator generateMimeFromPart: bounceMessage];
|
||||
}
|
||||
|
||||
client = [[self imap4Connection] client];
|
||||
|
||||
if (![imap4 doesMailboxExistAtURL: [container imap4URL]])
|
||||
{
|
||||
[[self imap4Connection] createMailbox: [[self imap4Connection] imap4FolderNameForURL: [container imap4URL]]
|
||||
atURL: [[self mailAccountFolder] imap4URL]];
|
||||
[imap4 flushFolderHierarchyCache];
|
||||
}
|
||||
|
||||
folder = [imap4 imap4FolderNameForURL: [container imap4URL]];
|
||||
|
||||
result = [client append: message_data toFolder: folder
|
||||
withFlags: [NSArray arrayWithObjects: @"draft", nil]];
|
||||
|
||||
if ([[result objectForKey: @"result"] boolValue])
|
||||
return [NSString stringWithFormat: @"%d", [self IMAP4IDFromAppendResult: result]];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@@ -61,7 +61,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
[response setHeader: @"private" forKey: @"Cache-Control"];
|
||||
[response setHeader: @"OPTIONS, POST" forKey: @"Allow"];
|
||||
[response setHeader: @"14.1" forKey: @"MS-Server-ActiveSync"];
|
||||
[response setHeader: @"2.5,12.0,12.1,14.0,14.1" forKey: @"MS-ASProtocolVersions"];
|
||||
[response setHeader: @"2.5,12.0,12.1,14.0,14.1,16.0" forKey: @"MS-ASProtocolVersions"];
|
||||
[response setHeader: @"Sync,SendMail,SmartForward,SmartReply,GetAttachment,GetHierarchy,CreateCollection,DeleteCollection,MoveCollection,FolderSync,FolderCreate,FolderDelete,FolderUpdate,MoveItems,GetItemEstimate,MeetingResponse,Search,Settings,Ping,ItemOperations,ResolveRecipients,ValidateCert" forKey: @"MS-ASProtocolCommands"];
|
||||
[response setHeader: @"OPTIONS, POST" forKey: @"Public"];
|
||||
}
|
||||
|
||||
@@ -251,7 +251,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Location
|
||||
if ([[self location] length])
|
||||
[s appendFormat: @"<Location xmlns=\"Calendar:\">%@</Location>", [[self location] activeSyncRepresentationInContext: context]];
|
||||
{
|
||||
if ([[context objectForKey: @"ASProtocolVersion"] floatValue] >= 16.0)
|
||||
[s appendFormat: @"<Location xmlns=\"AirSyncBase:\"><DisplayName>%@</DisplayName></Location>", [[self location] activeSyncRepresentationInContext: context]];
|
||||
else
|
||||
[s appendFormat: @"<Location xmlns=\"Calendar:\">%@</Location>", [[self location] activeSyncRepresentationInContext: context]];
|
||||
}
|
||||
|
||||
// Importance - NOT SUPPORTED - DO NOT ENABLE
|
||||
//o = [self priority];
|
||||
@@ -458,7 +463,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
occurences = [NSMutableArray arrayWithArray: [[self parent] events]];
|
||||
|
||||
if ((o = [theValues objectForKey: @"UID"]))
|
||||
if ((o = [theValues objectForKey: ([[context objectForKey: @"ASProtocolVersion"] floatValue] >= 16.0) ? @"ClientUid" : @"UID"]))
|
||||
[self setUid: o];
|
||||
|
||||
// FIXME: merge with iCalToDo
|
||||
@@ -537,8 +542,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
[self setComment: o];
|
||||
}
|
||||
|
||||
if ((o = [theValues objectForKey: @"Location"]))
|
||||
if ([[context objectForKey: @"ASProtocolVersion"] floatValue] < 16.0 && (o = [theValues objectForKey: @"Location"]))
|
||||
[self setLocation: o];
|
||||
else if ([[context objectForKey: @"ASProtocolVersion"] floatValue] >= 16.0 && (o = [theValues objectForKey: @"Location"]) && [o isKindOfClass: [NSDictionary class]])
|
||||
[self setLocation: [o objectForKey: @"DisplayName"]];
|
||||
|
||||
deltasecs = 0;
|
||||
start = nil;
|
||||
@@ -589,7 +596,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
{
|
||||
// Ignore the alarm for now
|
||||
}
|
||||
else if ((o = [theValues objectForKey: @"Reminder"]))
|
||||
else if ((o = [theValues objectForKey: @"Reminder"]) && [o length])
|
||||
{
|
||||
// NOTE: Outlook sends a 15 min reminder (18 hour for allday) if no reminder is specified
|
||||
// although no default reminder is defined (File -> Options -> Clendar -> Calendar Options - > Default Reminders)
|
||||
@@ -840,7 +847,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Attendees - we don't touch the values if we're an attendee. This is gonna
|
||||
// be done automatically by the ActiveSync client when invoking MeetingResponse.
|
||||
if (![self userIsAttendee: [context activeUser]])
|
||||
|
||||
Reference in New Issue
Block a user