diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.m b/SoObjects/Appointments/SOGoAppointmentFolder.m index 09594a465..5aaa3938a 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.m +++ b/SoObjects/Appointments/SOGoAppointmentFolder.m @@ -1888,18 +1888,18 @@ static Class sogoAppointmentFolderKlass = Nil; NSArray *elements; NSString *method, *filename; SOGoAppointmentObject *apt; - + filename = [NSString stringWithFormat: @"%@.ics", [event uid]]; apt = [SOGoAppointmentObject objectWithName: filename andContent: iCalString inContainer: self]; method = [[event parent] method]; if ([method isEqualToString: @"REQUEST"]) - elements = [apt postCalDAVEventRequestTo: recipients]; + elements = [apt postCalDAVEventRequestTo: recipients from: originator]; else if ([method isEqualToString: @"REPLY"]) - elements = [apt postCalDAVEventReplyTo: recipients]; + elements = [apt postCalDAVEventReplyTo: recipients from: originator]; else if ([method isEqualToString: @"CANCEL"]) - elements = [apt postCalDAVEventCancelTo: recipients]; + elements = [apt postCalDAVEventCancelTo: recipients from: originator]; else elements = nil; @@ -1970,6 +1970,10 @@ static Class sogoAppointmentFolderKlass = Nil; if ([cType hasPrefix: @"text/calendar"]) { originator = [request headerForKey: @"originator"]; + + if ([[originator lowercaseString] hasPrefix: @"mailto:"]) + originator = [originator substringFromIndex: 7]; + recipients = [[request headerForKey: @"recipient"] componentsSeparatedByString: @", "]; obj = [self caldavScheduleRequest: [request contentAsString] diff --git a/SoObjects/Appointments/SOGoAppointmentObject.h b/SoObjects/Appointments/SOGoAppointmentObject.h index 37f63201b..e6be8fd0c 100644 --- a/SoObjects/Appointments/SOGoAppointmentObject.h +++ b/SoObjects/Appointments/SOGoAppointmentObject.h @@ -48,11 +48,11 @@ - (NSException *) changeParticipationStatus: (NSString *) _status; -- (void) takeAttendeeStatus: (iCalPerson *) attendee; +- (void) takeAttendeeStatus: (iCalPerson *) attendee from: (NSString *) originator; -- (NSArray *) postCalDAVEventRequestTo: (NSArray *) recipients; -- (NSArray *) postCalDAVEventReplyTo: (NSArray *) recipients; -- (NSArray *) postCalDAVEventCancelTo: (NSArray *) recipients; +- (NSArray *) postCalDAVEventRequestTo: (NSArray *) recipients from: (NSString *) originator; +- (NSArray *) postCalDAVEventReplyTo: (NSArray *) recipients from: (NSString *) originator; +- (NSArray *) postCalDAVEventCancelTo: (NSArray *) recipients from: (NSString *) originator; /* "iCal multifolder saves" */ diff --git a/SoObjects/Appointments/SOGoAppointmentObject.m b/SoObjects/Appointments/SOGoAppointmentObject.m index cf83d2f73..97faf8401 100644 --- a/SoObjects/Appointments/SOGoAppointmentObject.m +++ b/SoObjects/Appointments/SOGoAppointmentObject.m @@ -362,6 +362,17 @@ [super saveComponent: newEvent]; } +// +// This method is used to update the status of an attendee. +// +// - theOwnerUser is owner of the calendar where the attendee +// participation state has changed. +// - uid is the actual UID of the user for whom we must +// update the calendar event (with the participation change) +// +// This method is called multiple times, in order to update the +// status of the attendee in calendars for the particular event UID. +// - (NSException *) _updateAttendee: (iCalPerson *) attendee ownerUser: (SOGoUser *) theOwnerUser forEventUID: (NSString *) eventUID @@ -409,14 +420,21 @@ return error; } + +// +// This method is invoked only from the SOGo Web interface. +// +// - theOwnerUser is owner of the calendar where the attendee +// participation state has changed. +// - (NSException *) _handleAttendee: (iCalPerson *) attendee ownerUser: (SOGoUser *) theOwnerUser statusChange: (NSString *) newStatus inEvent: (iCalEvent *) event { NSString *newContent, *currentStatus, *currentUser, *organizerUID; - NSException *ex; SOGoUser *ownerUser; + NSException *ex; ex = nil; @@ -442,14 +460,17 @@ newContent = [[event parent] versitString]; ex = [self saveContentString: newContent]; - + // If the current user isn't the organizer of the event + // that has just been updated, we update the event and + // send a notification ownerUser = [SOGoUser userWithLogin: owner roles: nil]; if (!(ex || [event userIsOrganizer: ownerUser])) { if ([[attendee rsvp] isEqualToString: @"true"] && [event isStillRelevant]) - [self sendResponseToOrganizer: event]; - + [self sendResponseToOrganizer: event + from: ownerUser]; + organizerUID = [[event organizer] uid]; if (organizerUID) ex = [self _updateAttendee: attendee @@ -514,6 +535,7 @@ } - (NSArray *) postCalDAVEventRequestTo: (NSArray *) recipients + from: (NSString *) originator { NSMutableArray *elements; NSEnumerator *recipientsEnum; @@ -546,6 +568,7 @@ } - (NSArray *) postCalDAVEventCancelTo: (NSArray *) recipients + from: (NSString *) originator { NSMutableArray *elements; NSEnumerator *recipientsEnum; @@ -577,7 +600,19 @@ return elements; } + +// +// This method is invoked by CalDAV clients such as +// Mozilla Lightning. We assume the SENT-BY has +// already been added, if required. +// +// It is used to updated the status of an attendee. +// The originator is the actualy owner of the calendar +// where the update took place. The status must then +// be propagated to the organizer and the other attendees. +// - (void) takeAttendeeStatus: (iCalPerson *) attendee + from: (NSString *) originator { iCalPerson *localAttendee; iCalEvent *event; @@ -595,17 +630,23 @@ iCalPerson *att; NSString *uid; int i; + + ownerUser = [SOGoUser userWithLogin:[[LDAPUserManager sharedUserManager] + getUIDForEmail: originator] + roles: nil]; - // We update for the organizer - ownerUser = [context activeUser]; - - [self _updateAttendee: attendee - ownerUser: ownerUser - forEventUID: [event uid] - withSequence: [event sequence] - forUID: [[SOGoUser userWithLogin: owner roles: nil] login] - shouldAddSentBy: NO]; - + // We update the copy of the organizer, only + // if it's a local user. +#warning add a check for only local users + uid = [[event organizer] uid]; + if (uid) + [self _updateAttendee: attendee + ownerUser: ownerUser + forEventUID: [event uid] + withSequence: [event sequence] + forUID: uid + shouldAddSentBy: NO]; + attendees = [event attendees]; for (i = 0; i < [attendees count]; i++) @@ -619,6 +660,12 @@ if (uid) { + // We skip the update that correspond to the originator + // since the CalDAV client will already have updated + // the actual event. + if ([ownerUser hasEmail: [att rfc822Email]]) + continue; + [self _updateAttendee: attendee ownerUser: ownerUser forEventUID: [event uid] @@ -635,6 +682,7 @@ } - (NSArray *) postCalDAVEventReplyTo: (NSArray *) recipients + from: (NSString *) originator { NSMutableArray *elements; NSEnumerator *recipientsEnum; @@ -643,10 +691,15 @@ iCalPerson *attendee, *person; SOGoAppointmentObject *recipientEvent; SOGoUser *ownerUser; + NSString *email; elements = [NSMutableArray array]; event = [self component: NO secure: NO]; - ownerUser = [SOGoUser userWithLogin: owner roles: nil]; + //ownerUser = [SOGoUser userWithLogin: owner roles: nil]; + + ownerUser = [SOGoUser userWithLogin: [[LDAPUserManager sharedUserManager] + getUIDForEmail: originator] + roles: nil]; attendee = [event findParticipant: ownerUser]; eventUID = [event uid]; @@ -663,9 +716,12 @@ if ([recipientEvent isNew]) [recipientEvent saveComponent: event]; else - [recipientEvent takeAttendeeStatus: attendee]; + [recipientEvent takeAttendeeStatus: attendee + from: originator]; } - [self sendIMIPReplyForEvent: event to: person]; + [self sendIMIPReplyForEvent: event + from: ownerUser + to: person]; [person release]; [elements addObject: [self _caldavSuccessCodeWithRecipient: recipient]]; @@ -674,6 +730,9 @@ return elements; } +// +// This method is invoked only from the SOGo Web interface. +// - (NSException *) changeParticipationStatus: (NSString *) _status { iCalEvent *event; @@ -686,7 +745,13 @@ event = [self component: NO secure: NO]; if (event) { + // owerUser will actually be the owner of the calendar + // where the participation change on the event has + // actually occured. The particpation change will of + // course be on the attendee that is the owner of the + // calendar where the participation change has occured. ownerUser = [SOGoUser userWithLogin: owner roles: nil]; + attendee = [event findParticipant: ownerUser]; if (attendee) ex = [self _handleAttendee: attendee diff --git a/SoObjects/Appointments/SOGoAptMailDutchDeletion.wo/SOGoAptMailDutchDeletion.html b/SoObjects/Appointments/SOGoAptMailDutchDeletion.wo/SOGoAptMailDutchDeletion.html index c4e107131..9c7fc4cd5 100644 --- a/SoObjects/Appointments/SOGoAptMailDutchDeletion.wo/SOGoAptMailDutchDeletion.html +++ b/SoObjects/Appointments/SOGoAptMailDutchDeletion.wo/SOGoAptMailDutchDeletion.html @@ -1,2 +1,2 @@ <#IsSubject>Gebeurtenis geannuleerd: <#summary/> -<#IsBody><#organizer/> heeft deze gebeurtenis geannuleerd: « <#summary/> ». \ No newline at end of file +<#IsBody><#organizer/> <#HasSentBy>(sent by <#sentBy/>) heeft deze gebeurtenis geannuleerd: « <#summary/> ». diff --git a/SoObjects/Appointments/SOGoAptMailDutchDeletion.wo/SOGoAptMailDutchDeletion.wod b/SoObjects/Appointments/SOGoAptMailDutchDeletion.wo/SOGoAptMailDutchDeletion.wod index 6d3d52eca..92428f429 100644 --- a/SoObjects/Appointments/SOGoAptMailDutchDeletion.wo/SOGoAptMailDutchDeletion.wod +++ b/SoObjects/Appointments/SOGoAptMailDutchDeletion.wo/SOGoAptMailDutchDeletion.wod @@ -16,3 +16,12 @@ summary: WOString { value = summary; escapeHTML = NO; } + +HasSentBy: WOConditional { + condition = hasSentBy; +} + +sentBy: WOString { + value = sentBy; + escapeHTML = NO; +} \ No newline at end of file diff --git a/SoObjects/Appointments/SOGoAptMailDutchInvitation.wo/SOGoAptMailDutchInvitation.html b/SoObjects/Appointments/SOGoAptMailDutchInvitation.wo/SOGoAptMailDutchInvitation.html index 8e2bf817d..02a92f4c2 100644 --- a/SoObjects/Appointments/SOGoAptMailDutchInvitation.wo/SOGoAptMailDutchInvitation.html +++ b/SoObjects/Appointments/SOGoAptMailDutchInvitation.wo/SOGoAptMailDutchInvitation.html @@ -1,2 +1,2 @@ <#IsSubject>Uitnodiging voor gebeurtenis: <#summary/> -<#IsBody><#organizer/> heeft u uitgenodigd voor <#summary/>. \ No newline at end of file +<#IsBody><#organizer/> <#HasSentBy>(sent by <#sentBy/>) heeft u uitgenodigd voor <#summary/>. diff --git a/SoObjects/Appointments/SOGoAptMailDutchInvitation.wo/SOGoAptMailDutchInvitation.wod b/SoObjects/Appointments/SOGoAptMailDutchInvitation.wo/SOGoAptMailDutchInvitation.wod index 6d3d52eca..92428f429 100644 --- a/SoObjects/Appointments/SOGoAptMailDutchInvitation.wo/SOGoAptMailDutchInvitation.wod +++ b/SoObjects/Appointments/SOGoAptMailDutchInvitation.wo/SOGoAptMailDutchInvitation.wod @@ -16,3 +16,12 @@ summary: WOString { value = summary; escapeHTML = NO; } + +HasSentBy: WOConditional { + condition = hasSentBy; +} + +sentBy: WOString { + value = sentBy; + escapeHTML = NO; +} \ No newline at end of file diff --git a/SoObjects/Appointments/SOGoAptMailFrenchDeletion.wo/SOGoAptMailFrenchDeletion.html b/SoObjects/Appointments/SOGoAptMailFrenchDeletion.wo/SOGoAptMailFrenchDeletion.html index b28fed22d..a025bde4d 100644 --- a/SoObjects/Appointments/SOGoAptMailFrenchDeletion.wo/SOGoAptMailFrenchDeletion.html +++ b/SoObjects/Appointments/SOGoAptMailFrenchDeletion.wo/SOGoAptMailFrenchDeletion.html @@ -1,2 +1,2 @@ <#IsSubject>Événement annulé : « <#summary/> » -<#IsBody><#organizer/> a annulé cet événement : « <#summary/> ». \ No newline at end of file +<#IsBody><#organizer/> <#HasSentBy>(envoyé par <#sentBy/>) a annulé cet événement : « <#summary/> ». diff --git a/SoObjects/Appointments/SOGoAptMailFrenchDeletion.wo/SOGoAptMailFrenchDeletion.wod b/SoObjects/Appointments/SOGoAptMailFrenchDeletion.wo/SOGoAptMailFrenchDeletion.wod index 6d3d52eca..92428f429 100644 --- a/SoObjects/Appointments/SOGoAptMailFrenchDeletion.wo/SOGoAptMailFrenchDeletion.wod +++ b/SoObjects/Appointments/SOGoAptMailFrenchDeletion.wo/SOGoAptMailFrenchDeletion.wod @@ -16,3 +16,12 @@ summary: WOString { value = summary; escapeHTML = NO; } + +HasSentBy: WOConditional { + condition = hasSentBy; +} + +sentBy: WOString { + value = sentBy; + escapeHTML = NO; +} \ No newline at end of file diff --git a/SoObjects/Appointments/SOGoAptMailFrenchInvitation.wo/SOGoAptMailFrenchInvitation.html b/SoObjects/Appointments/SOGoAptMailFrenchInvitation.wo/SOGoAptMailFrenchInvitation.html index 835952a13..8a4ec4b82 100644 --- a/SoObjects/Appointments/SOGoAptMailFrenchInvitation.wo/SOGoAptMailFrenchInvitation.html +++ b/SoObjects/Appointments/SOGoAptMailFrenchInvitation.wo/SOGoAptMailFrenchInvitation.html @@ -1,2 +1,2 @@ <#IsSubject>Invitation : <#summary/> -<#IsBody><#organizer/> vous a invité à « <#summary/> ». +<#IsBody><#organizer/> <#HasSentBy>(envoyé par <#sentBy/>) vous a invité à « <#summary/> ». diff --git a/SoObjects/Appointments/SOGoAptMailFrenchInvitation.wo/SOGoAptMailFrenchInvitation.wod b/SoObjects/Appointments/SOGoAptMailFrenchInvitation.wo/SOGoAptMailFrenchInvitation.wod index 6d3d52eca..92428f429 100644 --- a/SoObjects/Appointments/SOGoAptMailFrenchInvitation.wo/SOGoAptMailFrenchInvitation.wod +++ b/SoObjects/Appointments/SOGoAptMailFrenchInvitation.wo/SOGoAptMailFrenchInvitation.wod @@ -16,3 +16,12 @@ summary: WOString { value = summary; escapeHTML = NO; } + +HasSentBy: WOConditional { + condition = hasSentBy; +} + +sentBy: WOString { + value = sentBy; + escapeHTML = NO; +} \ No newline at end of file diff --git a/SoObjects/Appointments/SOGoAptMailGermanDeletion.wo/SOGoAptMailGermanDeletion.html b/SoObjects/Appointments/SOGoAptMailGermanDeletion.wo/SOGoAptMailGermanDeletion.html index 43b8d5c9b..3c0264a20 100644 --- a/SoObjects/Appointments/SOGoAptMailGermanDeletion.wo/SOGoAptMailGermanDeletion.html +++ b/SoObjects/Appointments/SOGoAptMailGermanDeletion.wo/SOGoAptMailGermanDeletion.html @@ -1,2 +1,2 @@ <#IsSubject>Termin abgesagt: <#summary/> -<#IsBody><#organizer/> hat diesen Termin abgesagt: <#summary/> +<#IsBody><#organizer/> <#HasSentBy>(sent by <#sentBy/>) hat diesen Termin abgesagt: <#summary/> diff --git a/SoObjects/Appointments/SOGoAptMailGermanDeletion.wo/SOGoAptMailGermanDeletion.wod b/SoObjects/Appointments/SOGoAptMailGermanDeletion.wo/SOGoAptMailGermanDeletion.wod index 6d3d52eca..92428f429 100644 --- a/SoObjects/Appointments/SOGoAptMailGermanDeletion.wo/SOGoAptMailGermanDeletion.wod +++ b/SoObjects/Appointments/SOGoAptMailGermanDeletion.wo/SOGoAptMailGermanDeletion.wod @@ -16,3 +16,12 @@ summary: WOString { value = summary; escapeHTML = NO; } + +HasSentBy: WOConditional { + condition = hasSentBy; +} + +sentBy: WOString { + value = sentBy; + escapeHTML = NO; +} \ No newline at end of file diff --git a/SoObjects/Appointments/SOGoAptMailGermanInvitation.wo/SOGoAptMailGermanInvitation.html b/SoObjects/Appointments/SOGoAptMailGermanInvitation.wo/SOGoAptMailGermanInvitation.html index 9500e1fa9..3f6163919 100644 --- a/SoObjects/Appointments/SOGoAptMailGermanInvitation.wo/SOGoAptMailGermanInvitation.html +++ b/SoObjects/Appointments/SOGoAptMailGermanInvitation.wo/SOGoAptMailGermanInvitation.html @@ -1,2 +1,2 @@ <#IsSubject>Termineinladung: <#summary/> -<#IsBody><#organizer/> hat Sie zu <#summary/> eingeladen. +<#IsBody><#organizer/> <#HasSentBy>(sent by <#sentBy/>) hat Sie zu <#summary/> eingeladen. diff --git a/SoObjects/Appointments/SOGoAptMailGermanInvitation.wo/SOGoAptMailGermanInvitation.wod b/SoObjects/Appointments/SOGoAptMailGermanInvitation.wo/SOGoAptMailGermanInvitation.wod index 6d3d52eca..92428f429 100644 --- a/SoObjects/Appointments/SOGoAptMailGermanInvitation.wo/SOGoAptMailGermanInvitation.wod +++ b/SoObjects/Appointments/SOGoAptMailGermanInvitation.wo/SOGoAptMailGermanInvitation.wod @@ -16,3 +16,12 @@ summary: WOString { value = summary; escapeHTML = NO; } + +HasSentBy: WOConditional { + condition = hasSentBy; +} + +sentBy: WOString { + value = sentBy; + escapeHTML = NO; +} \ No newline at end of file diff --git a/SoObjects/Appointments/SOGoAptMailItalianDeletion.wo/SOGoAptMailItalianDeletion.html b/SoObjects/Appointments/SOGoAptMailItalianDeletion.wo/SOGoAptMailItalianDeletion.html index ee71e81e4..754921b66 100644 --- a/SoObjects/Appointments/SOGoAptMailItalianDeletion.wo/SOGoAptMailItalianDeletion.html +++ b/SoObjects/Appointments/SOGoAptMailItalianDeletion.wo/SOGoAptMailItalianDeletion.html @@ -1,2 +1,2 @@ <#IsSubject>Evento cancellato : " <#summary/> " -<#IsBody><#organizer/> ha cancellato questo elemento: " <#summary/> ". \ No newline at end of file +<#IsBody><#organizer/> <#HasSentBy>(sent by <#sentBy/>) ha cancellato questo elemento: " <#summary/> ". diff --git a/SoObjects/Appointments/SOGoAptMailItalianDeletion.wo/SOGoAptMailItalianDeletion.wod b/SoObjects/Appointments/SOGoAptMailItalianDeletion.wo/SOGoAptMailItalianDeletion.wod index 6d3d52eca..92428f429 100644 --- a/SoObjects/Appointments/SOGoAptMailItalianDeletion.wo/SOGoAptMailItalianDeletion.wod +++ b/SoObjects/Appointments/SOGoAptMailItalianDeletion.wo/SOGoAptMailItalianDeletion.wod @@ -16,3 +16,12 @@ summary: WOString { value = summary; escapeHTML = NO; } + +HasSentBy: WOConditional { + condition = hasSentBy; +} + +sentBy: WOString { + value = sentBy; + escapeHTML = NO; +} \ No newline at end of file diff --git a/SoObjects/Appointments/SOGoAptMailItalianInvitation.wo/SOGoAptMailItalianInvitation.html b/SoObjects/Appointments/SOGoAptMailItalianInvitation.wo/SOGoAptMailItalianInvitation.html index 131c012b8..7dbc92fb8 100644 --- a/SoObjects/Appointments/SOGoAptMailItalianInvitation.wo/SOGoAptMailItalianInvitation.html +++ b/SoObjects/Appointments/SOGoAptMailItalianInvitation.wo/SOGoAptMailItalianInvitation.html @@ -1,2 +1,2 @@ <#IsSubject>Invito evento: <#summary/> -<#IsBody>Si è stati invitati da <#organizer> a <#summary/>. \ No newline at end of file +<#IsBody>Si è stati invitati da <#organizer> <#HasSentBy>(sent by <#sentBy/>) a <#summary/>. diff --git a/SoObjects/Appointments/SOGoAptMailItalianInvitation.wo/SOGoAptMailItalianInvitation.wod b/SoObjects/Appointments/SOGoAptMailItalianInvitation.wo/SOGoAptMailItalianInvitation.wod index 6d3d52eca..66b51444b 100644 --- a/SoObjects/Appointments/SOGoAptMailItalianInvitation.wo/SOGoAptMailItalianInvitation.wod +++ b/SoObjects/Appointments/SOGoAptMailItalianInvitation.wo/SOGoAptMailItalianInvitation.wod @@ -16,3 +16,12 @@ summary: WOString { value = summary; escapeHTML = NO; } + +HasSentBy: WOConditional { + condition = hasSentBy; +} + +sentBy: WOString { + value = sentBy; + escapeHTML = NO; +} diff --git a/SoObjects/Appointments/SOGoAptMailSpanishDeletion.wo/SOGoAptMailSpanishDeletion.html b/SoObjects/Appointments/SOGoAptMailSpanishDeletion.wo/SOGoAptMailSpanishDeletion.html index f70c7ff33..97636c29a 100644 --- a/SoObjects/Appointments/SOGoAptMailSpanishDeletion.wo/SOGoAptMailSpanishDeletion.html +++ b/SoObjects/Appointments/SOGoAptMailSpanishDeletion.wo/SOGoAptMailSpanishDeletion.html @@ -1,2 +1,2 @@ <#IsSubject>Evento cancelado: <#summary/> -<#IsBody><#organizer/> ha cancelado este evento: « <#summary/> ». \ No newline at end of file +<#IsBody><#organizer/> <#HasSentBy>(sent by <#sentBy/>) ha cancelado este evento: « <#summary/> ». diff --git a/SoObjects/Appointments/SOGoAptMailSpanishDeletion.wo/SOGoAptMailSpanishDeletion.wod b/SoObjects/Appointments/SOGoAptMailSpanishDeletion.wo/SOGoAptMailSpanishDeletion.wod index 6d3d52eca..92428f429 100644 --- a/SoObjects/Appointments/SOGoAptMailSpanishDeletion.wo/SOGoAptMailSpanishDeletion.wod +++ b/SoObjects/Appointments/SOGoAptMailSpanishDeletion.wo/SOGoAptMailSpanishDeletion.wod @@ -16,3 +16,12 @@ summary: WOString { value = summary; escapeHTML = NO; } + +HasSentBy: WOConditional { + condition = hasSentBy; +} + +sentBy: WOString { + value = sentBy; + escapeHTML = NO; +} \ No newline at end of file diff --git a/SoObjects/Appointments/SOGoAptMailSpanishInvitation.wo/SOGoAptMailSpanishInvitation.html b/SoObjects/Appointments/SOGoAptMailSpanishInvitation.wo/SOGoAptMailSpanishInvitation.html index 88d568790..22ddafe96 100644 --- a/SoObjects/Appointments/SOGoAptMailSpanishInvitation.wo/SOGoAptMailSpanishInvitation.html +++ b/SoObjects/Appointments/SOGoAptMailSpanishInvitation.wo/SOGoAptMailSpanishInvitation.html @@ -1,2 +1,2 @@ <#IsSubject>Invitación a evento: <#summary/> -<#IsBody><#organizer/> le ha invitado a <#summary/>. +<#IsBody><#organizer/> <#HasSentBy>(sent by <#sentBy/>) le ha invitado a <#summary/>. diff --git a/SoObjects/Appointments/SOGoAptMailSpanishInvitation.wo/SOGoAptMailSpanishInvitation.wod b/SoObjects/Appointments/SOGoAptMailSpanishInvitation.wo/SOGoAptMailSpanishInvitation.wod index 6d3d52eca..92428f429 100644 --- a/SoObjects/Appointments/SOGoAptMailSpanishInvitation.wo/SOGoAptMailSpanishInvitation.wod +++ b/SoObjects/Appointments/SOGoAptMailSpanishInvitation.wo/SOGoAptMailSpanishInvitation.wod @@ -16,3 +16,12 @@ summary: WOString { value = summary; escapeHTML = NO; } + +HasSentBy: WOConditional { + condition = hasSentBy; +} + +sentBy: WOString { + value = sentBy; + escapeHTML = NO; +} \ No newline at end of file diff --git a/SoObjects/Appointments/SOGoCalendarComponent.h b/SoObjects/Appointments/SOGoCalendarComponent.h index 2c3847dc5..a60ed016b 100644 --- a/SoObjects/Appointments/SOGoCalendarComponent.h +++ b/SoObjects/Appointments/SOGoCalendarComponent.h @@ -63,8 +63,10 @@ forObject: (iCalRepeatableEntityObject *) object toAttendees: (NSArray *) attendees; - (void) sendIMIPReplyForEvent: (iCalRepeatableEntityObject *) event + from: (SOGoUser *) from to: (iCalPerson *) recipient; -- (void) sendResponseToOrganizer: (iCalRepeatableEntityObject *) newComponent; +- (void) sendResponseToOrganizer: (iCalRepeatableEntityObject *) newComponent + from: (SOGoUser *) owner; // - (BOOL) isOrganizerOrOwner: (SOGoUser *) user; diff --git a/SoObjects/Appointments/SOGoCalendarComponent.m b/SoObjects/Appointments/SOGoCalendarComponent.m index 94a3c5bd3..d94176120 100644 --- a/SoObjects/Appointments/SOGoCalendarComponent.m +++ b/SoObjects/Appointments/SOGoCalendarComponent.m @@ -583,6 +583,7 @@ _occurenceHasID (iCalRepeatableEntityObject *occurence, NSString *recID) #warning fix this when sendEmailUsing blabla has been cleaned up - (void) sendIMIPReplyForEvent: (iCalRepeatableEntityObject *) event + from: (SOGoUser *) from to: (iCalPerson *) recipient { NSString *pageName, *language, *mailDate, *email; @@ -602,7 +603,8 @@ _occurenceHasID (iCalRepeatableEntityObject *occurence, NSString *recID) /* get WOApplication instance */ app = [WOApplication application]; - ownerUser = [SOGoUser userWithLogin: owner roles: nil]; + //ownerUser = [SOGoUser userWithLogin: owner roles: nil]; + ownerUser = from; language = [ownerUser language]; /* create page name */ pageName @@ -672,6 +674,7 @@ _occurenceHasID (iCalRepeatableEntityObject *occurence, NSString *recID) } - (void) sendResponseToOrganizer: (iCalRepeatableEntityObject *) newComponent + from: (SOGoUser *) from { iCalPerson *organizer, *attendee; iCalEvent *event; @@ -684,7 +687,7 @@ _occurenceHasID (iCalRepeatableEntityObject *occurence, NSString *recID) organizer = [event organizer]; attendee = [event findParticipant: ownerUser]; [event setAttendees: [NSArray arrayWithObject: attendee]]; - [self sendIMIPReplyForEvent: event to: organizer]; + [self sendIMIPReplyForEvent: event from: from to: organizer]; } } diff --git a/SoObjects/SOGo/SOGoUserDefaults.m b/SoObjects/SOGo/SOGoUserDefaults.m index 74633ec4a..bba5b9d5f 100644 --- a/SoObjects/SOGo/SOGoUserDefaults.m +++ b/SoObjects/SOGo/SOGoUserDefaults.m @@ -275,10 +275,13 @@ static NSString *uidColumnName = @"c_uid"; [d addEntriesFromDictionary: values]; [d setObject: uid forKey: @"uid"]; +#warning reenable when the code to use the SOGoUserManager is finished +#if 0 [[NSDistributedNotificationCenter defaultCenter] postNotificationName: ([fieldName isEqualToString: @"c_defaults"] ? @"SOGoUserDefaultsHaveChanged" : @"SOGoUserSettingsHaveChanged") object: nil userInfo: d]; +#endif [d release]; if ([[channel adaptorContext] hasOpenTransaction]) diff --git a/UI/MailPartViewers/UIxMailPartICalActions.m b/UI/MailPartViewers/UIxMailPartICalActions.m index 5ad40a4e3..1ce6137c7 100644 --- a/UI/MailPartViewers/UIxMailPartICalActions.m +++ b/UI/MailPartViewers/UIxMailPartICalActions.m @@ -1,6 +1,6 @@ /* UIxMailPartICalActions.m - this file is part of SOGo * - * Copyright (C) 2007 Inverse inc. + * Copyright (C) 2007-2008 Inverse inc. * * Author: Wolfgang Sourdeau * @@ -36,6 +36,7 @@ #import +#import #import #import #import @@ -168,16 +169,18 @@ #warning this is code copied from SOGoAppointmentObject... - (void) _updateAttendee: (iCalPerson *) attendee - withSequence: (NSNumber *) sequence - andCalUID: (NSString *) calUID - forUID: (NSString *) uid + ownerUser: (SOGoUser *) theOwnerUser + forEventUID: (NSString *) eventUID + withSequence: (NSNumber *) sequence + forUID: (NSString *) uid + shouldAddSentBy: (BOOL) b { SOGoAppointmentObject *eventObject; iCalEvent *event; iCalPerson *otherAttendee; NSString *iCalString; - eventObject = [self _eventObjectWithUID: calUID + eventObject = [self _eventObjectWithUID: eventUID forUser: [SOGoUser userWithLogin: uid roles: nil]]; if (![eventObject isNew]) { @@ -185,9 +188,22 @@ if ([[event sequence] compare: sequence] == NSOrderedSame) { - otherAttendee - = [event findParticipantWithEmail: [attendee rfc822Email]]; + SOGoUser *currentUser; + + otherAttendee = [event findParticipant: theOwnerUser]; [otherAttendee setPartStat: [attendee partStat]]; + + // If one has accepted / declined an invitation on behalf of + // the attendee, we add the user to the SENT-BY attribute. + currentUser = [context activeUser]; + if (b && ![[currentUser login] isEqualToString: [theOwnerUser login]]) + { + NSString *currentEmail; + currentEmail = [[currentUser allEmails] objectAtIndex: 0]; + [otherAttendee addAttribute: @"SENT-BY" + value: [NSString stringWithFormat: @"\"MAILTO:%@\"", currentEmail]]; + } + iCalString = [[event parent] versitString]; [eventObject saveContentString: iCalString]; } @@ -219,12 +235,50 @@ else rsvp = nil; [eventObject saveContentString: [calendar versitString]]; - if ([rsvp isEqualToString: @"true"]) - [eventObject sendResponseToOrganizer: chosenEvent]; + if ([rsvp isEqualToString: @"true"] && + [chosenEvent isStillRelevant]) + [eventObject sendResponseToOrganizer: chosenEvent + from: [context activeUser]]; organizerUID = [[chosenEvent organizer] uid]; if (organizerUID) - [self _updateAttendee: user withSequence: [chosenEvent sequence] - andCalUID: [chosenEvent uid] forUID: organizerUID]; + [self _updateAttendee: user + ownerUser: [context activeUser] + forEventUID: [chosenEvent uid] + withSequence: [chosenEvent sequence] + forUID: organizerUID + shouldAddSentBy: YES]; + + // We update the calendar of all participants that are + // local to the system. This is useful in case user A accepts + // invitation from organizer B and users C, D, E who are also + // attendees need to verify if A has accepted. + NSArray *attendees; + iCalPerson *att; + NSString *uid; + int i; + + attendees = [chosenEvent attendees]; + + for (i = 0; i < [attendees count]; i++) + { + att = [attendees objectAtIndex: i]; + + if (att == user) continue; + + uid = [[LDAPUserManager sharedUserManager] + getUIDForEmail: [att rfc822Email]]; + + if (uid) + { + [self _updateAttendee: user + ownerUser: [context activeUser] + forEventUID: [chosenEvent uid] + withSequence: [chosenEvent sequence] + forUID: uid + shouldAddSentBy: YES]; + } + } + response = [self responseWith204]; } else