*/
#import <Foundation/NSString.h>
-
+#import <Foundation/NSUserDefaults.h>
+
+#import <NGObjWeb/NSException+HTTP.h>
+#import <NGObjWeb/SoSecurityManager.h>
+#import <NGObjWeb/WOApplication.h>
+#import <NGObjWeb/WOContext+SoObjects.h>
+#import <NGExtensions/NSObject+Logs.h>
+#import <NGExtensions/NGHashMap.h>
#import <NGCards/iCalCalendar.h>
#import <NGCards/iCalPerson.h>
#import <NGCards/iCalRepeatableEntityObject.h>
-#import <NGMime/NGMime.h>
-#import <NGMail/NGMail.h>
-#import <NGMail/NGSendMail.h>
-
-#import <SOGo/AgenorUserManager.h>
-#import <SOGo/SOGoPermissions.h>
-#import <SOGo/SOGoUser.h>
+#import <NGMime/NGMimeBodyPart.h>
+#import <NGMime/NGMimeMultipartBody.h>
+#import <NGMail/NGMimeMessage.h>
-#import "common.h"
+#import <SoObjects/SOGo/LDAPUserManager.h>
+#import <SoObjects/SOGo/NSCalendarDate+SOGo.h>
+#import <SoObjects/SOGo/SOGoMailer.h>
+#import <SoObjects/SOGo/SOGoPermissions.h>
+#import <SoObjects/SOGo/SOGoUser.h>
+#import <SoObjects/Appointments/SOGoAppointmentFolder.h>
#import "SOGoAptMailNotification.h"
+#import "iCalEntityObject+SOGo.h"
#import "SOGoCalendarComponent.h"
static NSString *mailTemplateDefaultLanguage = nil;
mailTemplateDefaultLanguage = [[ud stringForKey:@"SOGoDefaultLanguage"]
retain];
if (!mailTemplateDefaultLanguage)
- mailTemplateDefaultLanguage = @"French";
+ mailTemplateDefaultLanguage = @"English";
sendEMailNotifications
= [ud boolForKey: @"SOGoAppointmentSendEMailNotifications"];
return nil;
}
-- (void) _filterPrivateComponent: (iCalEntityObject *) component
+- (void) _filterComponent: (iCalEntityObject *) component
{
[component setSummary: @""];
[component setComment: @""];
- (NSString *) contentAsString
{
- NSString *tmpContent, *email;
iCalCalendar *tmpCalendar;
iCalRepeatableEntityObject *tmpComponent;
- WOContext *context;
+// NSArray *roles;
+// NSString *uid;
+ SoSecurityManager *sm;
if (!calContent)
{
- tmpContent = [super contentAsString];
- calContent = tmpContent;
- if ([tmpContent length] > 0)
- {
- tmpCalendar = [iCalCalendar parseSingleFromSource: tmpContent];
- tmpComponent = (iCalRepeatableEntityObject *) [tmpCalendar firstChildWithTag: [self componentTag]];
- if (![tmpComponent isPublic])
- {
- context = [[WOApplication application] context];
- email = [[context activeUser] email];
- if (!([tmpComponent isOrganizer: email]
- || [tmpComponent isParticipant: email]))
- {
- // content = tmpContent;
- [self _filterPrivateComponent: tmpComponent];
- calContent = [tmpCalendar versitString];
- }
- }
- }
+// 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;
+
+ sm = [SoSecurityManager sharedSecurityManager];
+ if (![sm validatePermission: SOGoCalendarPerm_ViewAllComponent
+ onObject: self inContext: context])
+ calContent = content;
+ else if (![sm validatePermission: SOGoCalendarPerm_ViewDAndT
+ onObject: self inContext: context])
+ {
+ tmpCalendar = [[self calendar: NO] copy];
+ tmpComponent = (iCalRepeatableEntityObject *)
+ [tmpCalendar firstChildWithTag: [self componentTag]];
+ [self _filterComponent: tmpComponent];
+ calContent = [tmpCalendar versitString];
+ [tmpCalendar release];
+ }
+ else
+ calContent = nil;
[calContent retain];
}
return result;
}
-- (iCalCalendar *) calendar
+- (iCalCalendar *) calendar: (BOOL) create
{
- NSString *iCalString;
+ NSString *iCalString, *componentTag;
+ CardGroup *newComponent;
if (!calendar)
{
- iCalString = [self contentAsString];
- if (iCalString)
+ iCalString = [super contentAsString];
+ if ([iCalString length] > 0)
+ calendar = [iCalCalendar parseSingleFromSource: iCalString];
+ else
{
- calendar = [iCalCalendar parseSingleFromSource: iCalString];
- [calendar retain];
+ if (create)
+ {
+ calendar = [iCalCalendar groupWithTag: @"vcalendar"];
+ [calendar setVersion: @"2.0"];
+ [calendar setProdID: @"-//Inverse groupe conseil//SOGo 0.9//EN"];
+ componentTag = [[self componentTag] uppercaseString];
+ newComponent = [[calendar classForTag: componentTag]
+ groupWithTag: componentTag];
+ [calendar addChild: newComponent];
+ }
}
+ if (calendar)
+ [calendar retain];
}
return calendar;
}
-- (iCalRepeatableEntityObject *) component
+- (iCalRepeatableEntityObject *) component: (BOOL) create
{
- return (iCalRepeatableEntityObject *)
- [[self calendar]
- firstChildWithTag: [self componentTag]];
+ return
+ (iCalRepeatableEntityObject *) [[self calendar: create]
+ firstChildWithTag: [self componentTag]];
}
/* raw saving */
{
NSString *baseURL;
NSString *uid;
- WOContext *ctx;
NSArray *traversalObjects;
/* generate URL from traversal stack */
- ctx = [[WOApplication application] context];
- traversalObjects = [ctx objectTraversalStack];
+ traversalObjects = [context objectTraversalStack];
if ([traversalObjects count] > 0)
- baseURL = [[traversalObjects objectAtIndex:0] baseURLInContext:ctx];
+ baseURL = [[traversalObjects objectAtIndex:0] baseURLInContext: context];
else
{
baseURL = @"http://localhost/";
[self warnWithFormat:@"Unable to create baseURL from context!"];
}
- uid = [[AgenorUserManager sharedUserManager]
+ uid = [[LDAPUserManager sharedUserManager]
getUIDForEmail: [_person rfc822Email]];
return ((uid)
: nil);
}
+- (NSException *) changeParticipationStatus: (NSString *) _status
+{
+ iCalRepeatableEntityObject *component;
+ iCalPerson *person;
+ NSString *newContent;
+ NSException *ex;
+ NSString *myEMail;
+
+ ex = nil;
+
+ component = [self component: NO];
+ if (component)
+ {
+ myEMail = [[context activeUser] primaryEmail];
+ person = [self findParticipantWithUID: owner];
+ if (person)
+ {
+ // TODO: send iMIP reply mails?
+ [person setPartStat: _status];
+ newContent = [[component parent] versitString];
+ if (newContent)
+ {
+ ex = [self saveContentString: newContent];
+ if (ex)
+ // TODO: why is the exception wrapped?
+ /* Server Error */
+ ex = [NSException exceptionWithHTTPStatus: 500
+ reason: [ex reason]];
+ }
+ else
+ ex
+ = [NSException exceptionWithHTTPStatus: 500 /* Server Error */
+ reason: @"Could not generate iCalendar data ..."];
+ }
+ else
+ ex = [NSException exceptionWithHTTPStatus: 404 /* Not Found */
+ reason: @"user does not participate in this "
+ @"calendar component"];
+ }
+ else
+ ex = [NSException exceptionWithHTTPStatus: 500 /* Server Error */
+ reason: @"unable to parse component record"];
+
+ return ex;
+}
+
- (BOOL) sendEMailNotifications
{
return sendEMailNotifications;
}
+- (NSTimeZone *) timeZoneForUser: (NSString *) email
+{
+ NSString *uid;
+
+ uid = [[LDAPUserManager sharedUserManager] getUIDForEmail: email];
+
+ return [[SOGoUser userWithLogin: uid roles: nil] timeZone];
+}
+
- (void) sendEMailUsingTemplateNamed: (NSString *) _pageName
forOldObject: (iCalRepeatableEntityObject *) _oldObject
andNewObject: (iCalRepeatableEntityObject *) _newObject
{
NSString *pageName;
iCalPerson *organizer;
- NSString *cn, *sender, *iCalString;
- NGSendMail *sendmail;
+ NSString *cn, *email, *sender, *iCalString;
WOApplication *app;
unsigned i, count;
iCalPerson *attendee;
NSString *recipient;
SOGoAptMailNotification *p;
- NSString *subject, *text, *header;
+ NSString *mailDate, *subject, *text, *header;
NGMutableHashMap *headerMap;
NGMimeMessage *msg;
NGMimeBodyPart *bodyPart;
/* generate iCalString once */
iCalString = [[_newObject parent] versitString];
- /* get sendmail object */
- sendmail = [NGSendMail sharedSendMail];
-
/* get WOApplication instance */
app = [WOApplication application];
/* construct recipient */
cn = [attendee cn];
+ email = [attendee rfc822Email];
if (cn)
recipient = [NSString stringWithFormat: @"%@ <%@>",
- cn,
- [attendee rfc822Email]];
+ cn, email];
else
- recipient = [attendee rfc822Email];
+ recipient = email;
+#warning this could be optimized in a class hierarchy common with the \
+ SOGoObject's acl notification mechanism
/* create page name */
// TODO: select user's default language?
pageName = [NSString stringWithFormat: @"SOGoAptMail%@%@",
mailTemplateDefaultLanguage,
_pageName];
/* construct message content */
- p = [app pageWithName: pageName inContext: [WOContext context]];
+ p = [app pageWithName: pageName inContext: context];
[p setNewApt: _newObject];
[p setOldApt: _oldObject];
[p setHomePageURL: [self homePageURLForPerson: attendee]];
- [p setViewTZ: [self userTimeZone: cn]];
+ [p setViewTZ: [self timeZoneForUser: email]];
subject = [p getSubject];
text = [p getBody];
[headerMap setObject: @"multipart/mixed" forKey: @"content-type"];
[headerMap setObject: sender forKey: @"From"];
[headerMap setObject: recipient forKey: @"To"];
- [headerMap setObject: [NSCalendarDate date] forKey: @"date"];
+ mailDate = [[NSCalendarDate date] rfc822DateString];
+ [headerMap setObject: mailDate forKey: @"date"];
[headerMap setObject: subject forKey: @"Subject"];
msg = [NGMimeMessage messageWithHeader: headerMap];
[body release];
/* send the damn thing */
- [sendmail sendMimePart: msg
- toRecipients: [NSArray arrayWithObject: [attendee rfc822Email]]
- sender: [organizer rfc822Email]];
+ [[SOGoMailer sharedMailer]
+ sendMimePart: msg
+ toRecipients: [NSArray arrayWithObject: email]
+ sender: [organizer rfc822Email]];
}
}
}
-- (NSArray *) rolesOfUser: (NSString *) login
- inContext: (WOContext *) context
+// - (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
{
- AgenorUserManager *um;
- iCalRepeatableEntityObject *component;
- NSMutableArray *sogoRoles;
- NSString *email;
SOGoUser *user;
- sogoRoles = [NSMutableArray new];
- [sogoRoles autorelease];
+ user = [SOGoUser userWithLogin: uid roles: nil];
- um = [AgenorUserManager sharedUserManager];
- email = [um getEmailForUID: login];
+ return [self findParticipant: user];
+}
+
+- (iCalPerson *) findParticipant: (SOGoUser *) user
+{
+ iCalPerson *participant, *currentParticipant;
+ iCalEntityObject *component;
+ NSEnumerator *participants;
- component = [self component];
+ participant = nil;
+ component = [self component: NO];
if (component)
{
- if ([component isOrganizer: email])
- [sogoRoles addObject: SOGoRole_Organizer];
- else if ([component isParticipant: email])
- [sogoRoles addObject: SOGoRole_Participant];
- else if ([[container ownerInContext: nil] isEqualToString: login])
- [sogoRoles addObject: SoRole_Owner];
+ participants = [[component participants] objectEnumerator];
+ currentParticipant = [participants nextObject];
+ while (currentParticipant && !participant)
+ if ([user hasEmail: [currentParticipant rfc822Email]])
+ participant = currentParticipant;
+ else
+ currentParticipant = [participants nextObject];
}
+
+ return participant;
+}
+
+- (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;
+}
+
+- (NSString *) getUIDForICalPerson: (iCalPerson *) person
+{
+ LDAPUserManager *um;
+
+ um = [LDAPUserManager sharedUserManager];
+
+ return [um getUIDForEmail: [person rfc822Email]];
+}
+
+- (NSArray *) getUIDsForICalPersons: (NSArray *) iCalPersons
+{
+ iCalPerson *currentPerson;
+ NSEnumerator *persons;
+ NSMutableArray *uids;
+ NSString *uid;
+ LDAPUserManager *um;
+
+ uids = [NSMutableArray array];
+
+ um = [LDAPUserManager sharedUserManager];
+ persons = [iCalPersons objectEnumerator];
+ currentPerson = [persons nextObject];
+ while (currentPerson)
+ {
+ uid = [um getUIDForEmail: [currentPerson rfc822Email]];
+ if (uid)
+ [uids addObject: uid];
+ currentPerson = [persons nextObject];
+ }
+
+ return uids;
+}
+
+- (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;
+
+ 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;
+}
+
+- (NSArray *) aclsForUser: (NSString *) uid
+{
+ NSMutableArray *roles;
+ NSArray *superAcls;
+ iCalRepeatableEntityObject *component;
+ NSString *accessRole, *ownerRole;
+
+ roles = [NSMutableArray array];
+ superAcls = [super aclsForUser: uid];
+ if ([superAcls count] > 0)
+ [roles addObjectsFromArray: superAcls];
+
+ component = [self component: NO];
+ ownerRole = [self _roleOfOwner: component];
+ if ([owner isEqualToString: uid])
+ [roles addObject: ownerRole];
else
{
- user = [[SOGoUser alloc] initWithLogin: login roles: nil];
- [sogoRoles addObjectsFromArray: [user rolesForObject: container
- inContext: context]];
- [user release];
+ if (component)
+ {
+ 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])
+ [roles addObject: SOGoCalendarRole_Organizer];
}
- return sogoRoles;
+ return roles;
}
@end