diff --git a/ChangeLog b/ChangeLog index 31bb08301..419b641c0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,26 @@ 2007-12-06 Wolfgang Sourdeau + * SoObjects/Appointments/SOGoCalendarComponent.m + ([SOGoCalendarComponent -contentAsString]): securize the returned content. + ([SOGoCalendarComponent -aclsForUser:uid]): check whether the user + is an organizer or a participant as well. + + * SoObjects/Appointments/SOGoAppointmentObject.m + ([SOGoAppointmentObject -changeParticipationStatus:_status]): the + user we should change the status of is not the active user but the + owner of the object. This is for delegation. + + * SoObjects/Appointments/SOGoAppointmentFolder.m + ([SOGoAppointmentFolder -fetchContentObjectNames]): fetch the + elements through the fetchFields:from:to:title:component: method + method, so that the result is already filtered depending on the + acl. + + * UI/Scheduler/UIxComponentEditor.m ([UIxComponentEditor + -toolbar]): if the current user is a delegate, take the permission + "ModifyComponent" into account. Also, do not let him/her modify an + event for which he/she is the organizer. + * SoObjects/Contacts/SOGoContactLDAPFolder.m ([SOGoContactLDAPFolder -davResourceType]): declared as a carddav addressbook collection. diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.m b/SoObjects/Appointments/SOGoAppointmentFolder.m index 6deb3e3c5..5be6e5588 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.m +++ b/SoObjects/Appointments/SOGoAppointmentFolder.m @@ -26,6 +26,7 @@ #import #import +#import #import #import #import @@ -230,7 +231,6 @@ static NSNumber *sharedYes = nil; return filterData; } -#warning filters is leaked here - (NSArray *) _parseCalendarFilters: (id ) parentNode { NSEnumerator *children; @@ -1422,6 +1422,17 @@ static NSNumber *sharedYes = nil; // return objectNames; // } +- (NSArray *) fetchContentObjectNames +{ + static NSArray *cNameField = nil; + + if (!cNameField) + cNameField = [[NSArray alloc] initWithObjects: @"c_name", nil]; + + return [[self fetchFields: cNameField from: nil to: nil + title: nil component: nil] objectsForKey: @"c_name"]; +} + /* folder type */ - (NSString *) folderType diff --git a/SoObjects/Appointments/SOGoAppointmentObject.m b/SoObjects/Appointments/SOGoAppointmentObject.m index b8814b8e7..c3f283713 100644 --- a/SoObjects/Appointments/SOGoAppointmentObject.m +++ b/SoObjects/Appointments/SOGoAppointmentObject.m @@ -332,13 +332,15 @@ iCalEvent *event; iCalPerson *attendee; NSException *ex; + SOGoUser *ownerUser; ex = nil; event = [self component: NO secure: NO]; if (event) { - attendee = [event findParticipant: [context activeUser]]; + ownerUser = [SOGoUser userWithLogin: owner roles: nil]; + attendee = [event findParticipant: ownerUser]; if (attendee) ex = [self _handleAttendee: attendee statusChange: _status inEvent: event]; diff --git a/SoObjects/Appointments/SOGoCalendarComponent.m b/SoObjects/Appointments/SOGoCalendarComponent.m index 4236a6204..8411b7941 100644 --- a/SoObjects/Appointments/SOGoCalendarComponent.m +++ b/SoObjects/Appointments/SOGoCalendarComponent.m @@ -27,6 +27,7 @@ #import #import #import +#import #import #import #import @@ -142,6 +143,18 @@ static BOOL sendEMailNotifications = NO; return iCalString; } +- (NSString *) contentAsString +{ + NSString *secureContent; + + if ([[context request] isSoWebDAVRequest]) + secureContent = [self secureContentAsString]; + else + secureContent = [super contentAsString]; + + return secureContent; +} + - (iCalCalendar *) calendar: (BOOL) create secure: (BOOL) secure { NSString *componentTag; @@ -559,6 +572,7 @@ static BOOL sendEMailNotifications = NO; NSArray *superAcls; iCalRepeatableEntityObject *component; NSString *accessRole, *ownerRole; + SOGoUser *aclUser; roles = [NSMutableArray array]; superAcls = [super aclsForUser: uid]; @@ -573,6 +587,11 @@ static BOOL sendEMailNotifications = NO; { if (component) { + aclUser = [SOGoUser userWithLogin: uid roles: nil]; + if ([component userIsOrganizer: aclUser]) + [roles addObject: SOGoCalendarRole_Organizer]; + else if ([component userIsParticipant: aclUser]) + [roles addObject: SOGoCalendarRole_Participant]; accessRole = [container roleForComponentsWithAccessClass: [component symbolicAccessClass] forUser: uid]; diff --git a/SoObjects/Appointments/product.plist b/SoObjects/Appointments/product.plist index 4f0cb12bb..297b9b231 100644 --- a/SoObjects/Appointments/product.plist +++ b/SoObjects/Appointments/product.plist @@ -35,13 +35,14 @@ }; SOGoCalendarComponent = { superclass = "SOGoContentObject"; -/* defaultAccess = "SeeComponent"; */ defaultRoles = { "ViewAllComponent" = ( "Owner", "Organizer", "Participant", "ComponentModifier", "ComponentResponder", "ComponentViewer" ); "ViewDAndT" = ( "Organizer", "Participant", "ComponentDAndTViewer" ); "ModifyComponent" = ( "Owner", "Organizer" ); - "RespondToComponent" = ( "Participant" ); -/* "SeeComponent" = ( "Owner", "Organizer", "Participant", "ComponentModifier", "ComponentResponder", "ComponentViewer", "ComponentDAndTViewer" ); */ + "RespondToComponent" = ( "Participant", "ComponentModifier", "ComponentResponder" ); + "Access Object" = ( "Owner", "Organizer", "Participant", "ComponentModifier", "ComponentResponder", "ComponentViewer", "ComponentDAndTViewer" ); + "Access Contents Information" = ( "Owner", "Organizer", "Participant", "ComponentModifier", "ComponentResponder", "ComponentViewer", "ComponentDAndTViewer" ); + "WebDAV Access" = ( "Owner", "Organizer", "Participant", "ComponentModifier", "ComponentResponder", "ComponentViewer", "ComponentDAndTViewer" ); }; }; SOGoAppointmentObject = { diff --git a/UI/Scheduler/UIxComponentEditor.m b/UI/Scheduler/UIxComponentEditor.m index 9e5f812f8..6af7d1724 100644 --- a/UI/Scheduler/UIxComponentEditor.m +++ b/UI/Scheduler/UIxComponentEditor.m @@ -1025,6 +1025,7 @@ SoSecurityManager *sm; NSString *toolbarFilename, *adminToolbar; iCalPersonPartStat participationStatus; + SOGoUser *currentUser; if ([clientObject isKindOfClass: [SOGoAppointmentObject class]]) adminToolbar = @"SOGoAppointmentObject.toolbar"; @@ -1034,28 +1035,37 @@ sm = [SoSecurityManager sharedSecurityManager]; if ([[component attendees] count]) { - if ([component userIsOrganizer: ownerUser] - && ![sm validatePermission: SOGoCalendarPerm_ModifyComponent - onObject: clientObject - inContext: context]) - toolbarFilename = adminToolbar; - else if ([component userIsParticipant: ownerUser] - && ![sm validatePermission: SOGoCalendarPerm_RespondToComponent - onObject: clientObject - inContext: context]) - { - participationStatus - = [[component findParticipant: ownerUser] participationStatus]; - /* Lightning does not manage participation status within tasks */ - if (participationStatus == iCalPersonPartStatAccepted) - toolbarFilename = @"SOGoAppointmentObjectDecline.toolbar"; - else if (participationStatus == iCalPersonPartStatDeclined) - toolbarFilename = @"SOGoAppointmentObjectAccept.toolbar"; - else - toolbarFilename = @"SOGoAppointmentObjectAcceptOrDecline.toolbar"; - } - else + currentUser = [context activeUser]; + if ([component userIsOrganizer: currentUser]) toolbarFilename = @"SOGoComponentClose.toolbar"; + else + { + if ([component userIsOrganizer: ownerUser] + && ![sm validatePermission: SOGoCalendarPerm_ModifyComponent + onObject: clientObject + inContext: context]) + toolbarFilename = adminToolbar; + else if ([component userIsParticipant: ownerUser] + && !([sm validatePermission: SOGoCalendarPerm_RespondToComponent + onObject: clientObject + inContext: context] + && [sm validatePermission: SOGoCalendarPerm_ModifyComponent + onObject: clientObject + inContext: context])) + { + participationStatus + = [[component findParticipant: ownerUser] participationStatus]; + /* Lightning does not manage participation status within tasks */ + if (participationStatus == iCalPersonPartStatAccepted) + toolbarFilename = @"SOGoAppointmentObjectDecline.toolbar"; + else if (participationStatus == iCalPersonPartStatDeclined) + toolbarFilename = @"SOGoAppointmentObjectAccept.toolbar"; + else + toolbarFilename = @"SOGoAppointmentObjectAcceptOrDecline.toolbar"; + } + else + toolbarFilename = @"SOGoComponentClose.toolbar"; + } } else {