Skip to content

Commit

Permalink
Merge to 2.2.14
Browse files Browse the repository at this point in the history
  • Loading branch information
extrafu committed Jan 20, 2015
2 parents 2ae326c + d98ff69 commit 74b27a7
Show file tree
Hide file tree
Showing 30 changed files with 473 additions and 133 deletions.
3 changes: 2 additions & 1 deletion ActiveSync/NGVCard+ActiveSync.m
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#import <Foundation/NSCalendarDate.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSString.h>
#import <Foundation/NSTimeZone.h>

#import <NGExtensions/NSString+misc.h>

Expand Down Expand Up @@ -230,7 +231,7 @@ - (void) takeActiveSyncValues: (NSDictionary *) theValues
if ((o = [theValues objectForKey: @"Birthday"]))
{
o = [o calendarDate];
[self setBday: [o descriptionWithCalendarFormat: @"%Y-%m-%d"]];
[self setBday: [o descriptionWithCalendarFormat: @"%Y-%m-%d" timeZone: nil locale: nil]];
}

//
Expand Down
2 changes: 1 addition & 1 deletion ActiveSync/README
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ to negotiate the fees associated to your user base.

To contact Microsoft, please visit:

http://www.microsoft.com/en-us/legal/intellectualproperty/IPLicensing/Programs/exchangeactivesyncprotocol.aspx
http://www.microsoft.com/en-us/legal/intellectualproperty/

and send an email to [email protected]

Expand Down
20 changes: 11 additions & 9 deletions ActiveSync/SOGoActiveSyncDispatcher+Sync.m
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,10 @@ - (void) processSyncGetChanges: (id <DOMElement>) theDocumentElement
partstat = [attendee participationStatus];

if (partstat == iCalPersonPartStatNeedsAction)
continue;
{
DESTROY(pool);
continue;
}
}
}

Expand Down Expand Up @@ -772,10 +775,10 @@ - (void) processSyncGetChanges: (id <DOMElement>) theDocumentElement
[s appendString: @"</Add>"];

return_count++;

DESTROY(pool);
}
} // for ...

DESTROY(pool);
} // for (i = 0; i < max; i++) ...

if (more_available)
{
Expand Down Expand Up @@ -806,7 +809,6 @@ - (void) processSyncGetChanges: (id <DOMElement>) theDocumentElement
int j, k, return_count;
BOOL found_in_cache;


allMessages = [theCollection syncTokenFieldsWithProperties: nil matchingSyncToken: theSyncKey fromDate: theFilterType];
max = [allMessages count];

Expand Down Expand Up @@ -1017,7 +1019,7 @@ - (void) processSyncCommands: (id <DOMElement>) theDocumentElement
if ([[element tagName] isEqualToString: @"Add"])
{
// Add
[self processSyncAddCommand: aCommand
[self processSyncAddCommand: element
inCollection: theCollection
withType: theFolderType
inBuffer: theBuffer];
Expand All @@ -1026,7 +1028,7 @@ - (void) processSyncCommands: (id <DOMElement>) theDocumentElement
else if ([[element tagName] isEqualToString: @"Change"])
{
// Change
[self processSyncChangeCommand: aCommand
[self processSyncChangeCommand: element
inCollection: theCollection
withType: theFolderType
inBuffer: theBuffer];
Expand All @@ -1035,7 +1037,7 @@ - (void) processSyncCommands: (id <DOMElement>) theDocumentElement
else if ([[element tagName] isEqualToString: @"Delete"])
{
// Delete
[self processSyncDeleteCommand: aCommand
[self processSyncDeleteCommand: element
inCollection: theCollection
withType: theFolderType
inBuffer: theBuffer];
Expand All @@ -1044,7 +1046,7 @@ - (void) processSyncCommands: (id <DOMElement>) theDocumentElement
else if ([[element tagName] isEqualToString: @"Fetch"])
{
// Fetch
[self processSyncFetchCommand: aCommand
[self processSyncFetchCommand: element
inCollection: theCollection
withType: theFolderType
inBuffer: theBuffer];
Expand Down
199 changes: 152 additions & 47 deletions ActiveSync/SOGoActiveSyncDispatcher.m
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#import <Foundation/NSProcessInfo.h>
#import <Foundation/NSTimeZone.h>
#import <Foundation/NSURL.h>
#import <Foundation/NSValue.h>

#import <NGObjWeb/NSException+HTTP.h>
#import <NGObjWeb/SoPermissions.h>
Expand Down Expand Up @@ -1215,71 +1216,136 @@ - (void) processItemOperations: (id <DOMElement>) theDocumentElement
{
NSString *fileReference, *realCollectionId;
NSMutableString *s;
NSArray *fetchRequests;
id aFetch;
int i;

SOGoMicrosoftActiveSyncFolderType folderType;

fileReference = [[[(id)[theDocumentElement getElementsByTagName: @"FileReference"] lastObject] textValue] stringByUnescapingURL];
s = [NSMutableString string];

realCollectionId = [fileReference realCollectionIdWithFolderType: &folderType];
[s appendString: @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"];
[s appendString: @"<!DOCTYPE ActiveSync PUBLIC \"-//MICROSOFT//DTD ActiveSync//EN\" \"http://www.microsoft.com/\">"];
[s appendString: @"<ItemOperations xmlns=\"ItemOperations:\">"];
[s appendString: @"<Status>1</Status>"];
[s appendString: @"<Response>"];

fetchRequests = (id)[theDocumentElement getElementsByTagName: @"Fetch"];

if (folderType == ActiveSyncMailFolder)
if ([fetchRequests count])
{
id currentFolder, currentCollection, currentBodyPart;
NSString *folderName, *messageName, *pathToPart;
SOGoMailAccounts *accountsFolder;
SOGoUserFolder *userFolder;
SOGoMailObject *mailObject;
NSMutableData *bytes, *parts;
NSMutableArray *partLength;
NSData *d;

NSRange r1, r2;
bytes = [NSMutableData data];
parts = [NSMutableData data];
partLength = [NSMutableArray array];

r1 = [realCollectionId rangeOfString: @"/"];
r2 = [realCollectionId rangeOfString: @"/" options: 0 range: NSMakeRange(NSMaxRange(r1)+1, [realCollectionId length]-NSMaxRange(r1)-1)];

folderName = [realCollectionId substringToIndex: r1.location];
messageName = [realCollectionId substringWithRange: NSMakeRange(NSMaxRange(r1), r2.location-r1.location-1)];
pathToPart = [realCollectionId substringFromIndex: r2.location+1];

userFolder = [[context activeUser] homeFolderInContext: context];
accountsFolder = [userFolder lookupName: @"Mail" inContext: context acquire: NO];
currentFolder = [accountsFolder lookupName: @"0" inContext: context acquire: NO];
for (i = 0; i < [fetchRequests count]; i++)
{
aFetch = [fetchRequests objectAtIndex: i];
fileReference = [[[(id)[aFetch getElementsByTagName: @"FileReference"] lastObject] textValue] stringByUnescapingURL];
realCollectionId = [fileReference realCollectionIdWithFolderType: &folderType];

currentCollection = [currentFolder lookupName: [NSString stringWithFormat: @"folder%@", folderName]
inContext: context
acquire: NO];
if (folderType == ActiveSyncMailFolder)
{
id currentFolder, currentCollection, currentBodyPart;
NSString *folderName, *messageName, *pathToPart;
SOGoMailAccounts *accountsFolder;
SOGoUserFolder *userFolder;
SOGoMailObject *mailObject;

NSRange r1, r2;

r1 = [realCollectionId rangeOfString: @"/"];
r2 = [realCollectionId rangeOfString: @"/" options: 0 range: NSMakeRange(NSMaxRange(r1)+1, [realCollectionId length]-NSMaxRange(r1)-1)];

mailObject = [currentCollection lookupName: messageName inContext: context acquire: NO];
currentBodyPart = [mailObject lookupImap4BodyPartKey: pathToPart inContext: context];
folderName = [realCollectionId substringToIndex: r1.location];
messageName = [realCollectionId substringWithRange: NSMakeRange(NSMaxRange(r1), r2.location-r1.location-1)];
pathToPart = [realCollectionId substringFromIndex: r2.location+1];

userFolder = [[context activeUser] homeFolderInContext: context];
accountsFolder = [userFolder lookupName: @"Mail" inContext: context acquire: NO];
currentFolder = [accountsFolder lookupName: @"0" inContext: context acquire: NO];

s = [NSMutableString string];
[s appendString: @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"];
[s appendString: @"<!DOCTYPE ActiveSync PUBLIC \"-//MICROSOFT//DTD ActiveSync//EN\" \"http://www.microsoft.com/\">"];
[s appendString: @"<ItemOperations xmlns=\"ItemOperations:\">"];
[s appendString: @"<Status>1</Status>"];
[s appendString: @"<Response>"];
currentCollection = [currentFolder lookupName: [NSString stringWithFormat: @"folder%@", folderName]
inContext: context
acquire: NO];

[s appendString: @"<Fetch>"];
[s appendString: @"<Status>1</Status>"];
[s appendFormat: @"<FileReference xmlns=\"AirSyncBase:\">%@</FileReference>", [fileReference stringByEscapingURL]];
[s appendString: @"<Properties>"];
mailObject = [currentCollection lookupName: messageName inContext: context acquire: NO];
currentBodyPart = [mailObject lookupImap4BodyPartKey: pathToPart inContext: context];

[s appendFormat: @"<ContentType xmlns=\"AirSyncBase:\">%@/%@</ContentType>", [[currentBodyPart partInfo] objectForKey: @"type"], [[currentBodyPart partInfo] objectForKey: @"subtype"]];
[s appendFormat: @"<Data>%@</Data>", [[currentBodyPart fetchBLOB] activeSyncRepresentationInContext: context]];
[s appendString: @"<Fetch>"];
[s appendString: @"<Status>1</Status>"];
[s appendFormat: @"<FileReference xmlns=\"AirSyncBase:\">%@</FileReference>", [fileReference stringByEscapingURL]];
[s appendString: @"<Properties>"];

[s appendString: @"</Properties>"];
[s appendString: @"</Fetch>"];
[s appendFormat: @"<ContentType xmlns=\"AirSyncBase:\">%@/%@</ContentType>", [[currentBodyPart partInfo] objectForKey: @"type"], [[currentBodyPart partInfo] objectForKey: @"subtype"]];

if ([[theResponse headerForKey: @"Content-Type"] isEqualToString:@"application/vnd.ms-sync.multipart"])
{
[s appendFormat: @"<Part>%d</Part>", i+1];
[partLength addObject: [NSNumber numberWithInteger: [[currentBodyPart fetchBLOB] length]]];
[parts appendData:[currentBodyPart fetchBLOB]];
}
else
{
[s appendFormat: @"<Range>0-%d</Range>", [[[currentBodyPart fetchBLOB] activeSyncRepresentationInContext: context] length]-1];
[s appendFormat: @"<Data>%@</Data>", [[currentBodyPart fetchBLOB] activeSyncRepresentationInContext: context]];
}

[s appendString: @"</Properties>"];
[s appendString: @"</Fetch>"];
}
else
{
[theResponse setStatus: 500];
return;
}
}

[s appendString: @"</Response>"];
[s appendString: @"</ItemOperations>"];

d = [[s dataUsingEncoding: NSUTF8StringEncoding] xml2wbxml];
[theResponse setContent: d];
}
else
{
[theResponse setStatus: 500];

if ([[theResponse headerForKey: @"Content-Type"] isEqualToString:@"application/vnd.ms-sync.multipart"])
{
uint32_t PartCount;
uint32_t Offset;
uint32_t Len;

// 2.2.2.9.1.1 - MultiPartResponse -- http://msdn.microsoft.com/en-us/library/jj663270%28v=exchg.80%29.aspx
PartCount = [partLength count] + 1;
Offset = ((PartCount) * 2) * 4 + 4;
Len = [d length];

[bytes appendBytes: &PartCount length: 4];
[bytes appendBytes: &Offset length: 4];
[bytes appendBytes: &Len length: 4];

// 2.2.2.9.1.1.1 - PartMetaData -- http://msdn.microsoft.com/en-us/library/jj663267%28v=exchg.80%29.aspx
for (i = 0; i < [fetchRequests count]; i++)
{
Offset = Offset + Len;
Len = [[partLength objectAtIndex:i] intValue];
[bytes appendBytes: &Offset length: 4];
[bytes appendBytes: &Len length: 4];
}

// First part - webxml
[bytes appendData: d];

// Subsequent parts - requested data
[bytes appendData: parts];

[theResponse setContent: bytes];
}
else
{
[theResponse setContent: d];
}
}
}

Expand Down Expand Up @@ -2159,6 +2225,11 @@ - (void) processSendMail: (id <DOMElement>) theDocumentElement
NGMimeMessage *message;
NSException *error;
NSData *data;
NGMutableHashMap *map;
NGMimeMessage *messageToSend;
NGMimeMessageGenerator *generator;
NSDictionary *identity;
NSString *fullName, *email;

// We get the mail's data
data = [[[[(id)[theDocumentElement getElementsByTagName: @"MIME"] lastObject] textValue] stringByDecodingBase64] dataUsingEncoding: NSUTF8StringEncoding];
Expand All @@ -2167,6 +2238,24 @@ - (void) processSendMail: (id <DOMElement>) theDocumentElement
parser = [[NGMimeMessageParser alloc] init];
message = [parser parsePartFromData: data];
RELEASE(parser);

map = [NGHashMap hashMapWithDictionary: [message headers]];

identity = [[context activeUser] primaryIdentity];

fullName = [identity objectForKey: @"fullName"];
email = [identity objectForKey: @"email"];
if ([fullName length])
[map setObject: [NSString stringWithFormat: @"%@ <%@>", fullName, email] forKey: @"from"];
else
[map setObject: email forKey: @"from"];

messageToSend = [[[NGMimeMessage alloc] initWithHeader: map] autorelease];

[messageToSend setBody: [message body]];

generator = [[[NGMimeMessageGenerator alloc] init] autorelease];
data = [generator generateMimeFromPart: messageToSend];

error = [self _sendMail: data
recipients: [message allRecipients]
Expand Down Expand Up @@ -2295,6 +2384,8 @@ - (void) processSmartForward: (id <DOMElement>) theDocumentElement
NSException *error;

id body, bodyFromSmartForward;
NSString *fullName, *email;
NSDictionary *identity;

userFolder = [[context activeUser] homeFolderInContext: context];
accountsFolder = [userFolder lookupName: @"Mail" inContext: context acquire: NO];
Expand All @@ -2318,6 +2409,15 @@ - (void) processSmartForward: (id <DOMElement>) theDocumentElement
map = [NGHashMap hashMapWithDictionary: [messageFromSmartForward headers]];
[map setObject: @"multipart/mixed" forKey: @"content-type"];

identity = [[context activeUser] primaryIdentity];

fullName = [identity objectForKey: @"fullName"];
email = [identity objectForKey: @"email"];
if ([fullName length])
[map setObject: [NSString stringWithFormat: @"%@ <%@>", fullName, email] forKey: @"from"];
else
[map setObject: email forKey: @"from"];

messageToSend = [[[NGMimeMessage alloc] initWithHeader: map] autorelease];
body = [[[NGMimeMultipartBody alloc] initWithPart: messageToSend] autorelease];

Expand Down Expand Up @@ -2504,19 +2604,24 @@ - (NSException *) dispatchRequest: (id) theRequest
// Ping or Sync command with empty body
cmdName = [NSString stringWithFormat: @"process%@:inResponse:", cmdName];
}

aSelector = NSSelectorFromString(cmdName);

// The -processItemOperations: method will generate a multipart response when Content-Type is application/vnd.ms-sync.multipart
if ([[theRequest headerForKey: @"MS-ASAcceptMultiPart"] isEqualToString:@"T"])
[theResponse setHeader: @"application/vnd.ms-sync.multipart" forKey: @"Content-Type"];
else
[theResponse setHeader: @"application/vnd.ms-sync.wbxml" forKey: @"Content-Type"];

[self performSelector: aSelector withObject: documentElement withObject: theResponse];

[theResponse setHeader: @"application/vnd.ms-sync.wbxml" forKey: @"Content-Type"];
[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.0,2.1,2.5,12.0,12.1,14.0,14.1" forKey: @"MS-ASProtocolVersions"];

RELEASE(context);
RELEASE(pool);

return nil;
}

Expand Down
Loading

0 comments on commit 74b27a7

Please sign in to comment.