From 8bbe631dac2ead0784bb3574a834e1af0e8894bc Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Wed, 21 Oct 2009 21:17:11 +0000 Subject: [PATCH] Monotone-Parent: ffb403989e64c7ca37321c15ab24b50155dc2f68 Monotone-Revision: fe50cf1e82dc1e3027fc400eb2f405261b9ad9f3 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2009-10-21T21:17:11 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 20 +++++ Main/SOGo.h | 2 + Main/SOGo.m | 11 +++ NEWS | 3 +- SOPE/sope-patchset-r1660.diff | 79 ++++++++++++++++++- .../Appointments/SOGoAppointmentFolder.m | 32 ++++++-- .../SOGoUserFolder+Appointments.m | 45 +++++++++-- SoObjects/Contacts/SOGoUserFolder+Contacts.m | 2 +- SoObjects/SOGo/NSCalendarDate+SOGo.m | 9 +++ SoObjects/SOGo/SOGoContentObject.m | 8 +- SoObjects/SOGo/SOGoGCSFolder.m | 2 +- SoObjects/SOGo/SOGoObject.h | 1 + SoObjects/SOGo/SOGoObject.m | 25 +++--- SoObjects/SOGo/SOGoUserFolder.m | 6 +- SoObjects/SOGo/WORequest+SOGo.h | 1 + SoObjects/SOGo/WORequest+SOGo.m | 5 ++ 16 files changed, 217 insertions(+), 34 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3ce4db100..d6e9ac21b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2009-10-21 Wolfgang Sourdeau + + * SoObjects/Appointments/SOGoAppointmentFolder.m + (-davCalendarTimeZone): new DAV accessor that returns the + user's timezone. + + * SoObjects/Appointments/SOGoUserFolder+Appointments.m + (-davCalendarScheduleInboxURL, davCalendarScheduleOutboxURL): + return nil if used with iCal 4. + + * SoObjects/SOGo/SOGoContentObject.m (-davResourceType): removed + useless method. + + * SoObjects/SOGo/SOGoObject.m (-davURLAsString): new method that + returns the resource url as a string, by taking WOUseRelativeURLs + into account. + + * SoObjects/SOGo/WORequest+SOGo.m (-isICal4): new method that + determines whether to work-around iCal4 calamities. + 2009-10-20 Ludovic Marcotte * Added missing timezones diff --git a/Main/SOGo.h b/Main/SOGo.h index 96f4397a9..574f036d3 100644 --- a/Main/SOGo.h +++ b/Main/SOGo.h @@ -39,6 +39,8 @@ - (NSDictionary *) currentLocaleConsideringLanguages:(NSArray *)_langs; - (NSDictionary *) localeForLanguageNamed:(NSString *)_name; +- (NSString *) davURLAsString; + @end #endif /* MAIN_SOGO_H */ diff --git a/Main/SOGo.m b/Main/SOGo.m index 70d7cb9be..1d56d3f30 100644 --- a/Main/SOGo.m +++ b/Main/SOGo.m @@ -67,6 +67,7 @@ static BOOL doCrashOnSessionCreate = NO; static BOOL hasCheckedTables = NO; static BOOL debugRequests = NO; static BOOL debugLeaks = NO; +static BOOL useRelativeURLs = NO; static BOOL trustProxyAuthentication; @@ -125,6 +126,7 @@ static BOOL debugObjectAllocation = NO; [sInfo declareRoles: basicRoles asDefaultForPermission: SoPerm_WebDAVAccess]; trustProxyAuthentication = [ud boolForKey: @"SOGoTrustProxyAuthentication"]; + useRelativeURLs = [ud boolForKey: @"WOUseRelativeURLs"]; } - (id) init @@ -607,6 +609,15 @@ static BOOL debugObjectAllocation = NO; return [self _urlPreferringParticle: @"dav" overThisOne: @"so"]; } +- (NSString *) davURLAsString +{ + NSURL *davURL; + + davURL = [self davURL]; + + return (useRelativeURLs ? [davURL path] : [davURL absoluteString]); +} + - (NSURL *) soURL { return [self _urlPreferringParticle: @"so" overThisOne: @"dav"]; diff --git a/NEWS b/NEWS index 06366a7a8..49c2b223c 100644 --- a/NEWS +++ b/NEWS @@ -8,7 +8,8 @@ - a context menu is now available for tasks - added the capability of creating and managing lists of contacts (same as in Thunderbird) - added support for short date format in the calendar views -- added support for iCal delegation +- added support for iCal delegation (iCal 3) +- added preliminary support for iCal 4 - rewrote dTree.js to include major optimizations - added WebAuth support - added support for remote ICS subscriptions diff --git a/SOPE/sope-patchset-r1660.diff b/SOPE/sope-patchset-r1660.diff index 31136d551..901345d97 100644 --- a/SOPE/sope-patchset-r1660.diff +++ b/SOPE/sope-patchset-r1660.diff @@ -4315,7 +4315,13 @@ Index: sope-appserver/NGObjWeb/ChangeLog =================================================================== --- sope-appserver/NGObjWeb/ChangeLog (revision 1660) +++ sope-appserver/NGObjWeb/ChangeLog (working copy) -@@ -1,3 +1,22 @@ +@@ -1,3 +1,28 @@ ++2009-10-21 Wolfgang Sourdeau ++ ++ * WebDAV/SoObjectResultEntry.m (-valueForKey:): we now take ++ WOUseRelativeURLs into account when the "href" key is requested, ++ to work around a bug in iCal 4. ++ +2009-07-02 Wolfgang Sourdeau + + * WOMessage.m (-setHeaders:, -setHeader:forKey:, headerForKey:, @@ -4338,6 +4344,77 @@ Index: sope-appserver/NGObjWeb/ChangeLog 2009-06-10 Helge Hess * DAVPropMap.plist: mapped {DAV:}current-user-principal (v4.9.37) +Index: sope-appserver/NGObjWeb/DAVPropMap.plist +=================================================================== +--- sope-appserver/NGObjWeb/DAVPropMap.plist (revision 1660) ++++ sope-appserver/NGObjWeb/DAVPropMap.plist (working copy) +@@ -157,6 +157,7 @@ + "{urn:ietf:params:xml:ns:caldav}supported-calendar-data" = + davSupportedCalendarDataTypes; + "{urn:ietf:params:xml:ns:caldav}calendar-description" = davDescription; ++ "{urn:ietf:params:xml:ns:caldav}calendar-timezone" = davCalendarTimeZone; + + /* CardDAV */ + "{urn:ietf:params:xml:ns:carddav}addressbook-home-set" = davAddressbookHomeSet; +Index: sope-appserver/NGObjWeb/WebDAV/SoObjectResultEntry.m +=================================================================== +--- sope-appserver/NGObjWeb/WebDAV/SoObjectResultEntry.m (revision 1660) ++++ sope-appserver/NGObjWeb/WebDAV/SoObjectResultEntry.m (working copy) +@@ -25,7 +25,14 @@ + @implementation SoObjectResultEntry + + static BOOL debugOn = NO; ++static BOOL useRelativeURLs = NO; + +++ (void) initialize ++{ ++ useRelativeURLs = [[NSUserDefaults standardUserDefaults] ++ boolForKey: @"WOUseRelativeURLs"]; ++} ++ + - (id)initWithURI:(NSString *)_href object:(id)_o values:(NSDictionary *)_d { + if ((self = [super init])) { + if (debugOn) { +@@ -85,10 +92,36 @@ + return YES; + } + ++- (NSString *)_relativeHREF { ++ NSString *newHREF; ++ NSRange hostRange; ++ ++ if ([self->href hasPrefix: @"/"]) ++ return self->href; ++ else { ++ hostRange = [self->href rangeOfString: @"://"]; ++ if (hostRange.length > 0) { ++ newHREF = [self->href substringFromIndex: NSMaxRange (hostRange)]; ++ hostRange = [newHREF rangeOfString: @"/"]; ++ if (hostRange.length > 0) { ++ newHREF = [newHREF substringFromIndex: hostRange.location]; ++ } ++ } else { ++ newHREF = self->href; ++ } ++ ++ return newHREF; ++ } ++} ++ + - (id)valueForKey:(NSString *)_key { +- if ([_key isEqualToString:@"{DAV:}href"]) +- return self->href; +- ++ if ([_key isEqualToString:@"{DAV:}href"]) { ++ if (useRelativeURLs) ++ return [self _relativeHREF]; ++ else ++ return self->href; ++ } ++ + if ([_key isEqualToString:@"{DAV:}status"]) + return nil; + Index: sope-appserver/NGObjWeb/WebDAV/SoWebDAVRenderer.m =================================================================== --- sope-appserver/NGObjWeb/WebDAV/SoWebDAVRenderer.m (revision 1660) diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.m b/SoObjects/Appointments/SOGoAppointmentFolder.m index 848da0577..15fbd6a43 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.m +++ b/SoObjects/Appointments/SOGoAppointmentFolder.m @@ -46,6 +46,7 @@ #import #import #import +#import #import #import #import @@ -1674,6 +1675,24 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir - (NSException *) setDavCalendarOrder: (NSString *) newColor { + /* we fail silently */ + return nil; +} + +- (NSString *) davCalendarTimeZone +{ + SOGoUser *ownerUser; + NSString *ownerTimeZone; + + ownerUser = [SOGoUser userWithLogin: [self ownerInContext: context]]; + ownerTimeZone = [[ownerUser timeZone] name]; + + return [[iCalTimeZone timeZoneForName: ownerTimeZone] versitString]; +} + +- (NSException *) setDavCalendarTimeZone: (NSString *) newTimeZone +{ + /* we fail silently */ return nil; } @@ -1687,8 +1706,9 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir response = [NSMutableArray array]; subFolders = [[container subFolders] objectEnumerator]; while ((currentFolder = [subFolders nextObject])) - [response addObject: davElementWithContent (@"href", XMLNS_WEBDAV, - [currentFolder davURL])]; + [response + addObject: davElementWithContent (@"href", XMLNS_WEBDAV, + [currentFolder davURLAsString])]; responseValue = [davElementWithContent (@"calendar-free-busy-set", XMLNS_CALDAV, response) asWebDAVValue]; @@ -1720,7 +1740,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir while ((currentField = [addFields nextObject])) if ([currentField length]) [fields addObjectUniquely: currentField]; - baseURL = [[self davURL] absoluteString]; + baseURL = [self davURLAsString]; propertiesArray = [[properties allKeys] asPointersOfObjects]; propertiesCount = [properties count]; @@ -1813,7 +1833,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir max = [urls count]; cNames = [NSMutableDictionary dictionaryWithCapacity: max]; baseURL = [self davURL]; - baseURLString = [baseURL absoluteString]; + baseURLString = [self davURLAsString]; for (count = 0; count < max; count++) { @@ -1939,7 +1959,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir unsigned int count, max, propertiesCount; NSEnumerator *addFields; - baseURL = [[self davURL] absoluteString]; + baseURL = [self davURLAsString]; urls = [NSMutableArray array]; max = [refs length]; @@ -2358,7 +2378,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir resourcetype. Anything else will prevent the iPhone from querying the collection. */ request = [context request]; - if (![request isIPhone]) + if (!([request isIPhone] || [request isICal4])) { gdRT = [self groupDavResourceType]; gdVEventCol = [NSArray arrayWithObjects: [gdRT objectAtIndex: 0], diff --git a/SoObjects/Appointments/SOGoUserFolder+Appointments.m b/SoObjects/Appointments/SOGoUserFolder+Appointments.m index 154fdfc21..1adf97852 100644 --- a/SoObjects/Appointments/SOGoUserFolder+Appointments.m +++ b/SoObjects/Appointments/SOGoUserFolder+Appointments.m @@ -35,6 +35,8 @@ #import #import +#import + #import "SOGoAppointmentFolders.h" #import "SOGoUserFolder+Appointments.h" @@ -88,7 +90,7 @@ parent = [self privateCalendars: @"Calendar" inContext: context]; tag = [NSArray arrayWithObjects: @"href", @"DAV:", @"D", - [[parent davURL] path], nil]; + [parent davURLAsString], nil]; return [NSArray arrayWithObject: tag]; } @@ -100,7 +102,8 @@ parent = [self privateCalendars: @"Calendar" inContext: context]; tag = [NSArray arrayWithObjects: @"href", @"DAV:", @"D", - [NSString stringWithFormat: @"%@personal/", [[parent davURL] path]], + [NSString stringWithFormat: @"%@personal/", + [parent davURLAsString]], nil]; return [NSArray arrayWithObject: tag]; @@ -108,22 +111,50 @@ - (NSArray *) davCalendarScheduleInboxURL { - return [self _davPersonalCalendarURL]; + NSArray *url; + + if ([[context request] isICal4]) + url = nil; + else + url = [self _davPersonalCalendarURL]; + + return url; } - (NSArray *) davCalendarScheduleOutboxURL { - return [self _davPersonalCalendarURL]; + NSArray *url; + + if ([[context request] isICal4]) + url = nil; + else + url = [self _davPersonalCalendarURL]; + + return url; } - (NSArray *) davDropboxHomeURL { - return [self _davPersonalCalendarURL]; + NSArray *url; + + if ([[context request] isICal4]) + url = nil; + else + url = [self _davPersonalCalendarURL]; + + return url; } - (NSArray *) davNotificationsURL { - return [self _davPersonalCalendarURL]; + NSArray *url; + + if ([[context request] isICal4]) + url = nil; + else + url = [self _davPersonalCalendarURL]; + + return url; } - (WOResponse *) _prepareResponseFromContext: (WOContext *) queryContext @@ -329,7 +360,7 @@ response = [NSMutableArray array]; [response addObject: davElementWithContent (@"href", XMLNS_WEBDAV, - [collection davURL])]; + [collection davURLAsString])]; props = [NSMutableArray array]; max = [properties count]; for (count = 0; count < max; count++) diff --git a/SoObjects/Contacts/SOGoUserFolder+Contacts.m b/SoObjects/Contacts/SOGoUserFolder+Contacts.m index 87f3bb7e1..e9b58ab6c 100644 --- a/SoObjects/Contacts/SOGoUserFolder+Contacts.m +++ b/SoObjects/Contacts/SOGoUserFolder+Contacts.m @@ -51,7 +51,7 @@ parent = [self privateContacts: @"Contacts" inContext: context]; tag = [NSArray arrayWithObjects: @"href", @"DAV:", @"D", - [[parent davURL] path], nil]; + [parent davURLAsString], nil]; return [NSArray arrayWithObject: tag]; } diff --git a/SoObjects/SOGo/NSCalendarDate+SOGo.m b/SoObjects/SOGo/NSCalendarDate+SOGo.m index e2df779bf..2b1306ef7 100644 --- a/SoObjects/SOGo/NSCalendarDate+SOGo.m +++ b/SoObjects/SOGo/NSCalendarDate+SOGo.m @@ -113,9 +113,18 @@ static NSString *rfc822Months[] = {@"", @"Jan", @"Feb", @"Mar", @"Apr", timeZoneShift]; } +/* <<<<<<< variant A +#define secondsOfDistantFuture 1073741823.0 +#define secondsOfDistantPast -1518491648.0 +>>>>>>> variant B */ #define secondsOfDistantFuture 1073741823.0 #define secondsOfDistantPast -1073741823.0 +/* +####### Ancestor +#define secondsOfDistantFuture 63113990400.0 +#define secondsOfDistantPast -63113817600.0 +======= end */ + (id) distantFuture { diff --git a/SoObjects/SOGo/SOGoContentObject.m b/SoObjects/SOGo/SOGoContentObject.m index fa748e4ad..57c11f8cf 100644 --- a/SoObjects/SOGo/SOGoContentObject.m +++ b/SoObjects/SOGo/SOGoContentObject.m @@ -374,10 +374,10 @@ [content lengthOfBytesUsingEncoding: NSUTF8StringEncoding]]; } -- (NSString *) davResourceType -{ - return @""; -} +// - (NSString *) davResourceType +// { +// return @""; +// } - (NSException *) davMoveToTargetObject: (id) _target newName: (NSString *) _name diff --git a/SoObjects/SOGo/SOGoGCSFolder.m b/SoObjects/SOGo/SOGoGCSFolder.m index 2e88ad134..b773d13c8 100644 --- a/SoObjects/SOGo/SOGoGCSFolder.m +++ b/SoObjects/SOGo/SOGoGCSFolder.m @@ -1065,7 +1065,7 @@ static NSArray *childRecordFields = nil; newToken = 0; - baseURL = [[self davURL] absoluteString]; + baseURL = [self davURLAsString]; max = [records count]; syncResponses = [NSMutableArray arrayWithCapacity: max + 1]; diff --git a/SoObjects/SOGo/SOGoObject.h b/SoObjects/SOGo/SOGoObject.h index 11d8bf203..f0c0182a6 100644 --- a/SoObjects/SOGo/SOGoObject.h +++ b/SoObjects/SOGo/SOGoObject.h @@ -93,6 +93,7 @@ SEL SOGoSelectorForPropertySetter (NSString *property); - (NSURL *) soURL; - (NSURL *) soURLToBaseContainerForUser: (NSString *) uid; - (NSURL *) soURLToBaseContainerForCurrentUser; +- (NSString *) davURLAsString; - (NSString *) labelForKey: (NSString *) key; diff --git a/SoObjects/SOGo/SOGoObject.m b/SoObjects/SOGo/SOGoObject.m index 56c7e4840..000543baa 100644 --- a/SoObjects/SOGo/SOGoObject.m +++ b/SoObjects/SOGo/SOGoObject.m @@ -68,6 +68,7 @@ static BOOL kontactGroupDAV = YES; static BOOL sendACLAdvisories = NO; +static BOOL useRelativeURLs = NO; static NSDictionary *reportMap = nil; static NSMutableDictionary *setterMap = nil; @@ -178,6 +179,7 @@ SEL SOGoSelectorForPropertySetter (NSString *property) ud = [NSUserDefaults standardUserDefaults]; kontactGroupDAV = ![ud boolForKey:@"SOGoDisableKontact34GroupDAVHack"]; sendACLAdvisories = [ud boolForKey: @"SOGoACLsSendEMailNotifications"]; + useRelativeURLs = [ud boolForKey: @"WOUseRelativeURLs"]; if (!reportMap) { @@ -463,7 +465,7 @@ SEL SOGoSelectorForPropertySetter (NSString *property) NSString *usersUrl; usersUrl = [NSString stringWithFormat: @"%@%@/", - [[WOApplication application] davURL], owner]; + [[WOApplication application] davURLAsString], owner]; ownerHREF = davElementWithContent (@"href", @"DAV:", usersUrl); return [davElementWithContent (@"owner", @"DAV:", ownerHREF) @@ -491,7 +493,7 @@ SEL SOGoSelectorForPropertySetter (NSString *property) /* WOApplication has no support for the DAV methods we define here so we use the user's principal object as a reference */ usersUrl = [NSString stringWithFormat: @"%@%@/", - [[WOApplication application] davURL], owner]; + [[WOApplication application] davURLAsString], owner]; collectionHREF = davElementWithContent (@"href", @"DAV:", usersUrl); return [davElementWithContent (@"principal-collection-set", @@ -553,7 +555,7 @@ SEL SOGoSelectorForPropertySetter (NSString *property) if ([roles count]) { principalURL = [NSString stringWithFormat: @"%@%@/", - [[WOApplication application] davURL], + [[WOApplication application] davURLAsString], currentUID]; userHREF = davElementWithContent (@"href", @"DAV:", principalURL); [currentAce addObject: davElementWithContent (@"principal", @"DAV:", @@ -670,7 +672,7 @@ SEL SOGoSelectorForPropertySetter (NSString *property) NSString *davURL, *userLogin; NSArray *principalURL; - davURL = [[WOApplication application] davURL]; + davURL = [[WOApplication application] davURLAsString]; userLogin = [[context activeUser] login]; principalURL = [NSArray arrayWithObject: [NSString stringWithFormat: @"%@%@/", davURL, @@ -680,15 +682,11 @@ SEL SOGoSelectorForPropertySetter (NSString *property) - (void) _fillArrayWithPrincipalsOwnedBySelf: (NSMutableArray *) hrefs { - NSString *url; NSArray *roles; roles = [[context activeUser] rolesForObject: self inContext: context]; if ([roles containsObject: SoRole_Owner]) - { - url = [[self davURL] absoluteString]; - [hrefs addObject: url]; - } + [hrefs addObject: [self davURLAsString]]; } - (NSDictionary *) @@ -1189,6 +1187,15 @@ SEL SOGoSelectorForPropertySetter (NSString *property) return [self _urlPreferringParticle: @"dav" overThisOne: @"so"]; } +- (NSString *) davURLAsString +{ + NSURL *davURL; + + davURL = [self davURL]; + + return (useRelativeURLs ? [davURL path] : [davURL absoluteString]); +} + - (NSURL *) soURL { return [self _urlPreferringParticle: @"so" overThisOne: @"dav"]; diff --git a/SoObjects/SOGo/SOGoUserFolder.m b/SoObjects/SOGo/SOGoUserFolder.m index 40d5c9640..1bcdb660d 100644 --- a/SoObjects/SOGo/SOGoUserFolder.m +++ b/SoObjects/SOGo/SOGoUserFolder.m @@ -261,7 +261,7 @@ static NSString *LDAPContactInfoAttribute = nil; NSEnumerator *foldersEnum; SOGoUser *ownerUser; - baseHREF = [[container davURL] absoluteString]; + baseHREF = [container davURLAsString]; if ([baseHREF hasSuffix: @"/"]) baseHREF = [baseHREF substringToIndex: [baseHREF length] - 1]; foldersEnum = [folders objectEnumerator]; @@ -617,11 +617,9 @@ static NSString *LDAPContactInfoAttribute = nil; - (NSArray *) davPrincipalURL { NSArray *principalURL; - NSString *selfDAVPath; - selfDAVPath = [[self davURL] path]; principalURL = [NSArray arrayWithObjects: @"href", @"DAV:", @"D", - selfDAVPath, nil]; + [self davURLAsString], nil]; return [NSArray arrayWithObject: principalURL]; } diff --git a/SoObjects/SOGo/WORequest+SOGo.h b/SoObjects/SOGo/WORequest+SOGo.h index 41e2c209a..415c3dbb4 100644 --- a/SoObjects/SOGo/WORequest+SOGo.h +++ b/SoObjects/SOGo/WORequest+SOGo.h @@ -33,6 +33,7 @@ - (BOOL) isAppleDAVWithSubstring: (NSString *) osSubstring; - (BOOL) isIPhone; - (BOOL) isICal; +- (BOOL) isICal4; @end diff --git a/SoObjects/SOGo/WORequest+SOGo.m b/SoObjects/SOGo/WORequest+SOGo.m index 34855c895..d8d44eb34 100644 --- a/SoObjects/SOGo/WORequest+SOGo.m +++ b/SoObjects/SOGo/WORequest+SOGo.m @@ -131,4 +131,9 @@ return [self isAppleDAVWithSubstring: @"Mac OS X/10."]; } +- (BOOL) isICal4 +{ + return [self isAppleDAVWithSubstring: @"iCal/4."]; +} + @end