+2007-04-27 Wolfgang Sourdeau <wsourdeau@inverse.ca>
+
+ * SoObjects/SOGo/SOGoPermissions.m: added "SOGoRole_ObjectViewer"
+ and "SOGoRole_ObjectEditor".
+
+ * UI/Common/UIxUserRightsEditor.m ([UIxUserRightsEditor
+ -prepareRightsForm]): this method is no longer mandatory.
+
+ * UI/Contacts/UIxContactsUserRightsEditor.m
+ ([UIxContactsUserRightsEditor
+ -setUserCanCreateObjects:userCanCreateObjects]): new subclass
+ module to handle acls related to the address books. Partial
+ implementation.
+
+ * SoObjects/SOGo/SOGoFolder.m ([SOGoFolder
+ -setRoles:rolesforUser:uidforObjectAtPath:objectPathArray]): cache
+ newly set roles.
+ ([SOGoFolder
+ -removeAclsForUsers:usersforObjectAtPath:objectPathArray]): remove
+ specified roles from cache.
+ ([SOGoFolder -aclsForUser:uidforObjectAtPath:objectPathArray]):
+ put resulting roles in cache.
+
+ * SoObjects/SOGo/SOGoObject.m ([SOGoObject -init]): do not invoke
+ initWithName:inContainer:. Instead, directly initialize the ivars
+ as it is supposed to be to avoid an infinite loop whenever one of
+ those two methods are overriden.
+
+ * SoObjects/SOGo/SOGoContentObject.m ([-rolesOfUser:login]):
+ removed method.
+
+ * SoObjects/Contacts/SOGoContactLDAPEntry.m ([SOGoContactLDAPEntry
+ -aclsForUser:uid]): override method so that SOGo won't crash when
+ loading the contact card.
+
+2007-04-26 Wolfgang Sourdeau <wsourdeau@inverse.ca>
+
+ * SoObjects/Appointments/SOGoAppointmentFolder.m
+ ([SOGoAppointmentFolder -_privacySqlString]): the string for the
+ "freebusy" special user should only require opaque elements.
+
+2007-04-25 Wolfgang Sourdeau <wsourdeau@inverse.ca>
+
+ * SoObjects/Appointments/SOGoAppointmentFolder.m
+ ([SOGoAppointmentFolder -davResourceType]): fixed a problem with
+ our double declaration where the resulting XML would be screwed.
+ There is only one collection per namespace.
+
+ * SoObjects/SOGo/NSCalendarDate+SOGo.m ([NSCalendarDate
+ rfc822DateString]): new method that returns a string conform to
+ rfc 822 and suitable for email headers.
+
+ * SoObjects/Mailer/SOGoDraftObject.m: invoke the new
+ "rfc822DateString" category method on the date we put in the
+ header.
+
+2007-04-24 Wolfgang Sourdeau <wsourdeau@inverse.ca>
+
+ * UI/Common/UIxUserRightsEditor.m ([UIxUserRightsEditor -defaultAction])
+ ([UIxUserRightsEditor -saveUserRightsAction]): new action methods
+ which should never be overriden.
+ ([UIxUserRightsEditor -appendRight:newRight])
+ ([UIxUserRightsEditor -removeRight:right])
+ ([UIxUserRightsEditor -appendExclusiveRight:newRightfromList:list])
+ ([UIxUserRightsEditor -removeAllRightsFromList:list]): new utility
+ methods that can be used by the subclasses.
+ ([UIxUserRightsEditor -prepareRightsForm]): new method that should
+ mandatorily be overriden to prepare the elements of the subclassed
+ form.
+ ([UIxUserRightsEditor -updateRights]): new method that should
+ mandatorily be overriden to update the user rights from the
+ elements of the subclassed form.
+
+ * UI/Common/UIxAclEditor.m ([UIxAclEditor -_prepareUsers]): we
+ check if the uid is already listed before adding it to our array.
+ This is because the acl table can contain more than one record per
+ user/object relationship.
+
+ * SoObjects/SOGo/SOGoFolder.m ([SOGoFolder
+ -setRoles:rolesforUser:uidforObjectAtPath:objectPathArray]): the
+ "roles" parameter is now an NSArray instead of a string. Therefore
+ we loop throughout the array to populate the table. All the
+ relevant records are removed prior to the addition of the new
+ rights.
+
+ * SoObjects/Mailer/SOGoMailBaseObject.m ([SOGoMailBaseObject
+ -aclsForUser:uid]): new override that returns nil until we add
+ support for IMAP acls.
+
+ * SoObjects/Mailer/SOGoMailAccounts.m
+ ([SOGoMailAccounts -aclsForUser:uid]): same as below.
+
+ * SoObjects/Contacts/SOGoContactLDAPFolder.m
+ ([SOGoContactLDAPFolder -aclsForUser:uid]): same as below.
+
+ * SoObjects/Contacts/SOGoContactFolders.m ([SOGoContactFolders
+ -aclsForUser:uid]): override this method which will always return
+ nil.
+
+ * SoObjects/SOGo/SOGoPermissions.[hm]: added
+ [Public,Private,Confidential]
+ x[Viewer,DAndTViewer,Responder,Modifier]. Renamed
+ SOGoRole_ORganizer to SOGoCalendarRole_Organizer. Same for
+ ..._Participant. Removed SOGoRole_Assistant and SOGoRole_Delegate.
+
+ * SoObjects/Appointments/SOGoAppointmentFolder.m
+ ([SOGoAppointmentFolder -defaultAclRoles]): new overriden method
+ that defines default roles for new elements in the acl.
+
+ * UI/Scheduler/UIxCalUserRightsEditor.[hm]: new component class
+ module and subclass of UIxUserRightsEditor specific to the
+ handling of user rights on calendar folders.
+
+2007-04-23 Wolfgang Sourdeau <wsourdeau@inverse.ca>
+
+ * SoObjects/Appointments/SOGoAppointmentFolder.m
+ ([SOGoAppointmentFolder -groupDavResourceType]): return both
+ "vevent-collection" and "vtodo-collection".
+
+ * UI/Common/UIxUserRightsEditor.[hm]: new template class module
+ that implements the detailed editor of user rights per-object.
+
+2007-04-17 Wolfgang Sourdeau <wsourdeau@inverse.ca>
+
+ * SoObjects/SOGo/SOGoUser.m ([SOGoUser
+ -rolesForObject:objectinContext:context]): no longer query objects
+ for "roleForUser:". Instead, all objects should implement
+ "rolesForUser:".
+
+ * SoObjects/SOGo/SOGoContentObject.m ([SOGoContentObject -acls]):
+ new method to comply with the new acl "protocol" in SOGoObject.
+ Uses SOGoFolder's new facilities for ACLS.
+ ([SOGoContentObject -aclsForUser:uid]): idem.
+ ([SOGoContentObject -setRoles:rolesforUser:uid]): idem.
+ ([SOGoContentObject -removeAclsForUsers:users]): idem.
+
+ * SoObjects/SOGo/SOGoFolder.m ([SOGoFolder
+ -aclsForObjectAtPath:objectPathArray]): new method generic to GCS
+ based folders. This method is derived from the code that was in
+ UIxAclFolder before its removal.
+ ([SOGoFolder -aclsForUser:uidforObjectAtPath:objectPathArray]):
+ idem.
+ ([SOGoFolder
+ -removeAclsForUsers:usersforObjectAtPath:objectPathArray]): idem.
+ ([SOGoFolder
+ -setRoles:rolesforUser:uidforObjectAtPath:objectPathArray]): idem.
+ ([SOGoFolder -setRoleForUsers:uidsto:role])
+ ([SOGoFolder -setRoleForUsers:uidsto:role]): removed method.
+
+ * SoObjects/SOGo/SOGoObject.m ([SOGoObject -acls]): stub method
+ that requires overriding by subclasses.
+ ([SOGoObject -aclsForUser:uid]): idem.
+ ([SOGoObject -defaultAclRoles]): idem.
+ ([SOGoObject -setRoles:rolesforUser:uid]): idem.
+ ([SOGoObject -removeAclsForUsers:users]): idem.
+
+ * UI/Common/UIxObjectActions.m: new module implementing the web
+ actions common to SOGoObject and all its subclasses.
+ ([UIxObjectActions -addUserInAclsAction]): new method that adds a
+ user with the clientObject defaults user rights to the object's
+ acl.
+
+ * UI/Common/UIxAclEditor.m: modified module so as to simplify it
+ to the point where it will only list the users (and their name)
+ associated with an object acl.
+
+ * SoObjects/SOGo/SOGoAclsFolder.m: removed module because its
+ methods have been moved into SOGoObject and SOGoFolder during a
+ refactoring.
+
+ * UI/Scheduler/UIxComponentEditor.m ([UIxComponentEditor
+ -iCalParticipantsAndResourcesStringFromQueryParameters]): removed
+ method made useless by the programmatic handling of iCalendar
+ objects.
+ ([UIxComponentEditor -iCalParticipantsStringFromQueryParameters]): idem.
+ ([UIxComponentEditor -iCalResourcesStringFromQueryParameters]): idem.
+ ([UIxComponentEditor -iCalStringFromQueryParameter:_qpformat:_format]): idem.
+
+ * UI/WebServerResources/MailerUI.js (initDnd): enable drag and
+ drop on all folder nodes, not just on leaves.
+
+ * SoObjects/Contacts/SOGoContactLDAPFolder.m
+ ([SOGoContactLDAPFolder
+ -lookupContactsWithFilter:filtersortBy:sortKeyordering:sortOrdering]): request field "uid" when doing a search.
+
+2007-04-16 Wolfgang Sourdeau <wsourdeau@inverse.ca>
+
+ * Main/SOGo.m ([SOGo +initialize]): on GNUstep, trigger some
+ debugging facilities when the SOGoDebugObjectAllocation user
+ default is set.
+
2007-04-11 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* SoObjects/SOGo/NSString+Utilities.m ([NSString -boolValue]): new
#include <NGObjWeb/SoApplication.h>
-// @interface classtree : NSObject
-// {
-// Class topClass;
-// int indentLevel;
-// }
-
-// - (id) initWithTopClass: (Class) newTopClass;
-// - (void) dumpSiblings: (Class) node;
-
-// @end
-
-// @implementation classtree
-
-// + (id) newWithTopClass: (Class) newTopClass
-// {
-// id newTree;
-
-// newTree = [[self alloc] initWithTopClass: newTopClass];
-// [newTree autorelease];
-
-// return newTree;
-// }
-
-// - (id) initWithTopClass: (Class) newTopClass
-// {
-// if ((self = [self init]))
-// topClass = newTopClass;
-
-// return self;
-// }
-
-// #define indentGap 2
-
-// - (NSString *) indentSpaces
-// {
-// char *spaceString;
-
-// spaceString = malloc(sizeof (char *) * indentGap * indentLevel + 1);
-// *(spaceString + indentGap * indentLevel) = 0;
-// memset (spaceString, ' ', indentGap * indentLevel);
-
-// return [[NSString alloc] initWithCStringNoCopy: spaceString
-// length: indentGap * indentLevel
-// freeWhenDone: YES];
-// }
-
-// - (void) dumpNode: (Class) node
-// {
-// Class currentSubclass;
-// unsigned int count;
-
-// count = 0;
-// currentSubclass = node->subclass_list;
-// if (currentSubclass)
-// {
-// NSLog(@"%@%@:",
-// [[self indentSpaces] autorelease], NSStringFromClass(node));
-// indentLevel++;
-// [self dumpSiblings: currentSubclass];
-// indentLevel--;
-// }
-// else
-// NSLog(@"%@%@", [self indentSpaces], NSStringFromClass(node));
-// }
-
-// - (void) dumpSiblings: (Class) node
-// {
-// Class currentNode;
-
-// currentNode = node;
-// while (currentNode && currentNode->instance_size)
-// {
-// [self dumpNode: currentNode];
-// currentNode = currentNode->sibling_class;
-// }
-// }
-
-// - (void) dumpTree
-// {
-// indentLevel = 0;
-
-// [self dumpSiblings: topClass];
-// }
-
-// @end
-
@interface SOGo : SoApplication
{
NSMutableDictionary *localeLUT;
static unsigned int vMemSizeLimit = 0;
static BOOL doCrashOnSessionCreate = NO;
-+ (void)initialize {
+#ifdef GNUSTEP_BASE_LIBRARY
+static BOOL debugObjectAllocation = NO;
+#endif
+
++ (void) initialize
+{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
SoClassSecurityInfo *sInfo;
NSArray *basicRoles;
id tmp;
doCrashOnSessionCreate = [ud boolForKey:@"SOGoCrashOnSessionCreate"];
+#ifdef GNUSTEP_BASE_LIBRARY
+ debugObjectAllocation = [ud boolForKey: @"SOGoDebugObjectAllocation"];
+ if (debugObjectAllocation)
+ {
+ NSLog (@"activating stats on object allocation");
+ GSDebugAllocationActive (YES);
+ }
+#endif
/* vMem size check - default is 200MB */
- tmp = [ud objectForKey:@"SxVMemLimit"];
- vMemSizeLimit = (tmp != nil)
- ? [tmp intValue]
- : 200;
- if (vMemSizeLimit > 0) {
+ tmp = [ud objectForKey: @"SxVMemLimit"];
+ vMemSizeLimit = ((tmp != nil) ? [tmp intValue] : 200);
+ if (vMemSizeLimit > 0)
NSLog(@"Note: vmem size check enabled: shutting down app when "
@"vmem > %d MB", vMemSizeLimit);
- }
#if LIB_FOUNDATION_LIBRARY
if ([ud boolForKey:@"SOGoEnableDoubleReleaseCheck"])
- [NSAutoreleasePool enableDoubleReleaseCheck:YES];
+ [NSAutoreleasePool enableDoubleReleaseCheck: YES];
#endif
/* SoClass security declarations */
[sInfo declareRoles: basicRoles asDefaultForPermission: SoPerm_WebDAVAccess];
}
-- (id)init {
- if ((self = [super init])) {
- WOResourceManager *rm;
-
- /* ensure core SoClass'es are setup */
- [$(@"SOGoObject") soClass];
- [$(@"SOGoContentObject") soClass];
- [$(@"SOGoFolder") soClass];
-
- /* setup locale cache */
- self->localeLUT = [[NSMutableDictionary alloc] initWithCapacity:2];
+- (id) init
+{
+ if ((self = [super init]))
+ {
+ WOResourceManager *rm;
+
+ /* ensure core SoClass'es are setup */
+ [$(@"SOGoObject") soClass];
+ [$(@"SOGoContentObject") soClass];
+ [$(@"SOGoFolder") soClass];
+
+ /* setup locale cache */
+ localeLUT = [[NSMutableDictionary alloc] initWithCapacity:2];
- /* load products */
- [[SOGoProductLoader productLoader] loadProducts];
+ /* load products */
+ [[SOGoProductLoader productLoader] loadProducts];
- /* setup resource manager */
- rm = [[WEResourceManager alloc] init];
- [self setResourceManager:rm];
- }
+ /* setup resource manager */
+ rm = [[WEResourceManager alloc] init];
+ [self setResourceManager:rm];
+ }
+
return self;
}
-- (void)dealloc {
- [self->localeLUT release];
+- (void) dealloc
+{
+ [localeLUT release];
[super dealloc];
}
/* authenticator */
-- (id)authenticatorInContext:(id)_ctx {
+- (id) authenticatorInContext: (id) _ctx
+{
return [$(@"SOGoAuthenticator") sharedSOGoAuthenticator];
}
/* name lookup */
-- (BOOL)isUserName:(NSString *)_key inContext:(id)_ctx {
+- (BOOL) isUserName: (NSString *) _key
+ inContext: (id) _ctx
+{
if ([_key length] < 1)
return NO;
initWithName:_key inContainer:self] autorelease];
}
-- (void)_setupLocaleInContext:(WOContext *)_ctx {
+- (void) _setupLocaleInContext: (WOContext *) _ctx
+{
NSArray *langs;
NSDictionary *locale;
if ([[_ctx valueForKey:@"locale"] isNotNull])
return;
- langs = [[(WOContext *)_ctx request] browserLanguages];
+ langs = [[_ctx request] browserLanguages];
locale = [self currentLocaleConsideringLanguages:langs];
[_ctx takeValue:locale forKey:@"locale"];
}
-- (id)lookupName:(NSString *)_key inContext:(id)_ctx acquire:(BOOL)_flag {
+- (id) lookupName: (NSString *) _key
+ inContext: (id) _ctx
+ acquire: (BOOL) _flag
+{
id obj;
+#ifdef GNUSTEP_BASE_LIBRARY
+ if (debugObjectAllocation)
+ NSLog(@"objects allocated\n%s", GSDebugAllocationList (YES));
+#endif
/* put locale info into the context in case it's not there */
[self _setupLocaleInContext:_ctx];
/* WebDAV */
-- (NSString *)davDisplayName {
+- (NSString *) davDisplayName
+{
/* this is used in the UI, eg in the navigation */
return @"SOGo";
}
/* exception handling */
-- (WOResponse *)handleException:(NSException *)_exc
- inContext:(WOContext *)_ctx
+- (WOResponse *) handleException: (NSException *) _exc
+ inContext: (WOContext *) _ctx
{
printf("EXCEPTION: %s\n", [[_exc description] cString]);
abort();
/* runtime maintenance */
-// - (void) _dumpClassAllocation
-// {
-// classtree *ct;
-
-// ct = [classtree newWithTopClass: [NSObject class]];
-// [ct dumpTree];
-// }
-
-- (void)checkIfDaemonHasToBeShutdown {
- unsigned int limit, vmem;
-
- if ((limit = vMemSizeLimit) == 0)
- return;
-
- vmem = [[NSProcessInfo processInfo] virtualMemorySize]/1048576;
-
- if (vmem > limit) {
- [self logWithFormat:
- @"terminating app, vMem size limit (%d MB) has been reached"
- @" (currently %d MB)",
- limit, vmem];
-// [self _dumpClassAllocation];
- [self terminate];
- }
+- (void) checkIfDaemonHasToBeShutdown
+{
+ unsigned int vmem;
+
+ if (vMemSizeLimit > 0)
+ {
+ vmem = [[NSProcessInfo processInfo] virtualMemorySize]/1048576;
+
+ if (vmem > vMemSizeLimit)
+ {
+ [self logWithFormat:
+ @"terminating app, vMem size limit (%d MB) has been reached"
+ @" (currently %d MB)",
+ vMemSizeLimit, vmem];
+// if (debugObjectAllocation)
+// [self _dumpClassAllocation];
+ [self terminate];
+ }
+ }
}
-- (WOResponse *)dispatchRequest:(WORequest *)_request {
+- (WOResponse *) dispatchRequest: (WORequest *) _request
+{
static NSArray *runLoopModes = nil;
WOResponse *resp;
- resp = [super dispatchRequest:_request];
+ resp = [super dispatchRequest: _request];
- if ([self isTerminating])
- return resp;
-
- if (runLoopModes == nil)
- runLoopModes = [[NSArray alloc] initWithObjects:NSDefaultRunLoopMode, nil];
+ if (![self isTerminating])
+ {
+ if (!runLoopModes)
+ runLoopModes = [[NSArray alloc] initWithObjects: NSDefaultRunLoopMode, nil];
- // TODO: a bit complicated? (-perform:afterDelay: doesn't work?)
- [[NSRunLoop currentRunLoop] performSelector:
- @selector(checkIfDaemonHasToBeShutdown)
- target:self argument:nil
- order:1 modes:runLoopModes];
+ // TODO: a bit complicated? (-perform:afterDelay: doesn't work?)
+ [[NSRunLoop currentRunLoop] performSelector:
+ @selector (checkIfDaemonHasToBeShutdown)
+ target: self argument: nil
+ order:1 modes:runLoopModes];
+ }
+
return resp;
}
/* session management */
-- (id)createSessionForRequest:(WORequest *)_request {
- [self warnWithFormat:@"session creation requested!"];
+- (id) createSessionForRequest: (WORequest *) _request
+{
+ [self warnWithFormat: @"session creation requested!"];
if (doCrashOnSessionCreate)
abort();
return [super createSessionForRequest:_request];
/* localization */
-- (NSDictionary *)currentLocaleConsideringLanguages:(NSArray *)_langs {
- unsigned i, count;
+- (NSDictionary *) currentLocaleConsideringLanguages: (NSArray *) langs
+{
+ NSEnumerator *enumerator;
+ NSString *lname;
+ NSDictionary *locale;
+
+ enumerator = [langs objectEnumerator];
+ lname = nil;
+ locale = nil;
+ lname = [enumerator nextObject];
+ while (lname && !locale)
+ {
+ locale = [self localeForLanguageNamed: lname];
+ lname = [enumerator nextObject];
+ }
+
+ if (!locale)
+ locale = [self localeForLanguageNamed: @"English"];
- /* assume _langs is ordered by priority */
- count = [_langs count];
- for (i = 0; i < count; i++) {
- NSString *lname;
- NSDictionary *locale;
-
- lname = [_langs objectAtIndex:i];
- locale = [self localeForLanguageNamed:lname];
- if (locale != nil)
- return locale;
- }
/* no appropriate language, fallback to default */
- return [self localeForLanguageNamed:@"English"];
+ return locale;
}
-- (NSString *)pathToLocaleForLanguageNamed:(NSString *)_name {
+- (NSString *) pathToLocaleForLanguageNamed: (NSString *) _name
+{
static Class MainProduct = Nil;
NSString *lpath;
- lpath = [[self resourceManager] pathForResourceNamed:@"Locale"
- inFramework:nil
- languages:[NSArray arrayWithObject:_name]];
- if ([lpath isNotNull])
- return lpath;
-
- if (MainProduct == Nil) {
- if ((MainProduct = $(@"MainUIProduct")) == Nil)
- [self errorWithFormat:@"did not find MainUIProduct class!"];
- }
-
- lpath = [(id)MainProduct pathToLocaleForLanguageNamed:_name];
- if ([lpath isNotNull])
- return lpath;
-
- return nil;
+ lpath = [[self resourceManager] pathForResourceNamed: @"Locale"
+ inFramework: nil
+ languages: [NSArray arrayWithObject:_name]];
+ if (![lpath length])
+ {
+ if (!MainProduct)
+ {
+ MainProduct = $(@"MainUIProduct");
+ if (!MainProduct)
+ [self errorWithFormat: @"did not find MainUIProduct class!"];
+ }
+
+ lpath = [(id) MainProduct pathToLocaleForLanguageNamed: _name];
+ if (![lpath length])
+ lpath = nil;
+ }
+
+ return lpath;
}
-- (NSDictionary *)localeForLanguageNamed:(NSString *)_name {
+- (NSDictionary *) localeForLanguageNamed: (NSString *) _name
+{
NSString *lpath;
id data;
NSDictionary *locale;
-
- if (![_name isNotNull]) {
+
+ locale = nil;
+ if ([_name length] > 0)
+ {
+ locale = [localeLUT objectForKey: _name];
+ if (!locale)
+ {
+ lpath = [self pathToLocaleForLanguageNamed:_name];
+ if (lpath)
+ {
+ data = [NSData dataWithContentsOfFile: lpath];
+ if (data)
+ {
+ data = [[[NSString alloc] initWithData: data
+ encoding: NSUTF8StringEncoding] autorelease];
+ locale = [data propertyList];
+ if (locale)
+ [localeLUT setObject: locale forKey: _name];
+ else
+ [self logWithFormat:@"%s couldn't load locale with name:%@",
+ __PRETTY_FUNCTION__,
+ _name];
+ }
+ else
+ [self logWithFormat:@"%s didn't find locale with name: %@",
+ __PRETTY_FUNCTION__,
+ _name];
+ }
+ else
+ [self errorWithFormat:@"did not find Locale for language: %@", _name];
+ }
+ }
+ else
[self errorWithFormat:@"%s: name parameter must not be nil!",
- __PRETTY_FUNCTION__];
- return nil;
- }
-
- if ((locale = [self->localeLUT objectForKey:_name]) != nil)
- return locale;
-
- if ((lpath = [self pathToLocaleForLanguageNamed:_name]) == nil) {
- [self errorWithFormat:@"did not find Locale for language: %@", _name];
- return nil;
- }
-
- if ((data = [NSData dataWithContentsOfFile:lpath]) == nil) {
- [self logWithFormat:@"%s didn't find locale with name:%@",
- __PRETTY_FUNCTION__,
- _name];
- return nil;
- }
- data = [[[NSString alloc] initWithData:data
- encoding:NSUTF8StringEncoding] autorelease];
- locale = [data propertyList];
- if (locale == nil) {
- [self logWithFormat:@"%s couldn't load locale with name:%@",
- __PRETTY_FUNCTION__,
- _name];
- return nil;
- }
- [self->localeLUT setObject:locale forKey:_name];
+ __PRETTY_FUNCTION__];
+
return locale;
}
/* name (used by the WEResourceManager) */
-- (NSString *)name {
+- (NSString *) name
+{
return @"SOGo-0.9";
}
#import <NGObjWeb/NGObjWeb.h>
#import "common.h"
-int main(int argc, char **argv, char **env)
+int
+main (int argc, char **argv, char **env)
{
NSString *tzName;
NSUserDefaults *ud;
pool = [NSAutoreleasePool new];
#if LIB_FOUNDATION_LIBRARY
- [NSProcessInfo initializeWithArguments:argv count:argc environment:env];
+ [NSProcessInfo initializeWithArguments: argv count: argc environment: env];
#endif
[NGBundleManager defaultBundleManager];
tzName = @"Canada/Eastern";
[NSTimeZone setDefaultTimeZone: [NSTimeZone timeZoneWithName: tzName]];
- WOWatchDogApplicationMain(@"SOGo", argc, (void*)argv);
+ WOWatchDogApplicationMain (@"SOGo", argc, (void *) argv);
[pool release];
return 0;
+2007-04-27 Wolfgang Sourdeau <wsourdeau@inverse.ca>
+
+ * NGVCard.m ([NGVCard -n]): simplified method by returning the
+ values of the element returned by uniqueChildWithTag:.
+
2007-03-07 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* iCalEntityObject.m ([iCalEntityObject -symbolicAccessClass]):
- (NSArray *) n
{
- NSArray *elements, *n;
-
- elements = [self childrenWithTag: @"n"];
- if ([elements count] > 0)
- n = [[elements objectAtIndex: 0] values];
- else
- n = nil;
-
- return n;
+ return [[self uniqueChildWithTag: @"n"] values];
}
- (void) setOrg: (NSString *) anOrg
@class NSTimeZone;
@class GCSFolder;
+#import <NGCards/iCalEntityObject.h>
@interface SOGoAppointmentFolder : SOGoFolder
{
NSTimeZone *timeZone;
- (NSArray *) calendarFolders;
+- (NSString *) roleForComponentsWithAccessClass: (iCalAccessClass) accessClass
+ forUser: (NSString *) uid;
+
@end
#endif /* __Appointments_SOGoAppointmentFolder_H__ */
return classes;
}
-- (NSString *) groupDavResourceType
+- (NSArray *) groupDavResourceType
{
- return @"vevent-collection";
+ return [NSArray arrayWithObjects: @"vevent-collection",
+ @"vtodo-collection", nil];
}
- (NSArray *) davResourceType
{
static NSArray *colType = nil;
- NSArray *gdCol, *cdCol;
+ NSArray *cdCol, *gdRT, *gdVEventCol, *gdVTodoCol;
if (!colType)
{
+ gdRT = [self groupDavResourceType];
+ gdVEventCol = [NSArray arrayWithObjects: [gdRT objectAtIndex: 0],
+ XMLNS_GROUPDAV, nil];
+ gdVTodoCol = [NSArray arrayWithObjects: [gdRT objectAtIndex: 1],
+ XMLNS_GROUPDAV, nil];
cdCol = [NSArray arrayWithObjects: @"calendar", XMLNS_CALDAV, nil];
- gdCol = [NSArray arrayWithObjects: [self groupDavResourceType],
- XMLNS_GROUPDAV, nil];
- colType = [NSArray arrayWithObjects: @"collection", cdCol, gdCol, nil];
+ colType = [NSArray arrayWithObjects: @"collection", cdCol,
+ gdVEventCol, gdVTodoCol, nil];
[colType retain];
}
end, start];
}
+- (NSString *) _privacyClassificationStringsForUID: (NSString *) uid
+{
+ NSMutableString *classificationString;
+ NSString *currentRole;
+ unsigned int counter;
+ iCalAccessClass classes[] = {iCalAccessPublic, iCalAccessPrivate,
+ iCalAccessConfidential};
+
+ classificationString = [NSMutableString string];
+ for (counter = 0; counter < 3; counter++)
+ {
+ currentRole = [self roleForComponentsWithAccessClass: classes[counter]
+ forUser: uid];
+ if ([currentRole length] > 0)
+ [classificationString appendFormat: @"classification = %d or ",
+ classes[counter]];
+ }
+
+ return classificationString;
+}
+
- (NSString *) _privacySqlString
{
- NSString *privacySqlString, *owner, *currentUser, *email;
+ NSString *privacySqlString, *owner, *login, *email;
SOGoUser *activeUser;
activeUser = [context activeUser];
- currentUser = [activeUser login];
+ login = [activeUser login];
owner = [self ownerInContext: context];
- if ([currentUser isEqualToString: owner])
+ if ([login isEqualToString: owner])
privacySqlString = @"";
+ else if ([login isEqualToString: @"freebusy"])
+ privacySqlString = @"and (isopaque = 1)";
else
{
email = [activeUser email];
+
privacySqlString
= [NSString stringWithFormat:
- @"(classification != %d or (orgmail = '%@')"
+ @"(%@(orgmail = '%@')"
@" or ((partmails caseInsensitiveLike '%@%%'"
@" or partmails caseInsensitiveLike '%%\\n%@%%')))",
- iCalAccessPrivate, email, email, email];
+ [self _privacyClassificationStringsForUID: login],
+ email, email, email];
}
return privacySqlString;
}
+- (NSString *) roleForComponentsWithAccessClass: (iCalAccessClass) accessClass
+ forUser: (NSString *) uid
+{
+ NSString *accessRole, *prefix, *currentRole, *suffix;
+ NSEnumerator *acls;
+
+ accessRole = nil;
+
+ if (accessClass == iCalAccessPublic)
+ prefix = @"Public";
+ else if (accessClass == iCalAccessPrivate)
+ prefix = @"Private";
+ else
+ prefix = @"Confidential";
+
+ acls = [[self aclsForUser: uid] objectEnumerator];
+ currentRole = [acls nextObject];
+ while (currentRole && !accessRole)
+ if ([currentRole hasPrefix: prefix])
+ {
+ suffix = [currentRole substringFromIndex: [prefix length]];
+ accessRole = [NSString stringWithFormat: @"Component%@", suffix];
+ }
+ else
+ currentRole = [acls nextObject];
+
+ return accessRole;
+}
+
- (NSArray *) fetchFields: (NSArray *) _fields
fromFolder: (GCSFolder *) _folder
from: (NSCalendarDate *) _startDate
{
Class objectClass;
unsigned int count, max;
- NSString *currentId, *currentUser;
+ NSString *currentId;
id deleteObject;
- currentUser = [[context activeUser] login];
-
max = [ids count];
for (count = 0; count < max; count++)
{
return @"IPF.Appointment";
}
+/* acls */
+- (NSArray *) defaultAclRoles
+{
+ return [NSArray arrayWithObjects:
+ SOGoCalendarRole_PublicViewer,
+ SOGoCalendarRole_ConfidentialDAndTViewer,
+ nil];
+}
+
@end /* SOGoAppointmentFolder */
#import <SoObjects/SOGo/AgenorUserManager.h>
#import <SoObjects/SOGo/SOGoPermissions.h>
#import <SoObjects/SOGo/SOGoUser.h>
+#import <SoObjects/Appointments/SOGoAppointmentFolder.h>
#import "common.h"
return nil;
}
-- (void) _filterPrivateComponent: (iCalEntityObject *) component
+- (void) _filterComponent: (iCalEntityObject *) component
{
[component setSummary: @""];
[component setComment: @""];
- (NSString *) contentAsString
{
- NSString *tmpContent, *email;
+ NSString *tmpContent, *email, *uid, *role;
iCalCalendar *tmpCalendar;
iCalRepeatableEntityObject *tmpComponent;
{
tmpContent = [super contentAsString];
calContent = tmpContent;
- if ([tmpContent length] > 0)
+ uid = [[context activeUser] login];
+ if (![[self ownerInContext: context] isEqualToString: uid]
+ && [tmpContent length] > 0)
{
tmpCalendar = [iCalCalendar parseSingleFromSource: tmpContent];
- tmpComponent = (iCalRepeatableEntityObject *) [tmpCalendar firstChildWithTag: [self componentTag]];
- if (![tmpComponent isPublic])
- {
- email = [[context activeUser] email];
- if (!([tmpComponent isOrganizer: email]
- || [tmpComponent isParticipant: email]))
- {
- // content = tmpContent;
- [self _filterPrivateComponent: tmpComponent];
- calContent = [tmpCalendar versitString];
- }
+ tmpComponent = (iCalRepeatableEntityObject *)
+ [tmpCalendar firstChildWithTag: [self componentTag]];
+ email = [[context activeUser] email];
+ if (!([tmpComponent isOrganizer: email]
+ || [tmpComponent isParticipant: email]))
+ {
+ role = [container roleForComponentsWithAccessClass: [tmpComponent symbolicAccessClass]
+ forUser: uid];
+ if ([role length] > 0)
+ {
+ if ([role isEqualToString: SOGoCalendarPerm_ViewDAndT])
+ {
+ // content = tmpContent;
+ [self _filterComponent: tmpComponent];
+ calContent = [tmpCalendar versitString];
+ }
+ }
+ else
+ calContent = nil;
}
}
newComponent = [[calendar classForTag: componentTag]
groupWithTag: componentTag];
[calendar addChild: newComponent];
- isNew = YES;
+ isNew = YES;
}
}
if (calendar)
}
}
-- (NSArray *) rolesOfUser: (NSString *) login
-{
- AgenorUserManager *um;
- iCalRepeatableEntityObject *component;
- NSMutableArray *sogoRoles;
- NSString *email;
- SOGoUser *user;
-
- sogoRoles = [NSMutableArray new];
- [sogoRoles autorelease];
-
- um = [AgenorUserManager sharedUserManager];
- email = [um getEmailForUID: login];
-
- 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: context] isEqualToString: login])
- [sogoRoles addObject: SoRole_Owner];
- }
- else
- {
- user = [SOGoUser userWithLogin: login andRoles: nil];
- [sogoRoles addObjectsFromArray: [user rolesForObject: container
- inContext: context]];
- }
-
- return sogoRoles;
-}
+// - (NSArray *) rolesOfUser: (NSString *) login
+// {
+// AgenorUserManager *um;
+// iCalRepeatableEntityObject *component;
+// NSMutableArray *sogoRoles;
+// NSString *email;
+// SOGoUser *user;
+
+// sogoRoles = [NSMutableArray new];
+// [sogoRoles autorelease];
+
+// um = [AgenorUserManager sharedUserManager];
+// email = [um getEmailForUID: login];
+
+// component = [self component: NO];
+// if (component)
+// {
+// if ([component isOrganizer: email])
+// [sogoRoles addObject: SOGoCalendarRole_Organizer];
+// else if ([component isParticipant: email])
+// [sogoRoles addObject: SOGoCalendarRole_Participant];
+// else if ([[container ownerInContext: context] isEqualToString: login])
+// [sogoRoles addObject: SoRole_Owner];
+// }
+// else
+// {
+// user = [SOGoUser userWithLogin: login andRoles: nil];
+// [sogoRoles addObjectsFromArray: [user rolesForObject: container
+// inContext: context]];
+// }
+
+// return sogoRoles;
+// }
- (BOOL) isOrganizer: (NSString *) email
orOwner: (NSString *) login
return isParticipant;
}
+- (NSArray *) aclsForUser: (NSString *) uid
+{
+ NSMutableArray *roles;
+ NSArray *superAcls;
+ iCalRepeatableEntityObject *component;
+ NSString *email, *accessRole;
+
+ roles = [NSMutableArray array];
+ component = [self component: NO];
+ if (component)
+ {
+ email = [[AgenorUserManager sharedUserManager] getEmailForUID: uid];
+ if ([component isOrganizer: email])
+ [roles addObject: SOGoCalendarRole_Organizer];
+ if ([component isParticipant: email])
+ [roles addObject: SOGoCalendarRole_Participant];
+ accessRole = [container roleForComponentsWithAccessClass:
+ [component symbolicAccessClass]
+ forUser: uid];
+ if ([accessRole length] > 0)
+ [roles addObject: accessRole];
+ }
+
+ superAcls = [super aclsForUser: uid];
+ if ([superAcls count] > 0)
+ [roles addObjectsFromArray: superAcls];
+ if ([roles containsObject: SOGoRole_ObjectCreator])
+ [roles addObject: SOGoCalendarRole_ComponentModifier];
+
+ return roles;
+}
+
@end
02111-1307, USA.
*/
+#import <NGCards/iCalEntityObject.h>
#import <SOGo/SOGoGroupFolder.h>
#include "SOGoGroupAppointmentFolder.h"
classes = {
SOGoAppointmentFolder = {
- superclass = "SOGoFolder";
+ superclass = "SOGoFolder";
defaultRoles = {
- "View" = ( "Owner", "Delegate", "Assistant" );
- "FreeBusyLookup" = ( "Owner", "Delegate", "Assistant", "FreeBusy" );
- "Add Documents, Images, and Files" = ( "Owner", "Delegate" );
- "Access Contents Information" = ( "Owner", "Delegate", "Assistant" );
- "Delete Objects" = ( "Owner", "Organizer", "Delegate" );
+ "FreeBusyLookup" = ( "Owner", "FreeBusy", "AuthorizedSubscriber" );
+ "ViewWholePublicRecords" = ( "Owner", "PublicResponder", "PublicModifier", "PublicViewer" );
+ "ViewDAndTOfPublicRecords" = ( "Owner", "PublicDAndTViewer" );
+ "ModifyPublicRecords" = ( "Owner", "PublicModifier" );
+ "RespondToPublicRecords" = ( "Owner", "PublicModifier", "PublicResponder" );
+ "ViewWholePrivateRecords" = ( "Owner", "PrivateResponder", "PrivateModifier", "PrivateViewer" );
+ "ViewDAndTOfPrivateRecords" = ( "Owner", "PrivateDAndTViewer" );
+ "ModifyPrivateRecords" = ( "Owner", "PrivateModifier" );
+ "RespondToPrivateRecords" = ( "Owner", "PrivateModifier", "PrivateResponder" );
+ "ViewWholeConfidentialRecords" = ( "Owner", "ConfidentialResponder", "ConfidentialModifier", "ConfidentialViewer" );
+ "ViewDAndTOfConfidentialRecords" = ( "Owner", "ConfidentialDAndTViewer" );
+ "ModifyConfidentialRecords" = ( "Owner", "ConfidentialModifier" );
+ "RespondToConfidentialRecords" = ( "Owner", "ConfidentialModifier", "ConfidentialResponder" );
};
};
-
SOGoGroupAppointmentFolder = {
superclass = "SOGoAppointmentFolder";
};
-
- SOGoAppointmentObject = {
+ SOGoCalendarComponent = {
superclass = "SOGoContentObject";
defaultRoles = {
- "View" = ( "Owner", "Delegate", "Organizer", "Authenticated" );
- "Change Images and Files" = ( "Owner", "Delegate", "Organizer" );
- "Access Contents Information" = ( "Owner", "Delegate", "Assistant" );
+ "ViewAllComponent" = ( "Owner", "Organizer", "Participant", "ComponentViewer", "ComponentModifier" );
+ "ViewDAndT" = ( "Organizer", "Participant", "ComponentDAndTViewer" );
+ "ModifyComponent" = ( "Owner", "ComponentModifier" );
+ "RespondToComponent" = ( "Participant", "ComponentResponder" );
};
};
+ SOGoAppointmentObject = {
+ superclass = "SOGoCalendarComponent";
+ };
SOGoTaskObject = {
- superclass = "SOGoContentObject";
- defaultRoles = {
- "View" = ( "Owner", "Delegate", "Organizer", "Authenticated" );
- "Change Images and Files" = ( "Owner", "Delegate", "Organizer" );
- "Access Contents Information" = ( "Owner", "Delegate", "Assistant" );
- };
+ superclass = "SOGoCalendarComponent";
};
SOGoFreeBusyObject = {
superclass = "SOGoContentObject";
return [contactFolders allValues];
}
+/* acls */
+- (NSArray *) aclsForUser: (NSString *) uid
+{
+ return nil;
+}
+
// - (NSString *) roleOfUser: (NSString *) uid
// {
// NSArray *roles, *traversalPath;
EOQualifier *qualifier;
EOSortOrdering *ordering;
- NSLog (@"fetching records matching '*%@*', sorted by '%@' in order %d",
+ NSLog (@"fetching records matching '%@', sorted by '%@' in order %d",
filter, sortKey, sortOrdering);
fields = folderListingFields;
return @"text/x-vcard";
}
+- (NSArray *) aclsForUser: (NSString *) uid
+{
+ return nil;
+}
+
- (void) save
{
}
@"mail", @"telephonenumber", \
@"mailNickname", \
@"sAMAccountName", \
+ @"uid", \
nil]
@class WOContext;
- (void) dealloc
{
- if (connection)
- {
- if ([connection isBound])
- [connection unbind];
- [connection release];
- }
- if (contactIdentifier)
- [contactIdentifier release];
- if (userIdentifier)
- [userIdentifier release];
- if (rootDN)
- [rootDN release];
- if (entries)
- [entries release];
+ [connection release];
+ [contactIdentifier release];
+ [userIdentifier release];
+ [rootDN release];
+ [entries release];
[super dealloc];
}
if (filter && [filter length] > 0)
{
- qs = [NSString stringWithFormat:
- @"(cn='%@*')"
- @"OR (sn='%@*')"
- @"OR (displayName='%@*')"
- @"OR (mail='%@*')"
- @"OR (telephoneNumber='*%@*')",
- filter, filter, filter, filter, filter];
+ if ([filter isEqualToString: @"."])
+ qs = @"(cn='*')";
+ else
+ qs = [NSString stringWithFormat:
+ @"(cn='%@*')"
+ @"OR (sn='%@*')"
+ @"OR (displayName='%@*')"
+ @"OR (mail='%@*')"
+ @"OR (telephoneNumber='*%@*')",
+ filter, filter, filter, filter, filter];
qualifier = [EOQualifier qualifierWithQualifierFormat: qs];
}
else
if (filter && [filter length] > 0)
{
-// NSLog (@"%@: fetching records matching '*%@*', sorted by '%@'"
-// @" in order %d",
-// self, filter, sortKey, sortOrdering);
+ NSLog (@"%@: fetching records matching '%@', sorted by '%@'"
+ @" in order %d",
+ self, filter, sortKey, sortOrdering);
records = [NSMutableArray new];
[records autorelease];
return @"vcard-collection";
}
+/* acls */
+/* TODO: this might change one day when we support LDAP acls */
+- (NSArray *) aclsForUser: (NSString *) uid
+{
+ return nil;
+}
+
@end
#include "SOGoDraftObject.h"
#include <SoObjects/SOGo/WOContext+Agenor.h>
+#include <SoObjects/SOGo/NSCalendarDate+SOGo.h>
#include <NGMail/NGMimeMessage.h>
#include <NGMail/NGMimeMessageGenerator.h>
#include <NGMail/NGSendMail.h>
NGMutableHashMap *map;
NSDictionary *lInfo; // TODO: this should be some kind of object?
NSArray *emails;
- NSString *s;
+ NSString *s, *dateString;
id from, replyTo;
if ((lInfo = [self fetchInfo]) == nil)
[map setObject: [s asQPSubjectString] forKey:@"subject"];
/* add standard headers */
-
- [map addObject:[NSCalendarDate date] forKey:@"date"];
- [map addObject:@"1.0" forKey:@"MIME-Version"];
- [map addObject:userAgent forKey:@"X-Mailer"];
+
+ dateString = [[NSCalendarDate date] rfc822DateString];
+ [map addObject: dateString forKey:@"date"];
+ [map addObject: @"1.0" forKey:@"MIME-Version"];
+ [map addObject: userAgent forKey:@"X-Mailer"];
/* add custom headers */
return YES;
}
+/* acls */
+- (NSArray *) aclsForUser: (NSString *) uid
+{
+ return nil;
+}
+
+
@end /* SOGoMailAccounts */
return NO;
}
-/* debugging */
-
-- (NSString *)loggingPrefix {
- /* improve perf ... */
- return [NSString stringWithFormat:@"<0x%08X[%@]:%@>",
- self, NSStringFromClass([self class]),
- [self nameInContainer]];
+/* acls */
+#warning one day there will be code here to support IMAP acls
+- (NSArray *) aclsForUser: (NSString *) uid
+{
+ return nil;
}
+
@end /* SOGoMailBaseObject */
SOGoMailBaseObject = {
superclass = "SOGoObject";
};
-
SOGoMailAccounts = {
superclass = "SOGoMailBaseObject";
defaultRoles = {
- "Add Documents, Images, and Files" = ( "Owner", "Delegate" );
- "View" = ( "Owner", "Delegate", "Assistant" );
- "WebDAV Access" = ( "Owner", "Delegate", "Assistant" );
- "Access Contents Information" = ( "Owner", "Assistant", "Delegate" );
- "ReadAcls" = ( "Owner", "Delegate", "Assistant" );
+ "View" = ( "Owner", "AuthorizedSubscriber" );
+ "Access Contents Information" = ( "Owner", "AuthorizedSubscriber" );
+ "Add Documents, Images, and Files" = ( "Owner", "ObjectCreator" );
+ "Delete Objects" = ( "Owner", "ObjectEraser" );
+ "WebDAV Access" = ( "Owner", "AuthorizedSubscriber" );
+ "ReadAcls" = ( "Owner", "AuthorizedSubscriber" );
"SaveAcls" = ( "Owner" );
};
};
-
SOGoMailAccount = {
superclass = "SOGoMailBaseObject";
defaultRoles = {
- "Add Folders" = ( "Owner", "Delegate" );
- "Add Documents, Images, and Files" = ( "Owner", "Delegate" );
- "View" = ( "Owner", "Delegate", "Assistant" );
- "WebDAV Access" = ( "Owner", "Delegate", "Assistant" );
- "Access Contents Information" = ( "Owner", "Assistant", "Delegate" );
- "ReadAcls" = ( "Owner", "Delegate", "Assistant" );
+ "View" = ( "Owner", "AuthorizedSubscriber" );
+ "Access Contents Information" = ( "Owner", "AuthorizedSubscriber" );
+ "Add Documents, Images, and Files" = ( "Owner", "ObjectCreator" );
+ "Delete Objects" = ( "Owner", "ObjectEraser" );
+ "WebDAV Access" = ( "Owner", "AuthorizedSubscriber" );
+ "ReadAcls" = ( "Owner", "AuthorizedSubscriber" );
"SaveAcls" = ( "Owner" );
};
};
SOGoSharedMailAccount = {
superclass = "SOGoMailAccount";
};
-
SOGoMailFolder = {
superclass = "SOGoMailBaseObject";
defaultRoles = {
- "Add Folders" = ( "Owner", "Delegate" );
- "Add Documents, Images, and Files" = ( "Owner", "Delegate" );
- "View" = ( "Owner", "Delegate", "Assistant" );
- "WebDAV Access" = ( "Owner", "Delegate", "Assistant" );
- "Access Contents Information" = ( "Owner", "Assistant", "Delegate" );
- "ReadAcls" = ( "Owner", "Delegate", "Assistant" );
+ "View" = ( "Owner", "AuthorizedSubscriber" );
+ "Access Contents Information" = ( "Owner", "AuthorizedSubscriber" );
+ "Add Documents, Images, and Files" = ( "Owner", "ObjectCreator" );
+ "Delete Objects" = ( "Owner", "ObjectEraser" );
+ "WebDAV Access" = ( "Owner", "AuthorizedSubscriber" );
+ "ReadAcls" = ( "Owner", "AuthorizedSubscriber" );
"SaveAcls" = ( "Owner" );
};
};
SOGoSharedInboxFolder = {
superclass = "SOGoMailFolder";
};
-
SOGoTrashFolder = {
superclass = "SOGoMailFolder";
};
-
SOGoMailObject = {
superclass = "SOGoMailBaseObject";
};
-
SOGoMailBodyPart = {
superclass = "SOGoMailBaseObject";
};
SOGoVCardMailBodyPart = {
superclass = "SOGoMailBodyPart";
};
-
SOGoDraftsFolder = {
superclass = "SOGoMailBaseObject";
};
#include "SOGoLRUCache.h"
#warning we should rely on the LDAP sources instead...
-#define qualifierFormat @"mailNickname = %@"
+#define qualifierFormat @"uid = %@"
@interface AgenorUserManager (PrivateAPI)
- (NGLdapConnection *)ldapConnection;
@implementation AgenorUserManager
-static BOOL debugOn = NO;
-static BOOL useLDAP = NO;
-static NSString *ldapHost = nil;
+static BOOL debugOn = NO;
+static BOOL useLDAP = NO;
+static NSString *ldapHost = nil;
static NSString *ldapBaseDN = nil;
static NSNull *sharedNull = nil;
-static NSString *fallbackIMAP4Server = nil;
-static NSString *defaultMailDomain = nil;
-static NSString *shareLDAPClass = @"mineqMelBoite";
-static NSString *shareLoginSeparator = @".-.";
-static NSString *mailEmissionAttrName = @"mineqMelmailEmission";
+static NSString *fallbackIMAP4Server = nil;
+static NSString *defaultMailDomain = nil;
+static NSString *shareLDAPClass = @"mineqMelBoite";
+static NSString *shareLoginSeparator = @".-.";
+static NSString *mailEmissionAttrName = @"mineqMelmailEmission";
static NSString *changeInternetAccessAttrName = @"mineqOgoAccesInternet";
-static NSString *mailAutoresponderAttrName = @"mineqMelReponse"; /* sic! */
-static NSURL *AgenorProfileURL = nil;
+static NSString *mailAutoresponderAttrName = @"mineqMelReponse"; /* sic! */
+static NSURL *AgenorProfileURL = nil;
static NSArray *fromEMailAttrs = nil;
if (didInit) return;
didInit = YES;
- ud = [NSUserDefaults standardUserDefaults];
+ ud = [NSUserDefaults standardUserDefaults];
debugOn = [ud boolForKey:@"SOGoUserManagerDebugEnabled"];
useLDAP = [ud boolForKey:@"SOGoUserManagerUsesLDAP"];
if (useLDAP) {
- ldapHost = [[ud stringForKey:@"SOGoLDAPHost"] copy];
- ldapBaseDN = [[ud stringForKey:@"SOGoLDAPBaseDN"] copy];
+ ldapHost = [[ud stringForKey:@"LDAPHost"] copy];
+ ldapBaseDN = [[ud stringForKey:@"LDAPRootDN"] copy];
NSLog(@"Note: using LDAP host to manage accounts: %@", ldapHost);
}
else
- (id)init {
self = [super init];
if(self) {
- self->serverCache =
+ serverCache =
[[NSMutableDictionary alloc] initWithCapacity:10000];
- self->cnCache =
+ cnCache =
[[NSMutableDictionary alloc] initWithCapacity:10000];
- self->uidCache =
+ uidCache =
[[NSMutableDictionary alloc] initWithCapacity:10000];
- self->emailCache =
+ emailCache =
[[NSMutableDictionary alloc] initWithCapacity:10000];
- self->shareStoreCache =
+ shareStoreCache =
[[NSMutableDictionary alloc] initWithCapacity:10000];
- self->shareEMailCache =
+ shareEMailCache =
[[NSMutableDictionary alloc] initWithCapacity:10000];
- self->changeInternetAccessCache =
+ changeInternetAccessCache =
[[NSMutableDictionary alloc] initWithCapacity:10000];
- self->internetAutoresponderFlagCache =
+ internetAutoresponderFlagCache =
[[NSMutableDictionary alloc] initWithCapacity:10000];
- self->intranetAutoresponderFlagCache =
+ intranetAutoresponderFlagCache =
[[NSMutableDictionary alloc] initWithCapacity:10000];
- self->gcTimer = [[NSTimer scheduledTimerWithTimeInterval:
+ gcTimer = [[NSTimer scheduledTimerWithTimeInterval:
PoolScanInterval
target:self selector:@selector(_garbageCollect:)
userInfo:nil repeats:YES] retain];
}
- (void)dealloc {
- if (self->gcTimer) [self->gcTimer invalidate];
- [self->serverCache release];
- [self->cnCache release];
- [self->uidCache release];
- [self->emailCache release];
- [self->shareStoreCache release];
- [self->shareEMailCache release];
- [self->changeInternetAccessCache release];
- [self->internetAutoresponderFlagCache release];
- [self->intranetAutoresponderFlagCache release];
- [self->gcTimer release];
+ if (gcTimer) [gcTimer invalidate];
+ [serverCache release];
+ [cnCache release];
+ [uidCache release];
+ [emailCache release];
+ [shareStoreCache release];
+ [shareEMailCache release];
+ [changeInternetAccessCache release];
+ [internetAutoresponderFlagCache release];
+ [intranetAutoresponderFlagCache release];
+ [gcTimer release];
[super dealloc];
}
/* cache */
- (void)flush {
- [self->cnCache removeAllObjects];
- [self->serverCache removeAllObjects];
- [self->uidCache removeAllObjects];
- [self->emailCache removeAllObjects];
- [self->shareStoreCache removeAllObjects];
- [self->shareEMailCache removeAllObjects];
+ [cnCache removeAllObjects];
+ [serverCache removeAllObjects];
+ [uidCache removeAllObjects];
+ [emailCache removeAllObjects];
+ [shareStoreCache removeAllObjects];
+ [shareEMailCache removeAllObjects];
- [self->changeInternetAccessCache removeAllObjects];
- [self->internetAutoresponderFlagCache removeAllObjects];
- [self->intranetAutoresponderFlagCache removeAllObjects];
+ [changeInternetAccessCache removeAllObjects];
+ [internetAutoresponderFlagCache removeAllObjects];
+ [intranetAutoresponderFlagCache removeAllObjects];
}
- (void)_garbageCollect:(NSTimer *)_timer {
- (NGLdapConnection *)ldapConnection {
static NGLdapConnection *ldapConnection = nil;
if(!ldapConnection) {
- ldapConnection = [[NGLdapConnection alloc] initWithHostName:ldapHost];
+ ldapConnection = [[NGLdapConnection alloc] initWithHostName: ldapHost];
#if 0
[ldapConnection setUseCache:YES];
#endif
- (void)_cacheCN:(NSString *)_cn forUID:(NSString *)_uid {
if (_cn == nil) return;
- [self->cnCache setObject:_cn forKey:_uid];
+ [cnCache setObject:_cn forKey:_uid];
}
- (NSString *)_cachedCNForUID:(NSString *)_uid {
- return [self->cnCache objectForKey:_uid];
+ return [cnCache objectForKey:_uid];
}
- (void)_cacheServer:(NSString *)_server forUID:(NSString *)_uid {
if (_server == nil) return;
- [self->serverCache setObject:_server forKey:_uid];
+ [serverCache setObject:_server forKey:_uid];
}
- (NSString *)_cachedServerForUID:(NSString *)_uid {
- return [self->serverCache objectForKey:_uid];
+ return [serverCache objectForKey:_uid];
}
- (void)_cacheEmail:(NSString *)_email forUID:(NSString *)_uid {
if (_email == nil) return;
- [self->emailCache setObject:_email forKey:_uid];
+ [emailCache setObject:_email forKey:_uid];
}
- (NSString *)_cachedEmailForUID:(NSString *)_uid {
- return [self->emailCache objectForKey:_uid];
+ return [emailCache objectForKey:_uid];
}
- (void)_cacheUID:(NSString *)_uid forEmail:(NSString *)_email {
if (_uid == nil) return;
- [self->uidCache setObject:_uid forKey:_email];
+ [uidCache setObject:_uid forKey:_email];
}
- (NSString *)_cachedUIDForEmail:(NSString *)_email {
- return [self->uidCache objectForKey:_email];
+ return [uidCache objectForKey:_email];
}
q = [EOQualifier qualifierWithQualifierFormat:@"mail = %@", _email];
- conn = [self ldapConnection];
+ conn = [self ldapConnection];
resultEnum = [conn deepSearchAtBaseDN:ldapBaseDN
qualifier:q
attributes:uidAttrs];
unsigned i, count;
count = [_persons count];
- ma = [[[NSMutableArray alloc] initWithCapacity:count] autorelease];
+ ma = [[[NSMutableArray alloc] initWithCapacity:count] autorelease];
for (i = 0; i < count; i++) {
iCalPerson *p;
id uid;
- p = [_persons objectAtIndex:i];
+ p = [_persons objectAtIndex:i];
uid = [self getUIDForICalPerson:p];
if (uid != nil)
[ma addObject:uid];
NSString *email;
unsigned count;
- q = [EOQualifier qualifierWithQualifierFormat:qualifierFormat, _uid];
+ q = [EOQualifier qualifierWithQualifierFormat: qualifierFormat, _uid];
- conn = [self ldapConnection];
+ conn = [self ldapConnection];
resultEnum = [conn deepSearchAtBaseDN:ldapBaseDN
qualifier:q
attributes:fromEMailAttrs];
if (cnAttrs == nil)
cnAttrs = [[NSArray alloc] initWithObjects:@"cn", nil];
- q = [EOQualifier qualifierWithQualifierFormat:qualifierFormat, _uid];
+ q = [EOQualifier qualifierWithQualifierFormat: qualifierFormat, _uid];
conn = [self ldapConnection];
resultEnum = [conn deepSearchAtBaseDN:ldapBaseDN
NSEnumerator *resultEnum;
NGLdapEntry *entry;
- q = [EOQualifier qualifierWithQualifierFormat:qualifierFormat, _uid];
+ q = [EOQualifier qualifierWithQualifierFormat: qualifierFormat, _uid];
conn = [self ldapConnection];
resultEnum = [conn deepSearchAtBaseDN:ldapBaseDN
NSMutableArray *serverCandidates;
unsigned i, count;
- count = [attr count];
+ count = [attr count];
serverCandidates = [NSMutableArray arrayWithCapacity:count];
for (i = 0; i < count; i++) {
NSRange r;
}
/* check cache */
- if ((shares = [self->shareEMailCache objectForKey:_uid]) != nil)
+ if ((shares = [shareEMailCache objectForKey:_uid]) != nil)
return shares;
/* G and C mean "emission access" */
/* cache */
shares = (shares == nil) ? [NSArray array] : [[shares copy] autorelease];
- [self->shareEMailCache setObject:shares forKey:_uid];
+ [shareEMailCache setObject:shares forKey:_uid];
return shares;
}
}
/* check cache */
- if ((shares = [self->shareStoreCache objectForKey:_uid]) != nil)
+ if ((shares = [shareStoreCache objectForKey:_uid]) != nil)
return shares;
sharePattern = [_uid stringByAppendingString:@":*"];
shares = (shares == nil)
? [NSDictionary dictionary]
: [[shares copy] autorelease];
- [self->shareStoreCache setObject:shares forKey:_uid];
+ [shareStoreCache setObject:shares forKey:_uid];
return shares;
}
- (BOOL)isUserAllowedToChangeSOGoInternetAccess:(NSString *)_uid {
NSNumber *bv;
- bv = [self->changeInternetAccessCache objectForKey:_uid];
+ bv = [changeInternetAccessCache objectForKey:_uid];
if (!bv) {
BOOL value;
value = [self primaryIsUserAllowedToChangeSOGoInternetAccess:_uid];
- bv = [NSNumber numberWithBool:value];
- [self->changeInternetAccessCache setObject:bv forKey:_uid];
+ bv = [NSNumber numberWithBool:value];
+ [changeInternetAccessCache setObject:bv forKey:_uid];
}
return [bv boolValue];
}
if (attrs == nil)
attrs = [[NSArray alloc] initWithObjects:changeInternetAccessAttrName, nil];
- q = [EOQualifier qualifierWithQualifierFormat:qualifierFormat, _uid];
+ q = [EOQualifier qualifierWithQualifierFormat: qualifierFormat, _uid];
- conn = [self ldapConnection];
+ conn = [self ldapConnection];
resultEnum = [conn deepSearchAtBaseDN:ldapBaseDN
qualifier:q
attributes:attrs];
return [value boolValue];
}
-- (BOOL)isInternetAutoresponderEnabledForUser:(NSString *)_uid {
+- (BOOL) isInternetAutoresponderEnabledForUser: (NSString *) _uid
+{
NSNumber *bv;
+ BOOL value;
- bv = [self->internetAutoresponderFlagCache objectForKey:_uid];
+ bv = [internetAutoresponderFlagCache objectForKey:_uid];
if (!bv) {
- BOOL value;
-
value = [self primaryIsInternetAutoresponderEnabledForUser:_uid];
- bv = [NSNumber numberWithBool:value];
- [self->internetAutoresponderFlagCache setObject:bv forKey:_uid];
+ bv = [NSNumber numberWithBool:value];
+ [internetAutoresponderFlagCache setObject:bv forKey:_uid];
}
return [bv boolValue];
}
-- (BOOL)primaryIsInternetAutoresponderEnabledForUser:(NSString *)_uid {
+- (BOOL) primaryIsInternetAutoresponderEnabledForUser: (NSString *) _uid
+{
NGLdapAttribute *attr;
attr = [self primaryGetMailAutoresponderAttribute:_uid];
if (!attr) return NO;
- return [self isAutoresponderEnabledForAttribute:attr matchingPrefix:@"60~"];
+
+ return [self isAutoresponderEnabledForAttribute: attr
+ matchingPrefix: @"60~"];
}
-- (BOOL)isIntranetAutoresponderEnabledForUser:(NSString *)_uid {
+- (BOOL) isIntranetAutoresponderEnabledForUser: (NSString *) _uid
+{
NSNumber *bv;
+ BOOL value;
- bv = [self->intranetAutoresponderFlagCache objectForKey:_uid];
- if (!bv) {
- BOOL value;
-
- value = [self primaryIsIntranetAutoresponderEnabledForUser:_uid];
- bv = [NSNumber numberWithBool:value];
- [self->intranetAutoresponderFlagCache setObject:bv forKey:_uid];
- }
+ bv = [intranetAutoresponderFlagCache objectForKey:_uid];
+ if (!bv)
+ {
+ value = [self primaryIsIntranetAutoresponderEnabledForUser:_uid];
+ bv = [NSNumber numberWithBool:value];
+ [intranetAutoresponderFlagCache setObject:bv forKey:_uid];
+ }
+
return [bv boolValue];
}
-- (BOOL)primaryIsIntranetAutoresponderEnabledForUser:(NSString *)_uid {
+- (BOOL) primaryIsIntranetAutoresponderEnabledForUser: (NSString *) _uid
+{
NGLdapAttribute *attr;
attr = [self primaryGetMailAutoresponderAttribute:_uid];
return [self isAutoresponderEnabledForAttribute:attr matchingPrefix:@"50~"];
}
-- (BOOL)isAutoresponderEnabledForAttribute:(NGLdapAttribute *)_attr
- matchingPrefix:(NSString *)_prefix
+- (BOOL) isAutoresponderEnabledForAttribute: (NGLdapAttribute *)_attr
+ matchingPrefix: (NSString *)_prefix
{
unsigned i, count;
return YES;
}
}
+
return NO;
}
-- (NGLdapAttribute *)primaryGetMailAutoresponderAttribute:(NSString *)_uid {
+- (NGLdapAttribute *) primaryGetMailAutoresponderAttribute: (NSString *) _uid
+{
static NSArray *attrs = nil;
NGLdapConnection *conn;
EOQualifier *q;
if (attrs == nil)
attrs = [[NSArray alloc] initWithObjects:mailAutoresponderAttrName, nil];
- q = [EOQualifier qualifierWithQualifierFormat:qualifierFormat, _uid];
+ q = [EOQualifier qualifierWithQualifierFormat: qualifierFormat, _uid];
- conn = [self ldapConnection];
+ conn = [self ldapConnection];
resultEnum = [conn deepSearchAtBaseDN:ldapBaseDN
qualifier:q
attributes:attrs];
SOGoObject.h \
SOGoFolder.h \
SOGoContentObject.h \
- SOGoAclsFolder.h \
SOGoUserFolder.h \
SOGoGroupsFolder.h \
SOGoGroupFolder.h \
SOGoObject.m \
SOGoFolder.m \
SOGoContentObject.m \
- SOGoAclsFolder.m \
SOGoUserFolder.m \
SOGoGroupsFolder.m \
SOGoGroupFolder.m \
- (NSCalendarDate *) sundayOfWeek;
- (NSString *) shortDateString;
+- (NSString *) rfc822DateString;
+
@end
#endif /* NSCALENDARDATE_SCHEDULER_H */
02111-1307, USA.
*/
+#import <Foundation/NSCalendarDate.h>
+#import <Foundation/NSTimeZone.h>
#import <NGExtensions/NSCalendarDate+misc.h>
#import "NSCalendarDate+SOGo.h"
+static NSString *rfc822Days[] = {@"Sun", @"Mon", @"Tue", @"Wed", @"Thu",
+ @"Fri", @"Sat"};
+static NSString *rfc822Months[] = {@"", @"Jan", @"Feb", @"Mar", @"Apr",
+ @"May", @"Jun", @"Jul", @"Aug" , @"Sep",
+ @"Oct", @"Nov", @"Dec"};
+
@implementation NSCalendarDate (SOGoExtensions)
+ (id) dateFromShortDateString: (NSString *) dateString
return str;
}
+- (NSString *) rfc822DateString
+{
+ int timeZoneShift, tzSeconds;
+
+ tzSeconds = [[self timeZone] secondsFromGMT];
+ timeZoneShift = (tzSeconds / 3600);
+ tzSeconds -= timeZoneShift * 3600;
+ timeZoneShift *= 100;
+ timeZoneShift += tzSeconds / 60;
+
+ return
+ [NSString stringWithFormat: @"%@, %.2d %@ %d %.2d:%.2d:%.2d %.4d",
+ rfc822Days[[self dayOfWeek]], [self dayOfMonth],
+ rfc822Months[[self monthOfYear]], [self yearOfCommonEra],
+ [self hourOfDay], [self minuteOfHour], [self secondOfMinute],
+ timeZoneShift];
+}
+
@end
+++ /dev/null
-/* SOGoAclsFolder.m - this file is part of SOGo
- *
- * Copyright (C) 2006 Inverse groupe conseil
- *
- * 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.
- */
-
-#import <Foundation/NSArray.h>
-#import <Foundation/NSKeyValueCoding.h>
-#import <Foundation/NSString.h>
-
-#import <NGExtensions/NSNull+misc.h>
-#import <NGObjWeb/SoObject.h>
-#import <EOControl/EOQualifier.h>
-#import <GDLAccess/EOAdaptorChannel.h>
-#import <GDLContentStore/GCSFolder.h>
-#import <GDLContentStore/GCSFolderManager.h>
-
-#import "SOGoFolder.h"
-#import "SOGoAclsFolder.h"
-
-@implementation SOGoAclsFolder
-
-+ (id) aclsFolder
-{
- id aclsFolder;
-
- aclsFolder = [self new];
- [aclsFolder autorelease];
-
- return aclsFolder;
-}
-
-- (id) init
-{
- if ((self = [super init]))
- {
- ocsPath = nil;
- ocsFolder = nil;
- }
-
- return self;
-}
-
-- (void) dealloc
-{
- if (ocsPath)
- [ocsPath release];
- if (ocsFolder)
- [ocsFolder release];
- [super dealloc];
-}
-
-- (void) setOCSPath: (NSString *) newOCSPath
-{
- if (ocsPath)
- [ocsPath release];
- ocsPath = newOCSPath;
- if (ocsPath)
- [ocsPath retain];
-}
-
-- (GCSFolderManager *)folderManager {
- return [GCSFolderManager defaultFolderManager];
-}
-
-- (GCSFolder *)ocsFolderForPath:(NSString *)_path {
- return [[self folderManager] folderAtPath:_path];
-}
-
-- (GCSFolder *) ocsFolder {
- GCSFolder *folder;
-
- if (!ocsFolder)
- ocsFolder = [[self ocsFolderForPath: ocsPath] retain];
-
- if ([ocsFolder isNotNull])
- folder = ocsFolder;
- else
- folder = nil;
-
- return folder;
-}
-
-- (NSString *) _ocsPathForObject: (SOGoObject *) object
-{
- NSString *pathForObject;
- id currentObject;
- BOOL done;
-
- pathForObject = nil;
- currentObject = object;
- done = NO;
- while (currentObject && !done)
- if ([currentObject isKindOfClass: [SOGoFolder class]])
- {
- pathForObject = [(SOGoFolder *) currentObject ocsPath];
- done = YES;
-// if (!pathForObject)
-// currentObject = [currentObject container];
- }
- else
- currentObject = [currentObject container];
-
- return pathForObject;
-}
-
-- (NSArray *) aclsForObject: (SOGoObject *) object
-{
- EOQualifier *qualifier;
- NSString *objectPath;
-
- [self setOCSPath: [self _ocsPathForObject: object]];
-
- objectPath
- = [NSString stringWithFormat: @"/%@",
- [[object pathArrayToSoObject] componentsJoinedByString: @"/"]];
- qualifier
- = [EOQualifier qualifierWithQualifierFormat: @"c_object = %@", objectPath];
-
- return [[self ocsFolder] fetchAclMatchingQualifier: qualifier];
-}
-
-- (NSArray *) aclsForObject: (SOGoObject *) object
- forUser: (NSString *) uid
-{
- EOQualifier *qualifier;
- NSString *objectPath;
- NSArray *records;
-
- [self setOCSPath: [self _ocsPathForObject: object]];
-
- objectPath
- = [NSString stringWithFormat: @"/%@",
- [[object pathArrayToSoObject] componentsJoinedByString: @"/"]];
- qualifier = [EOQualifier
- qualifierWithQualifierFormat: @"(c_object = %@) AND (c_uid = %@)",
- objectPath, uid];
-
- records = [[self ocsFolder] fetchAclMatchingQualifier: qualifier];
-
- return [records valueForKey: @"c_role"];
-}
-
-- (void) removeUsersWithRole: (NSString *) role
- forObjectAtPath: (NSString *) objectPath
- inFolder: (GCSFolder *) folder
-{
- NSString *deleteSQL;
- EOAdaptorChannel *channel;
-
- channel = [folder acquireAclChannel];
-
- deleteSQL = [NSString stringWithFormat: @"DELETE FROM %@"
- @" WHERE c_object = '%@'"
- @" AND c_role = '%@'",
- [folder aclTableName], objectPath, role];
- [channel evaluateExpressionX: deleteSQL];
-}
-
-- (void) setRoleForObjectAtPath: (NSString *) objectPath
- forUser: (NSString *) uid
- to: (NSString *) role
- inFolder: (GCSFolder *) folder
-{
- NSString *SQL;
- EOAdaptorChannel *channel;
-
- channel = [folder acquireAclChannel];
-
- SQL = [NSString stringWithFormat: @"DELETE FROM %@"
- @" WHERE c_object = '%@'"
- @" AND c_uid = '%@'",
- [folder aclTableName], objectPath, uid];
- [channel evaluateExpressionX: SQL];
- SQL = [NSString stringWithFormat: @"INSERT INTO %@"
- @" (c_object, c_uid, c_role)"
- @" VALUES ('%@', '%@', '%@')", [folder aclTableName],
- objectPath, uid, role];
- [channel evaluateExpressionX: SQL];
-}
-
-/* FIXME: part of this code should be moved to sope-gdl/GCSFolder.m */
-- (void) setRoleForObject: (SOGoObject *) object
- forUsers: (NSArray *) uids
- to: (NSString *) role
-{
- GCSFolder *aclsFolder;
- NSString *objectPath, *currentUID;
- NSEnumerator *userUIDs;
-
- [self setOCSPath: [self _ocsPathForObject: object]];
- aclsFolder = [self ocsFolder];
-
- objectPath
- = [NSString stringWithFormat: @"/%@",
- [[object pathArrayToSoObject] componentsJoinedByString: @"/"]];
- [self removeUsersWithRole: role
- forObjectAtPath: objectPath
- inFolder: aclsFolder];
-
- userUIDs = [uids objectEnumerator];
- currentUID = [userUIDs nextObject];
- while (currentUID)
- {
- if ([currentUID length] > 0)
- [self setRoleForObjectAtPath: objectPath
- forUser: currentUID
- to: role
- inFolder: aclsFolder];
- currentUID = [userUIDs nextObject];
- }
-}
-
-@end
#import <SOGo/SOGoObject.h>
-@class NSString, NSException;
+@class NSArray;
+@class NSException;
+@class NSString;
@interface SOGoContentObject : SOGoObject
{
/* accessors */
-- (void)setOCSPath:(NSString *)_path;
-- (NSString *)ocsPath;
+- (void) setOCSPath: (NSString *) _path;
+- (NSString *) ocsPath;
/* folder */
-- (NSString *)ocsPathOfContainer;
-- (GCSFolder *)ocsFolder;
+- (NSString *) ocsPathOfContainer;
+- (GCSFolder *) ocsFolder;
/* content */
-- (NSString *)contentAsString;
-- (NSException *)saveContentString:(NSString *)_str
- baseVersion:(unsigned int)_baseVersion;
-- (NSException *)saveContentString:(NSString *)_str;
-- (NSException *)delete;
+- (NSString *) contentAsString;
+- (NSException *) saveContentString: (NSString *) _str
+ baseVersion: (unsigned int) _baseVersion;
+- (NSException *) saveContentString: (NSString *)_str;
+- (NSException *) delete;
/* etag support */
-- (id)davEntityTag;
+- (id) davEntityTag;
/* message type */
-- (NSString *)outlookMessageClass;
+- (NSString *) outlookMessageClass;
@end
#import <GDLContentStore/GCSFolder.h>
-#import <SOGo/SOGoUser.h>
-
#import "common.h"
#import "SOGoFolder.h"
+#import "SOGoUser.h"
+#import "SOGoPermissions.h"
#import "SOGoContentObject.h"
@interface SOGoContentObject(ETag)
// TODO: check superclass version
- (void)dealloc {
- [self->content release];
- [self->ocsPath release];
+ [content release];
+ [ocsPath release];
[super dealloc];
}
/* notifications */
- (void)sleep {
- [self->content release]; self->content = nil;
+ [content release]; content = nil;
[super sleep];
}
}
- (void)setOCSPath:(NSString *)_path {
- if ([self->ocsPath isEqualToString:_path])
+ if ([ocsPath isEqualToString:_path])
return;
- if (self->ocsPath)
+ if (ocsPath)
[self warnWithFormat:@"GCS path is already set! '%@'", _path];
- ASSIGNCOPY(self->ocsPath, _path);
+ ASSIGNCOPY(ocsPath, _path);
}
-- (NSString *)ocsPath {
- if (self->ocsPath == nil) {
- NSString *p;
+- (NSString *) ocsPath
+{
+ NSString *p;
- if ((p = [self ocsPathOfContainer]) != nil) {
- if (![p hasSuffix:@"/"]) p = [p stringByAppendingString:@"/"];
- p = [p stringByAppendingString:[self nameInContainer]];
- self->ocsPath = [p copy];
+ if (!ocsPath)
+ {
+ p = [self ocsPathOfContainer];
+ if (p)
+ {
+ if (![p hasSuffix:@"/"])
+ p = [p stringByAppendingString: @"/"];
+ ocsPath = [p stringByAppendingString: [self nameInContainer]];
+ [ocsPath retain];
+ }
}
- }
- return self->ocsPath;
+
+ return ocsPath;
}
- (NSString *)ocsPathOfContainer {
return [[self container] ocsPath];
}
-- (GCSFolder *)ocsFolder {
- if (![[self container] respondsToSelector:@selector(ocsFolder)])
- return nil;
-
- return [[self container] ocsFolder];
+- (GCSFolder *) ocsFolder
+{
+ return [container ocsFolder];
}
/* content */
-- (NSString *)contentAsString {
- GCSFolder *folder;
+- (NSString *) contentAsString
+{
+ if (!content)
+ {
+ content = [[self ocsFolder] fetchContentWithName: nameInContainer];
+ [content retain];
+ }
- if (self->content != nil)
- return self->content;
-
- if ((folder = [self ocsFolder]) == nil) {
- [self errorWithFormat:@"Did not find folder of content object."];
- return nil;
- }
-
- self->content = [[folder fetchContentWithName:[self nameInContainer]] copy];
- return self->content;
+ return content;
}
-- (NSException *)saveContentString:(NSString *)_str
- baseVersion:(unsigned int)_baseVersion
+- (NSException *) saveContentString: (NSString *) _str
+ baseVersion: (unsigned int) _baseVersion
{
/* Note: "iCal multifolder saves" are implemented in the apt subclass! */
GCSFolder *folder;
@"reassigned a new location for special new-location: %@", tmp];
/* kinda dangerous */
- ASSIGNCOPY(self->nameInContainer, tmp);
- ASSIGN(self->ocsPath, nil);
+ ASSIGNCOPY(nameInContainer, tmp);
+ ASSIGN(ocsPath, nil);
}
/* determine base version from etag in if-match header */
return [_ctx response];
}
-/* security */
-- (NSArray *) rolesOfUser: (NSString *) login
-{
- NSMutableArray *sogoRoles;
- SOGoUser *user;
-
- sogoRoles = [NSMutableArray new];
- [sogoRoles autorelease];
-
- if (![container nameExistsInFolder: nameInContainer])
- {
- user = [[SOGoUser alloc] initWithLogin: login roles: nil];
- [sogoRoles addObjectsFromArray: [user rolesForObject: container
- inContext: context]];
- [user release];
- }
-
- return sogoRoles;
-}
-
/* E-Tags */
-- (id)davEntityTag {
+- (id) davEntityTag
+{
// TODO: cache tag in ivar? => if you do, remember to flush after PUT
GCSFolder *folder;
char buf[64];
+ NSString *entityTag;
+ NSNumber *versionValue;
- if ((folder = [self ocsFolder]) == nil) {
- [self errorWithFormat:@"Did not find folder of content object."];
- return nil;
- }
-
- sprintf(buf, "\"gcs%08d\"",
- [[folder versionOfContentWithName:[self nameInContainer]]
- unsignedIntValue]);
- return [NSString stringWithCString:buf];
+ folder = [self ocsFolder];
+ if (folder)
+ {
+ versionValue = [folder versionOfContentWithName: [self nameInContainer]];
+ sprintf (buf, "\"gcs%08d\"", [versionValue unsignedIntValue]);
+ entityTag = [NSString stringWithCString: buf];
+ }
+ else
+ {
+ [self errorWithFormat:@"Did not find folder of content object."];
+ entityTag = nil;
+ }
+
+ return entityTag;
}
/* WebDAV */
-- (NSException *)davMoveToTargetObject:(id)_target newName:(NSString *)_name
- inContext:(id)_ctx
+- (NSException *) davMoveToTargetObject: (id) _target
+ newName: (NSString *) _name
+ inContext: (id) _ctx
{
/*
Note: even for new objects we won't get a new name but a preinstantiated
reason:@"this object cannot be copied via WebDAV"];
}
-- (NSException *)davCopyToTargetObject:(id)_target newName:(NSString *)_name
- inContext:(id)_ctx
+- (NSException *) davCopyToTargetObject: (id)_target
+ newName: (NSString *) _name
+ inContext: (id) _ctx
{
/*
Note: even for new objects we won't get a new name but a preinstantiated
return [self isFolderish];
}
+/* acls */
+
+- (NSArray *) acls
+{
+ return [container aclsForObjectAtPath: [self pathArrayToSoObject]];
+}
+
+- (NSArray *) aclsForUser: (NSString *) uid
+{
+ NSMutableArray *acls;
+ NSArray *ownAcls, *containerAcls;
+
+ acls = [NSMutableArray array];
+ ownAcls = [container aclsForUser: uid
+ forObjectAtPath: [self pathArrayToSoObject]];
+ [acls addObjectsFromArray: ownAcls];
+ containerAcls = [container aclsForUser: uid];
+ if ([containerAcls count] > 0)
+ {
+ if ([containerAcls containsObject: SOGoRole_ObjectCreator])
+ [acls addObject: SOGoRole_ObjectCreator];
+ if ([containerAcls containsObject: SOGoRole_ObjectEraser])
+ [acls addObject: SOGoRole_ObjectEraser];
+ }
+
+ return acls;
+}
+
+- (void) setRoles: (NSArray *) roles
+ forUser: (NSString *) uid
+{
+ return [container setRoles: roles
+ forUser: uid
+ forObjectAtPath: [self pathArrayToSoObject]];
+}
+
+- (void) removeAclsForUsers: (NSArray *) users
+{
+ return [container removeAclsForUsers: users
+ forObjectAtPath: [self pathArrayToSoObject]];
+}
+
/* message type */
-- (NSString *)outlookMessageClass {
+- (NSString *) outlookMessageClass
+{
return nil;
}
/* description */
-- (void)appendAttributesToDescription:(NSMutableString *)_ms {
+- (void) appendAttributesToDescription: (NSMutableString *) _ms
+{
[super appendAttributesToDescription:_ms];
[_ms appendFormat:@" ocs=%@", [self ocsPath]];
@class NSString, NSArray, NSDictionary;
@class GCSFolder;
-@class SOGoAclsFolder;
/*
SOGoFolder
cyclic references.
*/
+@class NSString;
+@class GCSFolder;
+@class NSMutableDictionary;
+
@interface SOGoFolder : SOGoObject
{
NSString *ocsPath;
GCSFolder *ocsFolder;
+ NSMutableDictionary *aclCache;
}
+ (NSString *) globallyUniqueObjectId;
- (BOOL) create;
- (NSException *) delete;
+/* acls as a container */
+- (NSArray *) aclsForObjectAtPath: (NSArray *) objectPathArray;
+- (NSArray *) aclsForUser: (NSString *) uid
+ forObjectAtPath: (NSArray *) objectPathArray;
+- (void) setRoles: (NSArray *) roles
+ forUser: (NSString *) uid
+ forObjectAtPath: (NSArray *) objectPathArray;
+- (void) removeAclsForUsers: (NSArray *) users
+ forObjectAtPath: (NSArray *) objectPathArray;
+
@end
@interface SOGoFolder (GroupDAVExtensions)
*/
#import <NGObjWeb/SoObject.h>
+#import <GDLAccess/EOAdaptorChannel.h>
#import <GDLContentStore/GCSFolderManager.h>
#import <GDLContentStore/GCSFolder.h>
#import <GDLContentStore/GCSFolderType.h>
+#import "SOGoPermissions.h"
#import "SOGoFolder.h"
#import "common.h"
#import <unistd.h>
#import <stdlib.h>
-#import "SOGoAclsFolder.h"
+static NSString *defaultUser = @"<default>";
@implementation SOGoFolder
-+ (int)version {
++ (int) version
+{
return [super version] + 0 /* v0 */;
}
-+ (void)initialize {
+
++ (void) initialize
+{
NSAssert2([super version] == 0,
@"invalid superclass (%@) version %i !",
NSStringFromClass([self superclass]), [super version]);
}
-+ (NSString *)globallyUniqueObjectId {
++ (NSString *) globallyUniqueObjectId
+{
/*
4C08AE1A-A808-11D8-AC5A-000393BBAFF6
SOGo-Web-28273-18283-288182
printf( "%x", *(int *) &f);
*/
- static int pid = 0;
- static int sequence = 0;
+ static int pid = 0;
+ static int sequence = 0;
static float rndm = 0;
float f;
- if (pid == 0) { /* break if we fork ;-) */
- pid = getpid();
- rndm = random();
- }
+ if (pid == 0)
+ { /* break if we fork ;-) */
+ pid = getpid();
+ rndm = random();
+ }
sequence++;
f = [[NSDate date] timeIntervalSince1970];
return [NSString stringWithFormat:@"%0X-%0X-%0X-%0X",
pid, *(int *)&f, sequence++, random];
}
-- (void)dealloc {
- [self->ocsFolder release];
- [self->ocsPath release];
+- (id) init
+{
+ if ((self = [super init]))
+ {
+ ocsPath = nil;
+ ocsFolder = nil;
+ aclCache = [NSMutableDictionary new];
+ }
+
+ return self;
+}
+
+- (void) dealloc
+{
+ [ocsFolder release];
+ [ocsPath release];
+ [aclCache release];
[super dealloc];
}
/* accessors */
-- (BOOL)isFolderish {
+- (BOOL) isFolderish
+{
return YES;
}
-- (void)setOCSPath:(NSString *)_path {
- if ([self->ocsPath isEqualToString:_path])
+- (void) setOCSPath: (NSString *) _path
+{
+ if ([ocsPath isEqualToString:_path])
return;
- if (self->ocsPath)
+ if (ocsPath)
[self warnWithFormat:@"GCS path is already set! '%@'", _path];
- ASSIGNCOPY(self->ocsPath, _path);
+ ASSIGNCOPY(ocsPath, _path);
}
-- (NSString *)ocsPath {
- return self->ocsPath;
+- (NSString *) ocsPath
+{
+ return ocsPath;
}
-- (GCSFolderManager *)folderManager {
+- (GCSFolderManager *) folderManager
+{
static GCSFolderManager *folderManager = nil;
if (!folderManager)
return folderManager;
}
-- (GCSFolder *)ocsFolderForPath:(NSString *)_path {
+- (GCSFolder *) ocsFolderForPath: (NSString *) _path
+{
return [[self folderManager] folderAtPath:_path];
}
-- (GCSFolder *) ocsFolder {
+- (GCSFolder *) ocsFolder
+{
GCSFolder *folder;
if (!ocsFolder)
return names;
}
+/* acls as a container */
+
+- (NSArray *) aclsForObjectAtPath: (NSArray *) objectPathArray;
+{
+ EOQualifier *qualifier;
+ NSString *qs;
+
+ qs = [NSString stringWithFormat: @"c_object = '/%@'",
+ [objectPathArray componentsJoinedByString: @"/"]];
+ qualifier = [EOQualifier qualifierWithQualifierFormat: qs];
+
+ return [[self ocsFolder] fetchAclMatchingQualifier: qualifier];
+}
+
+- (NSArray *) _fetchAclsForUser: (NSString *) uid
+ forObjectAtPath: (NSString *) objectPath
+{
+ EOQualifier *qualifier;
+ NSArray *records;
+ NSMutableArray *acls;
+ NSString *qs;
+
+ qs = [NSString stringWithFormat: @"(c_object = '/%@') AND (c_uid = '%@')",
+ objectPath, uid];
+ qualifier = [EOQualifier qualifierWithQualifierFormat: qs];
+ records = [[self ocsFolder] fetchAclMatchingQualifier: qualifier];
+
+ acls = [NSMutableArray array];
+ if ([records count] > 0)
+ {
+ [acls addObject: SOGoRole_AuthorizedSubscriber];
+ [acls addObjectsFromArray: [records valueForKey: @"c_role"]];
+ }
+
+ return acls;
+}
+
+- (void) _cacheRoles: (NSArray *) roles
+ forUser: (NSString *) uid
+ forObjectAtPath: (NSString *) objectPath
+{
+ NSMutableDictionary *aclsForObject;
+
+ aclsForObject = [aclCache objectForKey: objectPath];
+ if (!aclsForObject)
+ {
+ aclsForObject = [NSMutableDictionary dictionary];
+ [aclCache setObject: aclsForObject
+ forKey: objectPath];
+ }
+ if (roles)
+ [aclsForObject setObject: roles forKey: uid];
+ else
+ [aclsForObject removeObjectForKey: uid];
+}
+
+- (NSArray *) aclsForUser: (NSString *) uid
+ forObjectAtPath: (NSArray *) objectPathArray
+{
+ NSArray *acls;
+ NSString *objectPath;
+ NSDictionary *aclsForObject;
+
+ objectPath = [objectPathArray componentsJoinedByString: @"/"];
+ aclsForObject = [aclCache objectForKey: objectPath];
+ if (aclsForObject)
+ acls = [aclsForObject objectForKey: uid];
+ else
+ acls = nil;
+ if (!acls)
+ {
+ acls = [self _fetchAclsForUser: uid forObjectAtPath: objectPath];
+ [self _cacheRoles: acls forUser: uid forObjectAtPath: objectPath];
+ }
+
+ if (!([acls count] || [uid isEqualToString: defaultUser]))
+ acls = [self aclsForUser: defaultUser forObjectAtPath: objectPathArray];
+
+ return acls;
+}
+
+- (void) removeAclsForUsers: (NSArray *) users
+ forObjectAtPath: (NSArray *) objectPathArray
+{
+ EOQualifier *qualifier;
+ NSString *uids, *qs, *objectPath;
+ NSMutableDictionary *aclsForObject;
+
+ if ([users count] > 0)
+ {
+ objectPath = [objectPathArray componentsJoinedByString: @"/"];
+ aclsForObject = [aclCache objectForKey: objectPath];
+ if (aclsForObject)
+ [aclsForObject removeObjectsForKeys: users];
+ uids = [users componentsJoinedByString: @"') OR (c_uid = '"];
+ qs = [NSString
+ stringWithFormat: @"(c_object = '/%@') AND ((c_uid = '%@'))",
+ objectPath, uids];
+ qualifier = [EOQualifier qualifierWithQualifierFormat: qs];
+ [[self ocsFolder] deleteAclMatchingQualifier: qualifier];
+ }
+}
+
+- (void) setRoles: (NSArray *) roles
+ forUser: (NSString *) uid
+ forObjectAtPath: (NSArray *) objectPathArray
+{
+ EOAdaptorChannel *channel;
+ GCSFolder *folder;
+ NSEnumerator *userRoles;
+ NSString *SQL, *currentRole, *objectPath;
+
+ [self removeAclsForUsers: [NSArray arrayWithObject: uid]
+ forObjectAtPath: objectPathArray];
+ objectPath = [objectPathArray componentsJoinedByString: @"/"];
+ [self _cacheRoles: roles forUser: uid forObjectAtPath: objectPath];
+
+ folder = [self ocsFolder];
+ channel = [folder acquireAclChannel];
+ userRoles = [roles objectEnumerator];
+ currentRole = [userRoles nextObject];
+ while (currentRole)
+ {
+ if (![currentRole isEqualToString: SOGoRole_AuthorizedSubscriber])
+ {
+ SQL = [NSString stringWithFormat: @"INSERT INTO %@"
+ @" (c_object, c_uid, c_role)"
+ @" VALUES ('/%@', '%@', '%@')",
+ [folder aclTableName],
+ objectPath, uid, currentRole];
+ [channel evaluateExpressionX: SQL];
+ }
+ currentRole = [userRoles nextObject];
+ }
+
+ [folder releaseChannel: channel];
+}
+
+/* acls */
+- (NSArray *) defaultAclRoles
+{
+#warning this should be changed to something useful
+ return nil;
+}
+
+- (NSArray *) acls
+{
+ return [self aclsForObjectAtPath: [self pathArrayToSoObject]];
+}
+
+- (NSArray *) aclsForUser: (NSString *) uid
+{
+ return [self aclsForUser: uid
+ forObjectAtPath: [self pathArrayToSoObject]];
+}
+
+- (void) setRoles: (NSArray *) roles
+ forUser: (NSString *) uid
+{
+ return [self setRoles: roles
+ forUser: uid
+ forObjectAtPath: [self pathArrayToSoObject]];
+}
+
+- (void) removeAclsForUsers: (NSArray *) users
+{
+ return [self removeAclsForUsers: users
+ forObjectAtPath: [self pathArrayToSoObject]];
+}
+
/* WebDAV */
-- (BOOL)davIsCollection {
+- (BOOL) davIsCollection
+{
return [self isFolderish];
}
- (NSException *)matchesRequestConditionInContext:(id)_ctx;
+/* acls */
+
+- (NSArray *) defaultAclRoles;
+- (NSArray *) acls;
+- (NSArray *) aclsForUser: (NSString *) uid;
+- (void) setRoles: (NSArray *) roles
+ forUser: (NSString *) uid;
+- (void) removeAclsForUsers: (NSArray *) users;
+
/* description */
-- (void)appendAttributesToDescription:(NSMutableString *)_ms;
+- (void) appendAttributesToDescription:(NSMutableString *)_ms;
@end
#import <NGObjWeb/WORequest.h>
#import <NGObjWeb/WOApplication.h>
#import <NGCards/NSDictionary+NGCards.h>
+#import <GDLContentStore/GCSFolder.h>
#import "common.h"
#import "SOGoPermissions.h"
#import "SOGoUser.h"
-#import "SOGoAclsFolder.h"
#import "SOGoAuthenticator.h"
#import "SOGoUserFolder.h"
kontactGroupDAV =
[ud boolForKey:@"SOGoDisableKontact34GroupDAVHack"] ? NO : YES;
- /* SoClass security declarations */
+// SoClass security declarations
- /* require View permission to access the root (bound to authenticated ...) */
+// require View permission to access the root (bound to authenticated ...)
[[self soClassSecurityInfo] declareObjectProtected: SoPerm_View];
- /* to allow public access to all contained objects (subkeys) */
+// to allow public access to all contained objects (subkeys)
[[self soClassSecurityInfo] setDefaultAccess: @"allow"];
- /* require Authenticated role for View and WebDAV */
- [[self soClassSecurityInfo] declareRole: SoRole_Owner
- asDefaultForPermission: SoPerm_View];
- [[self soClassSecurityInfo] declareRole: SoRole_Owner
- asDefaultForPermission: SoPerm_WebDAVAccess];
+// /* require Authenticated role for View and WebDAV */
+// [[self soClassSecurityInfo] declareRole: SoRole_Owner
+// asDefaultForPermission: SoPerm_View];
+// [[self soClassSecurityInfo] declareRole: SoRole_Owner
+// asDefaultForPermission: SoPerm_WebDAVAccess];
}
+ (void) _fillDictionary: (NSMutableDictionary *) dictionary
NSDictionary *currentAcl;
SoClassSecurityInfo *sInfo;
- acls = [[[SOGoAclsFolder aclsFolder] aclsForObject: self] objectEnumerator];
+ acls = [[self acls] objectEnumerator];
aclsDictionary = [NSMutableDictionary dictionary];
sInfo = [[self class] soClassSecurityInfo];
}
- (id)initWithName:(NSString *)_name inContainer:(id)_container {
- if ((self = [super init])) {
- context = [[WOApplication application] context];
- [context retain];
- nameInContainer = [_name copy];
- container =
- [self doesRetainContainer] ? [_container retain] : _container;
- customOwner = nil;
- }
+ if ((self = [self init]))
+ {
+ context = [[WOApplication application] context];
+ [context retain];
+ nameInContainer = [_name copy];
+ container =
+ [self doesRetainContainer] ? [_container retain] : _container;
+ customOwner = nil;
+ }
+
return self;
}
-- (id)init {
- return [self initWithName:nil inContainer:nil];
+- (id) init
+{
+ if ((self = [super init]))
+ {
+ nameInContainer = nil;
+ container = nil;
+ }
+
+ return self;
}
- (void)dealloc {
return nil;
}
+/* acls */
+
+- (NSArray *) acls
+{
+ [self subclassResponsibility: _cmd];
+
+ return nil;
+}
+
+- (NSArray *) aclsForUser: (NSString *) uid
+{
+ [self subclassResponsibility: _cmd];
+
+ return nil;
+}
+
+- (NSArray *) defaultAclRoles
+{
+ [self subclassResponsibility: _cmd];
+
+ return nil;
+}
+
+- (void) setRoles: (NSArray *) roles
+ forUser: (NSString *) uid
+{
+ [self subclassResponsibility: _cmd];
+}
+
+- (void) removeAclsForUsers: (NSArray *) users
+{
+ [self subclassResponsibility: _cmd];
+}
+
/* description */
- (void)appendAttributesToDescription:(NSMutableString *)_ms {
#import <NGObjWeb/SoPermissions.h>
-extern NSString *SOGoRole_Assistant;
-extern NSString *SOGoRole_Delegate;
-extern NSString *SOGoRole_FreeBusyLookup;
+extern NSString *SOGoRole_ObjectCreator;
+extern NSString *SOGoRole_ObjectEraser;
+extern NSString *SOGoRole_ObjectViewer;
+extern NSString *SOGoRole_ObjectEditor;
+extern NSString *SOGoRole_AuthorizedSubscriber;
+
extern NSString *SOGoRole_FreeBusy;
+extern NSString *SOGoRole_FreeBusyLookup;
extern NSString *SOGoPerm_ReadAcls;
-extern NSString *SOGoPerm_CreateAndModifyAcls;
extern NSString *SOGoPerm_FreeBusyLookup;
-extern NSString *SOGoRole_Organizer;
-extern NSString *SOGoRole_Participant;
+extern NSString *SOGoCalendarRole_Organizer;
+extern NSString *SOGoCalendarRole_Participant;
+
+extern NSString *SOGoCalendarRole_PublicViewer;
+extern NSString *SOGoCalendarRole_PublicDAndTViewer;
+extern NSString *SOGoCalendarRole_PublicModifier;
+extern NSString *SOGoCalendarRole_PublicResponder;
+extern NSString *SOGoCalendarRole_PrivateViewer;
+extern NSString *SOGoCalendarRole_PrivateDAndTViewer;
+extern NSString *SOGoCalendarRole_PrivateModifier;
+extern NSString *SOGoCalendarRole_PrivateResponder;
+extern NSString *SOGoCalendarRole_ConfidentialViewer;
+extern NSString *SOGoCalendarRole_ConfidentialDAndTViewer;
+extern NSString *SOGoCalendarRole_ConfidentialModifier;
+extern NSString *SOGoCalendarRole_ConfidentialResponder;
+
+extern NSString *SOGoCalendarRole_ComponentViewer;
+extern NSString *SOGoCalendarRole_ComponentDAndTViewer;
+extern NSString *SOGoCalendarRole_ComponentModifier;
+extern NSString *SOGoCalendarRole_ComponentResponder;
+
+extern NSString *SOGoCalendarPerm_ViewWholePublicRecords;
+extern NSString *SOGoCalendarPerm_ViewDAndTOfPublicRecords;
+extern NSString *SOGoCalendarPerm_ModifyPublicRecords;
+extern NSString *SOGoCalendarPerm_RespondToPublicRecords;
+extern NSString *SOGoCalendarPerm_ViewWholePrivateRecords;
+extern NSString *SOGoCalendarPerm_ViewDAndTOfPrivateRecords;
+extern NSString *SOGoCalendarPerm_ModifyPrivateRecords;
+extern NSString *SOGoCalendarPerm_RespondToPrivateRecords;
+extern NSString *SOGoCalendarPerm_ViewWholeConfidentialRecords;
+extern NSString *SOGoCalendarPerm_ViewDAndTOfConfidentialRecords;
+extern NSString *SOGoCalendarPerm_ModifyConfidentialRecords;
+extern NSString *SOGoCalendarPerm_RespondToConfidentialRecords;
+
+extern NSString *SOGoCalendarPerm_ViewAllComponent;
+extern NSString *SOGoCalendarPerm_ViewDAndT;
+extern NSString *SOGoCalendarPerm_ModifyComponent;
+extern NSString *SOGoCalendarPerm_RespondToComponent;
#endif /* SOGOPERMISSIONS_H */
#import "SOGoPermissions.h"
-NSString *SOGoRole_Assistant = @"Assistant"; /* a colleague */
-NSString *SOGoRole_Delegate = @"Delegate"; /* a colleague or person that I
- trust in adding or modifying my
- data */
+/* General */
+NSString *SOGoRole_ObjectCreator = @"ObjectCreator";
+NSString *SOGoRole_ObjectEraser = @"ObjectEraser";
+NSString *SOGoRole_ObjectViewer = @"ObjectViewer";
+NSString *SOGoRole_ObjectEditor = @"ObjectEditor";
+NSString *SOGoRole_AuthorizedSubscriber = @"AuthorizedSubscriber";
+
+NSString *SOGoRole_FreeBusy = @"FreeBusy"; /* for the "freebusy" special user
+ */
NSString *SOGoRole_FreeBusyLookup = @"FreeBusyLookup"; /* for users that have
access to the
freebusy information
from a specific
calendar */
-NSString *SOGoRole_FreeBusy = @"FreeBusy"; /* for the "freebusy" special user
- */
/* Calendar */
-NSString *SOGoRole_Organizer = @"Organizer";
-NSString *SOGoRole_Participant = @"Participant";
+NSString *SOGoCalendarRole_Organizer = @"Organizer";
+NSString *SOGoCalendarRole_Participant = @"Participant";
-#warning ReadAcls still not used...
+NSString *SOGoCalendarRole_PublicViewer = @"PublicViewer";
+NSString *SOGoCalendarRole_PublicDAndTViewer = @"PublicDAndTViewer";
+NSString *SOGoCalendarRole_PublicModifier = @"PublicModifier";
+NSString *SOGoCalendarRole_PublicResponder = @"PublicResponder";
+NSString *SOGoCalendarRole_PrivateViewer = @"PrivateViewer";
+NSString *SOGoCalendarRole_PrivateDAndTViewer = @"PrivateDAndTViewer";
+NSString *SOGoCalendarRole_PrivateModifier = @"PrivateModifier";
+NSString *SOGoCalendarRole_PrivateResponder = @"PrivateResponder";
+NSString *SOGoCalendarRole_ConfidentialViewer = @"ConfidentialViewer";
+NSString *SOGoCalendarRole_ConfidentialDAndTViewer = @"ConfidentialDAndTViewer";
+NSString *SOGoCalendarRole_ConfidentialModifier = @"ConfidentialModifier";
+NSString *SOGoCalendarRole_ConfidentialResponder = @"ConfidentialResponder";
+
+NSString *SOGoCalendarRole_ComponentViewer = @"ComponentViewer";
+NSString *SOGoCalendarRole_ComponentDAndTViewer = @"ComponentDAndTViewer";
+NSString *SOGoCalendarRole_ComponentModifier = @"ComponentModifier";
+NSString *SOGoCalendarRole_ComponentResponder = @"ComponentResponder";
+
+/* permissions */
NSString *SOGoPerm_ReadAcls = @"ReadAcls"; /* the equivalent of "read-acl" in
the WebDAV acls spec, which is
currently missing from SOPE */
-NSString *SOGoPerm_CreateAndModifyAcls = @"CreateAndModifyAcls";
NSString *SOGoPerm_FreeBusyLookup = @"FreeBusyLookup";
+
+NSString *SOGoCalendarPerm_ViewWholePublicRecords = @"ViewWholePublicRecords";
+NSString *SOGoCalendarPerm_ViewDAndTOfPublicRecords = @"ViewDAndTOfPublicRecords";
+NSString *SOGoCalendarPerm_ModifyPublicRecords = @"ModifyPublicRecords";
+NSString *SOGoCalendarPerm_RespondToPublicRecords = @"RespondToPublicRecords";
+NSString *SOGoCalendarPerm_ViewWholePrivateRecords = @"ViewWholePrivateRecords";
+NSString *SOGoCalendarPerm_ViewDAndTOfPrivateRecords = @"ViewDAndTOfPrivateRecords";
+NSString *SOGoCalendarPerm_ModifyPrivateRecords = @"ModifyPrivateRecords";
+NSString *SOGoCalendarPerm_RespondToPrivateRecords = @"RespondToPrivateRecords";
+NSString *SOGoCalendarPerm_ViewWholeConfidentialRecords = @"ViewWholeConfidentialRecords";
+NSString *SOGoCalendarPerm_ViewDAndTOfConfidentialRecords = @"ViewDAndTOfConfidentialRecords";
+NSString *SOGoCalendarPerm_ModifyConfidentialRecords = @"ModifyConfidentialRecords";
+NSString *SOGoCalendarPerm_RespondToConfidentialRecords = @"RespondToConfidentialRecords";
+
+NSString *SOGoCalendarPerm_ViewAllComponent = @"ViewAllComponent";
+NSString *SOGoCalendarPerm_ViewDAndT = @"ViewDAndT";
+NSString *SOGoCalendarPerm_ModifyComponent = @"ModifyComponent";
+NSString *SOGoCalendarPerm_RespondToComponent = @"RespondToComponent";
02111-1307, USA.
*/
+#import <Foundation/NSArray.h>
+#import <Foundation/NSNull.h>
+#import <Foundation/NSTimeZone.h>
+#import <Foundation/NSUserDefaults.h>
+#import <NGObjWeb/WOApplication.h>
#import <NGObjWeb/SoObject.h>
-#import "AgenorUserManager.h"
-#import "SOGoAclsFolder.h"
-#import "common.h"
+#import <NGExtensions/NSNull+misc.h>
+#import "AgenorUserManager.h"
+#import "SOGoContentObject.h"
#import "SOGoUser.h"
+#import "SOGoPermissions.h"
static NSTimeZone *serverTimeZone = nil;
@interface NSObject (SOGoRoles)
-- (NSString *) roleOfUser: (NSString *) uid;
- (NSArray *) rolesOfUser: (NSString *) uid;
@end
timeZoneName = [[self userDefaults] stringForKey: @"TimeZone"];
if ([timeZoneName length] > 0)
userTimeZone = [NSTimeZone timeZoneWithName: timeZoneName];
- else
- userTimeZone = nil;
if (!userTimeZone)
- userTimeZone = [self serverTimeZone];
+ userTimeZone = serverTimeZone;
[userTimeZone retain];
}
inContext: (WOContext *) context
{
NSMutableArray *rolesForObject;
- SOGoAclsFolder *aclsFolder;
NSArray *sogoRoles;
- NSString *role;
rolesForObject = [NSMutableArray new];
[rolesForObject autorelease];
[rolesForObject addObject: SoRole_Owner];
if ([object isKindOfClass: [SOGoObject class]])
{
- aclsFolder = [SOGoAclsFolder aclsFolder];
- sogoRoles = [aclsFolder aclsForObject: (SOGoObject *) object
- forUser: login];
- if (sogoRoles)
- [rolesForObject addObjectsFromArray: sogoRoles];
- }
- if ([object respondsToSelector: @selector (rolesOfUser:)])
- {
- sogoRoles = [object rolesOfUser: login];
+ sogoRoles = [(SOGoObject *) object aclsForUser: login];
if (sogoRoles)
[rolesForObject addObjectsFromArray: sogoRoles];
}
- if ([object respondsToSelector: @selector (roleOfUser:)])
- {
- role = [object roleOfUser: login];
- if (role)
- [rolesForObject addObject: role];
- }
return rolesForObject;
}
"noJavascriptRetry" = "Retry";
"Publish the Free/Busy information" = "Publish the Free/Busy information";
+
+"Sorry, the user rights can not be configured for that object." = "Sorry, the user rights can not be configured for that object.";
"Associated Users:" = "Utilisateurs associés :";
"(Unchecked = assistant, checked = delegate)" = "(Coché = assistant, décoché = délégué)";
"Publish the Free/Busy information" = "Publier l'occupation du temps";
+
+"Sorry, the user rights can not be configured for that object." = "Sorry, the user rights can not be configured for that object.";
UIxAppNavView.m \
\
UIxAclEditor.m \
+ UIxObjectActions.m \
UIxFolderActions.m \
UIxElemBuilder.m \
UIxTabView.m \
UIxTabItem.m \
+ UIxUserRightsEditor.m \
\
UIxSortableTableHeader.m \
\
isSafe = NO;
label = "Close";
onclick = "window.close();";
- image = "tb-mail-stop-flat-24x24.png"; } )
+ image = "tb-mail-stop-flat-24x24.png"; } ),
+ ( { link = "#";
+ isSafe = NO;
+ label = "Edit User Rights";
+ onclick = "return openRightsForUser();";
+ image = "edit.png"; } ),
)
/* UIxAclEditor.h - this file is part of SOGo
*
- * Copyright (C) 2006 Inverse groupe conseil
+ * Copyright (C) 2006, 2007 Inverse groupe conseil
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
BOOL prepared;
BOOL publishInFreeBusy;
NSArray *acls;
+ NSArray *savedUIDs;
NSMutableArray *users;
- NSMutableArray *assistants;
- NSMutableArray *delegates;
NSString *currentUser;
- NSString *ownerLogin;
}
-- (NSArray *) aclsForFolder;
-- (NSString *) assistantsValue;
-- (NSString *) delegatesValue;
+- (NSArray *) aclsForObject;
-- (NSArray *) usersForFolder;
+- (NSArray *) usersForObject;
- (void) setCurrentUser: (NSString *) newCurrentUser;
- (NSString *) currentUser;
-- (NSString *) ownerLogin;
- (NSString *) ownerName;
@end
/* UIxAclEditor.m - this file is part of SOGo
*
- * Copyright (C) 2006 Inverse groupe conseil
+ * Copyright (C) 2006, 2007 Inverse groupe conseil
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
#import <NGObjWeb/WORequest.h>
#import <NGCards/iCalPerson.h>
#import <SoObjects/SOGo/AgenorUserManager.h>
-#import <SoObjects/SOGo/SOGoAclsFolder.h>
+#import <SoObjects/SOGo/SOGoContentObject.h>
#import <SoObjects/SOGo/SOGoPermissions.h>
#import "UIxAclEditor.h"
prepared = NO;
publishInFreeBusy = NO;
users = [NSMutableArray new];
- delegates = [NSMutableArray new];
- assistants = [NSMutableArray new];
- ownerLogin = nil;
currentUser = nil;
+ savedUIDs = nil;
}
return self;
- (void) dealloc
{
+ [savedUIDs release];
[users release];
- [delegates release];
- [assistants release];
- [ownerLogin release];
[currentUser release];
[super dealloc];
}
-- (NSArray *) aclsForFolder
+- (NSArray *) aclsForObject
{
- SOGoAclsFolder *folder;
-
if (!acls)
- {
- folder = [SOGoAclsFolder aclsFolder];
- acls = [folder aclsForObject: [self clientObject]];
- }
+ acls = [[self clientObject] acls];
return acls;
}
-- (NSString *) ownerLogin
-{
- if (!ownerLogin)
- {
- ownerLogin = [[self clientObject] ownerInContext: context];
- [ownerLogin retain];
- }
-
- return ownerLogin;
-}
-
- (NSString *) _displayNameForUID: (NSString *) uid
{
AgenorUserManager *um;
- (NSString *) ownerName
{
- return [self _displayNameForUID: [self ownerLogin]];
+ NSString *ownerLogin;
+
+ ownerLogin = [[self clientObject] ownerInContext: context];
+
+ return [self _displayNameForUID: ownerLogin];
}
- (void) _prepareUsers
{
NSEnumerator *aclsEnum;
- AgenorUserManager *um;
NSDictionary *currentAcl;
- NSString *currentUID;
+ NSString *currentUID, *ownerLogin;
- aclsEnum = [[self aclsForFolder] objectEnumerator];
- um = [AgenorUserManager sharedUserManager];
+ ownerLogin = [[self clientObject] ownerInContext: context];
+
+ aclsEnum = [[self aclsForObject] objectEnumerator];
currentAcl = [aclsEnum nextObject];
while (currentAcl)
{
currentUID = [currentAcl objectForKey: @"c_uid"];
- if ([currentUID isEqualToString: @"freebusy"])
- publishInFreeBusy = YES;
- else
- {
- if (![[um getCNForUID: currentUID]
- isEqualToString: [self ownerLogin]])
- {
- if ([[currentAcl objectForKey: @"c_role"]
- isEqualToString: SOGoRole_Delegate])
- [delegates addObject: currentUID];
- else
- [assistants addObject: currentUID];
- [users addObject: currentUID];
- }
- }
+ if (!([currentUID isEqualToString: ownerLogin]
+ || [users containsObject: currentUID]))
+ [users addObject: currentUID];
currentAcl = [aclsEnum nextObject];
prepared = YES;
}
}
-- (NSArray *) usersForFolder
+- (NSArray *) usersForObject
{
if (!prepared)
[self _prepareUsers];
return [self _displayNameForUID: currentUser];
}
-- (NSArray *) delegates
-{
- if (!prepared)
- [self _prepareUsers];
-
- return delegates;
-}
-
-- (NSString *) assistantsValue
-{
- if (!prepared)
- [self _prepareUsers];
-
- return [assistants componentsJoinedByString: @","];
-}
-
-- (NSString *) delegatesValue
-{
- if (!prepared)
- [self _prepareUsers];
-
- return [delegates componentsJoinedByString: @","];
-}
-
-- (BOOL) publishInFreeBusy
-{
- if (!prepared)
- [self _prepareUsers];
-
- return publishInFreeBusy;
-}
-
- (NSString *) toolbar
{
- NSString *currentLogin;
+ NSString *currentLogin, *ownerLogin;
currentLogin = [[context activeUser] login];
+ ownerLogin = [[self clientObject] ownerInContext: context];
- return (([[self ownerLogin] isEqualToString: currentLogin])
+ return (([ownerLogin isEqualToString: currentLogin])
? @"SOGoAclOwner.toolbar" : @"SOGoAclAssistant.toolbar");
}
-- (BOOL) clientIsCalendar
+- (void) setUserUIDS: (NSString *) retainedUsers
+{
+ if ([retainedUsers length] > 0)
+ savedUIDs = [retainedUsers componentsSeparatedByString: @","];
+ else
+ savedUIDs = [NSArray new];
+}
+
+- (BOOL) shouldTakeValuesFromRequest: (WORequest *) request
+ inContext: (WOContext *) context
{
- return [NSStringFromClass ([[self clientObject] class])
- isEqualToString: @"SOGoAppointmentFolder"];
+ return ([[request method] isEqualToString: @"POST"]);
}
-- (id) saveAclsAction
+- (id <WOActionResults>) saveAclsAction
{
- NSString *uids;
- NSArray *fbUsers;
- WORequest *request;
- SOGoAclsFolder *folder;
+ NSEnumerator *aclsEnum;
SOGoObject *clientObject;
+ NSString *currentUID, *ownerLogin;
- folder = [SOGoAclsFolder aclsFolder];
- request = [context request];
clientObject = [self clientObject];
- uids = [request formValueForKey: @"delegates"];
- [folder setRoleForObject: clientObject
- forUsers: [uids componentsSeparatedByString: @","]
- to: SOGoRole_Delegate];
- uids = [request formValueForKey: @"assistants"];
- [folder setRoleForObject: clientObject
- forUsers: [uids componentsSeparatedByString: @","]
- to: SOGoRole_Assistant];
- if ([self clientIsCalendar]) {
- if ([[request formValueForKey: @"freebusy"] intValue])
- fbUsers = [NSArray arrayWithObject: @"freebusy"];
- else
- fbUsers = nil;
- [folder setRoleForObject: clientObject
- forUsers: fbUsers
- to: SOGoRole_FreeBusy];
- }
+ ownerLogin = [clientObject ownerInContext: context];
+ aclsEnum = [[self aclsForObject] objectEnumerator];
+ currentUID = [[aclsEnum nextObject] objectForKey: @"c_uid"];
+ while (currentUID)
+ {
+ if ([currentUID isEqualToString: ownerLogin]
+ || [savedUIDs containsObject: currentUID])
+ [users removeObject: currentUID];
+ currentUID = [[aclsEnum nextObject] objectForKey: @"c_uid"];
+ }
+ [clientObject removeAclsForUsers: users];
return [self jsCloseWithRefreshMethod: nil];
}
+// - (id <WOActionResults>) addUserInAcls
+// {
+// SOGoObject *clientObject;
+// NSString *uid;
+
+// uid = [self queryParameterForKey: @"uid"];
+
+// clientObject = [self clientObject];
+// }
+
@end
#import <NGObjWeb/WOContext.h>
#import <NGObjWeb/WOContext+SoObjects.h>
+#import <NGObjWeb/WORequest.h>
#import <NGObjWeb/WOResponse.h>
#import <NGObjWeb/SoSecurityManager.h>
-/* SOGoAclsFolder.h - this file is part of SOGo
+/* UIxObjectActions.h - this file is part of SOGo
*
- * Copyright (C) 2006 Inverse groupe conseil
+ * Copyright (C) 2007 Inverse groupe conseil
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* Boston, MA 02111-1307, USA.
*/
-#ifndef SOGOACLSFOLDER_H
-#define SOGOACLSFOLDER_H
+#ifndef UIXOBJECTACTIONS_H
+#define UIXOBJECTACTIONS_H
-#import <Foundation/NSObject.h>
+#import <NGObjWeb/WODirectAction.h>
-@class NSString;
-@class GCSFolder;
-@class SOGoObject;
+@class WOResponse;
-@interface SOGoAclsFolder : NSObject
-{
- NSString *ocsPath;
- GCSFolder *ocsFolder;
-}
+@interface UIxObjectActions : WODirectAction
-+ (id) aclsFolder;
-
-- (NSArray *) aclsForObject: (SOGoObject *) object;
-- (NSArray *) aclsForObject: (SOGoObject *) object
- forUser: (NSString *) uid;
-- (void) setRoleForObject: (SOGoObject *) object
- forUsers: (NSArray *) uids
- to: (NSString *) role;
+- (WOResponse *) addUserInAclsAction;
@end
-#endif /* SOGOACLSOBJECT_H */
+#endif /* UIXOBJECTACTIONS_H */
--- /dev/null
+/* UIxObjectActions.m - this file is part of SOGo
+ *
+ * Copyright (C) 2007 Inverse groupe conseil
+ *
+ * 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.
+ */
+
+#import <Foundation/NSString.h>
+#import <Foundation/NSArray.h>
+#import <NGObjWeb/WOContext+SoObjects.h>
+#import <NGObjWeb/WORequest.h>
+#import <NGObjWeb/WOResponse.h>
+#import <SoObjects/SOGo/AgenorUserManager.h>
+#import <SoObjects/SOGo/SOGoObject.h>
+
+#import "UIxObjectActions.h"
+
+@implementation UIxObjectActions
+
+- (WOResponse *) addUserInAclsAction
+{
+ WOResponse *response;
+ WORequest *request;
+ NSString *uid, *email;
+ unsigned int code;
+ AgenorUserManager *um;
+ SOGoObject *clientObject;
+
+ code = 403;
+ request = [context request];
+ uid = [request formValueForKey: @"uid"];
+ if ([uid length] > 0)
+ {
+ um = [AgenorUserManager sharedUserManager];
+ email = [um getEmailForUID: uid];
+ if ([email length] > 0)
+ {
+ clientObject = [self clientObject];
+ [clientObject setRoles: [clientObject defaultAclRoles]
+ forUser: uid];
+ code = 204;
+ }
+ }
+
+ response = [context response];
+ [response setStatus: code];
+
+ return response;
+}
+
+@end
--- /dev/null
+/* UIxUserRightsEditor.h - this file is part of SOGo
+ *
+ * Copyright (C) 2007 Inverse groupe conseil
+ *
+ * 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.
+ */
+
+#ifndef UIXUSERRIGHTSEDITOR_H
+#define UIXUSERRIGHTSEDITOR_H
+
+#import <SOGoUI/UIxComponent.h>
+
+@class NSMutableArray;
+@class NSString;
+
+@protocol WOActionResults;
+
+@interface UIxUserRightsEditor : UIxComponent
+{
+ NSMutableArray *userRights;
+ NSString *uid;
+}
+
+- (NSString *) userDisplayName;
+- (NSString *) uid;
+
+- (void) appendRight: (NSString *) newRight;
+- (void) appendExclusiveRight: (NSString *) newRight
+ fromList: (NSArray *) list;
+- (void) removeRight: (NSString *) right;
+- (void) removeAllRightsFromList: (NSArray *) list;
+
+- (void) prepareRightsForm;
+- (void) updateRights;
+
+@end
+
+#endif /* UIXUSERRIGHTSEDITOR_H */
--- /dev/null
+/* UIxUserRightsEditor.m - this file is part of SOGo
+ *
+ * Copyright (C) 2007 Inverse groupe conseil
+ *
+ * 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.
+ */
+
+#import <NGObjWeb/NSException+HTTP.h>
+#import <NGObjWeb/WOResponse.h>
+#import <NGObjWeb/WORequest.h>
+#import <SoObjects/SOGo/AgenorUserManager.h>
+
+#import "UIxUserRightsEditor.h"
+
+@implementation UIxUserRightsEditor
+
+- (id) init
+{
+ if ((self = [super init]))
+ {
+ uid = nil;
+ userRights = [NSMutableArray new];
+ }
+
+ return self;
+}
+
+- (void) dealloc
+{
+ [uid release];
+ [userRights release];
+ [super dealloc];
+}
+
+- (NSString *) uid
+{
+ return uid;
+}
+
+- (NSString *) userDisplayName
+{
+ AgenorUserManager *um;
+
+ um = [AgenorUserManager sharedUserManager];
+
+ return [NSString stringWithFormat: @"%@ <%@>",
+ [um getCNForUID: uid],
+ [um getEmailForUID: uid]];
+}
+
+- (BOOL) _initRights
+{
+ BOOL response;
+ NSString *newUID, *email;
+ AgenorUserManager *um;
+ SOGoObject *clientObject;
+
+ response = NO;
+
+ newUID = [[context request] formValueForKey: @"uid"];
+ if ([newUID length] > 0)
+ {
+ um = [AgenorUserManager sharedUserManager];
+ email = [um getEmailForUID: newUID];
+ if ([email length] > 0)
+ {
+ ASSIGN (uid, newUID);
+ clientObject = [self clientObject];
+ [userRights addObjectsFromArray: [clientObject aclsForUser: uid]];
+ if (![userRights count])
+ [userRights addObjectsFromArray: [clientObject defaultAclRoles]];
+
+ response = YES;
+ }
+ }
+
+ return response;
+}
+
+- (id <WOActionResults>) defaultAction
+{
+ id <WOActionResults> response;
+
+ if (![self _initRights])
+ response = [NSException exceptionWithHTTPStatus: 403
+ reason: @"No such user."];
+ else
+ {
+ [self prepareRightsForm];
+ response = self;
+ }
+
+ return response;
+}
+
+- (id <WOActionResults>) saveUserRightsAction
+{
+ id <WOActionResults> response;
+
+ if (![self _initRights])
+ response = [NSException exceptionWithHTTPStatus: 403
+ reason: @"No such user."];
+ else
+ {
+ [self updateRights];
+ [[self clientObject] setRoles: userRights
+ forUser: uid];
+ response = [self jsCloseWithRefreshMethod: nil];
+ }
+
+ return response;
+}
+
+- (void) appendRight: (NSString *) newRight
+{
+ if (![userRights containsObject: newRight])
+ [userRights addObject: newRight];
+}
+
+- (void) removeRight: (NSString *) right
+{
+ if ([userRights containsObject: right])
+ [userRights removeObject: right];
+}
+
+- (void) appendExclusiveRight: (NSString *) newRight
+ fromList: (NSArray *) list
+{
+ [userRights removeObjectsInArray: list];
+ [self appendRight: newRight];
+}
+
+- (void) removeAllRightsFromList: (NSArray *) list
+{
+ [userRights removeObjectsInArray: list];
+}
+
+- (void) prepareRightsForm
+{
+}
+
+- (void) updateRights
+{
+ [self subclassResponsibility: _cmd];
+}
+
+@end
};
categories = {
+ SOGoObject = {
+ methods = {
+ addUserInAcls = {
+ protectedBy = "SaveAcls";
+ actionClass = "UIxObjectActions";
+ actionName = "addUserInAcls";
+ };
+ acls = {
+ protectedBy = "ReadAcls";
+ pageName = "UIxAclEditor";
+ };
+ saveAcls = {
+ protectedBy = "SaveAcls";
+ pageName = "UIxAclEditor";
+ actionName = "saveAcls";
+ };
+ userRights = {
+ protectedBy = "ReadAcls";
+ pageName = "UIxUserRightsEditor";
+ };
+ saveUserRights = {
+ protectedBy = "ReadAcls";
+ pageName = "UIxUserRightsEditor";
+ actionName = "saveUserRights";
+ };
+ };
+ };
SOGoFolder = {
methods = {
subscribe = {
- protectedBy = "View";
+ protectedBy = "<public>";
actionClass = "UIxFolderActions";
actionName = "subscribe";
};
unsubscribe = {
- protectedBy = "View";
+ protectedBy = "<public>";
actionClass = "UIxFolderActions";
actionName = "unsubscribe";
};
canAccessContent = {
- protectedBy = "View";
+ protectedBy = "<public>";
actionClass = "UIxFolderActions";
actionName = "canAccessContent";
};
activateFolder = {
- protectedBy = "View";
+ protectedBy = "<public>";
actionClass = "UIxFolderActions";
actionName = "activateFolder";
};
deactivateFolder = {
- protectedBy = "View";
+ protectedBy = "<public>";
actionClass = "UIxFolderActions";
- actionName = "deactivateFolder";
+ actionName = "deactivateFolder";
};
- acls = {
- protectedBy = "ReadAcls";
- pageName = "UIxAclEditor";
- };
- saveAcls = {
- protectedBy = "SaveAcls";
- pageName = "UIxAclEditor";
- actionName = "saveAcls";
- };
};
};
};
"Addressbook" = "Addressbook";
"Addresses" = "Addresses";
+"Update" = "Update";
"Cancel" = "Cancel";
"Common" = "Common";
"Contact editor" = "Contact editor";
= "You cannot subscribe to a folder that you own!";
"Unable to subscribe to that folder!"
= "Unable to subscribe to that folder!";
+
+"User rights for:" = "User rights for:";
+
+"This person can add cards to this addressbook."
+= "This person can add cards to this addressbook.";
+"This person can edit the cards of this addressbook."
+= "This person can edit the cards of this addressbook.";
+"This person can view the cards of this addressbook."
+= "This person can view the cards of this addressbook.";
+"This person can erase cards from this addressbook."
+= "This person can erase cards from this addressbook.";
"Address Books" = "Carnet d'adresses";
"Addresses" = "Adresses";
+"Update" = "Mettre à jour";
"Cancel" = "Annuler";
"Common" = "Identité";
"Contact editor" = "Éditer le contact";
= "Vous ne pouvez pas vous inscrire à un dossier qui vous appartient!";
"Unable to subscribe to that folder!"
= "Impossible de vous inscrire à ce dossier!";
+
+"User rights for:" = "Autorisations pour :";
+
+"This person can add cards to this addressbook."
+= "Cette personne peut ajouter des fiches à ce carnet d'adresses.";
+"This person can edit the cards of this addressbook."
+= "Cette personne peut éditer des fiches de ce carnet d'adresses.";
+"This person can view the cards of this addressbook."
+= "Cette personne peut visionner des fiches de ce carnet d'adresses.";
+"This person can erase cards from this addressbook."
+= "Cette personne peut effacer des fiches de ce carnet d'adresses.";
ContactsUI_OBJC_FILES = \
UIxContactsUserFolders.m \
UIxContactsMailerSelection.m \
+ UIxContactsUserRightsEditor.m \
\
ContactsUIProduct.m \
UIxContactsFilterPanel.m \
--- /dev/null
+/* UIxContactsUserRightsEditor.h - this file is part of SOGo
+ *
+ * Copyright (C) 2007 Inverse groupe conseil
+ *
+ * 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.
+ */
+
+#ifndef UIXCONTACTSUSERRIGHTSEDITOR_H
+#define UIXCONTACTSUSERRIGHTSEDITOR_H
+
+#import <UI/Common/UIxUserRightsEditor.h>
+
+@interface UIxContactsUserRightsEditor : UIxUserRightsEditor
+
+- (void) setUserCanCreateObjects: (BOOL) userCanCreateObjects;
+- (BOOL) userCanCreateObjects;
+
+- (void) setUserCanEraseObjects: (BOOL) userCanEraseObjects;
+- (BOOL) userCanEraseObjects;
+
+- (void) setUserCanEditObjects: (BOOL) userCanEditObjects;
+- (BOOL) userCanEditObjects;
+
+- (void) setUserCanViewObjects: (BOOL) userCanViewObjects;
+- (BOOL) userCanViewObjects;
+
+- (void) updateRights;
+
+@end
+
+#endif /* UIXCONTACTSUSERRIGHTSEDITOR_H */
--- /dev/null
+/* UIxContactsUserRightsEditor.m - this file is part of SOGo
+ *
+ * Copyright (C) 2007 Inverse groupe conseil
+ *
+ * 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.
+ */
+
+#import <Foundation/NSArray.h>
+#import <Foundation/NSEnumerator.h>
+#import <NGObjWeb/WORequest.h>
+#import <SoObjects/SOGo/SOGoPermissions.h>
+
+#import "UIxContactsUserRightsEditor.h"
+
+@implementation UIxContactsUserRightsEditor
+
+- (void) setUserCanCreateObjects: (BOOL) userCanCreateObjects
+{
+ if (userCanCreateObjects)
+ [self appendRight: SOGoRole_ObjectCreator];
+ else
+ [self removeRight: SOGoRole_ObjectCreator];
+}
+
+- (BOOL) userCanCreateObjects
+{
+ return [userRights containsObject: SOGoRole_ObjectCreator];
+}
+
+- (void) setUserCanEraseObjects: (BOOL) userCanEraseObjects
+{
+ if (userCanEraseObjects)
+ [self appendRight: SOGoRole_ObjectEraser];
+ else
+ [self removeRight: SOGoRole_ObjectEraser];
+}
+
+- (BOOL) userCanEraseObjects
+{
+ return [userRights containsObject: SOGoRole_ObjectEraser];
+}
+
+- (void) setUserCanEditObjects: (BOOL) userCanEditObjects
+{
+ if (userCanEditObjects)
+ [self appendRight: SOGoRole_ObjectEditor];
+ else
+ [self removeRight: SOGoRole_ObjectEditor];
+}
+
+- (BOOL) userCanEditObjects
+{
+ return [userRights containsObject: SOGoRole_ObjectEditor];
+}
+
+- (void) setUserCanViewObjects: (BOOL) userCanViewObjects
+{
+ if (userCanViewObjects)
+ [self appendRight: SOGoRole_ObjectViewer];
+ else
+ [self removeRight: SOGoRole_ObjectViewer];
+}
+
+- (BOOL) userCanViewObjects
+{
+ return [userRights containsObject: SOGoRole_ObjectViewer];
+}
+
+- (void) updateRights
+{
+ WORequest *request;
+
+ request = [context request];
+
+ if ([[request formValueForKey: @"ObjectCreator"] length] > 0)
+ [self appendRight: SOGoRole_ObjectCreator];
+ else
+ [self removeRight: SOGoRole_ObjectCreator];
+
+ if ([[request formValueForKey: @"ObjectEditor"] length] > 0)
+ [self appendRight: SOGoRole_ObjectEditor];
+ else
+ [self removeRight: SOGoRole_ObjectEditor];
+
+ if ([[request formValueForKey: @"ObjectViewer"] length] > 0)
+ [self appendRight: SOGoRole_ObjectViewer];
+ else
+ [self removeRight: SOGoRole_ObjectViewer];
+
+ if ([[request formValueForKey: @"ObjectEraser"] length] > 0)
+ [self appendRight: SOGoRole_ObjectEraser];
+ else
+ [self removeRight: SOGoRole_ObjectEraser];
+}
+
+@end
pageName = "UIxContactsListView";
};
new = {
- protectedBy = "View";
+ protectedBy = "Add Documents, Images, and Files";
pageName = "UIxContactEditor";
actionName = "new";
};
actionName = "mailerContacts";
};
delete = {
- protectedBy = "View";
+ protectedBy = "SaveAcls"; /* a hack to force "owner" */
pageName = "UIxContactsListView";
actionName = "delete";
};
+ userRights = {
+ protectedBy = "ReadAcls";
+ pageName = "UIxContactsUserRightsEditor";
+ };
+ saveUserRights = {
+ protectedBy = "SaveAcls";
+ pageName = "UIxContactsUserRightsEditor";
+ actionName = "saveUserRights";
+ };
};
};
SOGoContactGCSEntry = {
methods = {
view = {
- protectedBy = "View";
+ protectedBy = "Access Contents Information";
pageName = "UIxContactView";
};
delete = {
- protectedBy = "View";
+ protectedBy = "Delete Objects";
pageName = "UIxContactView";
actionName = "delete";
};
edit = {
- protectedBy = "View";
+ protectedBy = "Change Images And Files";
pageName = "UIxContactEditor";
};
save = {
- protectedBy = "View";
+ protectedBy = "Change Images And Files";
pageName = "UIxContactEditor";
actionName = "save";
};
pageName = "UIxContactEditor";
actionName = "write";
};
- vcard = {
- protectedBy = "View";
- pageName = "UIxContactView";
- actionName = "vcard";
- };
};
};
pageName = "UIxContactEditor";
actionName = "write";
};
- vcard = {
- protectedBy = "View";
- pageName = "UIxContactView";
- actionName = "vcard";
- };
};
};
};
pageName = "UIxMailEditorAttach";
actionName = "deleteAttachment";
};
-
send = {
protectedBy = "View";
pageName = "UIxMailEditor";
"View" = ( "Authenticated", "FreeBusy" );
};
};
- SOGoUserFolder = {
- superclass = "SOGoFolder";
+ SOGoFolder = {
+ superclass = "SOGoObject";
protectedBy = "<public>";
defaultAccess = "allow";
defaultRoles = {
- "View" = ( "Owner" );
- };
- /* protectedBy = "HomePage Access"; */
- };
- SOGoFolder = {
- superclass = "SOGoObject";
- protectedBy = "Access Contents Information";
- defaultRoles = {
- "Add Documents, Images, and Files" = ( "Owner", "Delegate" );
- "View" = ( "Owner", "Delegate", "Assistant" );
- "WebDAV Access" = ( "Owner", "Delegate", "Assistant" );
- "Access Contents Information" = ( "Owner", "Assistant", "Delegate" );
- "ReadAcls" = ( "Owner", "Delegate", "Assistant" );
+ "Add Documents, Images, and Files" = ( "Owner", "ObjectCreator" );
+ "View" = ( "Owner", "AuthorizedSubscriber" );
+ "Access Contents Information" = ( "Owner", "ObjectViewer", "AuthorizedSubscriber" );
+ "Change Images And Files" = ( "Owner", "ObjectEditor" );
+ "WebDAV Access" = ( "Owner", "AuthorizedSubscriber" );
+ "ReadAcls" = ( "Owner", "AuthorizedSubscriber" );
"SaveAcls" = ( "Owner" );
- "Delete Objects" = ( "Owner", "Delegate" );
+ "Delete Objects" = ( "Owner", "ObjectEraser" );
};
};
- SOGoGroupsFolder = {
- superclass = "SOGoObject";
- protectedBy = "View";
- };
- SOGoGroupFolder = {
- superclass = "SOGoObject";
- protectedBy = "View";
- };
- SOGoCustomGroupFolder = {
- superclass = "SOGoGroupFolder";
- protectedBy = "View";
- };
};
categories = {
"this year" = "this year";
-
/* Menu */
"Calendars" = "Calendars";
"OpenGroupware.org" = "OpenGroupware.org";
"Forbidden" = "Forbidden";
+/* acls */
+"User rights for:" = "User rights for:";
+"label_Public" = "Public";
+"label_Private" = "Private";
+"label_Confidential" = "Confidential";
+"View All" = "View All";
+"View the Date & Time" = "View the Date & Time";
+"Modify" = "Modify";
+"Respond To" = "Respond To";
+"None" = "None";
+"This person can create objects in my calendar."
+= "This person can create objects in my calendar.";
+"This person can erase objects from my calendar."
+= "This person can erase objects from my calendar.";
/* Button Titles */
"Close" = "Close";
"Invite Attendees" = "Invite Attendees";
"Documents" = "Documents";
+"Update" = "Update";
"Cancel" = "Cancel";
"show_rejected_apts" = "Show rejected appointments";
"hide_rejected_apts" = "Hide rejected appointments";
"prio_9" = "Low";
/* access classes (privacy) */
-"privacy_PUBLIC" = "Public";
-"privacy_CONFIDENTIAL" = "Confidential";
-"privacy_PRIVATE" = "Private";
+"PUBLIC_vevent" = "Public Event";
+"CONFIDENTIAL_vevent" = "Confidential Event";
+"PRIVATE_vevent" = "Private Event";
+"PUBLIC_vtodo" = "Public Task";
+"CONFIDENTIAL_vtodo" = "Confidential Task";
+"PRIVATE_vtodo" = "Private Task";
/* status type */
"status_" = "Not specified";
"Start" = "Start";
"End" = "End";
"Location" = "Location";
+"(Private Event)" = "(Événement privé)";
"closeThisWindowMessage" = "Thank you! You may now close this window.";
"Multicolumn Day View" = "Multicolumn Day View";
"OpenGroupware.org" = "OpenGroupware.org";
"Forbidden" = "Accès non autorisée";
+/* acls */
+"User rights for:" = "Autorisations pour :";
+"label_Public" = "Public";
+"label_Private" = "Privé";
+"label_Confidential" = "Confidentiel";
+"View All" = "Voir tout";
+"View the Date & Time" = "Voir la date & l'heure";
+"Modify" = "Modifier";
+"Respond To" = "Répondre";
+"None" = "Aucun";
+"This person can create objects in my calendar."
+= "Cette personne peut ajouter des objets à mon agenda.";
+"This person can erase objects from my calendar."
+= "Cette personne peut effacer des objets de mon agenda.";
/* Button Titles */
"Close" = "Fermer";
"Invite Attendees" = "Participants";
"Documents" = "Documents";
+"Update" = "Mettre à jour";
"Cancel" = "Annuler";
"show_rejected_apts" = "Afficher les rendez-vous refusés";
"hide_rejected_apts" = "Cacher les rendez-vous refusés";
/* Schedule */
-
"Schedule" = "Suivi de rendez-vous";
"No appointments found" = "Aucun rendez-vous";
"Meetings proposed by you" = "Rendez-vous que vous proposez";
"Hide already accepted and rejected appointments" = "Cacher les invitations refusées";
"Show already accepted and rejected appointments" = "Montrer aussi les invitations refusées";
-
/* Appointments */
"Appointment viewer" = "Visualisation de rendez-vous";
"prio_9" = "Basse";
/* access classes (privacy) */
-"privacy_PUBLIC" = "Public";
-"privacy_CONFIDENTIAL" = "Date et heure seulement";
-"privacy_PRIVATE" = "Privé";
+"PUBLIC_vevent" = "Événement public";
+"CONFIDENTIAL_vevent" = "Événement confidentiel";
+"PRIVATE_vevent" = "Événement privé";
+"PUBLIC_vtodo" = "Tâche publique";
+"CONFIDENTIAL_vtodo" = "Tâche confidentielle";
+"PRIVATE_vtodo" = "Tâche privée";
/* status type */
"status_" = "Non-spécifié";
"Start" = "Début";
"End" = "Fin";
"Location" = "Lieu";
+"(Private Event)" = "(Événement privé)";
"closeThisWindowMessage" = "Merci! Vous pouvez maintenant fermer cette fenêtre.";
"Multicolumn Day View" = "Multicolonne";
\
UIxCalFilterPanel.m \
UIxCalDayTable.m \
- \
UIxCalDateSelector.m \
+ UIxCalUserRightsEditor.m \
\
UIxComponent+Agenor.m \
UIxCalView.m \
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
-// $Id$
-
#ifndef __UIxCalDayView_H_
#define __UIxCalDayView_H_
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
-// $Id$
#import <Foundation/NSArray.h>
#import <Foundation/NSCalendarDate.h>
return userIsInTheCard;
}
-- (BOOL) titleShouldBeHidden
-{
- BOOL shouldBeHidden;
- SOGoUser *user;
- SOGoAuthenticator *sAuth;
-
- sAuth = [SOGoAuthenticator sharedSOGoAuthenticator];
- user = [sAuth userInContext: context];
-
- if ([[appointment objectForKey: @"owner"] isEqualToString: [user login]]
- || ([[appointment objectForKey: @"classification"] intValue]
- != iCalAccessConfidential))
- shouldBeHidden = NO;
- else
- shouldBeHidden = ![self _userIsInTheCard: [user email]];
-
- return shouldBeHidden;
-}
-
@end
--- /dev/null
+/* UIxCalUserRightsEditor.h - this file is part of SOGo
+ *
+ * Copyright (C) 2007 Inverse groupe conseil
+ *
+ * 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.
+ */
+
+#ifndef UIXCALUSERRIGHTSEDITOR_H
+#define UIXCALUSERRIGHTSEDITOR_H
+
+#import <UI/Common/UIxUserRightsEditor.h>
+
+@class NSArray;
+@class NSString;
+@class NSMutableDictionary;
+
+@interface UIxCalUserRightsEditor : UIxUserRightsEditor
+{
+ NSString *currentRight;
+ NSString *currentRightType;
+ NSMutableDictionary *rights;
+}
+
+- (NSArray *) objectRights;
+- (void) setCurrentRight: (NSString *) newCurrentRight;
+- (NSString *) currentRight;
+
+- (NSArray *) rightTypes;
+- (void) setCurrentRightType: (NSString *) newCurrentRightType;
+- (NSString *) currentRightType;
+- (NSString *) currentRightTypeLabel;
+- (NSString *) currentRightTypeName;
+- (NSString *) currentRightSelection;
+
+- (void) setUserCanCreateObjects: (BOOL) userCanCreateObjects;
+- (BOOL) userCanCreateObjects;
+
+- (void) setUserCanEraseObjects: (BOOL) userCanEraseObjects;
+- (BOOL) userCanEraseObjects;
+
+@end
+
+#endif /* UIXCALUSERRIGHTSEDITOR_H */
--- /dev/null
+/* UIxCalUserRightsEditor.m - this file is part of SOGo
+ *
+ * Copyright (C) 2007 Inverse groupe conseil
+ *
+ * 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.
+ */
+
+#import <Foundation/NSArray.h>
+#import <Foundation/NSEnumerator.h>
+#import <NGObjWeb/WORequest.h>
+#import <SoObjects/SOGo/SOGoPermissions.h>
+
+#import "UIxCalUserRightsEditor.h"
+
+@implementation UIxCalUserRightsEditor
+
+- (id) init
+{
+ if ((self = [super init]))
+ {
+ currentRight = nil;
+ currentRightType = nil;
+ rights = [NSMutableDictionary new];
+ [rights setObject: @"None" forKey: @"Public"];
+ [rights setObject: @"None" forKey: @"Private"];
+ [rights setObject: @"None" forKey: @"Confidential"];
+ }
+
+ return self;
+}
+
+- (void) dealloc
+{
+ [currentRight release];
+ [currentRightType release];
+ [rights release];
+ [super dealloc];
+}
+
+- (void) prepareRightsForm
+{
+ NSEnumerator *roles, *types;
+ NSString *role, *type;
+ unsigned int length;
+
+ roles = [userRights objectEnumerator];
+ role = [roles nextObject];
+ while (role)
+ {
+ types = [[self rightTypes] objectEnumerator];
+ type = [types nextObject];
+ while (type)
+ {
+ if ([role hasPrefix: type])
+ {
+ length = [type length];
+ [rights setObject: [role substringFromIndex: length]
+ forKey: type];
+ }
+ type = [types nextObject];
+ }
+ role = [roles nextObject];
+ }
+}
+
+- (NSArray *) _rightsForType: (NSString *) type
+{
+ NSMutableArray *rightsForType;
+ NSEnumerator *commonRights;
+ NSString *currentCommonRight;
+
+ rightsForType = [NSMutableArray new];
+ [rightsForType autorelease];
+ commonRights = [[self objectRights] objectEnumerator];
+ currentCommonRight = [commonRights nextObject];
+ while (currentCommonRight)
+ {
+ [rightsForType addObject: [NSString stringWithFormat: @"%@%@",
+ type, currentCommonRight]];
+ currentCommonRight = [commonRights nextObject];
+ }
+
+ return rightsForType;
+}
+
+- (void) updateRights
+{
+ NSEnumerator *types;
+ NSString *currentType, *currentValue;
+ NSArray *rightsForType;
+ WORequest *request;
+
+ request = [context request];
+ types = [[self rightTypes] objectEnumerator];
+ currentType = [types nextObject];
+ while (currentType)
+ {
+ rightsForType = [self _rightsForType: currentType];
+ currentValue
+ = [request formValueForKey:
+ [NSString stringWithFormat: @"%@Right", currentType]];
+ if ([currentValue isEqualToString: @"None"])
+ [self removeAllRightsFromList: rightsForType];
+ else
+ [self appendExclusiveRight: [NSString stringWithFormat: @"%@%@",
+ currentType, currentValue]
+ fromList: rightsForType];
+ currentType = [types nextObject];
+ }
+
+ if ([[request formValueForKey: @"ObjectCreator"] length] > 0)
+ [self appendRight: SOGoRole_ObjectCreator];
+ else
+ [self removeRight: SOGoRole_ObjectCreator];
+
+ if ([[request formValueForKey: @"ObjectEraser"] length] > 0)
+ [self appendRight: SOGoRole_ObjectEraser];
+ else
+ [self removeRight: SOGoRole_ObjectEraser];
+}
+
+- (NSArray *) objectRights
+{
+ return
+ [NSArray arrayWithObjects:
+ @"Viewer", @"DAndTViewer", @"Modifier", @"Responder", @"None", nil];
+}
+
+- (void) setCurrentRight: (NSString *) newCurrentRight
+{
+ ASSIGN (currentRight, newCurrentRight);
+}
+
+- (NSString *) currentRight
+{
+ return currentRight;
+}
+
+- (NSArray *) rightTypes
+{
+ return
+ [NSArray arrayWithObjects: @"Public", @"Confidential", @"Private", nil];
+}
+
+- (void) setCurrentRightType: (NSString *) newCurrentRightType
+{
+ ASSIGN (currentRightType, newCurrentRightType);
+}
+
+- (NSString *) currentRightType
+{
+ return currentRightType;
+}
+
+- (NSString *) currentRightTypeLabel
+{
+ return [self labelForKey:
+ [NSString stringWithFormat: @"label_%@", currentRightType]];
+}
+
+- (NSString *) currentRightTypeName
+{
+ return [NSString stringWithFormat: @"%@Right", currentRightType];
+}
+
+- (NSString *) currentRightSelection
+{
+ return [rights objectForKey: currentRightType];
+}
+
+- (void) setUserCanCreateObjects: (BOOL) userCanCreateObjects
+{
+ [self appendRight: SOGoRole_ObjectCreator];
+}
+
+- (BOOL) userCanCreateObjects
+{
+ return [userRights containsObject: SOGoRole_ObjectCreator];
+}
+
+- (void) setUserCanEraseObjects: (BOOL) userCanEraseObjects
+{
+ [self appendRight: SOGoRole_ObjectEraser];
+}
+
+- (BOOL) userCanEraseObjects
+{
+ return [userRights containsObject: SOGoRole_ObjectEraser];
+}
+
+@end
- (void) setAppointment:(id) _apt
{
- NSString *mailtoChunk;
- NSString *myEmail;
-
- ASSIGN(appointment, _apt);
-
- /* cache some info about apt for faster access */
-
- mailtoChunk = [_apt valueForKey: @"orgmail"];
- myEmail = [self emailForUser];
- if ([mailtoChunk rangeOfString: myEmail].length > 0)
- {
- aptFlags.isMyApt = YES;
- aptFlags.canAccessApt = YES;
- }
- else
- {
- NSString *partmails;
-
- aptFlags.isMyApt = NO;
-
- partmails = [_apt valueForKey: @"partmails"];
- if ([partmails rangeOfString: myEmail].length)
- aptFlags.canAccessApt = YES;
- else
- aptFlags.canAccessApt
- = ([[_apt valueForKey: @"classification"] intValue]
- == iCalAccessPublic);
- }
+ ASSIGN (appointment, _apt);
}
-- (void) setTasks: (NSArray *) _tasks
-{
- ASSIGN(tasks, _tasks);
-}
+// - (void) setAppointment:(id) _apt
+// {
+// NSString *mailtoChunk;
+// NSString *myEmail;
+// NSString *partmails;
-- (NSArray *) tasks
-{
- return tasks;
-}
+// ASSIGN(appointment, _apt);
+
+// /* cache some info about apt for faster access */
+
+// mailtoChunk = [_apt valueForKey: @"orgmail"];
+// myEmail = [self emailForUser];
+// if ([mailtoChunk rangeOfString: myEmail].length > 0)
+// {
+// aptFlags.isMyApt = YES;
+// aptFlags.canAccessApt = YES;
+// }
+// else
+// {
+// aptFlags.isMyApt = NO;
+
+// partmails = [_apt valueForKey: @"partmails"];
+// if ([partmails rangeOfString: myEmail].length)
+// aptFlags.canAccessApt = YES;
+// else
+// aptFlags.canAccessApt
+// = ([[_apt valueForKey: @"classification"] intValue]
+// == iCalAccessPublic);
+// }
+// }
- (id) appointment
{
return privateAptTooltipFormatter;
}
+- (void) setTasks: (NSArray *) _tasks
+{
+ ASSIGN(tasks, _tasks);
+}
+
+- (NSArray *) tasks
+{
+ return tasks;
+}
+
/* TODO: remove this */
- (NSString *) shortTextForApt
{
return activeFolders;
}
+- (void) _updatePrivacyInObjects: (NSArray *) objectInfos
+ fromFolder: (SOGoAppointmentFolder *) folder
+{
+ int hideDetails[] = {-1, -1, -1};
+ NSMutableDictionary *currentRecord;
+ int privacyFlag;
+ NSString *roleString, *userLogin;
+ NSEnumerator *infos;
+
+ userLogin = [[context activeUser] login];
+ infos = [objectInfos objectEnumerator];
+ currentRecord = [infos nextObject];
+ while (currentRecord)
+ {
+ privacyFlag = [[currentRecord objectForKey: @"classification"] intValue];
+ if (hideDetails[privacyFlag] == -1)
+ {
+ roleString = [folder roleForComponentsWithAccessClass: privacyFlag
+ forUser: userLogin];
+ hideDetails[privacyFlag] = ([roleString isEqualToString: @"ComponentDAndTViewer"]
+ ? 1 : 0);
+ }
+ if (hideDetails[privacyFlag])
+ {
+ [currentRecord setObject: [self labelForKey: @"(Private Event)"]
+ forKey: @"title"];
+ [currentRecord setObject: @"" forKey: @"location"];
+ }
+ currentRecord = [infos nextObject];
+ }
+}
+
- (NSArray *) _fetchCoreInfosForComponent: (NSString *) component
{
NSArray *currentInfos;
[currentInfos makeObjectsPerform: @selector (setObject:forKey:)
withObject: [currentFolder ownerInContext: nil]
withObject: @"owner"];
+ [self _updatePrivacyInObjects: currentInfos
+ fromFolder: currentFolder];
[infos addObjectsFromArray: currentInfos];
currentFolder = [folders nextObject];
}
- (BOOL) isWriteableClientObject;
- (NSException *) validateObjectForStatusChange;
-- (NSString *) iCalParticipantsAndResourcesStringFromQueryParameters;
-- (NSString *) iCalParticipantsStringFromQueryParameters;
-- (NSString *) iCalResourcesStringFromQueryParameters;
-- (NSString *) iCalStringFromQueryParameter: (NSString *) _qp
- format: (NSString *) _format;
-- (NSString *) iCalOrganizerString;
-
@end
#endif /* UIXCOMPONENTEDITOR_H */
- (NSString *) itemPrivacyText
{
- return [self labelForKey: [NSString stringWithFormat: @"privacy_%@", item]];
+ NSString *tag;
+
+ tag = [[self clientObject] componentTag];
+
+ return [self labelForKey: [NSString stringWithFormat: @"%@_%@", item, tag]];
}
- (NSString *) itemStatusText
return calendarList;
}
-- (NSString *) itemCalendarText
-{
- return item;
-}
-
- (NSString *) calendarsFoldersList
{
NSArray *calendars;
: @"visibility: hidden;");
}
-- (NSString *) iCalParticipantsAndResourcesStringFromQueryParameters
-{
- NSString *s;
+// - (NSString *) iCalParticipantsAndResourcesStringFromQueryParameters
+// {
+// NSString *s;
- s = [self iCalParticipantsStringFromQueryParameters];
- return [s stringByAppendingString:
- [self iCalResourcesStringFromQueryParameters]];
-}
-
-- (NSString *) iCalParticipantsStringFromQueryParameters
-{
- static NSString *iCalParticipantString = \
- @"ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;CN=\"%@\":MAILTO:%@\r\n";
+// s = [self iCalParticipantsStringFromQueryParameters];
+// return [s stringByAppendingString:
+// [self iCalResourcesStringFromQueryParameters]];
+// }
+
+// - (NSString *) iCalParticipantsStringFromQueryParameters
+// {
+// static NSString *iCalParticipantString = @"ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;CN=\"%@\":MAILTO:%@\r\n";
- return [self iCalStringFromQueryParameter: @"ps"
- format: iCalParticipantString];
-}
-
-- (NSString *) iCalResourcesStringFromQueryParameters
-{
- static NSString *iCalResourceString = \
- @"ATTENDEE;ROLE=NON-PARTICIPANT;CN=\"%@\":MAILTO:%@\r\n";
-
- return [self iCalStringFromQueryParameter: @"rs"
- format: iCalResourceString];
-}
-
-- (NSString *) iCalStringFromQueryParameter: (NSString *) _qp
- format: (NSString *) _format
-{
- AgenorUserManager *um;
- NSMutableString *iCalRep;
- NSString *s;
-
- um = [AgenorUserManager sharedUserManager];
- iCalRep = (NSMutableString *)[NSMutableString string];
- s = [self queryParameterForKey:_qp];
- if(s && [s length] > 0) {
- NSArray *es;
- unsigned i, count;
+// return [self iCalStringFromQueryParameter: @"ps"
+// format: iCalParticipantString];
+// }
+
+// - (NSString *) iCalResourcesStringFromQueryParameters
+// {
+// static NSString *iCalResourceString = @"ATTENDEE;ROLE=NON-PARTICIPANT;CN=\"%@\":MAILTO:%@\r\n";
+
+// return [self iCalStringFromQueryParameter: @"rs"
+// format: iCalResourceString];
+// }
+
+// - (NSString *) iCalStringFromQueryParameter: (NSString *) _qp
+// format: (NSString *) _format
+// {
+// AgenorUserManager *um;
+// NSMutableString *iCalRep;
+// NSString *s;
+
+// um = [AgenorUserManager sharedUserManager];
+// iCalRep = (NSMutableString *)[NSMutableString string];
+// s = [self queryParameterForKey:_qp];
+// if(s && [s length] > 0) {
+// NSArray *es;
+// unsigned i, count;
- es = [s componentsSeparatedByString: @","];
- count = [es count];
- for(i = 0; i < count; i++) {
- NSString *email, *cn;
+// es = [s componentsSeparatedByString: @","];
+// count = [es count];
+// for(i = 0; i < count; i++) {
+// NSString *email, *cn;
- email = [es objectAtIndex:i];
- cn = [um getCNForUID:[um getUIDForEmail:email]];
- [iCalRep appendFormat:_format, cn, email];
- }
- }
- return iCalRep;
-}
-
-- (NSString *) iCalOrganizerString
-{
- return [NSString stringWithFormat: @"ORGANIZER;CN=\"%@\":MAILTO:%@\r\n",
- [self cnForUser], [self emailForUser]];
-}
+// email = [es objectAtIndex:i];
+// cn = [um getCNForUID:[um getUIDForEmail:email]];
+// [iCalRep appendFormat:_format, cn, email];
+// }
+// }
+// return iCalRep;
+// }
- (NSException *) validateObjectForStatusChange
{
id co;
co = [self clientObject];
- if (![co
- respondsToSelector: @selector(changeParticipationStatus:)])
- return [NSException exceptionWithHTTPStatus:400 /* Bad Request */
+ if (![co respondsToSelector: @selector(changeParticipationStatus:)])
+ return [NSException exceptionWithHTTPStatus: 400 /* Bad Request */
reason:
@"method cannot be invoked on the specified object"];
[component setLocation: location];
[component setComment: comment];
[component setUrl: url];
+ [component setAccessClass: privacy];
[self _handleAttendeesEdition];
[self _handleOrganizer];
clientObject = [self clientObject];
editAttendees = {
protectedBy = "View";
pageName = "UIxAttendeesEditor";
- };
+ };
+ userRights = {
+ protectedBy = "ReadAcls";
+ pageName = "UIxCalUserRightsEditor";
+ };
+ saveUserRights = {
+ protectedBy = "SaveAcls";
+ pageName = "UIxCalUserRightsEditor";
+ actionName = "saveUserRights";
+ };
};
};
+ SOGoCalendarComponent = {
+ };
SOGoAppointmentObject = {
slots = {
};
methods = {
view = {
- protectedBy = "View";
+ protectedBy = "ViewAllComponent";
pageName = "UIxAppointmentView";
};
delete = {
- protectedBy = "View";
+ protectedBy = "Delete Objects";
pageName = "UIxAppointmentView";
actionName = "delete";
};
edit = {
- protectedBy = "View";
+ protectedBy = "ViewAllComponent";
pageName = "UIxAppointmentEditor";
};
editAsAppointment = {
- protectedBy = "View";
+ protectedBy = "ViewAllComponent";
pageName = "UIxAppointmentEditor";
};
save = {
- protectedBy = "View";
+ protectedBy = "ModifyComponent";
pageName = "UIxAppointmentEditor";
actionName = "save";
};
saveAsAppointment = {
- protectedBy = "View";
+ protectedBy = "ModifyComponent";
pageName = "UIxAppointmentEditor";
actionName = "save";
};
accept = {
- protectedBy = "View";
+ protectedBy = "RespondToComponent";
pageName = "UIxAppointmentEditor";
actionName = "accept";
};
decline = {
- protectedBy = "View";
+ protectedBy = "RespondToComponent";
pageName = "UIxAppointmentEditor";
actionName = "decline";
};
- test = {
- protectedBy = "View";
- pageName = "UIxAppointmentEditor";
- actionName = "test";
- };
};
};
};
methods = {
view = {
- protectedBy = "View";
+ protectedBy = "ViewAllComponent";
pageName = "UIxTaskView";
};
delete = {
- protectedBy = "View";
+ protectedBy = "Delete Objects";
pageName = "UIxTaskView";
actionName = "delete";
};
edit = {
- protectedBy = "View";
+ protectedBy = "ViewAllComponent";
pageName = "UIxTaskEditor";
};
editAsTask = {
- protectedBy = "View";
+ protectedBy = "ViewAllComponent";
pageName = "UIxTaskEditor";
};
save = {
- protectedBy = "Change Images and Files";
+ protectedBy = "ModifyComponent";
pageName = "UIxTaskEditor";
actionName = "save";
};
saveAsTask = {
- protectedBy = "Change Images and Files";
+ protectedBy = "ModifyComponent";
pageName = "UIxTaskEditor";
actionName = "save";
};
changeStatus = {
- protectedBy = "Change Images and Files";
+ protectedBy = "ModifyComponent";
pageName = "UIxTaskEditor";
actionName = "changeStatus";
};
accept = {
- protectedBy = "Change Images and Files";
+ protectedBy = "RespondToComponent";
pageName = "UIxTaskEditor";
actionName = "accept";
};
decline = {
- protectedBy = "Change Images and Files";
+ protectedBy = "RespondToComponent";
pageName = "UIxTaskEditor";
actionName = "decline";
};
- test = {
- protectedBy = "View";
- pageName = "UIxTaskEditor";
- actionName = "test";
- };
};
};
};
--- /dev/null
+<?xml version="1.0" standalone="yes"?>
+<!DOCTYPE var:component>
+<var:component xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ xmlns:const="http://www.skyrix.com/od/constant"
+ xmlns:uix="OGo:uix"
+ xmlns:label="OGo:label"
+ xmlns:rsrc="OGo:url"
+ className="UIxPageFrame"
+ title="title"
+ const:toolbar="none"
+ const:popup="YES">
+ <form id="userRightsForm" const:href="saveUserRights">
+ <input type="hidden" name="uid" var:value="uid"/>
+ <div class="title">
+ <label><var:string label:value="User rights for:"/><br/>
+ <span class="value"><var:string value="userDisplayName"/></span></label>
+ </div>
+ <div class="calendarUserRights">
+ <label><input type="checkbox" class="checkBox"
+ const:name="ObjectCreator"
+ var:checked="userCanCreateObjects"/><var:string
+ label:value="This person can add cards to this addressbook."/></label>
+ <br/>
+ <label><input type="checkbox" class="checkBox"
+ const:name="ObjectEditor"
+ var:checked="userCanEditObjects"/><var:string
+ label:value="This person can edit the cards of this addressbook."/></label>
+ <br/>
+ <label><input type="checkbox" class="checkBox"
+ const:name="ObjectViewer"
+ var:checked="userCanViewObjects"/><var:string
+ label:value="This person can view the cards of this addressbook."/></label>
+ <br/>
+ <label><input type="checkbox" class="checkBox"
+ const:name="ObjectEraser"
+ var:checked="userCanEraseObjects"/><var:string
+ label:value="This person can erase cards from this addressbook."/></label>
+ </div>
+ <div class="buttons">
+ <input const:name="updateButton" id="updateButton"
+ class="button" type="submit" label:value="Update"/>
+ <input const:name="cancelButton" id="cancelButton"
+ class="button" type="button" label:value="Cancel"/>
+ </div>
+ </form>
+</var:component>
><img rsrc:src="alarm.png" class="gradient"
/></var:if
></span
- ><var:if condition="titleShouldBeHidden" const:negate="YES"
- ><br
- /><var:string value="appointment.title" const:escapeHTML="NO"
- /></var:if
- ></div>
+ ><br/><var:string value="appointment.title" const:escapeHTML="NO" />
+ </div>
</div>
</div>
--- /dev/null
+<?xml version="1.0" standalone="yes"?>
+<!DOCTYPE var:component>
+<var:component xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ xmlns:const="http://www.skyrix.com/od/constant"
+ xmlns:uix="OGo:uix"
+ xmlns:label="OGo:label"
+ xmlns:rsrc="OGo:url"
+ className="UIxPageFrame"
+ title="title"
+ const:toolbar="none"
+ const:popup="YES">
+ <form id="userRightsForm" const:href="saveUserRights">
+ <input type="hidden" name="uid" var:value="uid"/>
+ <div class="title">
+ <label><var:string label:value="User rights for:"/><br/>
+ <span class="value"><var:string value="userDisplayName"/></span></label>
+ </div>
+ <div class="calendarUserRights">
+ <table>
+ <tr class="permissions">
+ <th class="eventType"><!-- space --></th>
+ <th><var:string label:value="View All"/></th>
+ <th><var:string label:value="View the Date & Time"/></th>
+ <th><var:string label:value="Modify"/></th>
+ <th><var:string label:value="Respond To"/></th>
+ <th><var:string label:value="None"/></th>
+ </tr
+ ><var:foreach list="rightTypes" item="currentRightType">
+ <tr>
+ <td class="eventType"><var:string
+ value="currentRightTypeLabel"/></td
+ ><var:foreach list="objectRights" item="currentRight">
+ <td><input type="radio"
+ var:name="currentRightTypeName"
+ var:value="currentRight"
+ var:selection="currentRightSelection"/></td
+ ></var:foreach>
+ </tr></var:foreach>
+ </table>
+ </div>
+ <div class="basicUserRights">
+ <label><input type="checkbox" class="checkBox"
+ const:name="ObjectCreator"
+ var:checked="userCanCreateObjects"/><var:string
+ label:value="This person can create objects in my calendar."/></label>
+ <br/>
+ <label><input type="checkbox" class="checkBox"
+ const:name="ObjectEraser"
+ var:checked="userCanEraseObjects"/><var:string
+ label:value="This person can erase objects from my calendar."/></label>
+ </div>
+ <div class="buttons">
+ <input const:name="updateButton" id="updateButton"
+ class="button" type="submit" label:value="Update"/>
+ <input const:name="cancelButton" id="cancelButton"
+ class="button" type="button" label:value="Cancel"/>
+ </div>
+ </form>
+</var:component>
<script type="text/javascript" rsrc:src="UIxComponentEditor.js"><!-- space --></script>
<div class="menu" id="privacy-menu">
- <ul id="">
- <li onmouseup="onMenuSetClassification(event, 'PUBLIC');"><var:string
- label:value="Public Event" /></li>
- <li onmouseup="onMenuSetClassification(event, 'CONFIDENTIAL');"><var:string
- label:value="Show Time and Date Only" /></li>
- <li onmouseup="onMenuSetClassification(event, 'PRIVACY');"><var:string
- label:value="Private Event" /></li>
+ <ul id="itemPrivacyList">
+ <var:foreach list="privacyClasses" item="item">
+ <li var:classification="item"><var:string
+ var:value="itemPrivacyText" /></li>
+ </var:foreach>
</ul>
</div>
<form id="aclForm" const:href="saveAcls">
<div class="acls">
<input type="hidden" name="action" value="saveAcls"/>
- <input type="hidden" name="delegates" var:value="delegatesValue"
- id="delegates"/>
- <input type="hidden" name="assistants" var:value="assistantsValue"
- id="assistants"/>
+ <input type="hidden" id="userUIDS" name="userUIDS"
+ var:value="userUIDS"/>
<label><var:string label:value="Owner:"/><br/>
<span class="value"><strong><var:string value="ownerName"/></strong></span></label><br/>
- <!-- var:component className="UIxContactSelector"
- const:checkBoxOnChange="return updateAclStatus(this);"
- contacts="usersForFolder" -->
-
<div class="userSelector" id="userRoles">
<span id="userSelectorButtons">
<a href="#"
label:title="Remove"
/></a>
</span>
- <input type="hidden"
- var:id="selectorIdList"
- var:name="selectorId"
- var:value="initialContactsAsString"/>
<ul id="userList" multiselect="yes">
- <var:foreach list="usersForFolder" item="currentUser"
+ <var:foreach list="usersForObject" item="currentUser"
><li var:id="currentUser">
<img rsrc:src="abcard.gif"/>
<var:string value="currentUserDisplayName"/></li>
</var:foreach>
</ul>
</div>
-
- <select id="userRoleDropDown" name="currentUserRole">
- <option value="assistant"><var:string label:value="Assistant"/></option>
- <option value="delegate"><var:string label:value="Delegate"/></option>
- </select><br/>
- <var:if condition="clientIsCalendar"
- ><label id="freeBusyLabel"><input type="checkbox"
- var:checked="publishInFreeBusy"
- class="checkBox" name="freebusy" id="freebusy"
- /><var:string label:value="Localizable/Publish the Free/Busy information"
- /></label></var:if>
</div>
</form>
</var:component>
--- /dev/null
+<?xml version="1.0" standalone="yes"?>
+<!DOCTYPE var:component>
+<var:component xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:var="http://www.skyrix.com/od/binding"
+ xmlns:const="http://www.skyrix.com/od/constant"
+ xmlns:uix="OGo:uix"
+ xmlns:label="OGo:label"
+ xmlns:rsrc="OGo:url"
+ className="UIxPageFrame"
+ title="title"
+ var:toolbar="toolbar"
+ const:popup="YES">
+ <div><var:string label:value="Sorry, the user rights can not be configured for that object."/></div>
+</var:component>
var cachedContacts = new Array();
var currentContactFolder = '/personal';
+var usersRightsWindowHeight = 180;
+var usersRightsWindowWidth = 450;
+
function openContactWindow(sender, url) {
var msgWin = window.open(url, null, "width=450,height=600,resizable=0");
msgWin.focus();
function initMailboxSelection(mailboxName) {
currentMailbox = mailboxName;
- log("initMailboxSelection: " + mailboxName);
+// log("initMailboxSelection: " + mailboxName);
var tree = $("d");
var treeNodes = document.getElementsByClassName("dTreeNode", tree);
var i = 0;
&& treeNodes[i].getAttribute("dataname") != currentMailbox)
i++;
if (i < treeNodes.length) {
- log ("found mailbox");
+// log ("found mailbox");
var links = document.getElementsByClassName("node", treeNodes[i]);
if (tree.selectedEntry)
tree.selectedEntry.deselect();
document.DNDManager.registerDestination(images[i]);
}
}
- var nodes = document.getElementsByClassName("leaf", tree);
+ var nodes = document.getElementsByClassName("nodeName", tree);
for (var i = 0; i < nodes.length; i++) {
nodes[i].dndAcceptType = mailboxSpanAcceptType;
nodes[i].dndEnter = mailboxSpanEnter;
position: absolute;
top: 5.5em;
left: 0px;
- width: 17em;
+ width: 18.5em;
bottom: 0px;
overflow: hidden;
}
top: 0.5em;
left: .2em;
right: .2em;
- height: 16em;
+ height: 17em;
}
DIV#tasksListView
{
position: absolute;
- top: 18.5em;
+ top: 20em;
bottom: 0px;
left: .2em;
right: .7em;
{
position: absolute;
top: 5.5em;
- left: 17em;
+ left: 18.5em;
right: 0px;
bottom: 0px;
margin: 0px;
{
cursor: e-resize;
top: 7.5em;
- left: 17em;
+ left: 18.5em;
width: 5px;
bottom: 0px;
}
var eventsToDelete = new Array();
var ownersOfEventsToDelete = new Array();
+var usersRightsWindowHeight = 250;
+var usersRightsWindowWidth = 502;
+
function newEvent(sender, type) {
var day = sender.getAttribute("day");
if (!day)
checkBox.type = "checkbox";
checkBox.addEventListener("change", updateCalendarStatus, false);
li.appendChild(checkBox);
+ li.appendChild(document.createTextNode(" "));
var colorBox = document.createElement("div");
colorBox.appendChild(document.createTextNode("OO"));
colorBox.addClassName("colorBox");
var contactId = folder.split(":")[0];
var styles = document.getElementsByTagName("style");
+
+ var url = URLForFolderID(folder) + "/canAccessContent";
+ triggerAjaxRequest(url, calendarEntryCallback, folder);
+
styles[0].innerHTML += ('.ownerIs' + contactId + ' {'
+ ' background-color: '
+ color
if (!$(userID)) {
var ul = $("userList");
ul.appendChild(nodeForUser(userName, userID));
- var roleList = $("assistants");
- if (roleList.value.length > 0) {
- var uids = roleList.value.split(",");
- uids.push(userID);
- roleList.value = uids.join(",");
- }
- else
- roleList.value = userID;
+ var url = window.location.href;
+ var elements = url.split("/");
+ elements[elements.length-1] = ("addUserInAcls?uid="
+ + userID);
+ triggerAjaxRequest(elements.join("/"), addUserCallback);
}
}
+function addUserCallback(http) {
+}
+
function nodeForUser(userName, userId) {
var node = document.createElement("li");
node.setAttribute("id", userId);
}
function saveAcls() {
- $("aclForm").submit();
-
- return false;
-}
-
-function updateSelectedRole(list) {
- var select = $("userRoleDropDown");
- var selection = list.getSelectedRows();
- if (selection.length > 0) {
- select.style.visibility = "visible;";
- var selected = selection[0];
- var assistantsValue = $("assistants");
- var uid = selected.getAttribute("id");
- var regexp = new RegExp("(^|,)" + uid + "(,|$)","i");
- if (regexp.test(assistantsValue.value))
- select.selectedIndex = 0;
- else
- select.selectedIndex = 1;
- }
- else
- select.style.visibility = "hidden;";
-}
-
-function onAclSelectionChange() {
- log("selectionchange");
- updateSelectedRole(this);
-}
-
-function onUserRoleDropDownChange() {
- var oldList;
- var newList;
-
- if (this.selectedIndex == 0) {
- oldList = $("delegates");
- newList = $("assistants");
- } else {
- oldList = $("assistants");
- newList = $("delegates");
- }
-
- var uid = $("userList").getSelectedRows()[0].getAttribute("id");
- var newListArray;
- if (newList.value.length > 0) {
- newListArray = newList.value.split(",");
- newListArray.push(uid);
- }
- else
- newListArray = new Array(uid);
- newList.value = newListArray.join(",");
-
- var oldListArray = oldList.value.split(",").without(uid);
- if (oldListArray.length > 0)
- oldList.value = oldListArray.join(",");
- else
- oldList.value = "";
-
- log("assistants: " + $("assistants").value);
- log("delegates: " + $("delegates").value);
+ var uidList = new Array();
+ var users = $("userList").childNodesWithTag("li");
+ for (var i = 0; i < users.length; i++)
+ uidList.push(users[i].getAttribute("id"));
+ $("userUIDS").value = uidList.join(",");
+ $("aclForm").submit();
+
+ return false;
}
function onUserAdd(event) {
}
function onUserRemove(event) {
- var userlist = $("userList");
- var node = userlist.getSelectedRows()[0];
- var uid = node.getAttribute("id");
- var regexp = new RegExp("(^|,)" + uid + "($|,)");
- var uids = $("assistants");
- if (!regexp.test(uids.value))
- uids = $("delegates");
- if (regexp.test(uids.value)) {
- var list = uids.value.split(",");
- var newList = new Array();
- for (var i = 0; i < list.length; i++) {
- if (list[i] != uid)
- newList.push(list[i]);
- }
- uids.value = newList.join(",");
- node.parentNode.removeChild(node);
- }
- updateSelectedRole(userlist);
+ var userList = $("userList");
+ var nodes = userList.getSelectedRows();
+ for (var i = 0; i < nodes.length; i++)
+ userList.removeChild(nodes[i]);
event.preventDefault();
}
refreshCallbackData["folder"]);
}
+function openRightsForUser(button) {
+ var nodes = $("userList").getSelectedRows();
+ if (nodes.length > 0) {
+ var url = window.location.href;
+ var elements = url.split("/");
+ elements[elements.length-1] = ("userRights?uid="
+ + nodes[0].getAttribute("id"));
+
+ window.open(elements.join("/"), "",
+ "width=" + this.userRightsWidth
+ + ",height=" + this.userRightsHeight
+ + ",resizable=0,scrollbars=0,toolbar=0,"
+ + "location=0,directories=0,status=0,menubar=0,copyhistory=0");
+ }
+
+ return false;
+}
+
+function onOpenUserRights(event) {
+ openRightsForUser();
+ event.preventDefault();
+}
+
function onAclLoadHandler() {
var ul = $("userList");
- ul.addEventListener("selectionchange",
- onAclSelectionChange, false);
var lis = ul.childNodesWithTag("li");
for (var i = 0; i < lis.length; i++) {
lis[i].addEventListener("mousedown", listRowMouseDownHandler, false);
+ lis[i].addEventListener("dblclick", onOpenUserRights, false);
lis[i].addEventListener("click", onRowClick, false);
}
- var select = $("userRoleDropDown");
- select.addEventListener("change", onUserRoleDropDownChange, false);
-
var buttons = $("userSelectorButtons").childNodesWithTag("a");
buttons[0].addEventListener("click", onUserAdd, false);
buttons[1].addEventListener("click", onUserRemove, false);
+
+ this.userRightsHeight = window.opener.getUsersRightsWindowHeight();
+ this.userRightsWidth = window.opener.getUsersRightsWindowWidth();
}
window.addEventListener("load", onAclLoadHandler, false);
--- /dev/null
+DIV.title
+{ color: #000;
+ vertical-align: bottom;
+ padding-top: 15px;
+ padding-left: 1em;
+ height: 33px;
+ background-color: #fff;
+ border-bottom: 1px solid #555; }
+
+DIV.title SPAN.value
+{ margin-left: 1em;
+ font-size: 18px;
+ font-weight: bold; }
+
+DIV.calendarUserRights
+{ margin: 1em;}
+
+DIV.calendarUserRights > TABLE
+{ background-color: #fff;
+ width: 45em;
+ color: #999;
+ border-collapse: collapse;
+ border-bottom: 1px solid #fff;
+ border-right: 1px solid #fff;
+ border-top: 2px solid #222;
+ border-left: 2px solid #222;
+ -moz-border-top-colors: ThreeDShadow ThreeDDarkShadow transparent;
+ -moz-border-left-colors: ThreeDShadow ThreeDDarkShadow transparent; }
+
+DIV.calendarUserRights > TABLE TR.permissions TH
+{ color: #00f;
+/* background-color: #ddd;
+ */ border-bottom: 1px solid #999; }
+
+DIV.calendarUserRights > TABLE TH
+{ width: 15em; }
+
+DIV.calendarUserRights > TABLE TD.eventType
+{ width: 5em;
+ text-align: right;
+ border-right: 1px solid #999; }
+
+DIV.calendarUserRights > TABLE TD
+{ text-align: center;
+ border-top: 1px solid #cecbff; }
+
+DIV.buttons
+{ text-align: right;
+ margin: 1em; }
--- /dev/null
+function onCancelClick(event) {
+ window.close();
+}
+
+function initACLButtons() {
+ $("cancelButton").addEventListener("click", onCancelClick, false);
+}
+
+window.addEventListener("load", initACLButtons, false);
-window.addEventListener("load", onComponentEditorLoad, false);
-
function onPopupAttendeesWindow(event) {
if (event)
event.preventDefault();
return false;
}
-function onMenuSetClassification(event, classification) {
+function onMenuSetClassification(event) {
event.cancelBubble = true;
- var node = event.target;
- if (node.tagName != "LI")
- node = node.getParentWithTagName("li");
- if (node.parentNode.chosenNode)
- node.parentNode.chosenNode.removeClassName("_chosen");
- node.addClassName("_chosen");
- node.parentNode.chosenNode = node;
+ var classification = this.getAttribute("classification");
+ if (this.parentNode.chosenNode)
+ this.parentNode.chosenNode.removeClassName("_chosen");
+ this.addClassName("_chosen");
+ this.parentNode.chosenNode = this;
log("classification: " + classification);
var privacyInput = document.getElementById("privacy");
else
ownerLogin = UserLogin;
urlElems[urlElems.length-4] = ownerLogin;
-
+
form.setAttribute("action", urlElems.join("/"));
- log ("after: " + form.getAttribute("action"));
}
function refreshAttendees() {
initializeAttendeesHref();
initializeDocumentHref();
initializePrivacyMenu();
- $("calendarList").addEventListener("change", onChangeCalendar, false);
+ var list = $("calendarList");
+ list.addEventListener("change", onChangeCalendar, false);
+ var onSelectionChangeEvent = document.createEvent("Event");
+ onSelectionChangeEvent.initEvent("change", false, false);
+ list.dispatchEvent(onSelectionChangeEvent);
+
+ var menuItems = $("itemPrivacyList").childNodesWithTag("li");
+ for (var i = 0; i < menuItems.length; i++)
+ menuItems[i].addEventListener("mouseup", onMenuSetClassification, false);
}
+
+window.addEventListener("load", onComponentEditorLoad, false);
--- /dev/null
+DIV.title
+{ color: #000;
+ vertical-align: bottom;
+ padding-top: 15px;
+ padding-left: 1em;
+ height: 33px;
+ background-color: #fff;
+ border-bottom: 1px solid #555; }
+
+DIV.title SPAN.value
+{ margin-left: 1em;
+ font-size: 18px;
+ font-weight: bold; }
+
+DIV.calendarUserRights
+{ margin: 1em;}
+
+DIV.calendarUserRights > TABLE
+{ background-color: #fff;
+ width: 45em;
+ color: #999;
+ border-collapse: collapse;
+ border-bottom: 1px solid #fff;
+ border-right: 1px solid #fff;
+ border-top: 2px solid #222;
+ border-left: 2px solid #222;
+ -moz-border-top-colors: ThreeDShadow ThreeDDarkShadow transparent;
+ -moz-border-left-colors: ThreeDShadow ThreeDDarkShadow transparent; }
+
+DIV.calendarUserRights > TABLE TR.permissions TH
+{ color: #00f;
+/* background-color: #ddd;
+ */ border-bottom: 1px solid #999; }
+
+DIV.calendarUserRights > TABLE TH
+{ width: 15em; }
+
+DIV.calendarUserRights > TABLE TD.eventType
+{ width: 5em;
+ text-align: right;
+ border-right: 1px solid #999; }
+
+DIV.calendarUserRights > TABLE TD
+{ text-align: center;
+ border-top: 1px solid #cecbff; }
+
+DIV.buttons
+{ text-align: right;
+ margin: 1em; }
--- /dev/null
+function onCancelClick(event) {
+ window.close();
+}
+
+function initACLButtons() {
+ $("cancelButton").addEventListener("click", onCancelClick, false);
+}
+
+window.addEventListener("load", initACLButtons, false);
DIV.pageContent
{ /* position: absolute;
- background: #ffa;
+ background-color: #ffa;
top: 3em;
left: 0px;
right: 0px;
table-layout: auto; }
DIV.linkbanner
-{
- background: #222;
+{ background-color: #222;
width: 100%;
top: 0px;
left: 0px;
color: #aaa; }
DIV.linkbanner A
-{
- top: 0px;
+{ top: 0px;
left: 0px;
color: #ddd;
text-decoration: none;
height: 3em;
overflow: auto;
border: 1px solid #444;
- background: #eee;
+ background-color: #eee;
text-align: left; }
TEXTAREA
vertical-align: middle; }
.menu LI:hover, .menu LI.submenu-selected
-{ background: #4b6983;
+{ background-color: #4b6983;
color: #fff; }
.menu LI.separator, .menu LI.separator:hover
-moz-border-left-colors: ThreeDDarkShadow ThreeDShadow transparent;
font-family: monospace;
font-weight: bold;
- background: #000;
+ background-color: #000;
color: #ddd;
top: 1em;
left: 0px;
DIV.dragHandle
{ position: absolute;
z-index: 1;
- background: #d4d0c8; }
+ background-color: #d4d0c8; }
DIV.dragHandle:active
-{ background: #99a; }
+{ background-color: #99a; }
/* search fields */
DIV#filterPanel
DIV.javascriptPopupBackground
{ position: absolute;
- background: #999;
+ background-color: #999;
-moz-opacity: 0.6;
z-index: 2;
top: 0px;
margin: 0px auto;
-moz-opacity: 1.0;
color: #000;
- background: #dedede; }
+ background-color: #dedede; }
DIV.noJavascriptErrorMessage
{ top: 10em;
DIV.dTreeNode A._selected SPAN.nodeName
{
- background: #4b6983;
+ background-color: #4b6983;
color: #fff;
}
DIV.dTreeNode SPAN._dragOver
{
- background: #4b6983;
+ background-color: #4b6983;
color: #fff;
}
{
position: relative;
color: #000;
- background: #d4d0c8;
+ background-color: #d4d0c8;
margin-top: 1.5em;
border-top: 2px solid #fff;
border-left: 2px solid #fff;
DIV.tabsContainer > UL LI.active
{ z-index: 5;
- background: #d4d0c8;
+ background-color: #d4d0c8;
border-bottom: 1px none #fff;
padding-top: 2px;
padding-bottom: 3px;
var folderPath = folderData[1];
if (username != UserLogin) {
var url = (UserFolderURL + "../" + username
- + "/" + folderPath + "/subscribe");
+ + folderPath + "/subscribe");
if (document.subscriptionAjaxRequest) {
document.subscriptionAjaxRequest.aborted = true;
document.subscriptionAjaxRequest.abort();
rfCbData);
}
else
- window.alert(labels["You cannot subscribe to a folder that you own!"].decodeEntities());
+ window.alert(labels["You cannot subscribe to a folder that you own!"]
+ .decodeEntities());
}
function folderUnsubscriptionCallback(http) {
function unsubscribeFromFolder(folder, refreshCallback, refreshCallbackData) {
if (document.body.hasClassName("popup")) {
- window.opener.unsubscribeFromFolder(folder, refreshCallback, refreshCallbackData);
+ window.opener.unsubscribeFromFolder(folder, refreshCallback,
+ refreshCallbackData);
}
else {
var folderData = folder.split(":");
document.unsubscriptionAjaxRequest.abort();
}
var rfCbData = { method: refreshCallback, data: refreshCallbackData };
- document.unsubscriptionAjaxRequest = triggerAjaxRequest(url,
- folderUnsubscriptionCallback,
- rfCbData);
+ document.unsubscriptionAjaxRequest
+ = triggerAjaxRequest(url, folderUnsubscriptionCallback,
+ rfCbData);
}
else
window.alert(labels["You cannot unsubscribe from a folder that you own!"].decodeEntities());
return w;
}
+function getUsersRightsWindowHeight() {
+ return usersRightsWindowHeight;
+}
+
+function getUsersRightsWindowWidth() {
+ return usersRightsWindowWidth;
+}
+
function onTabClick(event) {
var node = event.target;
var currentValue = number;
var index = 0;
- while (currentValue)
- {
- if (currentValue & 1)
+ while (currentValue) {
+ if (currentValue & 1)
colorTable[index]++;
- if (index == 3)
- index = 0;
- currentValue >>= 1;
- index++;
- }
+ if (index == 3)
+ index = 0;
+ currentValue >>= 1;
+ index++;
+ }
color = ("#"
+ d2h((256 / colorTable[2]) - 1)