diff --git a/ChangeLog b/ChangeLog index 6a4899045..229527c5e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,22 @@ 2010-07-15 Wolfgang Sourdeau + * SoObjects/SOGo/SOGoUser.m (-personalCalendarFolderInContext:): + we now make use of -[SOGoParentFolder + lookupPersonalFolder:ignoringRights:] with @"personal" and YES as + arguments. + + * SoObjects/Appointments/SOGoAppointmentFolder.m + (-lookupCalendarFolderForUID:): removed useless method, which can + be replaced with -[SOGoUser personalCalendarFolderInContext:]. + + * UI/Scheduler/UIxCalListingActions.m + (_aptFolder:withClientObject:): removed unused method. + + * UI/WebServerResources/UIxAppointmentEditor.js + (onComposeToAllAttendees): take the status image DIV into account + when detecting the user fullnames. + (onComposeToUndecidedAttendees): same as above. + * Tests/Integration/test-davacl.py (DAVCalendarPublicAclTest.testCollectionAccessNormalUser): print the amount of received hrefs. @@ -13,9 +30,12 @@ (_fetchPersonalFolders:withChannel:): we no longer check access rights from here as this method is too low level and prevent other mechanisms from working properly. - (-lookupName:inContext:acquire:): we now check the "AccessObject" - right from here before returning the found object. We also make - use of the new "ignoreRights" method (see below) to that end. + (-lookupPersonalFolder:ignoringRights:): new method enabling the + lookup of a user's personal folders only and offering the choice + of respecting (or not) the active user's permission before + returning it. + (-lookupName:inContext:acquire:): we now make use of the above + method when looking up personal folders ("personal" or not). (-toManyRelationShipKeys): same as lookupName... above. * SoObjects/SOGo/SOGoObject.m (-ignoreRights): new utility method diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.h b/SoObjects/Appointments/SOGoAppointmentFolder.h index 7e88ebfb5..7c1e70f3b 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.h +++ b/SoObjects/Appointments/SOGoAppointmentFolder.h @@ -123,7 +123,6 @@ typedef enum { - (id) lookupHomeFolderForUID: (NSString *) _uid inContext: (id) _ctx; -- (SOGoAppointmentFolder *) lookupCalendarFolderForUID: (NSString *) uid; - (NSArray *) lookupCalendarFoldersForUID: (NSString *) theUID; - (NSArray *) lookupCalendarFoldersForUIDs: (NSArray *) _uids inContext: (id) _ctx; diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.m b/SoObjects/Appointments/SOGoAppointmentFolder.m index ee1a9d3af..70a8e3aaf 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.m +++ b/SoObjects/Appointments/SOGoAppointmentFolder.m @@ -2644,36 +2644,6 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir return result; } -// -// This method returns the personal calendar of a specific user. -// -- (SOGoAppointmentFolder *) lookupCalendarFolderForUID: (NSString *) uid -{ - SOGoFolder *currentContainer; - SOGoAppointmentFolders *parent; - NSException *error; - - currentContainer = [[container container] container]; - currentContainer = [currentContainer lookupName: uid - inContext: context - acquire: NO]; - parent = [currentContainer lookupName: @"Calendar" inContext: context - acquire: NO]; - currentContainer = [parent lookupName: @"personal" inContext: context - acquire: NO]; - if (!currentContainer) - { - error = [parent newFolderWithName: [parent defaultFolderName] - andNameInContainer: @"personal"]; - if (!error) - currentContainer = [parent lookupName: @"personal" - inContext: context - acquire: NO]; - } - - return (SOGoAppointmentFolder *) currentContainer; -} - // // This method returns an array containing all the calendar folders // of a specific user, excluding her/his subscriptions. @@ -2712,6 +2682,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir NSMutableArray *folders; NSEnumerator *e; NSString *uid, *ownerLogin; + SOGoUser *user; id folder; ownerLogin = [self ownerInContext: context]; @@ -2725,7 +2696,8 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir folder = self; else { - folder = [self lookupCalendarFolderForUID: uid]; + user = [SOGoUser userWithLogin: uid]; + folder = [user personalCalendarFolderInContext: context]; if (![folder isNotNull]) [self logWithFormat:@"Note: did not find folder for uid: '%@'", uid]; } diff --git a/SoObjects/Appointments/SOGoAppointmentFolders.m b/SoObjects/Appointments/SOGoAppointmentFolders.m index 3cfba791b..7e861f424 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolders.m +++ b/SoObjects/Appointments/SOGoAppointmentFolders.m @@ -58,7 +58,6 @@ @interface SOGoParentFolder (Private) -- (NSException *) initSubscribedSubFolders; - (NSException *) _fetchPersonalFolders: (NSString *) sql withChannel: (EOAdaptorChannel *) fc; @@ -74,6 +73,33 @@ static SoSecurityManager *sm = nil; sm = [SoSecurityManager sharedSecurityManager]; } ++ (SOGoWebDAVAclManager *) webdavAclManager +{ + static SOGoWebDAVAclManager *aclManager = nil; + + if (!aclManager) + { + aclManager = [[super webdavAclManager] copy]; + [aclManager + registerDAVPermission: davElement (@"write", XMLNS_WEBDAV) + abstract: NO + withEquivalent: SoPerm_AddDocumentsImagesAndFiles + asChildOf: davElement (@"all", XMLNS_WEBDAV)]; + [aclManager + registerDAVPermission: davElement (@"write-properties", XMLNS_WEBDAV) + abstract: YES + withEquivalent: SoPerm_AddDocumentsImagesAndFiles + asChildOf: davElement (@"write", XMLNS_WEBDAV)]; + [aclManager + registerDAVPermission: davElement (@"write-content", XMLNS_WEBDAV) + abstract: YES + withEquivalent: SoPerm_AddDocumentsImagesAndFiles + asChildOf: davElement (@"write", XMLNS_WEBDAV)]; + } + + return aclManager; +} + - (id) init { if ((self = [super init])) @@ -489,33 +515,6 @@ static SoSecurityManager *sm = nil; return error; } -+ (SOGoWebDAVAclManager *) webdavAclManager -{ - static SOGoWebDAVAclManager *aclManager = nil; - - if (!aclManager) - { - aclManager = [[super webdavAclManager] copy]; - [aclManager - registerDAVPermission: davElement (@"write", XMLNS_WEBDAV) - abstract: NO - withEquivalent: SoPerm_AddDocumentsImagesAndFiles - asChildOf: davElement (@"all", XMLNS_WEBDAV)]; - [aclManager - registerDAVPermission: davElement (@"write-properties", XMLNS_WEBDAV) - abstract: YES - withEquivalent: SoPerm_AddDocumentsImagesAndFiles - asChildOf: davElement (@"write", XMLNS_WEBDAV)]; - [aclManager - registerDAVPermission: davElement (@"write-content", XMLNS_WEBDAV) - abstract: YES - withEquivalent: SoPerm_AddDocumentsImagesAndFiles - asChildOf: davElement (@"write", XMLNS_WEBDAV)]; - } - - return aclManager; -} - - (BOOL) hasProxyCalendarsWithWriteAccess: (BOOL) write forUserWithLogin: (NSString *) userLogin { diff --git a/SoObjects/Appointments/SOGoAppointmentObject.m b/SoObjects/Appointments/SOGoAppointmentObject.m index 896c23d2e..5e43eafc7 100644 --- a/SoObjects/Appointments/SOGoAppointmentObject.m +++ b/SoObjects/Appointments/SOGoAppointmentObject.m @@ -163,7 +163,8 @@ if (!object) { // Create the event in the user's personal calendar. - folder = [container lookupCalendarFolderForUID: uid]; + folder = [[SOGoUser userWithLogin: uid] + personalCalendarFolderInContext: context]; object = [SOGoAppointmentObject objectWithName: nameInContainer inContainer: folder]; [object setIsNew: YES]; @@ -265,7 +266,8 @@ // Invitations are always written to the personal folder; it's not necessay // to look into all folders of the user - folder = [container lookupCalendarFolderForUID: theUID]; + folder = [[SOGoUser userWithLogin: theUID] + personalCalendarFolderInContext: context]; object = [folder lookupName: nameInContainer inContext: context acquire: NO]; if (![object isKindOfClass: [NSException class]]) diff --git a/SoObjects/SOGo/SOGoParentFolder.h b/SoObjects/SOGo/SOGoParentFolder.h index bd5bee7de..cfd272121 100644 --- a/SoObjects/SOGo/SOGoParentFolder.h +++ b/SoObjects/SOGo/SOGoParentFolder.h @@ -54,6 +54,9 @@ - (NSException *) newFolderWithName: (NSString *) name nameInContainer: (NSString **) newNameInContainer; +- (id) lookupPersonalFolder: (NSString *) name + ignoringRights: (BOOL) ignoreRights; + @end #endif /* SOGOPARENTFOLDERS_H */ diff --git a/SoObjects/SOGo/SOGoParentFolder.m b/SoObjects/SOGo/SOGoParentFolder.m index e9ceb93aa..52982439a 100644 --- a/SoObjects/SOGo/SOGoParentFolder.m +++ b/SoObjects/SOGo/SOGoParentFolder.m @@ -392,23 +392,8 @@ static SoSecurityManager *sm = nil; obj = [super lookupName: name inContext: lookupContext acquire: NO]; if (!obj) { - // Lookup in personal folders - error = [self initSubFolders]; - if (error) - { - [self errorWithFormat: @"a database error occured: %@", [error reason]]; - obj = [NSException exceptionWithHTTPStatus: 503]; - } - else - { - obj = [subFolders objectForKey: name]; - if (obj && ![self ignoreRights] - && [sm validatePermission: SOGoPerm_AccessObject - onObject: obj - inContext: context]) - obj = nil; - } - + obj = [self lookupPersonalFolder: name + ignoringRights: NO]; if (!obj) { // Lookup in subscribed folders @@ -426,6 +411,31 @@ static SoSecurityManager *sm = nil; return obj; } +- (id) lookupPersonalFolder: (NSString *) name + ignoringRights: (BOOL) ignoreRights +{ + NSException *error; + id obj; + + error = [self initSubFolders]; + if (error) + { + [self errorWithFormat: @"a database error occured: %@", [error reason]]; + obj = [NSException exceptionWithHTTPStatus: 503]; + } + else + { + obj = [subFolders objectForKey: name]; + if (obj && !ignoreRights && ![self ignoreRights] + && [sm validatePermission: SOGoPerm_AccessObject + onObject: obj + inContext: context]) + obj = nil; + } + + return obj; +} + - (NSArray *) subFolders { NSMutableArray *ma; diff --git a/SoObjects/SOGo/SOGoUser.m b/SoObjects/SOGo/SOGoUser.m index 9d124b7c1..15b217c28 100644 --- a/SoObjects/SOGo/SOGoUser.m +++ b/SoObjects/SOGo/SOGoUser.m @@ -599,9 +599,8 @@ - (SOGoAppointmentFolder *) personalCalendarFolderInContext: (WOContext *) context { - return [[self calendarsFolderInContext: context] lookupName: @"personal" - inContext: context - acquire: NO]; + return [[self calendarsFolderInContext: context] lookupPersonalFolder: @"personal" + ignoringRights: YES]; } // - (id) schedulingCalendarInContext: (id) _ctx diff --git a/UI/Scheduler/UIxCalListingActions.m b/UI/Scheduler/UIxCalListingActions.m index dd6ab8986..3329bb799 100644 --- a/UI/Scheduler/UIxCalListingActions.m +++ b/UI/Scheduler/UIxCalListingActions.m @@ -234,25 +234,6 @@ static NSArray *tasksFields = nil; } } -- (SOGoAppointmentFolder *) _aptFolder: (NSString *) folder - withClientObject: (SOGoAppointmentFolder *) clientObject -{ - SOGoAppointmentFolder *aptFolder; - NSArray *folderParts; - - if ([folder isEqualToString: @"/"]) - aptFolder = clientObject; - else - { - folderParts = [folder componentsSeparatedByString: @":"]; - aptFolder - = [clientObject lookupCalendarFolderForUID: - [folderParts objectAtIndex: 0]]; - } - - return aptFolder; -} - - (void) _fixComponentTitle: (NSMutableDictionary *) component withType: (NSString *) type { diff --git a/UI/WebServerResources/UIxAppointmentEditor.js b/UI/WebServerResources/UIxAppointmentEditor.js index b1700d83b..fd9e6aacc 100644 --- a/UI/WebServerResources/UIxAppointmentEditor.js +++ b/UI/WebServerResources/UIxAppointmentEditor.js @@ -115,8 +115,15 @@ function onComposeToAllAttendees() var attendees = $$("DIV#attendeesMenu LI.attendee"); var addresses = new Array(); attendees.each(function(item) { - var address = item.firstChild.nodeValue.trim() + " <" + item.readAttribute("email") + ">"; - addresses.push(address); + var textChild = null; + var childNodes = item.childNodes; + for (var i = 0; !textChild && i < childNodes.length; i++) { + if (childNodes[i].nodeType == 3) { + textChild = childNodes[i]; + var address = textChild.nodeValue.trim() + " <" + item.readAttribute("email") + ">"; + addresses.push(address); + } + } }); if (window.opener) window.opener.openMailTo(addresses.join(",")); @@ -130,8 +137,15 @@ function onComposeToUndecidedAttendees() var attendees = $$("DIV#attendeesMenu LI.attendee.needs-action"); var addresses = new Array(); attendees.each(function(item) { - var address = item.firstChild.nodeValue.trim() + " <" + item.readAttribute("email") + ">"; - addresses.push(address); + var textChild = null; + var childNodes = item.childNodes; + for (var i = 0; !textChild && i < childNodes.length; i++) { + if (childNodes[i].nodeType == 3) { + textChild = childNodes[i]; + var address = textChild.nodeValue.trim() + " <" + item.readAttribute("email") + ">"; + addresses.push(address); + } + } }); if (window.opener) window.opener.openMailTo(addresses.join(","));