2006-12-14 22:15:05 +01:00
|
|
|
/* SOGoCalendarComponent.m - this file is part of SOGo
|
|
|
|
*
|
2009-04-30 23:17:55 +02:00
|
|
|
* Copyright (C) 2006-2009 Inverse inc.
|
2006-12-14 22:15:05 +01:00
|
|
|
*
|
|
|
|
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2008-07-04 18:06:09 +02:00
|
|
|
#import <Foundation/NSDictionary.h>
|
|
|
|
#import <Foundation/NSEnumerator.h>
|
2007-01-31 21:15:28 +01:00
|
|
|
#import <Foundation/NSString.h>
|
2007-08-09 22:58:01 +02:00
|
|
|
#import <Foundation/NSUserDefaults.h>
|
2007-01-31 21:15:28 +01:00
|
|
|
|
2007-08-07 20:37:31 +02:00
|
|
|
#import <NGObjWeb/NSException+HTTP.h>
|
|
|
|
#import <NGObjWeb/SoSecurityManager.h>
|
|
|
|
#import <NGObjWeb/WOApplication.h>
|
|
|
|
#import <NGObjWeb/WOContext+SoObjects.h>
|
2007-12-06 23:54:01 +01:00
|
|
|
#import <NGObjWeb/WORequest+So.h>
|
2007-08-09 22:58:01 +02:00
|
|
|
#import <NGExtensions/NSObject+Logs.h>
|
|
|
|
#import <NGExtensions/NGHashMap.h>
|
2006-12-14 22:15:05 +01:00
|
|
|
#import <NGCards/iCalCalendar.h>
|
2008-12-05 17:11:41 +01:00
|
|
|
#import <NGCards/iCalDateTime.h>
|
2007-11-18 11:16:25 +01:00
|
|
|
#import <NGCards/iCalEvent.h>
|
2007-01-31 21:15:28 +01:00
|
|
|
#import <NGCards/iCalPerson.h>
|
|
|
|
#import <NGCards/iCalRepeatableEntityObject.h>
|
2007-08-09 22:58:01 +02:00
|
|
|
#import <NGMime/NGMimeBodyPart.h>
|
|
|
|
#import <NGMime/NGMimeMultipartBody.h>
|
|
|
|
#import <NGMail/NGMimeMessage.h>
|
2007-01-31 21:15:28 +01:00
|
|
|
|
2007-11-13 23:38:05 +01:00
|
|
|
#import <SoObjects/SOGo/iCalEntityObject+Utilities.h>
|
2007-05-09 21:11:32 +02:00
|
|
|
#import <SoObjects/SOGo/LDAPUserManager.h>
|
2007-08-07 23:19:02 +02:00
|
|
|
#import <SoObjects/SOGo/NSCalendarDate+SOGo.h>
|
2007-08-09 22:58:01 +02:00
|
|
|
#import <SoObjects/SOGo/SOGoMailer.h>
|
2007-04-11 20:57:54 +02:00
|
|
|
#import <SoObjects/SOGo/SOGoPermissions.h>
|
|
|
|
#import <SoObjects/SOGo/SOGoUser.h>
|
2007-11-18 11:16:25 +01:00
|
|
|
#import <SoObjects/SOGo/WORequest+SOGo.h>
|
2007-04-26 03:16:19 +02:00
|
|
|
#import <SoObjects/Appointments/SOGoAppointmentFolder.h>
|
2007-01-31 21:15:28 +01:00
|
|
|
|
2007-11-18 11:16:25 +01:00
|
|
|
#import "SOGoAptMailICalReply.h"
|
2007-01-31 21:15:28 +01:00
|
|
|
#import "SOGoAptMailNotification.h"
|
2007-06-01 22:42:39 +02:00
|
|
|
#import "iCalEntityObject+SOGo.h"
|
2007-11-18 11:16:25 +01:00
|
|
|
#import "iCalPerson+SOGo.h"
|
2008-07-17 23:12:43 +02:00
|
|
|
#import "iCalRepeatableEntityObject+SOGo.h"
|
2006-12-14 22:15:05 +01:00
|
|
|
#import "SOGoCalendarComponent.h"
|
2008-07-17 23:12:43 +02:00
|
|
|
#import "SOGoComponentOccurence.h"
|
2006-12-14 22:15:05 +01:00
|
|
|
|
2007-01-31 21:15:28 +01:00
|
|
|
static BOOL sendEMailNotifications = NO;
|
|
|
|
|
2006-12-14 22:15:05 +01:00
|
|
|
@implementation SOGoCalendarComponent
|
|
|
|
|
2007-01-31 21:15:28 +01:00
|
|
|
+ (void) initialize
|
|
|
|
{
|
|
|
|
NSUserDefaults *ud;
|
|
|
|
static BOOL didInit = NO;
|
|
|
|
|
|
|
|
if (!didInit)
|
|
|
|
{
|
|
|
|
didInit = YES;
|
|
|
|
|
|
|
|
ud = [NSUserDefaults standardUserDefaults];
|
|
|
|
sendEMailNotifications
|
|
|
|
= [ud boolForKey: @"SOGoAppointmentSendEMailNotifications"];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-07-17 23:12:43 +02:00
|
|
|
- (id) init
|
|
|
|
{
|
|
|
|
if ((self = [super init]))
|
|
|
|
{
|
|
|
|
fullCalendar = nil;
|
|
|
|
safeCalendar = nil;
|
|
|
|
originalCalendar = nil;
|
2008-11-18 01:06:37 +01:00
|
|
|
componentTag = nil;
|
2008-07-17 23:12:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) dealloc
|
|
|
|
{
|
|
|
|
[fullCalendar release];
|
|
|
|
[safeCalendar release];
|
|
|
|
[originalCalendar release];
|
2008-11-18 01:06:37 +01:00
|
|
|
[componentTag release];
|
2008-07-17 23:12:43 +02:00
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
2007-01-31 21:15:28 +01:00
|
|
|
- (NSString *) davContentType
|
2006-12-14 22:15:05 +01:00
|
|
|
{
|
2007-01-31 21:15:28 +01:00
|
|
|
return @"text/calendar";
|
2006-12-14 22:15:05 +01:00
|
|
|
}
|
|
|
|
|
2007-02-15 21:59:02 +01:00
|
|
|
- (NSString *) componentTag
|
|
|
|
{
|
2008-11-18 01:06:37 +01:00
|
|
|
if (!componentTag)
|
|
|
|
[self subclassResponsibility: _cmd];
|
2008-11-22 22:52:40 +01:00
|
|
|
|
2008-11-18 01:06:37 +01:00
|
|
|
return componentTag;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setComponentTag: (NSString *) theTag
|
|
|
|
{
|
|
|
|
ASSIGN(componentTag, theTag);
|
2007-02-15 21:59:02 +01:00
|
|
|
}
|
|
|
|
|
2007-04-26 03:16:19 +02:00
|
|
|
- (void) _filterComponent: (iCalEntityObject *) component
|
2007-03-07 22:33:13 +01:00
|
|
|
{
|
2009-01-06 16:40:27 +01:00
|
|
|
NSString *type;
|
|
|
|
int classification;
|
|
|
|
|
|
|
|
type = @"vtodo";
|
|
|
|
classification = 0;
|
|
|
|
|
|
|
|
if ([component isKindOfClass: [iCalEvent class]])
|
|
|
|
type = @"vevent";
|
|
|
|
|
|
|
|
if ([component symbolicAccessClass] == iCalAccessPrivate)
|
|
|
|
classification = 1;
|
2009-01-20 20:23:09 +01:00
|
|
|
else if ([component symbolicAccessClass] == iCalAccessConfidential)
|
2009-01-06 16:40:27 +01:00
|
|
|
classification = 2;
|
|
|
|
|
|
|
|
[component setSummary: [self labelForKey: [NSString stringWithFormat: @"%@_class%d", type, classification]]];
|
2007-03-07 22:33:13 +01:00
|
|
|
[component setComment: @""];
|
|
|
|
[component setUserComment: @""];
|
|
|
|
[component setLocation: @""];
|
|
|
|
[component setCategories: @""];
|
|
|
|
[component setUrl: @""];
|
|
|
|
[component removeAllAttendees];
|
|
|
|
[component removeAllAlarms];
|
|
|
|
}
|
|
|
|
|
2007-11-18 11:16:25 +01:00
|
|
|
- (NSString *) secureContentAsString
|
2007-03-07 22:33:13 +01:00
|
|
|
{
|
|
|
|
iCalCalendar *tmpCalendar;
|
|
|
|
iCalRepeatableEntityObject *tmpComponent;
|
2007-07-04 22:12:28 +02:00
|
|
|
// NSArray *roles;
|
|
|
|
SoSecurityManager *sm;
|
2007-11-18 11:16:25 +01:00
|
|
|
NSString *iCalString;
|
2007-03-07 22:33:13 +01:00
|
|
|
|
2007-07-04 22:12:28 +02:00
|
|
|
// uid = [[context activeUser] login];
|
|
|
|
// roles = [self aclsForUser: uid];
|
|
|
|
// if ([roles containsObject: SOGoCalendarRole_Organizer]
|
|
|
|
// || [roles containsObject: SOGoCalendarRole_Participant]
|
|
|
|
// || [roles containsObject: SOGoCalendarRole_ComponentViewer])
|
|
|
|
// calContent = content;
|
|
|
|
// else if ([roles containsObject: SOGoCalendarRole_ComponentDAndTViewer])
|
|
|
|
// {
|
|
|
|
// tmpCalendar = [[self calendar: NO] copy];
|
|
|
|
// tmpComponent = (iCalRepeatableEntityObject *)
|
|
|
|
// [tmpCalendar firstChildWithTag: [self componentTag]];
|
|
|
|
// [self _filterComponent: tmpComponent];
|
|
|
|
// calContent = [tmpCalendar versitString];
|
|
|
|
// [tmpCalendar release];
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// calContent = nil;
|
|
|
|
|
2007-11-18 11:16:25 +01:00
|
|
|
sm = [SoSecurityManager sharedSecurityManager];
|
2008-06-13 22:22:51 +02:00
|
|
|
if (activeUserIsOwner
|
|
|
|
|| [[self ownerInContext: context] isEqualToString: [[context activeUser] login]]
|
|
|
|
|| ![sm validatePermission: SOGoCalendarPerm_ViewAllComponent
|
|
|
|
onObject: self inContext: context])
|
|
|
|
iCalString = content;
|
2007-11-18 11:16:25 +01:00
|
|
|
else if (![sm validatePermission: SOGoCalendarPerm_ViewDAndT
|
|
|
|
onObject: self inContext: context])
|
|
|
|
{
|
2008-07-23 19:40:51 +02:00
|
|
|
tmpCalendar = [[self calendar: NO secure: NO] mutableCopy];
|
2007-11-18 11:16:25 +01:00
|
|
|
tmpComponent = (iCalRepeatableEntityObject *)
|
|
|
|
[tmpCalendar firstChildWithTag: [self componentTag]];
|
|
|
|
[self _filterComponent: tmpComponent];
|
2009-01-06 16:40:27 +01:00
|
|
|
|
|
|
|
// We add an additional header here to inform clients (if necessary) that
|
|
|
|
// we churned the content of the calendar.
|
|
|
|
[tmpComponent addChild: [CardElement simpleElementWithTag: @"X-SOGo-Secure"
|
|
|
|
value: @"YES"]];
|
2007-11-18 11:16:25 +01:00
|
|
|
iCalString = [tmpCalendar versitString];
|
|
|
|
[tmpCalendar release];
|
2007-03-07 22:33:13 +01:00
|
|
|
}
|
2007-11-18 11:16:25 +01:00
|
|
|
else
|
|
|
|
iCalString = nil;
|
2007-03-07 22:33:13 +01:00
|
|
|
|
2007-11-18 11:16:25 +01:00
|
|
|
return iCalString;
|
2007-11-13 23:38:05 +01:00
|
|
|
}
|
2007-03-07 22:33:13 +01:00
|
|
|
|
2008-07-17 23:12:43 +02:00
|
|
|
static inline BOOL
|
|
|
|
_occurenceHasID (iCalRepeatableEntityObject *occurence, NSString *recID)
|
|
|
|
{
|
|
|
|
unsigned int seconds, recSeconds;
|
|
|
|
|
|
|
|
seconds = [recID intValue];
|
|
|
|
recSeconds = [[occurence recurrenceId] timeIntervalSince1970];
|
|
|
|
|
|
|
|
return (seconds == recSeconds);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (iCalRepeatableEntityObject *) lookupOccurence: (NSString *) recID
|
|
|
|
{
|
|
|
|
iCalRepeatableEntityObject *component, *occurence, *currentOccurence;
|
|
|
|
NSArray *occurences;
|
|
|
|
unsigned int count, max;
|
|
|
|
|
|
|
|
occurence = nil;
|
|
|
|
|
|
|
|
component = [self component: NO secure: NO];
|
|
|
|
if ([component hasRecurrenceRules])
|
|
|
|
{
|
|
|
|
occurences = [[self calendar: NO secure: NO] allObjects];
|
|
|
|
max = [occurences count];
|
|
|
|
count = 1;
|
|
|
|
while (!occurence && count < max)
|
|
|
|
{
|
|
|
|
currentOccurence = [occurences objectAtIndex: count];
|
|
|
|
if (_occurenceHasID (currentOccurence, recID))
|
|
|
|
occurence = currentOccurence;
|
|
|
|
else
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return occurence;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (SOGoComponentOccurence *) occurence: (iCalRepeatableEntityObject *) component
|
|
|
|
{
|
|
|
|
[self subclassResponsibility: _cmd];
|
|
|
|
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (iCalRepeatableEntityObject *) newOccurenceWithID: (NSString *) recID
|
|
|
|
{
|
|
|
|
iCalRepeatableEntityObject *masterOccurence, *newOccurence;
|
|
|
|
iCalCalendar *calendar;
|
|
|
|
NSCalendarDate *recDate;
|
|
|
|
|
|
|
|
recDate = [NSCalendarDate dateWithTimeIntervalSince1970: [recID intValue]];
|
|
|
|
masterOccurence = [self component: NO secure: NO];
|
2009-03-16 22:21:43 +01:00
|
|
|
|
2008-07-17 23:12:43 +02:00
|
|
|
if ([masterOccurence doesOccurOnDate: recDate])
|
|
|
|
{
|
|
|
|
newOccurence = [masterOccurence mutableCopy];
|
|
|
|
[newOccurence autorelease];
|
|
|
|
[newOccurence removeAllRecurrenceRules];
|
|
|
|
[newOccurence removeAllExceptionRules];
|
|
|
|
[newOccurence removeAllExceptionDates];
|
|
|
|
[newOccurence setOrganizer: nil];
|
|
|
|
[newOccurence setRecurrenceId: recDate];
|
|
|
|
|
2008-11-03 15:16:32 +01:00
|
|
|
calendar = [masterOccurence parent];
|
2008-07-17 23:12:43 +02:00
|
|
|
[calendar addChild: newOccurence];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
newOccurence = nil;
|
|
|
|
|
|
|
|
return newOccurence;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) toManyRelationshipKeys
|
|
|
|
{
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) toOneRelationshipKeys
|
|
|
|
{
|
|
|
|
NSMutableArray *keys;
|
|
|
|
NSArray *occurences;
|
|
|
|
NSCalendarDate *recID;
|
|
|
|
unsigned int count, max, seconds;
|
|
|
|
|
|
|
|
keys = [NSMutableArray array];
|
|
|
|
[keys addObject: @"master"];
|
|
|
|
occurences = [[self calendar: NO secure: NO] allObjects];
|
|
|
|
max = [occurences count];
|
|
|
|
for (count = 1; count < max; count++)
|
|
|
|
{
|
|
|
|
recID = [[occurences objectAtIndex: count] recurrenceId];
|
|
|
|
if (recID)
|
|
|
|
{
|
|
|
|
seconds = [recID timeIntervalSince1970];
|
|
|
|
[keys addObject: [NSString stringWithFormat: @"occurence%d",
|
|
|
|
seconds]];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return keys;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) lookupName: (NSString *) lookupName
|
|
|
|
inContext: (id) localContext
|
|
|
|
acquire: (BOOL) acquire
|
|
|
|
{
|
|
|
|
id obj;
|
|
|
|
iCalRepeatableEntityObject *occurence;
|
|
|
|
NSString *recID;
|
|
|
|
BOOL isNewOccurence;
|
|
|
|
|
|
|
|
obj = [super lookupName: lookupName
|
|
|
|
inContext: localContext
|
|
|
|
acquire: acquire];
|
|
|
|
if (!obj)
|
|
|
|
{
|
|
|
|
if ([lookupName isEqualToString: @"master"])
|
|
|
|
obj = [self occurence: [self component: NO secure: NO]];
|
|
|
|
else if ([lookupName hasPrefix: @"occurence"])
|
|
|
|
{
|
|
|
|
recID = [lookupName substringFromIndex: 9];
|
|
|
|
occurence = [self lookupOccurence: recID];
|
2009-03-16 22:02:59 +01:00
|
|
|
if (occurence)
|
|
|
|
isNewOccurence = NO;
|
|
|
|
else
|
2008-07-17 23:12:43 +02:00
|
|
|
{
|
|
|
|
occurence = [self newOccurenceWithID: recID];
|
|
|
|
isNewOccurence = YES;
|
|
|
|
}
|
|
|
|
if (occurence)
|
|
|
|
{
|
|
|
|
obj = [self occurence: occurence];
|
|
|
|
if (isNewOccurence)
|
|
|
|
[obj setIsNew: isNewOccurence];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
2007-12-06 23:54:01 +01:00
|
|
|
- (NSString *) contentAsString
|
|
|
|
{
|
|
|
|
NSString *secureContent;
|
|
|
|
|
|
|
|
if ([[context request] isSoWebDAVRequest])
|
|
|
|
secureContent = [self secureContentAsString];
|
|
|
|
else
|
|
|
|
secureContent = [super contentAsString];
|
|
|
|
|
|
|
|
return secureContent;
|
|
|
|
}
|
|
|
|
|
2008-03-18 18:26:34 +01:00
|
|
|
- (NSString *) davCalendarData
|
|
|
|
{
|
|
|
|
return [self contentAsString];
|
|
|
|
}
|
|
|
|
|
2007-11-18 11:16:25 +01:00
|
|
|
- (iCalCalendar *) calendar: (BOOL) create secure: (BOOL) secure
|
2006-12-14 22:15:05 +01:00
|
|
|
{
|
2008-07-17 23:12:43 +02:00
|
|
|
iCalRepeatableEntityObject *newComponent;
|
2008-08-05 03:53:01 +02:00
|
|
|
iCalCalendar **calendar, *returnedCopy;
|
2008-11-18 01:06:37 +01:00
|
|
|
NSString *iCalString, *tag;
|
2007-11-18 11:16:25 +01:00
|
|
|
|
|
|
|
if (secure)
|
2008-07-17 23:12:43 +02:00
|
|
|
calendar = &safeCalendar;
|
2007-11-18 11:16:25 +01:00
|
|
|
else
|
2008-07-17 23:12:43 +02:00
|
|
|
calendar = &fullCalendar;
|
2006-12-14 22:15:05 +01:00
|
|
|
|
2008-07-17 23:12:43 +02:00
|
|
|
if (!*calendar)
|
2006-12-14 22:15:05 +01:00
|
|
|
{
|
2008-07-17 23:12:43 +02:00
|
|
|
if (secure)
|
|
|
|
iCalString = [self secureContentAsString];
|
|
|
|
else
|
|
|
|
iCalString = content;
|
|
|
|
|
|
|
|
if ([iCalString length] > 0)
|
2007-11-18 11:16:25 +01:00
|
|
|
{
|
2008-07-17 23:12:43 +02:00
|
|
|
ASSIGN (*calendar, [iCalCalendar parseSingleFromSource: iCalString]);
|
|
|
|
if (!secure)
|
|
|
|
originalCalendar = [*calendar copy];
|
2007-11-18 11:16:25 +01:00
|
|
|
}
|
2007-03-18 16:08:41 +01:00
|
|
|
else
|
2008-07-17 23:12:43 +02:00
|
|
|
{
|
|
|
|
if (create)
|
|
|
|
{
|
|
|
|
ASSIGN (*calendar, [iCalCalendar groupWithTag: @"vcalendar"]);
|
|
|
|
[*calendar setVersion: @"2.0"];
|
2009-03-19 02:21:39 +01:00
|
|
|
[*calendar setProdID: @"-//Inverse inc./SOGo 1.0//EN"];
|
2008-11-18 01:06:37 +01:00
|
|
|
tag = [[self componentTag] uppercaseString];
|
|
|
|
newComponent = [[*calendar classForTag: tag]
|
|
|
|
groupWithTag: tag];
|
2008-07-17 23:12:43 +02:00
|
|
|
[newComponent setUid: [self globallyUniqueObjectId]];
|
|
|
|
[*calendar addChild: newComponent];
|
|
|
|
}
|
|
|
|
}
|
2006-12-14 22:15:05 +01:00
|
|
|
}
|
|
|
|
|
2008-08-05 03:53:01 +02:00
|
|
|
returnedCopy = [*calendar mutableCopy];
|
|
|
|
[returnedCopy autorelease];
|
|
|
|
|
|
|
|
return returnedCopy;
|
2006-12-14 22:15:05 +01:00
|
|
|
}
|
|
|
|
|
2007-11-18 11:16:25 +01:00
|
|
|
- (id) component: (BOOL) create secure: (BOOL) secure
|
2007-01-31 19:43:15 +01:00
|
|
|
{
|
2007-11-18 11:16:25 +01:00
|
|
|
return [[self calendar: create secure: secure]
|
|
|
|
firstChildWithTag: [self componentTag]];
|
2007-01-04 16:18:30 +01:00
|
|
|
}
|
|
|
|
|
2008-12-05 17:11:41 +01:00
|
|
|
- (void) _updateRecurrenceIDsWithEvent: (iCalRepeatableEntityObject*) newEvent
|
2008-07-17 23:12:43 +02:00
|
|
|
{
|
2008-12-05 17:11:41 +01:00
|
|
|
iCalRepeatableEntityObject *oldMaster, *currentComponent;
|
|
|
|
iCalDateTime *currentDate;
|
2008-07-17 23:12:43 +02:00
|
|
|
int deltaSecs;
|
2008-12-05 17:11:41 +01:00
|
|
|
NSArray *components, *dates;
|
|
|
|
NSMutableArray *newDates;
|
2008-07-17 23:12:43 +02:00
|
|
|
unsigned int count, max;
|
2008-12-05 17:11:41 +01:00
|
|
|
NSCalendarDate *recID, *newDate;
|
2008-07-17 23:12:43 +02:00
|
|
|
|
2008-12-05 17:11:41 +01:00
|
|
|
// Compute time interval from previous event definition.
|
2008-07-17 23:12:43 +02:00
|
|
|
oldMaster = (iCalRepeatableEntityObject *)
|
|
|
|
[originalCalendar firstChildWithTag: [self componentTag]];
|
2008-12-05 17:11:41 +01:00
|
|
|
deltaSecs = [[newEvent startDate]
|
2008-07-17 23:12:43 +02:00
|
|
|
timeIntervalSinceDate: [oldMaster startDate]];
|
2008-12-05 17:11:41 +01:00
|
|
|
|
|
|
|
components = [[newEvent parent] events];
|
2008-07-17 23:12:43 +02:00
|
|
|
max = [components count];
|
2008-12-05 17:11:41 +01:00
|
|
|
|
|
|
|
if (max > 0)
|
2008-07-17 23:12:43 +02:00
|
|
|
{
|
2008-12-05 17:11:41 +01:00
|
|
|
// Update recurrence-id attribute of occurences.
|
|
|
|
for (count = 1; count < max; count++)
|
|
|
|
{
|
|
|
|
currentComponent = [components objectAtIndex: count];
|
|
|
|
recID = [[currentComponent recurrenceId] addTimeInterval: deltaSecs];
|
|
|
|
[currentComponent setRecurrenceId: recID];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Update exception dates in master vEvent.
|
|
|
|
currentComponent = [components objectAtIndex: 0];
|
|
|
|
dates = [currentComponent childrenWithTag: @"exdate"];
|
|
|
|
max = [dates count];
|
|
|
|
if (max > 0)
|
|
|
|
{
|
|
|
|
newDates = [NSMutableArray arrayWithCapacity: max];
|
|
|
|
for (count = 0; count < max; count++)
|
|
|
|
{
|
|
|
|
currentDate = [dates objectAtIndex: count];
|
|
|
|
newDate = [[currentDate dateTime] addTimeInterval: deltaSecs];
|
|
|
|
[newDates addObject: newDate];
|
|
|
|
}
|
|
|
|
[currentComponent removeAllExceptionDates];
|
|
|
|
for (count = 0; count < max; count++)
|
|
|
|
[currentComponent addToExceptionDates: [newDates objectAtIndex: count]];
|
2008-12-31 03:57:54 +01:00
|
|
|
}
|
2008-07-17 23:12:43 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-11-18 11:16:25 +01:00
|
|
|
- (void) saveComponent: (iCalRepeatableEntityObject *) newObject
|
2007-01-31 19:43:15 +01:00
|
|
|
{
|
2008-12-01 20:20:25 +01:00
|
|
|
NSString *newiCalString, *newUid;
|
2007-01-04 16:18:30 +01:00
|
|
|
|
2008-07-17 23:12:43 +02:00
|
|
|
if (!isNew
|
|
|
|
&& [newObject isRecurrent])
|
2008-12-05 17:11:41 +01:00
|
|
|
// We update an repeating event -- update exception dates
|
|
|
|
// and recurrence-ids.
|
|
|
|
[self _updateRecurrenceIDsWithEvent: newObject];
|
2008-12-01 20:20:25 +01:00
|
|
|
|
|
|
|
// As much as we can, we try to use c_name == c_uid in order
|
|
|
|
// to avoid tricky scenarios with some CalDAV clients. For example,
|
|
|
|
// if Alice invites Bob (both use SOGo) and Bob accepts the invitation
|
|
|
|
// using Lightning before having refreshed his calendar, he'll end up
|
|
|
|
// with a duplicate of the event in his database tables.
|
|
|
|
if (isNew)
|
|
|
|
{
|
|
|
|
newUid = nameInContainer;
|
|
|
|
|
|
|
|
if ([newUid hasSuffix: @".ics"])
|
|
|
|
newUid = [newUid substringToIndex: [newUid length]-4];
|
|
|
|
[newObject setUid: newUid];
|
|
|
|
}
|
|
|
|
|
2007-11-18 11:16:25 +01:00
|
|
|
newiCalString = [[newObject parent] versitString];
|
2007-01-04 16:18:30 +01:00
|
|
|
|
2007-11-18 11:16:25 +01:00
|
|
|
[self saveContentString: newiCalString];
|
2007-01-04 16:18:30 +01:00
|
|
|
}
|
|
|
|
|
2007-11-18 11:16:25 +01:00
|
|
|
/* raw saving */
|
2006-12-14 22:15:05 +01:00
|
|
|
|
2007-01-31 21:15:28 +01:00
|
|
|
/* EMail Notifications */
|
|
|
|
- (NSString *) homePageURLForPerson: (iCalPerson *) _person
|
|
|
|
{
|
|
|
|
NSString *baseURL;
|
|
|
|
NSString *uid;
|
|
|
|
NSArray *traversalObjects;
|
|
|
|
|
|
|
|
/* generate URL from traversal stack */
|
2007-04-11 20:57:54 +02:00
|
|
|
traversalObjects = [context objectTraversalStack];
|
2007-01-31 21:15:28 +01:00
|
|
|
if ([traversalObjects count] > 0)
|
2007-04-11 20:57:54 +02:00
|
|
|
baseURL = [[traversalObjects objectAtIndex:0] baseURLInContext: context];
|
2007-01-31 21:15:28 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
baseURL = @"http://localhost/";
|
|
|
|
[self warnWithFormat:@"Unable to create baseURL from context!"];
|
|
|
|
}
|
2007-11-18 11:16:25 +01:00
|
|
|
uid = [_person uid];
|
2007-01-31 21:15:28 +01:00
|
|
|
|
|
|
|
return ((uid)
|
|
|
|
? [NSString stringWithFormat:@"%@%@", baseURL, uid]
|
|
|
|
: nil);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) sendEMailNotifications
|
|
|
|
{
|
|
|
|
return sendEMailNotifications;
|
|
|
|
}
|
|
|
|
|
2007-04-11 20:57:54 +02:00
|
|
|
- (NSTimeZone *) timeZoneForUser: (NSString *) email
|
|
|
|
{
|
|
|
|
NSString *uid;
|
|
|
|
|
2007-05-09 21:11:32 +02:00
|
|
|
uid = [[LDAPUserManager sharedUserManager] getUIDForEmail: email];
|
2007-04-11 20:57:54 +02:00
|
|
|
|
2007-05-09 21:30:06 +02:00
|
|
|
return [[SOGoUser userWithLogin: uid roles: nil] timeZone];
|
2007-04-11 20:57:54 +02:00
|
|
|
}
|
|
|
|
|
2008-10-01 21:32:14 +02:00
|
|
|
- (void) sendEMailUsingTemplateNamed: (NSString *) newPageName
|
|
|
|
forObject: (iCalRepeatableEntityObject *) object
|
2008-11-18 01:06:37 +01:00
|
|
|
previousObject: (iCalRepeatableEntityObject *) previousObject
|
2008-10-01 21:32:14 +02:00
|
|
|
toAttendees: (NSArray *) attendees
|
2007-01-31 21:15:28 +01:00
|
|
|
{
|
|
|
|
NSString *pageName;
|
2008-07-08 17:40:47 +02:00
|
|
|
NSString *senderEmail, *shortSenderEmail, *email, *iCalString;
|
2007-01-31 21:15:28 +01:00
|
|
|
WOApplication *app;
|
|
|
|
unsigned i, count;
|
|
|
|
iCalPerson *attendee;
|
2007-08-22 17:11:41 +02:00
|
|
|
NSString *recipient, *language;
|
2007-01-31 21:15:28 +01:00
|
|
|
SOGoAptMailNotification *p;
|
2007-08-07 23:19:02 +02:00
|
|
|
NSString *mailDate, *subject, *text, *header;
|
2007-01-31 21:15:28 +01:00
|
|
|
NGMutableHashMap *headerMap;
|
|
|
|
NGMimeMessage *msg;
|
|
|
|
NGMimeBodyPart *bodyPart;
|
|
|
|
NGMimeMultipartBody *body;
|
2008-11-18 01:06:37 +01:00
|
|
|
SOGoUser *ownerUser;
|
2007-01-31 21:15:28 +01:00
|
|
|
|
2008-07-04 18:06:09 +02:00
|
|
|
if (sendEMailNotifications
|
2008-10-01 21:32:14 +02:00
|
|
|
&& [object isStillRelevant])
|
2007-01-31 21:15:28 +01:00
|
|
|
{
|
2008-10-01 21:32:14 +02:00
|
|
|
count = [attendees count];
|
2007-11-18 11:16:25 +01:00
|
|
|
if (count)
|
|
|
|
{
|
|
|
|
/* sender */
|
2008-08-09 17:20:56 +02:00
|
|
|
ownerUser = [SOGoUser userWithLogin: owner roles: nil];
|
2008-11-05 22:04:16 +01:00
|
|
|
//currentUser = [context activeUser];
|
|
|
|
//shortSenderEmail = [[currentUser allEmails] objectAtIndex: 0];
|
|
|
|
// senderEmail = [NSString stringWithFormat: @"%@ <%@>",
|
|
|
|
// [ownerUser cn], shortSenderEmail];
|
|
|
|
shortSenderEmail = [[object organizer] rfc822Email];
|
|
|
|
senderEmail = [[object organizer] mailAddress];
|
2008-08-09 17:20:56 +02:00
|
|
|
// NSLog (@"sending '%@' from %@",
|
2008-10-01 21:32:14 +02:00
|
|
|
// [(iCalCalendar *) [object parent] method], senderEmail);
|
2007-11-18 11:16:25 +01:00
|
|
|
/* generate iCalString once */
|
2008-10-01 21:32:14 +02:00
|
|
|
iCalString = [[object parent] versitString];
|
2008-08-09 17:20:56 +02:00
|
|
|
|
2007-11-18 11:16:25 +01:00
|
|
|
/* get WOApplication instance */
|
|
|
|
app = [WOApplication application];
|
2007-01-31 21:15:28 +01:00
|
|
|
|
2007-11-18 11:16:25 +01:00
|
|
|
/* generate dynamic message content */
|
2007-01-31 21:15:28 +01:00
|
|
|
|
2007-11-18 11:16:25 +01:00
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
2008-10-01 21:32:14 +02:00
|
|
|
attendee = [attendees objectAtIndex: i];
|
2009-03-24 16:34:15 +01:00
|
|
|
// Don't send a notification to the event organizer nor a deletion
|
|
|
|
// notification to an attendee who already declined the invitation.
|
|
|
|
if (![[attendee uid] isEqualToString: owner] &&
|
|
|
|
!([[attendee partStat] compare: @"DECLINED"] == NSOrderedSame &&
|
|
|
|
[newPageName compare: @"Deletion"] == NSOrderedSame))
|
2007-11-18 11:16:25 +01:00
|
|
|
{
|
|
|
|
/* construct recipient */
|
|
|
|
recipient = [attendee mailAddress];
|
|
|
|
email = [attendee rfc822Email];
|
|
|
|
|
2008-08-09 17:20:56 +02:00
|
|
|
language = [ownerUser language];
|
2007-11-07 16:40:23 +01:00
|
|
|
#warning this could be optimized in a class hierarchy common with the \
|
2007-11-18 11:16:25 +01:00
|
|
|
SOGoObject acl notification mechanism
|
|
|
|
/* create page name */
|
|
|
|
pageName = [NSString stringWithFormat: @"SOGoAptMail%@%@",
|
2008-10-01 21:32:14 +02:00
|
|
|
language, newPageName];
|
2007-11-18 11:16:25 +01:00
|
|
|
/* construct message content */
|
|
|
|
p = [app pageWithName: pageName inContext: context];
|
2008-10-01 21:32:14 +02:00
|
|
|
[p setApt: object];
|
2008-11-18 01:06:37 +01:00
|
|
|
[p setPreviousApt: previousObject];
|
2008-10-24 18:12:21 +02:00
|
|
|
|
|
|
|
if ([[object organizer] cn] && [[[object organizer] cn] length])
|
|
|
|
{
|
|
|
|
[p setOrganizerName: [[object organizer] cn]];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
[p setOrganizerName: [ownerUser cn]];
|
|
|
|
}
|
|
|
|
|
2007-11-18 11:16:25 +01:00
|
|
|
subject = [p getSubject];
|
|
|
|
text = [p getBody];
|
2008-11-22 08:20:22 +01:00
|
|
|
NSLog(@"Template: %@", pageName);
|
2008-12-23 16:51:12 +01:00
|
|
|
NSLog(@"Sender => Recipient: %@ => %@", senderEmail, recipient);
|
|
|
|
NSLog(@"Subject: %@", subject);
|
2007-11-18 11:16:25 +01:00
|
|
|
|
|
|
|
/* construct message */
|
|
|
|
headerMap = [NGMutableHashMap hashMapWithCapacity: 5];
|
2007-02-15 21:59:02 +01:00
|
|
|
|
2007-11-18 11:16:25 +01:00
|
|
|
/* NOTE: multipart/alternative seems like the correct choice but
|
|
|
|
* unfortunately Thunderbird doesn't offer the rich content alternative
|
|
|
|
* at all. Mail.app shows the rich content alternative _only_
|
|
|
|
* so we'll stick with multipart/mixed for the time being.
|
|
|
|
*/
|
|
|
|
[headerMap setObject: @"multipart/mixed" forKey: @"content-type"];
|
2008-07-08 17:40:47 +02:00
|
|
|
[headerMap setObject: senderEmail forKey: @"from"];
|
2007-12-14 21:02:51 +01:00
|
|
|
[headerMap setObject: recipient forKey: @"to"];
|
2007-11-18 11:16:25 +01:00
|
|
|
mailDate = [[NSCalendarDate date] rfc822DateString];
|
|
|
|
[headerMap setObject: mailDate forKey: @"date"];
|
2007-12-14 21:02:51 +01:00
|
|
|
[headerMap setObject: subject forKey: @"subject"];
|
2007-11-18 11:16:25 +01:00
|
|
|
msg = [NGMimeMessage messageWithHeader: headerMap];
|
|
|
|
|
|
|
|
/* multipart body */
|
|
|
|
body = [[NGMimeMultipartBody alloc] initWithPart: msg];
|
|
|
|
|
|
|
|
/* text part */
|
|
|
|
headerMap = [NGMutableHashMap hashMapWithCapacity: 1];
|
|
|
|
[headerMap setObject: @"text/plain; charset=utf-8"
|
|
|
|
forKey: @"content-type"];
|
|
|
|
bodyPart = [NGMimeBodyPart bodyPartWithHeader: headerMap];
|
|
|
|
[bodyPart setBody: [text dataUsingEncoding: NSUTF8StringEncoding]];
|
|
|
|
|
|
|
|
/* attach text part to multipart body */
|
|
|
|
[body addBodyPart: bodyPart];
|
2007-01-31 21:15:28 +01:00
|
|
|
|
2007-11-18 11:16:25 +01:00
|
|
|
/* calendar part */
|
|
|
|
header = [NSString stringWithFormat: @"text/calendar; method=%@;"
|
|
|
|
@" charset=utf-8",
|
2008-10-01 21:32:14 +02:00
|
|
|
[(iCalCalendar *) [object parent] method]];
|
2007-11-18 11:16:25 +01:00
|
|
|
headerMap = [NGMutableHashMap hashMapWithCapacity: 1];
|
|
|
|
[headerMap setObject:header forKey: @"content-type"];
|
|
|
|
bodyPart = [NGMimeBodyPart bodyPartWithHeader: headerMap];
|
|
|
|
[bodyPart setBody: [iCalString dataUsingEncoding: NSUTF8StringEncoding]];
|
|
|
|
|
|
|
|
/* attach calendar part to multipart body */
|
|
|
|
[body addBodyPart: bodyPart];
|
2007-01-31 21:15:28 +01:00
|
|
|
|
2007-11-18 11:16:25 +01:00
|
|
|
/* attach multipart body to message */
|
|
|
|
[msg setBody: body];
|
|
|
|
[body release];
|
|
|
|
|
|
|
|
/* send the damn thing */
|
|
|
|
[[SOGoMailer sharedMailer]
|
|
|
|
sendMimePart: msg
|
|
|
|
toRecipients: [NSArray arrayWithObject: email]
|
2008-07-08 17:40:47 +02:00
|
|
|
sender: shortSenderEmail];
|
2007-11-18 11:16:25 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-01-31 21:15:28 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-07-10 17:26:41 +02:00
|
|
|
#warning fix this when sendEmailUsing blabla has been cleaned up
|
|
|
|
- (void) sendIMIPReplyForEvent: (iCalRepeatableEntityObject *) event
|
2008-11-10 16:38:05 +01:00
|
|
|
from: (SOGoUser *) from
|
2008-07-10 17:26:41 +02:00
|
|
|
to: (iCalPerson *) recipient
|
2007-11-13 23:38:05 +01:00
|
|
|
{
|
2007-11-18 11:16:25 +01:00
|
|
|
NSString *pageName, *language, *mailDate, *email;
|
|
|
|
WOApplication *app;
|
2008-07-10 17:26:41 +02:00
|
|
|
iCalPerson *attendee;
|
2007-11-18 11:16:25 +01:00
|
|
|
NSString *iCalString;
|
|
|
|
SOGoAptMailICalReply *p;
|
|
|
|
NGMutableHashMap *headerMap;
|
|
|
|
NGMimeMessage *msg;
|
|
|
|
NGMimeBodyPart *bodyPart;
|
|
|
|
NGMimeMultipartBody *body;
|
|
|
|
NSData *bodyData;
|
2008-07-10 17:26:41 +02:00
|
|
|
SOGoUser *ownerUser;
|
2007-11-18 11:16:25 +01:00
|
|
|
|
2007-11-29 20:37:37 +01:00
|
|
|
if (sendEMailNotifications)
|
2007-11-18 11:16:25 +01:00
|
|
|
{
|
2008-07-10 17:26:41 +02:00
|
|
|
/* get WOApplication instance */
|
|
|
|
app = [WOApplication application];
|
|
|
|
|
2008-11-10 16:38:05 +01:00
|
|
|
//ownerUser = [SOGoUser userWithLogin: owner roles: nil];
|
|
|
|
ownerUser = from;
|
2008-07-10 17:26:41 +02:00
|
|
|
language = [ownerUser language];
|
|
|
|
/* create page name */
|
|
|
|
pageName
|
|
|
|
= [NSString stringWithFormat: @"SOGoAptMail%@ICalReply", language];
|
|
|
|
/* construct message content */
|
|
|
|
p = [app pageWithName: pageName inContext: context];
|
|
|
|
[p setApt: event];
|
2008-07-10 18:18:43 +02:00
|
|
|
|
|
|
|
attendee = [event findParticipant: ownerUser];
|
|
|
|
[p setAttendee: attendee];
|
2008-07-10 17:26:41 +02:00
|
|
|
|
|
|
|
/* construct message */
|
|
|
|
headerMap = [NGMutableHashMap hashMapWithCapacity: 5];
|
|
|
|
|
|
|
|
/* NOTE: multipart/alternative seems like the correct choice but
|
|
|
|
* unfortunately Thunderbird doesn't offer the rich content alternative
|
|
|
|
* at all. Mail.app shows the rich content alternative _only_
|
|
|
|
* so we'll stick with multipart/mixed for the time being.
|
|
|
|
*/
|
|
|
|
[headerMap setObject: @"multipart/mixed" forKey: @"content-type"];
|
|
|
|
[headerMap setObject: [attendee mailAddress] forKey: @"from"];
|
|
|
|
[headerMap setObject: [recipient mailAddress] forKey: @"to"];
|
|
|
|
mailDate = [[NSCalendarDate date] rfc822DateString];
|
|
|
|
[headerMap setObject: mailDate forKey: @"date"];
|
|
|
|
[headerMap setObject: [p getSubject] forKey: @"subject"];
|
|
|
|
msg = [NGMimeMessage messageWithHeader: headerMap];
|
|
|
|
|
|
|
|
NSLog (@"sending 'REPLY' from %@ to %@",
|
|
|
|
[attendee mailAddress], [recipient mailAddress]);
|
|
|
|
|
|
|
|
/* multipart body */
|
|
|
|
body = [[NGMimeMultipartBody alloc] initWithPart: msg];
|
|
|
|
|
|
|
|
/* text part */
|
|
|
|
headerMap = [NGMutableHashMap hashMapWithCapacity: 1];
|
|
|
|
[headerMap setObject: @"text/plain; charset=utf-8"
|
|
|
|
forKey: @"content-type"];
|
|
|
|
bodyPart = [NGMimeBodyPart bodyPartWithHeader: headerMap];
|
|
|
|
bodyData = [[p getBody] dataUsingEncoding: NSUTF8StringEncoding];
|
|
|
|
[bodyPart setBody: bodyData];
|
|
|
|
|
|
|
|
/* attach text part to multipart body */
|
|
|
|
[body addBodyPart: bodyPart];
|
|
|
|
|
|
|
|
/* calendar part */
|
|
|
|
headerMap = [NGMutableHashMap hashMapWithCapacity: 1];
|
|
|
|
[headerMap setObject: @"text/calendar; method=REPLY; charset=utf-8"
|
|
|
|
forKey: @"content-type"];
|
|
|
|
bodyPart = [NGMimeBodyPart bodyPartWithHeader: headerMap];
|
|
|
|
iCalString = [[event parent] versitString];
|
|
|
|
[bodyPart setBody: [iCalString dataUsingEncoding: NSUTF8StringEncoding]];
|
|
|
|
|
|
|
|
/* attach calendar part to multipart body */
|
|
|
|
[body addBodyPart: bodyPart];
|
|
|
|
|
|
|
|
/* attach multipart body to message */
|
|
|
|
[msg setBody: body];
|
|
|
|
[body release];
|
|
|
|
|
|
|
|
/* send the damn thing */
|
|
|
|
email = [recipient rfc822Email];
|
|
|
|
[[SOGoMailer sharedMailer]
|
|
|
|
sendMimePart: msg
|
|
|
|
toRecipients: [NSArray arrayWithObject: email]
|
|
|
|
sender: [attendee rfc822Email]];
|
|
|
|
}
|
|
|
|
}
|
2008-07-10 17:11:01 +02:00
|
|
|
|
2008-08-14 00:40:05 +02:00
|
|
|
- (void) sendResponseToOrganizer: (iCalRepeatableEntityObject *) newComponent
|
2008-11-10 16:38:05 +01:00
|
|
|
from: (SOGoUser *) from
|
2008-07-10 17:26:41 +02:00
|
|
|
{
|
|
|
|
iCalPerson *organizer, *attendee;
|
|
|
|
iCalEvent *event;
|
|
|
|
SOGoUser *ownerUser;
|
2008-07-10 17:11:01 +02:00
|
|
|
|
2008-08-14 00:40:05 +02:00
|
|
|
event = [newComponent itipEntryWithMethod: @"reply"];
|
2008-07-10 17:26:41 +02:00
|
|
|
ownerUser = [SOGoUser userWithLogin: owner roles: nil];
|
|
|
|
if (![event userIsOrganizer: ownerUser])
|
|
|
|
{
|
|
|
|
organizer = [event organizer];
|
|
|
|
attendee = [event findParticipant: ownerUser];
|
|
|
|
[event setAttendees: [NSArray arrayWithObject: attendee]];
|
2008-11-10 16:38:05 +01:00
|
|
|
[self sendIMIPReplyForEvent: event from: from to: organizer];
|
2007-11-18 11:16:25 +01:00
|
|
|
}
|
2007-11-13 23:38:05 +01:00
|
|
|
}
|
|
|
|
|
2007-06-01 22:42:39 +02:00
|
|
|
// - (BOOL) isOrganizerOrOwner: (SOGoUser *) user
|
|
|
|
// {
|
|
|
|
// BOOL isOrganizerOrOwner;
|
|
|
|
// iCalRepeatableEntityObject *component;
|
|
|
|
// NSString *organizerEmail;
|
|
|
|
|
|
|
|
// component = [self component: NO];
|
|
|
|
// organizerEmail = [[component organizer] rfc822Email];
|
|
|
|
// if (component && [organizerEmail length] > 0)
|
|
|
|
// isOrganizerOrOwner = [user hasEmail: organizerEmail];
|
|
|
|
// else
|
|
|
|
// isOrganizerOrOwner
|
|
|
|
// = [[container ownerInContext: context] isEqualToString: [user login]];
|
|
|
|
|
|
|
|
// return isOrganizerOrOwner;
|
|
|
|
// }
|
|
|
|
|
|
|
|
- (iCalPerson *) findParticipantWithUID: (NSString *) uid
|
2007-03-18 16:08:41 +01:00
|
|
|
{
|
2007-11-13 23:38:05 +01:00
|
|
|
iCalEntityObject *component;
|
2007-06-01 22:42:39 +02:00
|
|
|
SOGoUser *user;
|
2007-03-18 16:08:41 +01:00
|
|
|
|
2007-06-01 22:42:39 +02:00
|
|
|
user = [SOGoUser userWithLogin: uid roles: nil];
|
2007-11-18 11:16:25 +01:00
|
|
|
component = [self component: NO secure: NO];
|
2007-03-18 16:08:41 +01:00
|
|
|
|
2007-11-13 23:38:05 +01:00
|
|
|
return [component findParticipant: user];
|
2007-03-18 16:08:41 +01:00
|
|
|
}
|
|
|
|
|
2007-05-09 21:11:32 +02:00
|
|
|
- (iCalPerson *) iCalPersonWithUID: (NSString *) uid
|
|
|
|
{
|
|
|
|
iCalPerson *person;
|
|
|
|
LDAPUserManager *um;
|
|
|
|
NSDictionary *contactInfos;
|
|
|
|
|
|
|
|
um = [LDAPUserManager sharedUserManager];
|
|
|
|
contactInfos = [um contactInfosForUserWithUIDorEmail: uid];
|
|
|
|
|
|
|
|
person = [iCalPerson new];
|
|
|
|
[person autorelease];
|
|
|
|
[person setCn: [contactInfos objectForKey: @"cn"]];
|
|
|
|
[person setEmail: [contactInfos objectForKey: @"c_email"]];
|
|
|
|
|
|
|
|
return person;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSArray *) getUIDsForICalPersons: (NSArray *) iCalPersons
|
|
|
|
{
|
|
|
|
iCalPerson *currentPerson;
|
|
|
|
NSEnumerator *persons;
|
|
|
|
NSMutableArray *uids;
|
2007-05-28 18:02:19 +02:00
|
|
|
NSString *uid;
|
2007-05-09 21:11:32 +02:00
|
|
|
|
|
|
|
uids = [NSMutableArray array];
|
|
|
|
|
|
|
|
persons = [iCalPersons objectEnumerator];
|
2008-08-10 23:44:25 +02:00
|
|
|
while ((currentPerson = [persons nextObject]))
|
2007-05-09 21:11:32 +02:00
|
|
|
{
|
2007-11-18 11:16:25 +01:00
|
|
|
uid = [currentPerson uid];
|
2007-05-23 07:29:54 +02:00
|
|
|
if (uid)
|
|
|
|
[uids addObject: uid];
|
2007-05-09 21:11:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return uids;
|
|
|
|
}
|
|
|
|
|
2008-08-10 23:44:25 +02:00
|
|
|
- (NSException *) copyToFolder: (SOGoGCSFolder *) newFolder
|
|
|
|
{
|
|
|
|
NSArray *elements;
|
|
|
|
NSString *newUID;
|
|
|
|
unsigned int count, max;
|
|
|
|
iCalCalendar *calendar;
|
|
|
|
SOGoCalendarComponent *newComponent;
|
|
|
|
|
|
|
|
newUID = [self globallyUniqueObjectId];
|
|
|
|
calendar = [self calendar: NO secure: NO];
|
|
|
|
|
|
|
|
elements = [calendar allObjects];
|
|
|
|
max = [elements count];
|
|
|
|
for (count = 0; count < max; count++)
|
|
|
|
[[elements objectAtIndex: count] setUid: newUID];
|
|
|
|
|
|
|
|
newComponent = [[self class] objectWithName:
|
|
|
|
[NSString stringWithFormat: @"%@.ics", newUID]
|
|
|
|
inContainer: newFolder];
|
|
|
|
|
|
|
|
return [newComponent saveContentString: [calendar versitString]];
|
|
|
|
}
|
|
|
|
|
2007-06-01 22:42:39 +02:00
|
|
|
- (NSString *) _roleOfOwner: (iCalRepeatableEntityObject *) component
|
|
|
|
{
|
|
|
|
NSString *role;
|
|
|
|
iCalPerson *organizer;
|
|
|
|
SOGoUser *ownerUser;
|
|
|
|
|
|
|
|
if (component)
|
|
|
|
{
|
|
|
|
organizer = [component organizer];
|
|
|
|
if ([[organizer rfc822Email] length] > 0)
|
|
|
|
{
|
|
|
|
ownerUser = [SOGoUser userWithLogin: owner roles: nil];
|
|
|
|
if ([component userIsOrganizer: ownerUser])
|
|
|
|
role = SOGoCalendarRole_Organizer;
|
|
|
|
else if ([component userIsParticipant: ownerUser])
|
|
|
|
role = SOGoCalendarRole_Participant;
|
|
|
|
else
|
|
|
|
role = SOGoRole_None;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
role = SOGoCalendarRole_Organizer;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
role = SOGoCalendarRole_Organizer;
|
2007-09-04 17:03:10 +02:00
|
|
|
|
2007-06-01 22:42:39 +02:00
|
|
|
return role;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) _compiledRoleForOwner: (NSString *) ownerRole
|
|
|
|
andUser: (NSString *) userRole
|
|
|
|
{
|
|
|
|
NSString *role;
|
|
|
|
|
|
|
|
if ([userRole isEqualToString: SOGoCalendarRole_ComponentModifier]
|
|
|
|
|| ([userRole isEqualToString: SOGoCalendarRole_ComponentResponder]
|
|
|
|
&& [ownerRole isEqualToString: SOGoCalendarRole_Participant]))
|
|
|
|
role = ownerRole;
|
|
|
|
else
|
|
|
|
role = SOGoRole_None;
|
|
|
|
|
|
|
|
return role;
|
|
|
|
}
|
|
|
|
|
2007-04-26 03:16:19 +02:00
|
|
|
- (NSArray *) aclsForUser: (NSString *) uid
|
|
|
|
{
|
|
|
|
NSMutableArray *roles;
|
|
|
|
NSArray *superAcls;
|
|
|
|
iCalRepeatableEntityObject *component;
|
2007-06-01 22:42:39 +02:00
|
|
|
NSString *accessRole, *ownerRole;
|
2007-12-06 23:54:01 +01:00
|
|
|
SOGoUser *aclUser;
|
2007-04-26 03:16:19 +02:00
|
|
|
|
|
|
|
roles = [NSMutableArray array];
|
2007-06-01 22:42:39 +02:00
|
|
|
superAcls = [super aclsForUser: uid];
|
|
|
|
if ([superAcls count] > 0)
|
|
|
|
[roles addObjectsFromArray: superAcls];
|
|
|
|
|
2007-11-18 11:16:25 +01:00
|
|
|
component = [self component: NO secure: NO];
|
2007-06-01 22:42:39 +02:00
|
|
|
ownerRole = [self _roleOfOwner: component];
|
|
|
|
if ([owner isEqualToString: uid])
|
|
|
|
[roles addObject: ownerRole];
|
|
|
|
else
|
2007-04-26 03:16:19 +02:00
|
|
|
{
|
2007-06-01 22:42:39 +02:00
|
|
|
if (component)
|
|
|
|
{
|
2007-12-06 23:54:01 +01:00
|
|
|
aclUser = [SOGoUser userWithLogin: uid roles: nil];
|
|
|
|
if ([component userIsOrganizer: aclUser])
|
|
|
|
[roles addObject: SOGoCalendarRole_Organizer];
|
|
|
|
else if ([component userIsParticipant: aclUser])
|
|
|
|
[roles addObject: SOGoCalendarRole_Participant];
|
2007-06-01 22:42:39 +02:00
|
|
|
accessRole = [container roleForComponentsWithAccessClass:
|
|
|
|
[component symbolicAccessClass]
|
|
|
|
forUser: uid];
|
|
|
|
if ([accessRole length] > 0)
|
|
|
|
{
|
|
|
|
[roles addObject: accessRole];
|
|
|
|
[roles addObject: [self _compiledRoleForOwner: ownerRole
|
|
|
|
andUser: accessRole]];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ([roles containsObject: SOGoRole_ObjectCreator])
|
2007-04-26 03:16:19 +02:00
|
|
|
[roles addObject: SOGoCalendarRole_Organizer];
|
|
|
|
}
|
|
|
|
|
|
|
|
return roles;
|
|
|
|
}
|
|
|
|
|
2008-07-17 23:12:43 +02:00
|
|
|
/* SOGoComponentOccurence protocol */
|
|
|
|
|
|
|
|
- (iCalRepeatableEntityObject *) occurence
|
|
|
|
{
|
|
|
|
return [self component: YES secure: NO];
|
|
|
|
}
|
|
|
|
|
2006-12-14 22:15:05 +01:00
|
|
|
@end
|