From b9c25cf29dad6f52eb297d32b50bde2576ef2b7d Mon Sep 17 00:00:00 2001 From: Wolfgang Sourdeau Date: Thu, 8 Nov 2007 19:56:18 +0000 Subject: [PATCH] Monotone-Parent: 3a085f426d0d1d08eb05a5e1cc11cb42d8ea82d4 Monotone-Revision: 8a8e7d68b4c6cc0ee67c2aa92e9417ba89858e50 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2007-11-08T19:56:18 Monotone-Branch: ca.inverse.sogo --- Main/SOGo.m | 9 +- .../Appointments/SOGoAppointmentObject.m | 352 +++++++++--------- SoObjects/SOGo/GNUmakefile | 4 + SoObjects/SOGo/WORequest+SOGo.h | 34 ++ SoObjects/SOGo/WORequest+SOGo.m | 36 ++ 5 files changed, 260 insertions(+), 175 deletions(-) create mode 100644 SoObjects/SOGo/WORequest+SOGo.h create mode 100644 SoObjects/SOGo/WORequest+SOGo.m diff --git a/Main/SOGo.m b/Main/SOGo.m index e7690fda5..32be4cedd 100644 --- a/Main/SOGo.m +++ b/Main/SOGo.m @@ -47,6 +47,7 @@ #import #import #import +#import #import "build.h" #import "SOGoProductLoader.h" @@ -236,13 +237,11 @@ static BOOL debugObjectAllocation = NO; - (id) authenticatorInContext: (WOContext *) context { id authenticator; - NSString *key; - key = [[context request] requestHandlerKey]; - if ([key isEqualToString: @"dav"]) - authenticator = [SOGoDAVAuthenticator sharedSOGoDAVAuthenticator]; - else + if ([[context request] handledByDefaultHandler]) authenticator = [SOGoWebAuthenticator sharedSOGoWebAuthenticator]; + else + authenticator = [SOGoDAVAuthenticator sharedSOGoDAVAuthenticator]; return authenticator; } diff --git a/SoObjects/Appointments/SOGoAppointmentObject.m b/SoObjects/Appointments/SOGoAppointmentObject.m index 8b2f12b54..7cc44e230 100644 --- a/SoObjects/Appointments/SOGoAppointmentObject.m +++ b/SoObjects/Appointments/SOGoAppointmentObject.m @@ -22,6 +22,7 @@ #import #import +#import #import #import #import @@ -32,6 +33,7 @@ #import #import #import +#import #import "NSArray+Appointments.h" #import "SOGoAppointmentFolder.h" @@ -196,158 +198,163 @@ NSException *storeError, *delError; BOOL updateForcesReconsider; - updateForcesReconsider = NO; - - if ([_iCal length] == 0) - return [NSException exceptionWithHTTPStatus: 400 /* Bad Request */ - reason: @"got no iCalendar content to store!"]; - - um = [LDAPUserManager sharedUserManager]; - - /* handle old content */ - - oldContent = [self contentAsString]; /* if nil, this is a new appointment */ - if ([oldContent length] == 0) + if ([[context request] handledByDefaultHandler]) { - /* new appointment */ - [self debugWithFormat:@"saving new appointment: %@", _iCal]; - oldApt = nil; + updateForcesReconsider = NO; + + if ([_iCal length] == 0) + return [NSException exceptionWithHTTPStatus: 400 /* Bad Request */ + reason: @"got no iCalendar content to store!"]; + + um = [LDAPUserManager sharedUserManager]; + + /* handle old content */ + + oldContent = [self contentAsString]; /* if nil, this is a new appointment */ + if ([oldContent length] == 0) + { + /* new appointment */ + [self debugWithFormat:@"saving new appointment: %@", _iCal]; + oldApt = nil; + } + else + oldApt = (iCalEvent *) [self component: NO]; + + /* compare sequence if requested */ + if (_v != 0) { + // TODO + } + + /* handle new content */ + + newApt = (iCalEvent *) [self component: NO]; + if (!newApt) + return [NSException exceptionWithHTTPStatus: 400 /* Bad Request */ + reason: @"could not parse iCalendar content!"]; + + /* diff */ + + changes = [iCalEventChanges changesFromEvent: oldApt toEvent: newApt]; + uids = [self getUIDsForICalPersons: [changes deletedAttendees]]; + removedUIDs = [NSMutableArray arrayWithArray: uids]; + + uids = [self getUIDsForICalPersons: [newApt attendees]]; + storeUIDs = [NSMutableArray arrayWithArray: uids]; + props = [changes updatedProperties]; + + /* detect whether sequence has to be increased */ + if ([changes hasChanges]) + [newApt increaseSequence]; + + /* preserve organizer */ + + organizer = [newApt organizer]; + uid = [self getUIDForICalPerson: organizer]; + if (!uid) + uid = [self ownerInContext: nil]; + if (uid) { + if (![storeUIDs containsObject:uid]) + [storeUIDs addObject:uid]; + [removedUIDs removeObject:uid]; + } + + /* organizer might have changed completely */ + + if (oldApt && ([props containsObject: @"organizer"])) { + uid = [self getUIDForICalPerson:[oldApt organizer]]; + if (uid) { + if (![storeUIDs containsObject:uid]) { + if (![removedUIDs containsObject:uid]) { + [removedUIDs addObject:uid]; + } + } + } + } + + [self debugWithFormat:@"UID ops:\n store: %@\n remove: %@", + storeUIDs, removedUIDs]; + + /* if time did change, all participants have to re-decide ... + * ... exception from that rule: the organizer + */ + + if (oldApt != nil && + ([props containsObject: @"startDate"] || + [props containsObject: @"endDate"] || + [props containsObject: @"duration"])) + { + NSArray *ps; + unsigned i, count; + + ps = [newApt attendees]; + count = [ps count]; + for (i = 0; i < count; i++) { + iCalPerson *p; + + p = [ps objectAtIndex:i]; + if (![p hasSameEmailAddress:organizer]) + [p setParticipationStatus:iCalPersonPartStatNeedsAction]; + } + _iCal = [[newApt parent] versitString]; + updateForcesReconsider = YES; + } + + /* perform storing */ + + storeError = [self saveContentString: _iCal inUIDs: storeUIDs]; + delError = [self deleteInUIDs: removedUIDs]; + + // TODO: make compound + if (storeError != nil) return storeError; + if (delError != nil) return delError; + + /* email notifications */ + if ([self sendEMailNotifications] + && [self _aptIsStillRelevant: newApt]) + { + attendees + = [NSMutableArray arrayWithArray: [changes insertedAttendees]]; + [attendees removePerson: organizer]; + [self sendEMailUsingTemplateNamed: @"Invitation" + forOldObject: nil + andNewObject: newApt + toAttendees: attendees]; + + if (updateForcesReconsider) { + attendees = [NSMutableArray arrayWithArray:[newApt attendees]]; + [attendees removeObjectsInArray:[changes insertedAttendees]]; + [attendees removePerson:organizer]; + [self sendEMailUsingTemplateNamed: @"Update" + forOldObject: oldApt + andNewObject: newApt + toAttendees: attendees]; + } + + attendees + = [NSMutableArray arrayWithArray: [changes deletedAttendees]]; + [attendees removePerson: organizer]; + if ([attendees count]) + { + iCalEvent *cancelledApt; + + cancelledApt = [newApt copy]; + [(iCalCalendar *) [cancelledApt parent] setMethod: @"cancel"]; + [self sendEMailUsingTemplateNamed: @"Removal" + forOldObject: nil + andNewObject: cancelledApt + toAttendees: attendees]; + [cancelledApt release]; + } + } } else - oldApt = (iCalEvent *) [self component: NO]; - - /* compare sequence if requested */ - - if (_v != 0) { - // TODO - } - - /* handle new content */ - - newApt = (iCalEvent *) [self component: NO]; - if (!newApt) - return [NSException exceptionWithHTTPStatus: 400 /* Bad Request */ - reason: @"could not parse iCalendar content!"]; - - /* diff */ - - changes = [iCalEventChanges changesFromEvent: oldApt toEvent: newApt]; - uids = [self getUIDsForICalPersons: [changes deletedAttendees]]; - removedUIDs = [NSMutableArray arrayWithArray: uids]; - - uids = [self getUIDsForICalPersons: [newApt attendees]]; - storeUIDs = [NSMutableArray arrayWithArray: uids]; - props = [changes updatedProperties]; - - /* detect whether sequence has to be increased */ - if ([changes hasChanges]) - [newApt increaseSequence]; - - /* preserve organizer */ - - organizer = [newApt organizer]; - uid = [self getUIDForICalPerson: organizer]; - if (!uid) - uid = [self ownerInContext: nil]; - if (uid) { - if (![storeUIDs containsObject:uid]) - [storeUIDs addObject:uid]; - [removedUIDs removeObject:uid]; - } - - /* organizer might have changed completely */ - - if (oldApt && ([props containsObject: @"organizer"])) { - uid = [self getUIDForICalPerson:[oldApt organizer]]; - if (uid) { - if (![storeUIDs containsObject:uid]) { - if (![removedUIDs containsObject:uid]) { - [removedUIDs addObject:uid]; - } - } - } - } - - [self debugWithFormat:@"UID ops:\n store: %@\n remove: %@", - storeUIDs, removedUIDs]; - - /* if time did change, all participants have to re-decide ... - * ... exception from that rule: the organizer - */ - - if (oldApt != nil && - ([props containsObject: @"startDate"] || - [props containsObject: @"endDate"] || - [props containsObject: @"duration"])) - { - NSArray *ps; - unsigned i, count; - - ps = [newApt attendees]; - count = [ps count]; - for (i = 0; i < count; i++) { - iCalPerson *p; - - p = [ps objectAtIndex:i]; - if (![p hasSameEmailAddress:organizer]) - [p setParticipationStatus:iCalPersonPartStatNeedsAction]; - } - _iCal = [[newApt parent] versitString]; - updateForcesReconsider = YES; - } - - /* perform storing */ - - storeError = [self saveContentString: _iCal inUIDs: storeUIDs]; - delError = [self deleteInUIDs: removedUIDs]; - - // TODO: make compound - if (storeError != nil) return storeError; - if (delError != nil) return delError; - - /* email notifications */ - if ([self sendEMailNotifications] - && [self _aptIsStillRelevant: newApt]) - { - attendees - = [NSMutableArray arrayWithArray: [changes insertedAttendees]]; - [attendees removePerson: organizer]; - [self sendEMailUsingTemplateNamed: @"Invitation" - forOldObject: nil - andNewObject: newApt - toAttendees: attendees]; - - if (updateForcesReconsider) { - attendees = [NSMutableArray arrayWithArray:[newApt attendees]]; - [attendees removeObjectsInArray:[changes insertedAttendees]]; - [attendees removePerson:organizer]; - [self sendEMailUsingTemplateNamed: @"Update" - forOldObject: oldApt - andNewObject: newApt - toAttendees: attendees]; - } - - attendees - = [NSMutableArray arrayWithArray: [changes deletedAttendees]]; - [attendees removePerson: organizer]; - if ([attendees count]) - { - iCalEvent *cancelledApt; - - cancelledApt = [newApt copy]; - [(iCalCalendar *) [cancelledApt parent] setMethod: @"cancel"]; - [self sendEMailUsingTemplateNamed: @"Removal" - forOldObject: nil - andNewObject: cancelledApt - toAttendees: attendees]; - [cancelledApt release]; - } - } + [self primarySaveContentString: _iCal]; return nil; } -- (NSException *)deleteWithBaseSequence:(int)_v { +- (NSException *) deleteWithBaseSequence: (int)_v +{ /* Note: We need to delete in all participants folders and send iMIP messages for all external accounts. @@ -364,10 +371,12 @@ */ iCalEvent *apt; NSMutableArray *attendees, *removedUIDs; + NSException *error; + if ([[context request] handledByDefaultHandler]) + { /* load existing content */ - - apt = (iCalEvent *) [self component: NO]; + apt = (iCalEvent *) [self component: NO]; /* compare sequence if requested */ @@ -375,35 +384,38 @@ // // TODO // } - removedUIDs = [NSMutableArray arrayWithArray: - [self attendeeUIDsFromAppointment: apt]]; - if (![removedUIDs containsObject: owner]) - [removedUIDs addObject: owner]; + removedUIDs = [NSMutableArray arrayWithArray: + [self attendeeUIDsFromAppointment: apt]]; + if (![removedUIDs containsObject: owner]) + [removedUIDs addObject: owner]; - if ([self sendEMailNotifications] - && [self _aptIsStillRelevant: apt]) - { - /* send notification email to attendees excluding organizer */ - attendees = [NSMutableArray arrayWithArray:[apt attendees]]; - [attendees removePerson:[apt organizer]]; + if ([self sendEMailNotifications] + && [self _aptIsStillRelevant: apt]) + { + /* send notification email to attendees excluding organizer */ + attendees = [NSMutableArray arrayWithArray:[apt attendees]]; + [attendees removePerson:[apt organizer]]; - /* flag appointment as being cancelled */ - [(iCalCalendar *) [apt parent] setMethod: @"cancel"]; - [apt increaseSequence]; + /* flag appointment as being cancelled */ + [(iCalCalendar *) [apt parent] setMethod: @"cancel"]; + [apt increaseSequence]; - /* remove all attendees to signal complete removal */ - [apt removeAllAttendees]; + /* remove all attendees to signal complete removal */ + [apt removeAllAttendees]; - /* send notification email */ - [self sendEMailUsingTemplateNamed: @"Deletion" - forOldObject: nil - andNewObject: apt - toAttendees: attendees]; + /* send notification email */ + [self sendEMailUsingTemplateNamed: @"Deletion" + forOldObject: nil + andNewObject: apt + toAttendees: attendees]; + } + + error = [self deleteInUIDs: removedUIDs]; } + else + error = [self primaryDelete]; - /* perform */ - - return [self deleteInUIDs: removedUIDs]; + return error; } - (NSException *) saveContentString: (NSString *) _iCalString diff --git a/SoObjects/SOGo/GNUmakefile b/SoObjects/SOGo/GNUmakefile index 46c94b95b..1d9df45cf 100644 --- a/SoObjects/SOGo/GNUmakefile +++ b/SoObjects/SOGo/GNUmakefile @@ -48,6 +48,8 @@ libSOGo_HEADER_FILES = \ SOGoWebAuthenticator.h \ SOGoMailer.h \ SOGoUser.h \ + \ + WORequest+SOGo.h libSOGo_OBJC_FILES = \ SOGoObject.m \ @@ -79,6 +81,8 @@ libSOGo_OBJC_FILES = \ SOGoWebAuthenticator.m \ SOGoMailer.m \ SOGoUser.m \ + \ + WORequest+SOGo.m # tools diff --git a/SoObjects/SOGo/WORequest+SOGo.h b/SoObjects/SOGo/WORequest+SOGo.h new file mode 100644 index 000000000..647f0de34 --- /dev/null +++ b/SoObjects/SOGo/WORequest+SOGo.h @@ -0,0 +1,34 @@ +/* WORequest+SOGo.h - this file is part of SOGo + * + * Copyright (C) 2007 Inverse groupe conseil + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef WOREQUEST_SOGo_H +#define WOREQUEST_SOGo_H + +#import + +@interface WORequest (SOGoSOPEUtilities) + +- (BOOL) handledByDefaultHandler; + +@end + +#endif /* WOREQUEST_SOGo_H */ diff --git a/SoObjects/SOGo/WORequest+SOGo.m b/SoObjects/SOGo/WORequest+SOGo.m new file mode 100644 index 000000000..776cacf9d --- /dev/null +++ b/SoObjects/SOGo/WORequest+SOGo.m @@ -0,0 +1,36 @@ +/* WORequest+SOGo.m - this file is part of SOGo + * + * Copyright (C) 2007 Inverse groupe conseil + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#import +#import + +#import "WORequest+SOGo.h" + +@implementation WORequest (SOGoSOPEUtilities) + +- (BOOL) handledByDefaultHandler +{ +#warning this should be changed someday + return (![requestHandlerKey isEqualToString: @"dav"]); +} + +@end