From: wolfgang Date: Fri, 2 May 2008 23:28:37 +0000 (+0000) Subject: git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1404 d1b88da0-ebda-0310... X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=833e15e7d4fa7edfb8698d0ac2e1ba6466e1abd9;p=scalable-opengroupware.org git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1404 d1b88da0-ebda-0310-925b-ed51d893ca5b --- diff --git a/ChangeLog b/ChangeLog index 5d53d29d..e955a197 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,97 @@ +2008-05-02 Wolfgang Sourdeau + + * Main/SOGo.m ([SOGo -davURL], [SOGo -soURL]): copied methods from + SOGoObject. + + * SoObjects/SOGo/SOGoUserFolder.m ([SOGoUserFolder + -davDisplayName]): new overriden method to provide a display name + to the users principal. + + * SoObjects/SOGo/SOGoPermissions.[hm]: removed the "Save Acls" + permission since its purposes matches SOPE's "Change Permissions". + + * SoObjects/SOGo/SOGoGCSFolder.m ([SOGoGCSFolder + +webdavAclManager]): new overriden method. + + * SoObjects/SOGo/SOGoParentFolder.m ([SOGoParentFolder + +webdavAclManager]): new overriden method. + + * UI/MailPartViewers/UIxMailPartTextViewer.m (convertChars): do + not cast pointers to unsigned int to avoid problems with big + endian archs. + + * SoObjects/Contacts/SOGoContactLDAPFolder.m ([-davNamespaces]): + removed method. + + * SoObjects/Contacts/SOGoContactGCSFolder.m ([-davNamespaces]): + removed method. + + * SoObjects/SOGo/SOGoGCSFolder.m ([SOGoGCSFolder + +webdavAclManager]): new overriden method. + + * SoObjects/SOGo/SOGoFolder.m ([SOGoFolder +webdavAclManager]): + new overriden method. + + * SoObjects/Appointments/SOGoAppointmentObject.m + ([SOGoAppointmentObject +webdavAclManager]): new overriden method. + + * SoObjects/Appointments/SOGoAppointmentFolder.m + ([SOGoAppointmentFolder +webdavAclManager]): new overriden method. + ([-davNamespaces]): removed method. + ([-lookupGroupFolderForUIDs:_uidsinContext:]) + ([-lookupGroupCalendarFolderForUIDs:_uidsinContext:_ctx]): + disabled methods. + + * SoObjects/SOGo/SOGoWebDAVAclManager.[hm]: new class module that + implements the rendering of DAV acl trees as well as their mapping + from SOGo permissions. + + * SoObjects/SOGo/SOGoObject.m ([SOGoObject +initialize]): libSOGo + is now a framework, so we can simplify the loading of the DAVReportMap. + ([-lookupGroupsFolder]): disabled method. + ([SOGoObject -davOwner], [SOGoObject -davAclRestrictions]) + ([SOGoObject -davPrincipalCollectionSet]) + ([SOGoObject -davCurrentUserPrivilegeSet]) + ([SOGoObject -davSupportedPrivilegeSet], [SOGoObject -davAcl]) + ([SOGoObject -davPrincipalMatch:localContext]) + ([SOGoObject -davSupportedReportSet]): (re-)implemented dav + methods with our new dav rendering paradigm. + ([-davNamespaces]): removed method. + ([SOGoObject -domNode:nodegetChildNodesByType:type]): new helper + method to help subclass with parsing dav requests, especially wrt + REPORT ones. + ([SOGoObject +webdavAclManager]): new overridable method that + returns a properly configured DAV acl manager (see above). + + * SoObjects/Appointments/SOGoUserFolder+Appointments.[hm]: new + category module that implements DAV methods required by CalDAV. + + * UI/SOGoUI/UIxComponent.m ([UIxComponent -applicationPath]): + disabled all mentions of "SOGoGroupFolder*". + + * SoObjects/SOGo/SOGoDAVRendererTypes.[hm]: removed subclass + module, superseded by the new method mentionned below. + + * SoObjects/SOGo/SOGoWebDAVValue.m ([SOGoWebDAVValue + -stringForTag:_keyrawName:setTaginContext:contextprefixes:prefixes]): + a simple wrapper that returns an uninterpreted NSString to SOPE. + + * SoObjects/SOGo/NSArray+DAV.[hm], + * SoObjects/SOGo/NSDictionary+DAV.[hm], + * SoObjects/SOGo/NSObject+DAV.[hm], + * SoObjects/SOGo/NSString+DAV.[hm], + * SoObjects/SOGo/NSURL+DAV.[hm]: new class category modules that + handle the correct generation of DAV entries, with namespace + accounting. Those were implemented to enable the use of a simple + SoWebDAVValue as the root of the resulting string, thereby + avoiding the xml escaping done by SOPE when returning a real NSString. + +2008-04-25 Wolfgang Sourdeau + + * SoObjects/SOGo/LDAPSource.m ([LDAPSource -fetchContactsMatching:match]) + ([LDAPSource -lookupContactEntryWithUIDorEmail:uid]): take all the + mail fields into account when doing a search. + 2008-04-23 Wolfgang Sourdeau * SoObjects/SOGo/SOGoObject.m ([SOGoObject +initialize]): the diff --git a/Main/SOGo.m b/Main/SOGo.m index afb19b09..4f42cb1f 100644 --- a/Main/SOGo.m +++ b/Main/SOGo.m @@ -39,6 +39,7 @@ #import #import #import +#import #import @@ -515,6 +516,52 @@ static BOOL debugObjectAllocation = NO; return locale; } +- (NSURL *) _urlPreferringParticle: (NSString *) expected + overThisOne: (NSString *) possible +{ + NSURL *serverURL, *url; + NSMutableArray *path; + NSString *baseURL, *urlMethod; + WOContext *context; + + context = [self context]; + serverURL = [context serverURL]; + baseURL = [[self baseURLInContext: context] stringByUnescapingURL]; + path = [NSMutableArray arrayWithArray: [baseURL componentsSeparatedByString: + @"/"]]; + if ([baseURL hasPrefix: @"http"]) + { + [path removeObjectAtIndex: 1]; + [path removeObjectAtIndex: 0]; + [path replaceObjectAtIndex: 0 withObject: @""]; + } + urlMethod = [path objectAtIndex: 2]; + if (![urlMethod isEqualToString: expected]) + { + if ([urlMethod isEqualToString: possible]) + [path replaceObjectAtIndex: 2 withObject: expected]; + else + [path insertObject: expected atIndex: 2]; + } + + url = [[NSURL alloc] initWithScheme: [serverURL scheme] + host: [serverURL host] + path: [path componentsJoinedByString: @"/"]]; + [url autorelease]; + + return url; +} + +- (NSURL *) davURL +{ + return [self _urlPreferringParticle: @"dav" overThisOne: @"so"]; +} + +- (NSURL *) soURL +{ + return [self _urlPreferringParticle: @"so" overThisOne: @"dav"]; +} + /* name (used by the WEResourceManager) */ - (NSString *) name diff --git a/SOPE/sope-patchset-r1620.diff b/SOPE/sope-patchset-r1620.diff index 531ded53..b7416d02 100644 --- a/SOPE/sope-patchset-r1620.diff +++ b/SOPE/sope-patchset-r1620.diff @@ -1,181 +1,3 @@ -Index: sope-gdl1/PostgreSQL/PostgreSQL72Channel.m -=================================================================== ---- sope-gdl1/PostgreSQL/PostgreSQL72Channel.m (révision 1620) -+++ sope-gdl1/PostgreSQL/PostgreSQL72Channel.m (copie de travail) -@@ -713,6 +713,39 @@ - return ms; - } - -+/* GCSEOAdaptorChannel protocol */ -+static NSString *sqlFolderFormat = (@"CREATE TABLE %@ (\n" \ -+ @" c_name VARCHAR (256) NOT NULL,\n" -+ @" c_content VARCHAR (100000) NOT NULL,\n" -+ @" c_creationdate INT4 NOT NULL,\n" -+ @" c_lastmodified INT4 NOT NULL,\n" -+ @" c_version INT4 NOT NULL,\n" -+ @" c_deleted INT4 NULL\n" -+ @")"); -+static NSString *sqlFolderACLFormat = (@"CREATE TABLE %@ (\n" \ -+ @" c_uid VARCHAR (256) NOT NULL,\n" -+ @" c_object VARCHAR (256) NOT NULL,\n" -+ @" c_role VARCHAR (80) NOT NULL\n" -+ @")"); -+ -+- (NSException *) createGCSFolderTableWithName: (NSString *) tableName -+{ -+ NSString *sql; -+ -+ sql = [NSString stringWithFormat: sqlFolderFormat, tableName]; -+ -+ return [self evaluateExpressionX: sql]; -+} -+ -+- (NSException *) createGCSFolderACLTableWithName: (NSString *) tableName -+{ -+ NSString *sql; -+ -+ sql = [NSString stringWithFormat: sqlFolderACLFormat, tableName]; -+ -+ return [self evaluateExpressionX: sql]; -+} -+ - @end /* PostgreSQL72Channel */ - - @implementation PostgreSQL72Channel(PrimaryKeyGeneration) -Index: sope-gdl1/Oracle8/OracleAdaptorChannel.m -=================================================================== ---- sope-gdl1/Oracle8/OracleAdaptorChannel.m (révision 1620) -+++ sope-gdl1/Oracle8/OracleAdaptorChannel.m (copie de travail) -@@ -30,6 +30,7 @@ - - #import - -+static BOOL debugOn = NO; - // - // - // -@@ -41,10 +42,19 @@ - - @implementation OracleAdaptorChannel (Private) - --- (void) _cleanup -++ (void) initialize - { -+ NSUserDefaults *ud; -+ -+ ud = [NSUserDefaults standardUserDefaults]; -+ debugOn = [ud boolForKey: @"OracleAdaptorDebug"]; -+} -+ -+- (void) _cleanup -+{ - column_info *info; - int c; -+ sword result; - - [_resultSetProperties removeAllObjects]; - -@@ -58,11 +68,29 @@ - // so we just free the value instead. - if (info->value) - { -- if (OCIDescriptorFree((dvoid *)info->value, (ub4)OCI_DTYPE_LOB) != OCI_SUCCESS) -+ if (info->type == SQLT_CLOB -+ || info->type == SQLT_BLOB -+ || info->type == SQLT_BFILEE -+ || info->type == SQLT_CFILEE) -+ { -+ result = OCIDescriptorFree((dvoid *)info->value, (ub4) OCI_DTYPE_LOB); -+ if (result != OCI_SUCCESS) -+ { -+ NSLog (@"value was not a LOB descriptor"); -+ abort(); -+ } -+ } -+ else - free(info->value); - info->value = NULL; - } -- free(info); -+ else -+ { -+ NSLog (@"trying to free an already freed value!"); -+ abort(); -+ } -+ free(info); -+ - [_row_buffer removeObjectAtIndex: c]; - } - -@@ -231,6 +259,9 @@ - - [self _cleanup]; - -+ if (debugOn) -+ [self logWithFormat: @"expression: %@", theExpression]; -+ - if (!theExpression || ![theExpression length]) - { - [NSException raise: @"OracleInvalidExpressionException" -@@ -302,7 +333,9 @@ - // We read the maximum width of a column - info->max_width = 0; - status = OCIAttrGet((dvoid*)param, (ub4)OCI_DTYPE_PARAM, (dvoid*)&(info->max_width), (ub4 *)0, (ub4)OCI_ATTR_DATA_SIZE, (OCIError *)_oci_err); -- -+ -+ if (debugOn) -+ NSLog(@"name: %s, type: %d", cname, info->type); - attribute = [EOAttribute attributeWithOracleType: info->type name: cname length: clen width: info->max_width]; - [_resultSetProperties addObject: attribute]; - -Index: sope-gdl1/Oracle8/OracleAdaptorChannelController.m -=================================================================== ---- sope-gdl1/Oracle8/OracleAdaptorChannelController.m (révision 1620) -+++ sope-gdl1/Oracle8/OracleAdaptorChannelController.m (copie de travail) -@@ -31,6 +31,8 @@ - #import - #import - -+static BOOL debugOn = NO; -+ - // - // - // -@@ -48,6 +50,14 @@ - // - @implementation OracleAdaptorChannelController - -++ (void) initialize -+{ -+ NSUserDefaults *ud; -+ -+ ud = [NSUserDefaults standardUserDefaults]; -+ debugOn = [ud boolForKey: @"OracleAdaptorDebug"]; -+} -+ - - (EODelegateResponse) adaptorChannel: (id) theChannel - willInsertRow: (NSMutableDictionary *) theRow - forEntity: (EOEntity *) theEntity -@@ -56,7 +66,8 @@ - NSArray *keys; - int i, c; - -- NSLog(@"willInsertRow: %@ %@", [theRow description], [theEntity description]); -+ if (debugOn) -+ NSLog(@"willInsertRow: %@ %@", [theRow description], [theEntity description]); - - s = AUTORELEASE([[NSMutableString alloc] init]); - -@@ -101,7 +112,8 @@ - NSArray *keys; - int i, c; - -- NSLog(@"willUpdatetRow: %@ %@", [theRow description], [theQualifier description]); -+ if (debugOn) -+ NSLog(@"willUpdateRow: %@ %@", [theRow description], [theQualifier description]); - - s = AUTORELEASE([[NSMutableString alloc] init]); - Index: sope-mime/NGImap4/NGImap4Connection.m =================================================================== --- sope-mime/NGImap4/NGImap4Connection.m (révision 1620) @@ -1353,6 +1175,184 @@ Index: sope-mime/NGMime/NGMimeContentDispositionHeaderFieldGenerator.m } return data; } +Index: sope-gdl1/PostgreSQL/PostgreSQL72Channel.m +=================================================================== +--- sope-gdl1/PostgreSQL/PostgreSQL72Channel.m (révision 1620) ++++ sope-gdl1/PostgreSQL/PostgreSQL72Channel.m (copie de travail) +@@ -713,6 +713,39 @@ + return ms; + } + ++/* GCSEOAdaptorChannel protocol */ ++static NSString *sqlFolderFormat = (@"CREATE TABLE %@ (\n" \ ++ @" c_name VARCHAR (256) NOT NULL,\n" ++ @" c_content VARCHAR (100000) NOT NULL,\n" ++ @" c_creationdate INT4 NOT NULL,\n" ++ @" c_lastmodified INT4 NOT NULL,\n" ++ @" c_version INT4 NOT NULL,\n" ++ @" c_deleted INT4 NULL\n" ++ @")"); ++static NSString *sqlFolderACLFormat = (@"CREATE TABLE %@ (\n" \ ++ @" c_uid VARCHAR (256) NOT NULL,\n" ++ @" c_object VARCHAR (256) NOT NULL,\n" ++ @" c_role VARCHAR (80) NOT NULL\n" ++ @")"); ++ ++- (NSException *) createGCSFolderTableWithName: (NSString *) tableName ++{ ++ NSString *sql; ++ ++ sql = [NSString stringWithFormat: sqlFolderFormat, tableName]; ++ ++ return [self evaluateExpressionX: sql]; ++} ++ ++- (NSException *) createGCSFolderACLTableWithName: (NSString *) tableName ++{ ++ NSString *sql; ++ ++ sql = [NSString stringWithFormat: sqlFolderACLFormat, tableName]; ++ ++ return [self evaluateExpressionX: sql]; ++} ++ + @end /* PostgreSQL72Channel */ + + @implementation PostgreSQL72Channel(PrimaryKeyGeneration) +Index: sope-gdl1/Oracle8/OracleAdaptorChannel.m +=================================================================== +--- sope-gdl1/Oracle8/OracleAdaptorChannel.m (révision 1620) ++++ sope-gdl1/Oracle8/OracleAdaptorChannel.m (copie de travail) +@@ -30,6 +30,7 @@ + + #import + ++static BOOL debugOn = NO; + // + // + // +@@ -41,10 +42,19 @@ + + @implementation OracleAdaptorChannel (Private) + +-- (void) _cleanup +++ (void) initialize + { ++ NSUserDefaults *ud; ++ ++ ud = [NSUserDefaults standardUserDefaults]; ++ debugOn = [ud boolForKey: @"OracleAdaptorDebug"]; ++} ++ ++- (void) _cleanup ++{ + column_info *info; + int c; ++ sword result; + + [_resultSetProperties removeAllObjects]; + +@@ -58,11 +68,29 @@ + // so we just free the value instead. + if (info->value) + { +- if (OCIDescriptorFree((dvoid *)info->value, (ub4)OCI_DTYPE_LOB) != OCI_SUCCESS) ++ if (info->type == SQLT_CLOB ++ || info->type == SQLT_BLOB ++ || info->type == SQLT_BFILEE ++ || info->type == SQLT_CFILEE) ++ { ++ result = OCIDescriptorFree((dvoid *)info->value, (ub4) OCI_DTYPE_LOB); ++ if (result != OCI_SUCCESS) ++ { ++ NSLog (@"value was not a LOB descriptor"); ++ abort(); ++ } ++ } ++ else + free(info->value); + info->value = NULL; + } +- free(info); ++ else ++ { ++ NSLog (@"trying to free an already freed value!"); ++ abort(); ++ } ++ free(info); ++ + [_row_buffer removeObjectAtIndex: c]; + } + +@@ -231,6 +259,9 @@ + + [self _cleanup]; + ++ if (debugOn) ++ [self logWithFormat: @"expression: %@", theExpression]; ++ + if (!theExpression || ![theExpression length]) + { + [NSException raise: @"OracleInvalidExpressionException" +@@ -302,7 +333,9 @@ + // We read the maximum width of a column + info->max_width = 0; + status = OCIAttrGet((dvoid*)param, (ub4)OCI_DTYPE_PARAM, (dvoid*)&(info->max_width), (ub4 *)0, (ub4)OCI_ATTR_DATA_SIZE, (OCIError *)_oci_err); +- ++ ++ if (debugOn) ++ NSLog(@"name: %s, type: %d", cname, info->type); + attribute = [EOAttribute attributeWithOracleType: info->type name: cname length: clen width: info->max_width]; + [_resultSetProperties addObject: attribute]; + +Index: sope-gdl1/Oracle8/OracleAdaptorChannelController.m +=================================================================== +--- sope-gdl1/Oracle8/OracleAdaptorChannelController.m (révision 1620) ++++ sope-gdl1/Oracle8/OracleAdaptorChannelController.m (copie de travail) +@@ -31,6 +31,8 @@ + #import + #import + ++static BOOL debugOn = NO; ++ + // + // + // +@@ -48,6 +50,14 @@ + // + @implementation OracleAdaptorChannelController + +++ (void) initialize ++{ ++ NSUserDefaults *ud; ++ ++ ud = [NSUserDefaults standardUserDefaults]; ++ debugOn = [ud boolForKey: @"OracleAdaptorDebug"]; ++} ++ + - (EODelegateResponse) adaptorChannel: (id) theChannel + willInsertRow: (NSMutableDictionary *) theRow + forEntity: (EOEntity *) theEntity +@@ -56,7 +66,8 @@ + NSArray *keys; + int i, c; + +- NSLog(@"willInsertRow: %@ %@", [theRow description], [theEntity description]); ++ if (debugOn) ++ NSLog(@"willInsertRow: %@ %@", [theRow description], [theEntity description]); + + s = AUTORELEASE([[NSMutableString alloc] init]); + +@@ -101,7 +112,8 @@ + NSArray *keys; + int i, c; + +- NSLog(@"willUpdatetRow: %@ %@", [theRow description], [theQualifier description]); ++ if (debugOn) ++ NSLog(@"willUpdateRow: %@ %@", [theRow description], [theQualifier description]); + + s = AUTORELEASE([[NSMutableString alloc] init]); + Index: sope-core/NGExtensions/NGExtensions/NSString+Ext.h =================================================================== --- sope-core/NGExtensions/NGExtensions/NSString+Ext.h (révision 1620) @@ -1763,7 +1763,7 @@ Index: sope-appserver/NGObjWeb/DAVPropMap.plist =================================================================== --- sope-appserver/NGObjWeb/DAVPropMap.plist (révision 1620) +++ sope-appserver/NGObjWeb/DAVPropMap.plist (copie de travail) -@@ -24,6 +24,13 @@ +@@ -24,13 +24,19 @@ "{DAV:}status" = "davStatus"; "{http://apache.org/dav/props/}executable" = "davIsExecutable"; @@ -1777,14 +1777,32 @@ Index: sope-appserver/NGObjWeb/DAVPropMap.plist /* used with Apple WebDAV */ "{DAV:}quota" = davQuota; "{DAV:}quotaused" = davQuotaUsed; -@@ -120,17 +127,21 @@ + "{http://www.apple.com/webdav_fs/props/}appledoubleheader"=appleDoubleHeader; + + /* Novell NetDrive */ +- "{DAV:}owner" = davOwner; + "{DAV:}locktoken" = davLockToken; + "{DAV:}activelock" = davActiveLock; + // TODO: non-standard?, also used by WebDrive +@@ -120,17 +126,32 @@ "{http://ucb.openoffice.org/dav/props/}IsRemoveable" = isOOoRemoveable; "{http://ucb.openoffice.org/dav/props/}IsVolume" = isOOoVolume; "{http://ucb.openoffice.org/dav/props/}TargetURL" = davOOoTargetURL; - + /* WebDAV ACL */ ++ "{DAV:}owner" = davOwner; ++ "{DAV:}group" = davGroup; ++ "{DAV:}supported-privilege-set" = davSupportedPrivilegeSet; ++ "{DAV:}principal-collection-set" = davPrincipalCollectionSet; ++ "{DAV:}acl" = davAcl; ++ "{DAV:}acl-restrictions" = davAclRestrictions; "{DAV:}current-user-privilege-set" = davCurrentUserPrivilegeSet; ++ "{DAV:}inherited-acl-set" = davInheritedAclSet; ++ "{DAV:}principal-URL" = davPrincipalURL; ++ "{DAV:}alternate-URI-set" = davAlternateURISet; ++ "{DAV:}group-member-set" = davGroupMemberSet; ++ "{DAV:}group-membership" = davGroupMembership; /* CalDAV */ + "{urn:ietf:params:xml:ns:caldav}calendar-data" = davCalendarData; @@ -1801,7 +1819,7 @@ Index: sope-appserver/NGObjWeb/DAVPropMap.plist /* CardDAV */ "{urn:ietf:params:xml:ns:carddav}supported-address-data" = -@@ -138,13 +149,13 @@ +@@ -138,13 +159,13 @@ "{urn:ietf:params:xml:ns:carddav}addressbook-description" = davDescription; /* Apple CalServer */ diff --git a/SoObjects/Appointments/GNUmakefile b/SoObjects/Appointments/GNUmakefile index 7893f0d4..f4fb6874 100644 --- a/SoObjects/Appointments/GNUmakefile +++ b/SoObjects/Appointments/GNUmakefile @@ -6,6 +6,7 @@ WOBUNDLE_NAME = Appointments Appointments_PRINCIPAL_CLASS = SOGoAppointmentsProduct +# SOGoGroupAppointmentFolder.m Appointments_OBJC_FILES = \ Product.m \ NSArray+Appointments.m \ @@ -19,8 +20,8 @@ Appointments_OBJC_FILES = \ SOGoTaskObject.m \ SOGoAppointmentFolder.m \ SOGoAppointmentFolders.m \ - SOGoGroupAppointmentFolder.m \ SOGoFreeBusyObject.m \ + SOGoUserFolder+Appointments.m \ \ SOGoAptMailNotification.m \ SOGoAptMailInvitation.m \ diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.h b/SoObjects/Appointments/SOGoAppointmentFolder.h index 8b0d97ed..7e340bba 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.h +++ b/SoObjects/Appointments/SOGoAppointmentFolder.h @@ -113,10 +113,10 @@ - (NSArray *) lookupCalendarFoldersForICalPerson: (NSArray *) _persons inContext: (id) _ctx; -- (id) lookupGroupFolderForUIDs: (NSArray *) _uids - inContext: (id) _ctx; -- (id) lookupGroupCalendarFolderForUIDs: (NSArray *) _uids - inContext: (id) _ctx; +// - (id) lookupGroupFolderForUIDs: (NSArray *) _uids +// inContext: (id) _ctx; +// - (id) lookupGroupCalendarFolderForUIDs: (NSArray *) _uids +// inContext: (id) _ctx; /* bulk fetches */ diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.m b/SoObjects/Appointments/SOGoAppointmentFolder.m index bf618a8b..889e3390 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.m +++ b/SoObjects/Appointments/SOGoAppointmentFolder.m @@ -49,13 +49,15 @@ #import // #import +#import +#import +#import #import -#import +// #import #import #import -#import -#import #import +#import #import "SOGoAppointmentObject.h" #import "SOGoAppointmentFolders.h" @@ -110,6 +112,139 @@ static NSNumber *sharedYes = nil; sharedYes = [[NSNumber numberWithBool: YES] retain]; } ++ (SOGoWebDAVAclManager *) webdavAclManager +{ + SOGoWebDAVAclManager *webdavAclManager = nil; + NSString *nsCD, *nsD, *nsI; + + if (!webdavAclManager) + { + nsD = @"DAV:"; + nsCD = @"urn:ietf:params:xml:ns:caldav"; + nsI = @"urn:inverse:params:xml:ns:inverse-dav"; + + webdavAclManager = [SOGoWebDAVAclManager new]; + [webdavAclManager registerDAVPermission: davElement (@"read", nsD) + abstract: YES + withEquivalent: SoPerm_WebDAVAccess + asChildOf: davElement (@"all", nsD)]; + [webdavAclManager registerDAVPermission: davElement (@"read-current-user-privilege-set", nsD) + abstract: YES + withEquivalent: SoPerm_WebDAVAccess + asChildOf: davElement (@"read", nsD)]; + [webdavAclManager registerDAVPermission: davElement (@"read-free-busy", nsD) + abstract: NO + withEquivalent: SoPerm_AccessContentsInformation + asChildOf: davElement (@"read", nsD)]; + [webdavAclManager registerDAVPermission: davElement (@"write", nsD) + abstract: YES + withEquivalent: nil + asChildOf: davElement (@"all", nsD)]; + [webdavAclManager registerDAVPermission: davElement (@"bind", nsD) + abstract: NO + withEquivalent: SoPerm_AddDocumentsImagesAndFiles + asChildOf: davElement (@"write", nsD)]; + [webdavAclManager registerDAVPermission: davElement (@"schedule", + nsCD) + abstract: NO + withEquivalent: nil + asChildOf: davElement (@"bind", nsD)]; + [webdavAclManager registerDAVPermission: davElement (@"schedule-post", + nsCD) + abstract: NO + withEquivalent: nil + asChildOf: davElement (@"schedule", nsCD)]; + [webdavAclManager registerDAVPermission: + davElement (@"schedule-post-vevent", nsCD) + abstract: NO + withEquivalent: nil + asChildOf: davElement (@"schedule-post", nsCD)]; + [webdavAclManager registerDAVPermission: + davElement (@"schedule-post-vtodo", nsCD) + abstract: NO + withEquivalent: nil + asChildOf: davElement (@"schedule-post", nsCD)]; + [webdavAclManager registerDAVPermission: + davElement (@"schedule-post-vjournal", nsCD) + abstract: NO + withEquivalent: nil + asChildOf: davElement (@"schedule-post", nsCD)]; + [webdavAclManager registerDAVPermission: + davElement (@"schedule-post-vfreebusy", nsCD) + abstract: NO + withEquivalent: nil + asChildOf: davElement (@"schedule-post", nsCD)]; + [webdavAclManager registerDAVPermission: davElement (@"schedule-deliver", + nsCD) + abstract: NO + withEquivalent: nil + asChildOf: davElement (@"schedule", nsCD)]; + [webdavAclManager registerDAVPermission: + davElement (@"schedule-deliver-vevent", nsCD) + abstract: NO + withEquivalent: nil + asChildOf: davElement (@"schedule-deliver", nsCD)]; + [webdavAclManager registerDAVPermission: + davElement (@"schedule-deliver-vtodo", nsCD) + abstract: NO + withEquivalent: nil + asChildOf: davElement (@"schedule-deliver", nsCD)]; + [webdavAclManager registerDAVPermission: + davElement (@"schedule-deliver-vjournal", nsCD) + abstract: NO + withEquivalent: nil + asChildOf: davElement (@"schedule-deliver", nsCD)]; + [webdavAclManager registerDAVPermission: + davElement (@"schedule-deliver-vfreebusy", nsCD) + abstract: NO + withEquivalent: nil + asChildOf: davElement (@"schedule-deliver", nsCD)]; + [webdavAclManager registerDAVPermission: davElement (@"schedule-respond", + nsCD) + abstract: NO + withEquivalent: nil + asChildOf: davElement (@"schedule", nsCD)]; + [webdavAclManager registerDAVPermission: + davElement (@"schedule-respond-vevent", nsCD) + abstract: NO + withEquivalent: nil + asChildOf: davElement (@"schedule-respond", nsCD)]; + [webdavAclManager registerDAVPermission: + davElement (@"schedule-respond-vtodo", nsCD) + abstract: NO + withEquivalent: nil + asChildOf: davElement (@"schedule-respond", nsCD)]; + [webdavAclManager registerDAVPermission: davElement (@"unbind", nsD) + abstract: NO + withEquivalent: SoPerm_DeleteObjects + asChildOf: davElement (@"write", nsD)]; + [webdavAclManager + registerDAVPermission: davElement (@"write-properties", nsD) + abstract: YES + withEquivalent: SoPerm_ChangePermissions /* hackish */ + asChildOf: davElement (@"write", nsD)]; + [webdavAclManager + registerDAVPermission: davElement (@"write-content", nsD) + abstract: YES + withEquivalent: nil + asChildOf: davElement (@"write", nsD)]; + [webdavAclManager registerDAVPermission: davElement (@"admin", nsI) + abstract: YES + withEquivalent: nil + asChildOf: davElement (@"all", nsD)]; + [webdavAclManager registerDAVPermission: davElement (@"read-acl", nsD) + abstract: YES + withEquivalent: SOGoPerm_ReadAcls + asChildOf: davElement (@"admin", nsI)]; + [webdavAclManager registerDAVPermission: davElement (@"write-acl", nsD) + abstract: YES + withEquivalent: SoPerm_ChangePermissions + asChildOf: davElement (@"admin", nsI)]; + } + + return webdavAclManager; +} + - (id) initWithName: (NSString *) name inContainer: (id) newContainer { @@ -593,16 +728,6 @@ static NSNumber *sharedYes = nil; } } -- (NSArray *) davNamespaces -{ - NSMutableArray *ns; - - ns = [NSMutableArray arrayWithArray: [super davNamespaces]]; - [ns addObjectUniquely: @"urn:ietf:params:xml:ns:caldav"]; - - return ns; -} - - (NSString *) davCalendarColor { NSString *color; @@ -1649,37 +1774,37 @@ static NSNumber *sharedYes = nil; return [self lookupCalendarFoldersForUIDs:uids inContext:_ctx]; } -- (id) lookupGroupFolderForUIDs: (NSArray *) _uids - inContext: (id)_ctx -{ - SOGoCustomGroupFolder *folder; +// - (id) lookupGroupFolderForUIDs: (NSArray *) _uids +// inContext: (id)_ctx +// { +// SOGoCustomGroupFolder *folder; - if (_uids == nil) - return nil; +// if (_uids == nil) +// return nil; - folder = [[SOGoCustomGroupFolder alloc] initWithUIDs:_uids inContainer:self]; - return [folder autorelease]; -} +// folder = [[SOGoCustomGroupFolder alloc] initWithUIDs:_uids inContainer:self]; +// return [folder autorelease]; +// } -- (id) lookupGroupCalendarFolderForUIDs: (NSArray *) _uids - inContext: (id) _ctx -{ - SOGoCustomGroupFolder *folder; +// - (id) lookupGroupCalendarFolderForUIDs: (NSArray *) _uids +// inContext: (id) _ctx +// { +// SOGoCustomGroupFolder *folder; - if ((folder = [self lookupGroupFolderForUIDs:_uids inContext:_ctx]) == nil) - return nil; +// if ((folder = [self lookupGroupFolderForUIDs:_uids inContext:_ctx]) == nil) +// return nil; - folder = [folder lookupName:@"Calendar" inContext:_ctx acquire:NO]; - if (![folder isNotNull]) - return nil; - if ([folder isKindOfClass:[NSException class]]) { - [self debugWithFormat:@"Note: could not lookup 'Calendar' in folder: %@", - folder]; - return nil; - } +// folder = [folder lookupName:@"Calendar" inContext:_ctx acquire:NO]; +// if (![folder isNotNull]) +// return nil; +// if ([folder isKindOfClass:[NSException class]]) { +// [self debugWithFormat:@"Note: could not lookup 'Calendar' in folder: %@", +// folder]; +// return nil; +// } - return folder; -} +// return folder; +// } /* bulk fetches */ diff --git a/SoObjects/Appointments/SOGoAppointmentObject.m b/SoObjects/Appointments/SOGoAppointmentObject.m index c3f28371..71863150 100644 --- a/SoObjects/Appointments/SOGoAppointmentObject.m +++ b/SoObjects/Appointments/SOGoAppointmentObject.m @@ -33,9 +33,12 @@ #import #import #import +#import #import #import #import +#import +#import #import #import "NSArray+Appointments.h" @@ -48,6 +51,76 @@ @implementation SOGoAppointmentObject ++ (SOGoWebDAVAclManager *) webdavAclManager +{ + SOGoWebDAVAclManager *webdavAclManager = nil; + NSString *nsD, *nsI; + + if (!webdavAclManager) + { + nsD = @"DAV:"; + nsI = @"urn:inverse:params:xml:ns:inverse-dav"; + +// extern NSString *SOGoCalendarPerm_ViewAllComponent; +// extern NSString *SOGoCalendarPerm_ViewDAndT; +// extern NSString *SOGoCalendarPerm_ModifyComponent; +// extern NSString *SOGoCalendarPerm_RespondToComponent; + + webdavAclManager = [SOGoWebDAVAclManager new]; + [webdavAclManager registerDAVPermission: davElement (@"read", nsD) + abstract: YES + withEquivalent: nil + asChildOf: davElement (@"all", nsD)]; + [webdavAclManager registerDAVPermission: davElement (@"read-current-user-privilege-set", nsD) + abstract: YES + withEquivalent: SoPerm_WebDAVAccess + asChildOf: davElement (@"read", nsD)]; + [webdavAclManager registerDAVPermission: davElement (@"view-whole-component", nsI) + abstract: NO + withEquivalent: SOGoCalendarPerm_ViewAllComponent + asChildOf: davElement (@"read", nsD)]; + [webdavAclManager registerDAVPermission: davElement (@"view-date-and-time", nsI) + abstract: NO + withEquivalent: SOGoCalendarPerm_ViewDAndT + asChildOf: davElement (@"view-whole-component", nsI)]; + [webdavAclManager registerDAVPermission: davElement (@"write", nsD) + abstract: YES + withEquivalent: nil + asChildOf: davElement (@"all", nsD)]; + [webdavAclManager + registerDAVPermission: davElement (@"write-properties", nsD) + abstract: YES + withEquivalent: SoPerm_ChangePermissions /* hackish */ + asChildOf: davElement (@"write", nsD)]; + [webdavAclManager + registerDAVPermission: davElement (@"write-content", nsD) + abstract: YES + withEquivalent: SOGoCalendarPerm_ModifyComponent + asChildOf: davElement (@"write", nsD)]; + [webdavAclManager + registerDAVPermission: davElement (@"respond-to-component", nsI) + abstract: YES + withEquivalent: SOGoCalendarPerm_RespondToComponent + asChildOf: davElement (@"write-content", nsD)]; + [webdavAclManager registerDAVPermission: davElement (@"admin", nsI) + abstract: YES + withEquivalent: nil + asChildOf: davElement (@"all", nsD)]; + [webdavAclManager + registerDAVPermission: davElement (@"read-acl", nsD) + abstract: YES + withEquivalent: SOGoPerm_ReadAcls + asChildOf: davElement (@"admin", nsI)]; + [webdavAclManager + registerDAVPermission: davElement (@"write-acl", nsD) + abstract: YES + withEquivalent: nil + asChildOf: davElement (@"admin", nsI)]; + } + + return webdavAclManager; +} + - (NSString *) componentTag { return @"vevent"; diff --git a/SoObjects/Appointments/SOGoAptMailDeletion.m b/SoObjects/Appointments/SOGoAptMailDeletion.m index 02b7c949..936f39fe 100644 --- a/SoObjects/Appointments/SOGoAptMailDeletion.m +++ b/SoObjects/Appointments/SOGoAptMailDeletion.m @@ -39,7 +39,7 @@ @implementation SOGoAptMailGermanDeletion @end -@interface SOGoAptMailItalinDeletion : SOGoAptMailNotification +@interface SOGoAptMailItalianDeletion : SOGoAptMailNotification @end @implementation SOGoAptMailItalianDeletion diff --git a/SoObjects/Appointments/SOGoUserFolder+Appointments.h b/SoObjects/Appointments/SOGoUserFolder+Appointments.h new file mode 100644 index 00000000..d1edfa28 --- /dev/null +++ b/SoObjects/Appointments/SOGoUserFolder+Appointments.h @@ -0,0 +1,42 @@ +/* SOGoUserFolder+Appointments.h - this file is part of SOGo + * + * Copyright (C) 2008 Inverse groupe conseil + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef SOGOUSERFOLDER_APPOINTMENTS_H +#define SOGOUSERFOLDER_APPOINTMENTS_H + +@class NSArray; + +#import + +@interface SOGoUserFolder (SOGoCalDAVSupport) + +- (NSArray *) davCalendarUserAddressSet; + +// - (NSArray *) davCalendarHomeSet +// - (NSArray *) davCalendarScheduleInboxURL +// - (NSString *) davCalendarScheduleOutboxURL +// - (NSString *) davDropboxHomeURL +// - (NSString *) davNotificationsURL + +@end + +#endif /* SOGOUSERFOLDER_APPOINTMENTS_H */ diff --git a/SoObjects/Appointments/SOGoUserFolder+Appointments.m b/SoObjects/Appointments/SOGoUserFolder+Appointments.m new file mode 100644 index 00000000..fa890c75 --- /dev/null +++ b/SoObjects/Appointments/SOGoUserFolder+Appointments.m @@ -0,0 +1,130 @@ +/* SOGoUserFolder+Appointments.m - this file is part of SOGo + * + * Copyright (C) 2008 Inverse groupe conseil + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#import +#import + +#import + +#import "SOGoUserFolder+Appointments.h" + +@implementation SOGoUserFolder (SOGoCalDAVSupport) + +- (NSArray *) davCalendarUserAddressSet +{ + NSArray *tag, *allEmails; + NSMutableArray *addresses; + NSEnumerator *emails; + NSString *currentEmail; + + addresses = [NSMutableArray array]; + + allEmails = [[context activeUser] allEmails]; + emails = [allEmails objectEnumerator]; + while ((currentEmail = [emails nextObject])) + { + tag = [NSArray arrayWithObjects: @"href", @"DAV:", @"D", + [NSString stringWithFormat: @"MAILTO:%@", currentEmail], + nil]; + [addresses addObject: tag]; + } + + return addresses; +} + + +// /* CalDAV support */ +// - (NSArray *) davCalendarHomeSet +// { +// /* +// +// http://cal.example.com/home/bernard/calendars/ +// + +// Note: this is the *container* for calendar collections, not the +// collections itself. So for use its the home folder, the +// public folder and the groups folder. +// */ +// NSArray *tag; +// SOGoAppointmentFolders *parent; + +// parent = [self privateCalendars: @"Calendar" inContext: context]; +// tag = [NSArray arrayWithObjects: @"href", @"DAV:", @"D", +// [parent davURL], nil]; + +// return [NSArray arrayWithObject: tag]; +// } + +// - (NSArray *) davCalendarScheduleInboxURL +// { +// NSArray *tag; +// SOGoAppointmentFolders *parent; + +// parent = [self privateCalendars: @"Calendar" inContext: context]; +// tag = [NSArray arrayWithObjects: @"href", @"DAV:", @"D", +// [NSString stringWithFormat: @"%@personal/", [parent davURL]], +// nil]; + +// return [NSArray arrayWithObject: tag]; +// } + +// - (NSString *) davCalendarScheduleOutboxURL +// { +// NSArray *tag; +// SOGoAppointmentFolders *parent; + +// parent = [self privateCalendars: @"Calendar" inContext: context]; +// tag = [NSArray arrayWithObjects: @"href", @"DAV:", @"D", +// [NSString stringWithFormat: @"%@personal/", [parent davURL]], +// nil]; + +// return [NSArray arrayWithObject: tag]; +// } + +// - (NSString *) davDropboxHomeURL +// { +// NSArray *tag; +// SOGoAppointmentFolders *parent; + +// parent = [self privateCalendars: @"Calendar" inContext: context]; +// tag = [NSArray arrayWithObjects: @"href", @"DAV:", @"D", +// [NSString stringWithFormat: @"%@personal/", [parent davURL]], +// nil]; + +// return [NSArray arrayWithObject: tag]; +// } + +// - (NSString *) davNotificationsURL +// { +// NSArray *tag; +// SOGoAppointmentFolders *parent; + +// parent = [self privateCalendars: @"Calendar" inContext: context]; +// tag = [NSArray arrayWithObjects: @"href", @"DAV:", @"D", +// [NSString stringWithFormat: @"%@personal/", [parent davURL]], +// nil]; + +// return [NSArray arrayWithObject: tag]; +// } + +@end diff --git a/SoObjects/Appointments/product.plist b/SoObjects/Appointments/product.plist index ce2616d7..d8a5652a 100644 --- a/SoObjects/Appointments/product.plist +++ b/SoObjects/Appointments/product.plist @@ -30,9 +30,9 @@ "RespondToConfidentialRecords" = ( "Owner", "ConfidentialModifier", "ConfidentialResponder" ); }; }; - SOGoGroupAppointmentFolder = { - superclass = "SOGoAppointmentFolder"; - }; +// SOGoGroupAppointmentFolder = { +// superclass = "SOGoAppointmentFolder"; +// }; SOGoCalendarComponent = { superclass = "SOGoContentObject"; defaultRoles = { diff --git a/SoObjects/Contacts/SOGoContactGCSFolder.m b/SoObjects/Contacts/SOGoContactGCSFolder.m index 0c285bae..2fbe1963 100644 --- a/SoObjects/Contacts/SOGoContactGCSFolder.m +++ b/SoObjects/Contacts/SOGoContactGCSFolder.m @@ -384,16 +384,6 @@ return classes; } -- (NSArray *) davNamespaces -{ - NSMutableArray *ns; - - ns = [NSMutableArray arrayWithArray: [super davNamespaces]]; - [ns addObjectUniquely: @"urn:ietf:params:xml:ns:carddav"]; - - return ns; -} - - (NSString *) groupDavResourceType { return @"vcard-collection"; diff --git a/SoObjects/Contacts/SOGoContactLDAPFolder.m b/SoObjects/Contacts/SOGoContactLDAPFolder.m index f3d17328..ce125336 100644 --- a/SoObjects/Contacts/SOGoContactLDAPFolder.m +++ b/SoObjects/Contacts/SOGoContactLDAPFolder.m @@ -130,11 +130,6 @@ ASSIGN (ldapSource, newLDAPSource); } -- (NSArray *) davNamespaces -{ - return [NSArray arrayWithObject: @"urn:ietf:params:xml:ns:carddav"]; -} - - (NSString *) groupDavResourceType { return @"vcard-collection"; diff --git a/SoObjects/Mailer/product.plist b/SoObjects/Mailer/product.plist index b97c93e9..6d013e67 100644 --- a/SoObjects/Mailer/product.plist +++ b/SoObjects/Mailer/product.plist @@ -43,7 +43,7 @@ "Delete Objects" = ( "Owner", "ObjectEraser" ); "WebDAV Access" = ( "Owner", "ObjectViewer" ); "ReadAcls" = ( "Owner", "MailAdministrator" ); - "SaveAcls" = ( "Owner", "MailAdministrator" ); + "Change Permissions" = ( "Owner", "MailAdministrator" ); }; }; /* SOGoSharedInboxFolder = { diff --git a/SoObjects/SOGo/DAVReportMap.plist b/SoObjects/SOGo/DAVReportMap.plist index 5481dcd0..7523eab8 100644 --- a/SoObjects/SOGo/DAVReportMap.plist +++ b/SoObjects/SOGo/DAVReportMap.plist @@ -10,6 +10,9 @@ "{urn:ietf:params:xml:ns:carddav}supported-collation-set" = davSupportedCollectionSet; + /* WebDAV ACL */ + "{DAV:}principal-match" = davPrincipalMatch; + /* Inverse DAV */ "{urn:inverse:params:xml:ns:inverse-dav}collection-query" = davCollectionQuery; diff --git a/SoObjects/SOGo/GNUmakefile b/SoObjects/SOGo/GNUmakefile index 29432aa3..5ba08a0a 100644 --- a/SoObjects/SOGo/GNUmakefile +++ b/SoObjects/SOGo/GNUmakefile @@ -17,6 +17,9 @@ TOOL_NAME = \ SOGo_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) +# SOGoCustomGroupFolder.h \ +# SOGoGroupsFolder.h \ +# SOGoGroupFolder.h SOGo_HEADER_FILES = \ SOGoCache.h \ SOGoObject.h \ @@ -24,28 +27,30 @@ SOGo_HEADER_FILES = \ SOGoFolder.h \ SOGoParentFolder.h \ SOGoUserFolder.h \ - SOGoGroupsFolder.h \ - SOGoGroupFolder.h \ - SOGoCustomGroupFolder.h \ \ LDAPUserManager.h \ LDAPSource.h \ SOGoDateFormatter.h \ SOGoPermissions.h \ - SOGoDAVRendererTypes.h \ iCalEntityObject+Utilities.h \ + NSArray+DAV.h \ NSArray+Utilities.h \ + NSCalendarDate+SOGo.h \ + NSDictionary+DAV.h \ NSDictionary+URL.h \ NSDictionary+Utilities.h \ + NSNull+Utilities.h \ + NSNumber+Utilities.h \ + NSObject+DAV.h \ NSObject+Utilities.h \ + NSString+DAV.h \ NSString+Utilities.h \ - NSNumber+Utilities.h \ - NSNull+Utilities.h \ - NSDictionary+URL.h \ - NSCalendarDate+SOGo.h \ + NSURL+DAV.h \ \ SOGoDAVAuthenticator.h \ SOGoWebAuthenticator.h \ + SOGoWebDAVAclManager.h \ + SOGoWebDAVValue.h \ SOGoMailer.h \ SOGoUser.h \ \ @@ -54,6 +59,9 @@ SOGo_HEADER_FILES = \ \ WORequest+SOGo.h +# SOGoCustomGroupFolder.m \ +# SOGoGroupsFolder.m \ +# SOGoGroupFolder.m SOGo_OBJC_FILES = \ SOGoCache.m \ SOGoObject.m \ @@ -62,28 +70,31 @@ SOGo_OBJC_FILES = \ SOGoGCSFolder.m \ SOGoParentFolder.m \ SOGoUserFolder.m \ - SOGoGroupsFolder.m \ - SOGoGroupFolder.m \ - SOGoCustomGroupFolder.m \ \ SOGoDateFormatter.m \ SOGoPermissions.m \ LDAPUserManager.m \ LDAPSource.m \ - SOGoDAVRendererTypes.m \ AgenorUserDefaults.m \ iCalEntityObject+Utilities.m \ + NSArray+DAV.m \ NSArray+Utilities.m \ + NSCalendarDate+SOGo.m \ + NSDictionary+DAV.m \ NSDictionary+URL.m \ NSDictionary+Utilities.m \ + NSNull+Utilities.m \ + NSNumber+Utilities.m \ + NSObject+DAV.m \ NSObject+Utilities.m \ + NSString+DAV.m \ NSString+Utilities.m \ - NSNumber+Utilities.m \ - NSNull+Utilities.m \ - NSCalendarDate+SOGo.m \ + NSURL+DAV.m \ \ SOGoDAVAuthenticator.m \ SOGoWebAuthenticator.m \ + SOGoWebDAVAclManager.m \ + SOGoWebDAVValue.m \ SOGoMailer.m \ SOGoUser.m \ \ diff --git a/SoObjects/SOGo/GNUmakefile.preamble b/SoObjects/SOGo/GNUmakefile.preamble index c2edd529..97419b75 100644 --- a/SoObjects/SOGo/GNUmakefile.preamble +++ b/SoObjects/SOGo/GNUmakefile.preamble @@ -3,6 +3,8 @@ SOGo_INCLUDE_DIRS += -I.. -I../.. -DSOGO_MAJOR_VERSION="\"$(MAJOR_VERSION)\"" -DSOGO_MINOR_VERSION="\"$(MINOR_VERSION)\"" SOGo_LIBRARIES_DEPEND_UPON += \ + -L../../OGoContentStore/$(GNUSTEP_OBJ_DIR)/ \ + -L../../SOPE/NGCards/$(GNUSTEP_OBJ_DIR)/ \ -lOGoContentStore \ -lGDLAccess \ -lNGObjWeb \ diff --git a/SoObjects/SOGo/LDAPSource.m b/SoObjects/SOGo/LDAPSource.m index f3239afb..8a87147d 100644 --- a/SoObjects/SOGo/LDAPSource.m +++ b/SoObjects/SOGo/LDAPSource.m @@ -31,6 +31,7 @@ #import "LDAPSource.h" #import "LDAPUserManager.h" +#import "NSArray+Utilities.h" static NSArray *commonSearchFields; static int timeLimit; @@ -268,7 +269,8 @@ static int sizeLimit; [self _initLDAPConnection]; entries = [ldapConnection deepSearchAtBaseDN: baseDN - qualifier: [self _qualifierForBindFilter: loginToCheck] + qualifier: + [self _qualifierForBindFilter: loginToCheck] attributes: [NSArray arrayWithObject: @"dn"]]; userEntry = [entries nextObject]; if (userEntry) @@ -318,9 +320,13 @@ static int sizeLimit; /* contact management */ - (EOQualifier *) _qualifierForFilter: (NSString *) filter { - NSString *qs; + NSString *qs, *mailFormat, *fieldFormat; EOQualifier *qualifier; + fieldFormat = [NSString stringWithFormat: @"(%%@='%@*')", filter]; + mailFormat = [[mailFields stringsWithFormat: fieldFormat] + componentsJoinedByString: @" OR "]; + if ([filter length] > 0) { if ([filter isEqualToString: @"."]) @@ -330,9 +336,9 @@ static int sizeLimit; @"(cn='%@*')" @"OR (sn='%@*')" @"OR (displayName='%@*')" - @"OR (mail='%@*')" + @"OR %@" @"OR (telephoneNumber='*%@*')", - filter, filter, filter, filter, filter]; + filter, filter, filter, mailFormat, filter]; qualifier = [EOQualifier qualifierWithQualifierFormat: qs]; } else @@ -343,12 +349,13 @@ static int sizeLimit; - (EOQualifier *) _qualifierForUIDFilter: (NSString *) uid { - NSString *qs; + NSString *qs, *mailFormat, *fieldFormat; - qs = [NSString stringWithFormat: (@"(%@='%@') OR (mail='%@')" - @" OR (mozillaSecondEmail='%@')" - @" OR (xmozillasecondemail='%@')"), - UIDField, uid, uid, uid, uid]; + fieldFormat = [NSString stringWithFormat: @"(%%@='%@')", uid]; + mailFormat = [[mailFields stringsWithFormat: fieldFormat] + componentsJoinedByString: @" OR "]; + qs = [NSString stringWithFormat: (@"(%@='%@') OR %@"), + UIDField, uid, mailFormat]; return [EOQualifier qualifierWithQualifierFormat: qs]; } @@ -418,20 +425,20 @@ static int sizeLimit; intoContactEntry: (NSMutableDictionary *) contactEntry { NSEnumerator *emailFields; - NSString *currentFieldName, *value; + NSString *currentFieldName; NSMutableArray *emails; + NSArray *allValues; emails = [NSMutableArray new]; emailFields = [mailFields objectEnumerator]; while ((currentFieldName = [emailFields nextObject])) { - value = [[ldapEntry attributeWithName: currentFieldName] - stringValueAtIndex: 0]; - if (value) - [emails addObject: value]; + allValues = [[ldapEntry attributeWithName: currentFieldName] + allStringValues]; + [emails addObjectsFromArray: allValues]; } - [emails autorelease]; [contactEntry setObject: emails forKey: @"c_emails"]; + [emails release]; } - (void) _fillConstraints: (NGLdapEntry *) ldapEntry @@ -474,14 +481,12 @@ static int sizeLimit; contactEntry = [NSMutableDictionary dictionary]; attributes = [[self _searchAttributes] objectEnumerator]; - currentAttribute = [attributes nextObject]; - while (currentAttribute) + while ((currentAttribute = [attributes nextObject])) { value = [[ldapEntry attributeWithName: currentAttribute] stringValueAtIndex: 0]; if (value) [contactEntry setObject: value forKey: currentAttribute]; - currentAttribute = [attributes nextObject]; } value = [[ldapEntry attributeWithName: IDField] stringValueAtIndex: 0]; if (!value) diff --git a/SoObjects/SOGo/LDAPUserManager.m b/SoObjects/SOGo/LDAPUserManager.m index e586b65b..b630c895 100644 --- a/SoObjects/SOGo/LDAPUserManager.m +++ b/SoObjects/SOGo/LDAPUserManager.m @@ -333,8 +333,7 @@ static BOOL defaultMailDomainIsConfigured = NO; forKey: @"MailAccess"]; ldapSources = [sources objectEnumerator]; - currentSource = [ldapSources nextObject]; - while (currentSource) + while ((currentSource = [ldapSources nextObject])) { userEntry = [currentSource lookupContactEntryWithUIDorEmail: uid]; if (userEntry) @@ -355,7 +354,6 @@ static BOOL defaultMailDomainIsConfigured = NO; [currentUser setObject: [NSNumber numberWithBool: NO] forKey: @"MailAccess"]; } - currentSource = [ldapSources nextObject]; } if (!cn) @@ -505,13 +503,9 @@ static BOOL defaultMailDomainIsConfigured = NO; contacts = [NSMutableArray array]; ldapSources = [sources objectEnumerator]; - currentSource = [ldapSources nextObject]; - while (currentSource) - { - [contacts addObjectsFromArray: - [currentSource fetchContactsMatching: filter]]; - currentSource = [ldapSources nextObject]; - } + while ((currentSource = [ldapSources nextObject])) + [contacts addObjectsFromArray: + [currentSource fetchContactsMatching: filter]]; return [self _compactAndCompleteContacts: [contacts objectEnumerator]]; } diff --git a/SoObjects/SOGo/NSArray+DAV.h b/SoObjects/SOGo/NSArray+DAV.h new file mode 100644 index 00000000..6804a210 --- /dev/null +++ b/SoObjects/SOGo/NSArray+DAV.h @@ -0,0 +1,38 @@ +/* NSArray+DAV.h - this file is part of SOGo + * + * Copyright (C) 2008 Inverse groupe conseil + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef NSARRAY_DAV_H +#define NSARRAY_DAV_H + +#import + +@class NSMutableDictionary; +@class NSString; + +@interface NSArray (SOGoWebDAVExtensions) + +- (NSString *) + asWebDavStringWithNamespaces: (NSMutableDictionary *) namespaces; + +@end + +#endif /* NSARRAY_DAV_H */ diff --git a/SoObjects/SOGo/NSArray+DAV.m b/SoObjects/SOGo/NSArray+DAV.m new file mode 100644 index 00000000..ae70ad7f --- /dev/null +++ b/SoObjects/SOGo/NSArray+DAV.m @@ -0,0 +1,45 @@ +/* NSArray+DAV.m - this file is part of SOGo + * + * Copyright (C) 2008 Inverse groupe conseil + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#import "NSObject+DAV.h" + +#import "NSArray+DAV.h" + +@implementation NSArray (SOGoWebDAVExtensions) + +- (NSString *) + asWebDavStringWithNamespaces: (NSMutableDictionary *) namespaces +{ + NSMutableString *webdavString; + NSEnumerator *children; + NSObject *child; + + webdavString = [NSMutableString string]; + children = [self objectEnumerator]; + while ((child = [children nextObject])) + [webdavString appendString: + [child asWebDavStringWithNamespaces: namespaces]]; + + return webdavString; +} + +@end diff --git a/SoObjects/SOGo/NSDictionary+DAV.h b/SoObjects/SOGo/NSDictionary+DAV.h new file mode 100644 index 00000000..a885b116 --- /dev/null +++ b/SoObjects/SOGo/NSDictionary+DAV.h @@ -0,0 +1,37 @@ +/* NSDictionary+DAV.h - this file is part of SOGo + * + * Copyright (C) 2008 Inverse groupe conseil + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef NSDICTIONARY_DAV_H +#define NSDICTIONARY_DAV_H + +#import + +@class NSString; + +@interface NSDictionary (SOGoWebDAVExtensions) + +- (NSString *) + asWebDavStringWithNamespaces: (NSMutableDictionary *) namespaces; + +@end + +#endif /* NSDICTIONARY_DAV_H */ diff --git a/SoObjects/SOGo/NSDictionary+DAV.m b/SoObjects/SOGo/NSDictionary+DAV.m new file mode 100644 index 00000000..6ea330de --- /dev/null +++ b/SoObjects/SOGo/NSDictionary+DAV.m @@ -0,0 +1,95 @@ +/* NSDictionary+DAV.m - this file is part of SOGo + * + * Copyright (C) 2008 Inverse groupe conseil + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#import +#import + +#import "NSDictionary+DAV.h" + +@implementation NSDictionary (SOGoWebDAVExtensions) + +- (NSString *) _namespaceDecl: (NSDictionary *) namespaces +{ + NSMutableString *decl; + NSEnumerator *keys; + NSString *key; + + decl = [NSMutableString string]; + keys = [[namespaces allKeys] objectEnumerator]; + while ((key = [keys nextObject])) + [decl appendFormat: @" xmlns:%@=\"%@\"", + [namespaces objectForKey: key], key]; + + return decl; +} + +- (NSString *) _newTagInNamespaces: (NSMutableDictionary *) namespaces + forNS: (NSString *) newNS +{ + NSString *newTag; + + newTag = [NSString stringWithFormat: @"n%d", [namespaces count]]; + [namespaces setObject: newTag forKey: newNS]; + + return newTag; +} + +- (NSString *) + asWebDavStringWithNamespaces: (NSMutableDictionary *) namespaces +{ + NSMutableString *webdavString; + NSString *nsTag, *ns, *subString, *element; + BOOL firstLevel; + + if (!namespaces) + { + firstLevel = YES; + namespaces = [NSMutableDictionary new]; + [namespaces setObject: @"D" forKey: @"DAV:"]; + } + else + firstLevel = NO; + + webdavString = [NSMutableString string]; + ns = [self objectForKey: @"ns"]; + nsTag = [namespaces objectForKey: ns]; + if (!nsTag) + nsTag = [self _newTagInNamespaces: namespaces forNS: ns]; + element = [NSString stringWithFormat: @"%@:%@", + nsTag, [self objectForKey: @"method"]]; + [webdavString appendFormat: @"<%@", element]; + subString = [[self objectForKey: @"content"] + asWebDavStringWithNamespaces: namespaces]; + if (firstLevel) + { + [webdavString appendString: [self _namespaceDecl: namespaces]]; + [namespaces release]; + } + if (subString) + [webdavString appendFormat: @">%@", subString, element]; + else + [webdavString appendString: @"/>"]; + + return webdavString; +} + +@end diff --git a/SoObjects/SOGo/NSObject+DAV.h b/SoObjects/SOGo/NSObject+DAV.h new file mode 100644 index 00000000..844ac000 --- /dev/null +++ b/SoObjects/SOGo/NSObject+DAV.h @@ -0,0 +1,48 @@ +/* NSObject+DAV.h - this file is part of SOGo + * + * Copyright (C) 2008 Inverse groupe conseil + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef NSOBJECT_DAV_H +#define NSOBJECT_DAV_H + +#import + +@class NSMutableDictionary; +@class NSString; +@class SOGoWebDAVValue; + +#define davElement(t,n) \ + [NSDictionary dictionaryWithObjectsAndKeys: t, @"method", n, @"ns", nil] + +#define davElementWithContent(t,n,c) \ + [NSDictionary dictionaryWithObjectsAndKeys: t, @"method", \ + n, @"ns", \ + c, @"content", nil] + +@interface NSObject (SOGoWebDAVExtensions) + +- (NSString *) + asWebDavStringWithNamespaces: (NSMutableDictionary *) namespaces; +- (SOGoWebDAVValue *) asWebDAVValue; + +@end + +#endif /* NSOBJECT_DAV_H */ diff --git a/SoObjects/SOGo/NSObject+DAV.m b/SoObjects/SOGo/NSObject+DAV.m new file mode 100644 index 00000000..5a95acf2 --- /dev/null +++ b/SoObjects/SOGo/NSObject+DAV.m @@ -0,0 +1,44 @@ +/* NSObject+DAV.m - this file is part of SOGo + * + * Copyright (C) 2008 Inverse groupe conseil + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#import "SOGoWebDAVValue.h" + +#import "NSObject+DAV.h" + +@implementation NSObject (SOGoWebDAVExtensions) + +- (NSString *) + asWebDavStringWithNamespaces: (NSMutableDictionary *) namespaces +{ + [self subclassResponsibility: _cmd]; + + return nil; +} + +- (SOGoWebDAVValue *) asWebDAVValue +{ + return [SOGoWebDAVValue + valueForObject: [self asWebDavStringWithNamespaces: nil] + attributes: nil]; +} + +@end diff --git a/SoObjects/SOGo/NSString+DAV.h b/SoObjects/SOGo/NSString+DAV.h new file mode 100644 index 00000000..068e8f8b --- /dev/null +++ b/SoObjects/SOGo/NSString+DAV.h @@ -0,0 +1,37 @@ +/* NSString+DAV.h - this file is part of SOGo + * + * Copyright (C) 2008 Inverse groupe conseil + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef NSSTRING_DAV_H +#define NSSTRING_DAV_H + +#import + +@class NSMutableDictionary; + +@interface NSString (SOGoWebDAVExtensions) + +- (NSString *) + asWebDavStringWithNamespaces: (NSMutableDictionary *) namespaces; + +@end + +#endif /* NSSTRING_DAV_H */ diff --git a/SoObjects/SOGo/NSString+DAV.m b/SoObjects/SOGo/NSString+DAV.m new file mode 100644 index 00000000..25d88661 --- /dev/null +++ b/SoObjects/SOGo/NSString+DAV.m @@ -0,0 +1,35 @@ +/* NSString+DAV.m - this file is part of SOGo + * + * Copyright (C) 2008 Inverse groupe conseil + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#import + +#import "NSString+DAV.h" + +@implementation NSString (SOGoWebDAVExtensions) + +- (NSString *) + asWebDavStringWithNamespaces: (NSMutableDictionary *) namespaces +{ + return [self stringByEscapingXMLString]; +} + +@end diff --git a/SoObjects/SOGo/NSURL+DAV.h b/SoObjects/SOGo/NSURL+DAV.h new file mode 100644 index 00000000..be39c2f1 --- /dev/null +++ b/SoObjects/SOGo/NSURL+DAV.h @@ -0,0 +1,37 @@ +/* NSURL+DAV.h - this file is part of SOGo + * + * Copyright (C) 2008 Inverse groupe conseil + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef NSURL_DAV_H +#define NSURL_DAV_H + +#import + +@class NSMutableDictionary; + +@interface NSURL (SOGoWebDAVExtensions) + +- (NSString *) + asWebDavStringWithNamespaces: (NSMutableDictionary *) namespaces; + +@end + +#endif /* NSURL_DAV_H */ diff --git a/SoObjects/SOGo/NSURL+DAV.m b/SoObjects/SOGo/NSURL+DAV.m new file mode 100644 index 00000000..8068246d --- /dev/null +++ b/SoObjects/SOGo/NSURL+DAV.m @@ -0,0 +1,36 @@ +/* NSURL+DAV.m - this file is part of SOGo + * + * Copyright (C) 2008 Inverse groupe conseil + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#import +#import + +#import "NSURL+DAV.h" + +@implementation NSURL (SOGoWebDAVExtensions) + +- (NSString *) + asWebDavStringWithNamespaces: (NSMutableDictionary *) namespaces +{ + return [[self absoluteString] stringByEscapingXMLString]; +} + +@end diff --git a/SoObjects/SOGo/SOGoDAVRendererTypes.m b/SoObjects/SOGo/SOGoDAVRendererTypes.m deleted file mode 100644 index 5d74a9c5..00000000 --- a/SoObjects/SOGo/SOGoDAVRendererTypes.m +++ /dev/null @@ -1,198 +0,0 @@ -/* SOGoDAVRendererTypes.m - this file is part of SOGo - * - * Copyright (C) 2006, 2008 Inverse groupe conseil - * - * Author: Wolfgang Sourdeau - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This file is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#import -#import -#import - -#import - -#import "SOGoDAVRendererTypes.h" - -@implementation SOGoDAVSet - -+ (id) davSetWithArray: (NSArray *) newValues - ofValuesTaggedAs: (NSString *) newValueTag -{ - id davSet; - - davSet = [self new]; - [davSet setValueTag: newValueTag]; - [davSet setValues: newValues]; - [davSet autorelease]; - - return davSet; -} - -- (id) init -{ - if ((self = [super init])) - { - valueTag = nil; - values = nil; - } - - return self; -} - -- (void) dealloc -{ - [valueTag release]; - [values release]; - [super dealloc]; -} - -- (void) setValueTag: (NSString *) newValueTag -{ - ASSIGN (valueTag, newValueTag); -} - -- (void) setValues: (NSArray *) newValues -{ - ASSIGN (values, newValues); -} - -- (NSString *) stringForTag: (NSString *) _key - rawName: (NSString *) setTag - inContext: (id) context - prefixes: (NSDictionary *) prefixes -{ - NSMutableString *resultString; - id currentValue; - NSString *valueString; - NSEnumerator *valueEnum; - - resultString = [NSMutableString new]; - [resultString autorelease]; - -// [resultString appendFormat: @"<%@>", setTag]; - valueEnum = [values objectEnumerator]; - while ((currentValue = [valueEnum nextObject])) - { - if ([currentValue isKindOfClass: [SoWebDAVValue class]]) - valueString - = [currentValue stringForTag: - [NSString stringWithFormat: @"{DAV:}%@", valueTag] - rawName: [NSString stringWithFormat: @"D:%@", valueTag] - inContext: context - prefixes: prefixes]; - else - valueString = [[currentValue description] stringByEscapingXMLString]; - - [resultString appendFormat: valueString]; -// [resultString appendFormat: @"<%@>%@", -// valueTag, valueString, valueTag]; - } -// [resultString appendFormat: @"", setTag]; - - NSLog(@"dav rendering for key '%@' and tag '%@':\n", _key, setTag, - resultString); - - return resultString; -} - -- (NSString *) stringValue -{ - return [self stringForTag: valueTag rawName: valueTag - inContext: nil prefixes: nil]; -} - -@end - -@implementation SOGoDAVDictionary - -+ (id) davDictionary: (NSDictionary *) newValues - taggedAs: (NSString *) newValueTag; -{ - SOGoDAVDictionary *davDictionary; - - davDictionary = [self new]; - [davDictionary setValueTag: newValueTag]; - [davDictionary setValues: newValues]; - [davDictionary autorelease]; - - return davDictionary; -} - -- (id) init -{ - if ((self = [super init])) - { - valueTag = nil; - values = nil; - } - - return self; -} - -- (void) dealloc -{ - [valueTag release]; - [values release]; - [super dealloc]; -} - -- (void) setValueTag: (NSString *) newValueTag -{ - ASSIGN (valueTag, newValueTag); -} - -- (void) setValues: (NSDictionary *) newValues -{ - ASSIGN (values, newValues); -} - -- (NSString *) stringForTag: (NSString *) _key - rawName: (NSString *) setTag - inContext: (id) context - prefixes: (NSDictionary *) prefixes -{ - NSMutableString *resultString; - id currentValue; - NSEnumerator *objects; - NSString *currentKey, *valueString; - - resultString = [NSMutableString string]; - - [resultString appendFormat: @"<%@>", valueTag]; - objects = [[values allKeys] objectEnumerator]; - while ((currentKey = [objects nextObject])) - { - currentValue = [values objectForKey: currentKey]; - if ([currentValue isKindOfClass: [SoWebDAVValue class]]) - valueString - = [currentValue stringForTag: - [NSString stringWithFormat: @"{DAV:}%@", valueTag] - rawName: [NSString stringWithFormat: @"D:%@", valueTag] - inContext: context - prefixes: prefixes]; - else - valueString = [[currentValue description] stringByEscapingXMLString]; - - [resultString appendFormat: @"<%@>%@", currentKey, valueString, currentKey]; - } - [resultString appendFormat: @"", valueTag]; - - return resultString; -} - -@end diff --git a/SoObjects/SOGo/SOGoFolder.m b/SoObjects/SOGo/SOGoFolder.m index 1d821ae3..f931cc49 100644 --- a/SoObjects/SOGo/SOGoFolder.m +++ b/SoObjects/SOGo/SOGoFolder.m @@ -26,13 +26,42 @@ #import +#import "NSObject+DAV.h" #import "NSString+Utilities.h" #import "SOGoPermissions.h" +#import "SOGoWebDAVAclManager.h" + #import "SOGoFolder.h" +@interface SOGoObject (SOGoDAVHelpers) + +- (void) _fillArrayWithPrincipalsOwnedBySelf: (NSMutableArray *) hrefs; + +@end + @implementation SOGoFolder ++ (SOGoWebDAVAclManager *) webdavAclManager +{ + SOGoWebDAVAclManager *webdavAclManager = nil; + + if (!webdavAclManager) + { + webdavAclManager = [SOGoWebDAVAclManager new]; + [webdavAclManager registerDAVPermission: davElement (@"read", @"DAV:") + abstract: YES + withEquivalent: SoPerm_WebDAVAccess + asChildOf: davElement (@"all", @"DAV:")]; + [webdavAclManager registerDAVPermission: davElement (@"read-current-user-privilege-set", @"DAV:") + abstract: YES + withEquivalent: nil + asChildOf: davElement (@"read", @"DAV:")]; + } + + return webdavAclManager; +} + - (id) init { if ((self = [super init])) @@ -75,6 +104,11 @@ return [NSArray array]; } +- (NSArray *) toManyRelationshipKeys +{ + return nil; +} + - (BOOL) isValidContentName: (NSString *) name { return ([name length] > 0); @@ -192,6 +226,24 @@ return rType; } +/* web dav acl helper */ +- (void) _fillArrayWithPrincipalsOwnedBySelf: (NSMutableArray *) hrefs +{ + NSEnumerator *children; + NSString *currentKey; + + [super _fillArrayWithPrincipalsOwnedBySelf: hrefs]; + children = [[self toOneRelationshipKeys] objectEnumerator]; + while ((currentKey = [children nextObject])) + [[self lookupName: currentKey inContext: context + acquire: NO] _fillArrayWithPrincipalsOwnedBySelf: hrefs]; + + children = [[self toManyRelationshipKeys] objectEnumerator]; + while ((currentKey = [children nextObject])) + [[self lookupName: currentKey inContext: context + acquire: NO] _fillArrayWithPrincipalsOwnedBySelf: hrefs]; +} + /* folder type */ - (BOOL) isEqual: (id) otherFolder @@ -211,6 +263,11 @@ /* acls */ +- (NSString *) defaultUserID +{ + return nil; +} + - (NSArray *) subscriptionRoles { return [NSArray arrayWithObjects: SoRole_Owner, SOGoRole_ObjectViewer, @@ -223,4 +280,9 @@ return nil; } +- (NSArray *) aclUsers +{ + return nil; +} + @end diff --git a/SoObjects/SOGo/SOGoGCSFolder.m b/SoObjects/SOGo/SOGoGCSFolder.m index e3d7c56c..6c4e9905 100644 --- a/SoObjects/SOGo/SOGoGCSFolder.m +++ b/SoObjects/SOGo/SOGoGCSFolder.m @@ -21,9 +21,6 @@ * Boston, MA 02111-1307, USA. */ -#import -#import "SOGoDAVRendererTypes.h" - #import #import #import @@ -54,12 +51,14 @@ #import "NSDictionary+Utilities.h" #import "NSArray+Utilities.h" +#import "NSObject+DAV.h" #import "NSString+Utilities.h" #import "SOGoContentObject.h" #import "SOGoParentFolder.h" #import "SOGoPermissions.h" #import "SOGoUser.h" +#import "SOGoWebDAVAclManager.h" #import "WORequest+SOGo.h" #import "SOGoGCSFolder.h" @@ -69,6 +68,62 @@ static BOOL sendFolderAdvisories = NO; @implementation SOGoGCSFolder ++ (SOGoWebDAVAclManager *) webdavAclManager +{ + SOGoWebDAVAclManager *webdavAclManager = nil; + + if (!webdavAclManager) + { + webdavAclManager = [SOGoWebDAVAclManager new]; + [webdavAclManager registerDAVPermission: davElement (@"read", @"DAV:") + abstract: YES + withEquivalent: SoPerm_WebDAVAccess + asChildOf: davElement (@"all", @"DAV:")]; + [webdavAclManager registerDAVPermission: davElement (@"read-current-user-privilege-set", @"DAV:") + abstract: YES + withEquivalent: SoPerm_WebDAVAccess + asChildOf: davElement (@"read", @"DAV:")]; + [webdavAclManager registerDAVPermission: davElement (@"write", @"DAV:") + abstract: YES + withEquivalent: nil + asChildOf: davElement (@"all", @"DAV:")]; + [webdavAclManager registerDAVPermission: davElement (@"bind", @"DAV:") + abstract: NO + withEquivalent: SoPerm_AddDocumentsImagesAndFiles + asChildOf: davElement (@"write", @"DAV:")]; + [webdavAclManager registerDAVPermission: davElement (@"unbind", @"DAV:") + abstract: NO + withEquivalent: SoPerm_DeleteObjects + asChildOf: davElement (@"write", @"DAV:")]; + [webdavAclManager + registerDAVPermission: davElement (@"write-properties", @"DAV:") + abstract: YES + withEquivalent: SoPerm_ChangePermissions /* hackish */ + asChildOf: davElement (@"write", @"DAV:")]; + [webdavAclManager + registerDAVPermission: davElement (@"write-content", @"DAV:") + abstract: YES + withEquivalent: nil + asChildOf: davElement (@"write", @"DAV:")]; + [webdavAclManager registerDAVPermission: davElement (@"admin", @"urn:inverse:params:xml:ns:inverse-dav") + abstract: YES + withEquivalent: nil + asChildOf: davElement (@"all", @"DAV:")]; + [webdavAclManager + registerDAVPermission: davElement (@"read-acl", @"DAV:") + abstract: YES + withEquivalent: SOGoPerm_ReadAcls + asChildOf: davElement (@"admin", @"urn:inverse:params:xml:ns:inverse-dav")]; + [webdavAclManager + registerDAVPermission: davElement (@"write-acl", @"DAV:") + abstract: YES + withEquivalent: SoPerm_ChangePermissions + asChildOf: davElement (@"admin", @"urn:inverse:params:xml:ns:inverse-dav")]; + } + + return webdavAclManager; +} + + (void) initialize { NSUserDefaults *ud; @@ -273,8 +328,7 @@ static BOOL sendFolderAdvisories = NO; } else error = [NSException exceptionWithHTTPStatus: 400 - reason: [NSString stringWithFormat: - @"Empty string"]]; + reason: @"Empty string"]; } else error = [NSException exceptionWithHTTPStatus: 403 diff --git a/SoObjects/SOGo/SOGoObject.h b/SoObjects/SOGo/SOGoObject.h index 5c8f87b1..eb1736f2 100644 --- a/SoObjects/SOGo/SOGoObject.h +++ b/SoObjects/SOGo/SOGoObject.h @@ -24,6 +24,14 @@ #import +#import + +#if LIB_FOUNDATION_LIBRARY +#error SOGo will not work properly with libFoundation. +#error Please use gnustep-base instead. +#endif + + /* SOGoObject @@ -48,8 +56,8 @@ @class GCSFolder; @class SOGoUserFolder; -@class SOGoGroupsFolder; -@class SOGoDAVSet; +@class SOGoWebDAVValue; +@class SOGoWebDAVAclManager; #define $(class) NSClassFromString(class) @@ -58,6 +66,7 @@ WOContext *context; NSString *nameInContainer; NSString *owner; + SOGoWebDAVAclManager *webdavAclManager; id container; } @@ -90,7 +99,6 @@ /* looking up shared objects */ - (SOGoUserFolder *) lookupUserFolder; -- (SOGoGroupsFolder *) lookupGroupsFolder; - (void) sleep; @@ -103,8 +111,6 @@ - (NSException *)delete; - (id)GETAction:(id)_ctx; -- (SOGoDAVSet *) davCurrentUserPrivilegeSet; - /* etag support */ - (NSException *) matchesRequestConditionInContext:(id)_ctx; @@ -129,8 +135,10 @@ - (NSString *) httpURLForAdvisoryToUser: (NSString *) uid; - (NSString *) resourceURLForAdvisoryToUser: (NSString *) uid; -/* dav */ -- (NSArray *) davNamespaces; +/* dav acls */ +- (SOGoWebDAVValue *) davCurrentUserPrivilegeSet; + +/* inverse dav extensions for acls */ - (NSString *) davRecordForUser: (NSString *) user; /* description */ @@ -139,4 +147,17 @@ @end +@interface SOGoObject (SOGo) + +- (NSString *) contentAsString; + +@end + +@interface SOGoObject (SOGoDomHelpers) + +- (NSArray *) domNode: (id ) node + getChildNodesByType: (DOMNodeType) type; + +@end + #endif /* __SoObjects_SOGoObject_H__ */ diff --git a/SoObjects/SOGo/SOGoObject.m b/SoObjects/SOGo/SOGoObject.m index eada235b..9f99e009 100644 --- a/SoObjects/SOGo/SOGoObject.m +++ b/SoObjects/SOGo/SOGoObject.m @@ -1,28 +1,25 @@ -/* - Copyright (C) 2004-2005 SKYRIX Software AG - - This file is part of OpenGroupware.org. - - OGo is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - OGo 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 Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with OGo; see the file COPYING. If not, write to the - Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -#if LIB_FOUNDATION_LIBRARY -#error SOGo will not work properly with libFoundation. -#error Please use gnustep-base instead. -#endif +/* SOGoGCSFolder.m - this file is part of SOGo + * + * Copyright (C) 2004-2005 SKYRIX Software AG + * Copyright (C) 2006-2008 Inverse groupe conseil + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ #import @@ -36,10 +33,8 @@ #import #import -#import #import #import -#import #import #import #import @@ -60,14 +55,15 @@ #import "NSArray+Utilities.h" #import "NSCalendarDate+SOGo.h" #import "NSDictionary+Utilities.h" +#import "NSObject+DAV.h" #import "NSObject+Utilities.h" #import "NSString+Utilities.h" #import "SOGoCache.h" -#import "SOGoDAVAuthenticator.h" -#import "SOGoDAVRendererTypes.h" #import "SOGoPermissions.h" #import "SOGoUser.h" #import "SOGoUserFolder.h" +#import "SOGoWebDAVAclManager.h" +#import "SOGoWebDAVValue.h" #import "SOGoObject.h" @@ -76,136 +72,62 @@ static BOOL sendACLAdvisories = NO; static NSDictionary *reportMap = nil; -@interface SOGoObject(Content) -- (NSString *) contentAsString; -@end - -@interface SoClassSecurityInfo (SOGoAcls) - -+ (id) defaultWebDAVPermissionsMap; - -- (NSArray *) allPermissions; -- (NSArray *) allDAVPermissions; -- (NSArray *) DAVPermissionsForRole: (NSString *) role; -- (NSArray *) DAVPermissionsForRoles: (NSArray *) roles; - -@end - -@implementation SoClassSecurityInfo (SOGoAcls) - -+ (id) defaultWebDAVPermissionsMap -{ - return [NSDictionary dictionaryWithObjectsAndKeys: - @"read", SoPerm_AccessContentsInformation, - @"bind", SoPerm_AddDocumentsImagesAndFiles, - @"unbind", SoPerm_DeleteObjects, - @"write-acl", SoPerm_ChangePermissions, - @"write-content", SoPerm_ChangeImagesAndFiles, - @"read-free-busy", SOGoPerm_FreeBusyLookup, - NULL]; -} - -- (NSArray *) allPermissions -{ - return [defRoles allKeys]; -} +@implementation SOGoObject -- (NSArray *) allDAVPermissions ++ (SOGoWebDAVAclManager *) webdavAclManager { - NSEnumerator *allPermissions; - NSMutableArray *davPermissions; - NSDictionary *davPermissionsMap; - NSString *sopePermission, *davPermission; - - davPermissions = [NSMutableArray array]; - - davPermissionsMap = [[self class] defaultWebDAVPermissionsMap]; - allPermissions = [[self allPermissions] objectEnumerator]; - sopePermission = [allPermissions nextObject]; - while (sopePermission) - { - davPermission = [davPermissionsMap objectForCaseInsensitiveKey: sopePermission]; - if (davPermission && ![davPermissions containsObject: davPermission]) - [davPermissions addObject: davPermission]; - sopePermission = [allPermissions nextObject]; - } + SOGoWebDAVAclManager *webdavAclManager = nil; - return davPermissions; -} + if (!webdavAclManager) + webdavAclManager = [SOGoWebDAVAclManager new]; -- (NSArray *) DAVPermissionsForRole: (NSString *) role -{ - return [self DAVPermissionsForRoles: [NSArray arrayWithObject: role]]; + return webdavAclManager; } -- (NSArray *) DAVPermissionsForRoles: (NSArray *) roles +/* ++ (id) WebDAVPermissionsMap { - NSEnumerator *allPermissions; - NSMutableArray *davPermissions; - NSDictionary *davPermissionsMap; - NSString *sopePermission, *davPermission; + static NSDictionary *permissions = nil; - davPermissions = [NSMutableArray array]; - - davPermissionsMap = [[self class] defaultWebDAVPermissionsMap]; - allPermissions = [[self allPermissions] objectEnumerator]; - sopePermission = [allPermissions nextObject]; - while (sopePermission) + if (!permissions) { - if ([[defRoles objectForCaseInsensitiveKey: sopePermission] - firstObjectCommonWithArray: roles]) - { - davPermission - = [davPermissionsMap objectForCaseInsensitiveKey: sopePermission]; - if (davPermission - && ![davPermissions containsObject: davPermission]) - [davPermissions addObject: davPermission]; - } - sopePermission = [allPermissions nextObject]; + permissions = [NSDictionary dictionaryWithObjectsAndKeys: + davElement (@"read", @"DAV:"), + SoPerm_AccessContentsInformation, + davElement (@"bind", @"DAV:"), + SoPerm_AddDocumentsImagesAndFiles, + davElement (@"unbind", @"DAV:"), + SoPerm_DeleteObjects, + davElement (@"write-acl", @"DAV:"), + SoPerm_ChangePermissions, + davElement (@"write-content", @"DAV:"), + SoPerm_ChangeImagesAndFiles, NULL]; + [permissions retain]; } - return davPermissions; -} - -@end - -@implementation SOGoObject - -+ (void) _loadReportMap -{ - NSFileManager *fm; - NSEnumerator *paths; - NSString *currentPath, *filename; - - [self logWithFormat: @"Loading DAV REPORT map:"]; - - fm = [NSFileManager defaultManager]; - paths = [NSStandardLibraryPaths() objectEnumerator]; - while (!reportMap && (currentPath = [paths nextObject])) - { - filename = [NSString stringWithFormat: @"%@/SOGo-%s.%s/SOGo.framework" - @"/Resources/DAVReportMap.plist", - currentPath, - SOGO_MAJOR_VERSION, SOGO_MINOR_VERSION]; - [self logWithFormat: @" %@", filename]; - if ([fm fileExistsAtPath: filename]) - { - reportMap = [[NSDictionary alloc] initWithContentsOfFile: filename]; - [self logWithFormat: @"found!"]; - } - } -} + return permissions; + } */ + (void) initialize { NSUserDefaults *ud; + NSString *filename; + NSBundle *bundle; ud = [NSUserDefaults standardUserDefaults]; kontactGroupDAV = ![ud boolForKey:@"SOGoDisableKontact34GroupDAVHack"]; sendACLAdvisories = [ud boolForKey: @"SOGoACLsSendEMailNotifications"]; if (!reportMap) - [self _loadReportMap]; + { + bundle = [NSBundle bundleForClass: self]; + filename = [bundle pathForResource: @"DAVReportMap" ofType: @"plist"]; + if (filename + && [[NSFileManager defaultManager] fileExistsAtPath: filename]) + reportMap = [[NSDictionary alloc] initWithContentsOfFile: filename]; + else + [self logWithFormat: @"DAV REPORT map not found!"]; + } // SoClass security declarations // require View permission to access the root (bound to authenticated ...) @@ -250,51 +172,6 @@ static NSDictionary *reportMap = nil; return [[self class] globallyUniqueObjectId]; } -+ (void) _fillDictionary: (NSMutableDictionary *) dictionary - withDAVMethods: (NSString *) firstMethod, ... -{ - va_list ap; - NSString *aclMethodName; - NSString *methodName; - SEL methodSel; - - va_start (ap, firstMethod); - aclMethodName = firstMethod; - while (aclMethodName) - { - methodName = [aclMethodName davMethodToObjC]; - methodSel = NSSelectorFromString (methodName); - if (methodSel && [self instancesRespondToSelector: methodSel]) - [dictionary setObject: methodName - forKey: [NSString stringWithFormat: @"{DAV:}%@", - aclMethodName]]; - else - NSLog(@"************ method '%@' is still unimplemented!", - methodName); - aclMethodName = va_arg (ap, NSString *); - } - - va_end (ap); -} - -+ (NSDictionary *) defaultWebDAVAttributeMap -{ - static NSMutableDictionary *map = nil; - - if (!map) - { - map = [NSMutableDictionary - dictionaryWithDictionary: [super defaultWebDAVAttributeMap]]; - [map retain]; - [self _fillDictionary: map - withDAVMethods: @"owner", @"group", @"supported-privilege-set", - @"current-user-privilege-set", @"acl", @"acl-restrictions", - @"inherited-acl-set", @"principal-collection-set", nil]; - } - - return map; -} - /* containment */ + (id) objectWithName: (NSString *)_name inContainer:(id)_container @@ -307,156 +184,6 @@ static NSDictionary *reportMap = nil; return object; } -/* DAV ACL properties */ -- (NSString *) davOwner -{ - return [NSString stringWithFormat: @"%@%@", - [WOApplication davURL], - [self ownerInContext: nil]]; -} - -- (NSString *) davAclRestrictions -{ - NSMutableString *restrictions; - - restrictions = [NSMutableString string]; - [restrictions appendString: @""]; - [restrictions appendString: @""]; - - return restrictions; -} - -- (SOGoDAVSet *) davPrincipalCollectionSet -{ - NSString *usersUrl; - - usersUrl = [NSString stringWithFormat: @"%@users", - [self rootURLInContext: context]]; - - return [SOGoDAVSet davSetWithArray: [NSArray arrayWithObject: usersUrl] - ofValuesTaggedAs: @"D:href"]; -} - -- (SOGoDAVSet *) davCurrentUserPrivilegeSet -{ - SOGoDAVAuthenticator *sAuth; - SoUser *user; - NSArray *roles; - SoClassSecurityInfo *sInfo; - NSArray *davPermissions; - - sAuth = [SOGoDAVAuthenticator sharedSOGoDAVAuthenticator]; - user = [sAuth userInContext: context]; - roles = [user rolesForObject: self inContext: context]; - sInfo = [[self class] soClassSecurityInfo]; - - davPermissions - = [[sInfo DAVPermissionsForRoles: roles] stringsWithFormat: @""]; - - return [SOGoDAVSet davSetWithArray: davPermissions - ofValuesTaggedAs: @"D:privilege"]; -} - -- (SOGoDAVSet *) davSupportedPrivilegeSet -{ - SoClassSecurityInfo *sInfo; - NSArray *allPermissions; - - sInfo = [[self class] soClassSecurityInfo]; - - allPermissions = [[sInfo allDAVPermissions] stringsWithFormat: @""]; - - return [SOGoDAVSet davSetWithArray: allPermissions - ofValuesTaggedAs: @"D:privilege"]; -} - -- (NSArray *) _davAcesFromAclsDictionary: (NSDictionary *) aclsDictionary -{ - NSEnumerator *keys; - NSArray *privileges; - NSMutableString *currentAce; - NSMutableArray *davAces; - NSString *currentKey, *principal; - SOGoDAVSet *privilegesDS; - - davAces = [NSMutableArray array]; - keys = [[aclsDictionary allKeys] objectEnumerator]; - currentKey = [keys nextObject]; - while (currentKey) - { - currentAce = [NSMutableString string]; - if ([currentKey hasPrefix: @":"]) - [currentAce - appendFormat: @"", - [currentKey substringFromIndex: 1]]; - else - { - principal = [NSString stringWithFormat: @"%@users/%@", - [self rootURLInContext: context], - currentKey]; - [currentAce - appendFormat: @"%@", - principal]; - } - - privileges = [[aclsDictionary objectForKey: currentKey] - stringsWithFormat: @""]; - privilegesDS = [SOGoDAVSet davSetWithArray: privileges - ofValuesTaggedAs: @"privilege"]; - [currentAce appendString: [privilegesDS stringForTag: @"{DAV:}grant" - rawName: @"grant" - inContext: nil prefixes: nil]]; - [davAces addObject: currentAce]; - currentKey = [keys nextObject]; - } - - return davAces; -} - -- (void) _appendRolesForPseudoPrincipals: (NSMutableDictionary *) aclsDictionary - withClassSecurityInfo: (SoClassSecurityInfo *) sInfo -{ - NSArray *perms; - - perms = [sInfo DAVPermissionsForRole: SoRole_Owner]; - if ([perms count]) - [aclsDictionary setObject: perms forKey: @":owner"]; - perms = [sInfo DAVPermissionsForRole: SoRole_Authenticated]; - if ([perms count]) - [aclsDictionary setObject: perms forKey: @":authenticated"]; - perms = [sInfo DAVPermissionsForRole: SoRole_Anonymous]; - if ([perms count]) - [aclsDictionary setObject: perms forKey: @":unauthenticated"]; -} - -- (SOGoDAVSet *) davAcl -{ - NSArray *roles; - NSEnumerator *uids; - NSMutableDictionary *aclsDictionary; - NSString *currentUID; - SoClassSecurityInfo *sInfo; - - aclsDictionary = [NSMutableDictionary dictionary]; - uids = [[self aclUsers] objectEnumerator]; - sInfo = [[self class] soClassSecurityInfo]; - - currentUID = [uids nextObject]; - while (currentUID) - { - roles = [self aclsForUser: currentUID]; - [aclsDictionary setObject: [sInfo DAVPermissionsForRoles: roles] - forKey: currentUID]; - currentUID = [uids nextObject]; - } - [self _appendRolesForPseudoPrincipals: aclsDictionary - withClassSecurityInfo: sInfo]; - - return [SOGoDAVSet davSetWithArray: - [self _davAcesFromAclsDictionary: aclsDictionary] - ofValuesTaggedAs: @"D:ace"]; -} - /* end of properties */ - (BOOL) doesRetainContainer @@ -472,6 +199,7 @@ static NSDictionary *reportMap = nil; nameInContainer = nil; container = nil; owner = nil; + webdavAclManager = [[self class] webdavAclManager]; } return self; @@ -614,16 +342,14 @@ static NSDictionary *reportMap = nil; { id obj; SOGoCache *cache; - NSString *objcMethod; + NSString *objcMethod, *httpMethod; cache = [SOGoCache sharedCache]; obj = [cache objectNamed: lookupName inContainer: self]; if (!obj) { - obj = [[self soClass] lookupKey: lookupName inContext: localContext]; - if (obj) - [obj bindToObject: self inContext: localContext]; - else + httpMethod = [[localContext request] method]; + if ([httpMethod isEqualToString: @"REPORT"]) { objcMethod = [self _reportSelector: lookupName]; if (objcMethod) @@ -634,6 +360,12 @@ static NSDictionary *reportMap = nil; [obj autorelease]; } } + else + { + obj = [[self soClass] lookupKey: lookupName inContext: localContext]; + if (obj) + [obj bindToObject: self inContext: localContext]; + } if (obj) [cache registerObject: obj withName: lookupName inContainer: self]; @@ -652,10 +384,10 @@ static NSDictionary *reportMap = nil; return [container lookupUserFolder]; } -- (SOGoGroupsFolder *) lookupGroupsFolder -{ - return [[self lookupUserFolder] lookupGroupsFolder]; -} +// - (SOGoGroupsFolder *) lookupGroupsFolder +// { +// return [[self lookupUserFolder] lookupGroupsFolder]; +// } - (void) sleep { @@ -686,6 +418,316 @@ static NSDictionary *reportMap = nil; return [self nameInContainer]; } +/* DAV ACL properties */ +- (SOGoWebDAVValue *) davOwner +{ + NSDictionary *ownerHREF; + NSString *usersUrl; + + usersUrl = [NSString stringWithFormat: @"%@%@/", + [[WOApplication application] davURL], owner]; + ownerHREF = davElementWithContent (@"href", @"DAV:", usersUrl); + + return [davElementWithContent (@"owner", @"DAV:", ownerHREF) + asWebDAVValue]; +} + +- (SOGoWebDAVValue *) davAclRestrictions +{ + NSArray *restrictions; + + restrictions = [NSArray arrayWithObjects: + davElement (@"grant-only", @"DAV:"), + davElement (@"no-invert", @"DAV:"), + nil]; + + return [davElementWithContent (@"acl-restrictions", @"DAV:", restrictions) + asWebDAVValue]; +} + +- (SOGoWebDAVValue *) davPrincipalCollectionSet +{ + NSString *usersUrl; + NSDictionary *collectionHREF; + + /* WOApplication has no support for the DAV methods we define here so we + use the user's principal object as a reference */ + usersUrl = [NSString stringWithFormat: @"%@%@/", + [[WOApplication application] davURL], owner]; + collectionHREF = davElementWithContent (@"href", @"DAV:", usersUrl); + + return [davElementWithContent (@"principal-collection-set", + @"DAV:", + [NSArray arrayWithObject: collectionHREF]) + asWebDAVValue]; +} + +- (NSArray *) _davPrivilegesFromRoles: (NSArray *) roles +{ + NSEnumerator *privileges; + NSDictionary *privilege; + NSMutableArray *davPrivileges; + + davPrivileges = [NSMutableArray array]; + + privileges = [[webdavAclManager davPermissionsForRoles: roles + onObject: self] objectEnumerator]; + while ((privilege = [privileges nextObject])) + [davPrivileges addObject: davElementWithContent (@"privilege", @"DAV:", + privilege)]; + + return davPrivileges; +} + +- (SOGoWebDAVValue *) davCurrentUserPrivilegeSet +{ + NSArray *userRoles; + + userRoles = [[context activeUser] rolesForObject: self inContext: context]; + + return [davElementWithContent (@"current-user-privilege-set", + @"DAV:", + [self _davPrivilegesFromRoles: userRoles]) + asWebDAVValue]; +} + +- (SOGoWebDAVValue *) davSupportedPrivilegeSet +{ + return [davElementWithContent (@"supported-privilege-set", + @"DAV:", + [webdavAclManager treeAsWebDAVValue]) + asWebDAVValue]; +} + +#warning this method has probably some code shared with its pseudo principal equivalent +- (void) _fillAces: (NSMutableArray *) aces + withRolesForUID: (NSString *) currentUID +{ + NSMutableArray *currentAce; + NSArray *roles; + NSDictionary *currentGrant, *userHREF; + NSString *principalURL; + + currentAce = [NSMutableArray new]; + roles = [[SOGoUser userWithLogin: currentUID roles: nil] + rolesForObject: self + inContext: context]; + if ([roles count]) + { + principalURL = [NSString stringWithFormat: @"%@%@/", + [[WOApplication application] davURL], + currentUID]; + userHREF = davElementWithContent (@"href", @"DAV:", principalURL); + [currentAce addObject: davElementWithContent (@"principal", @"DAV:", + userHREF)]; + currentGrant + = davElementWithContent (@"grant", @"DAV:", + [self _davPrivilegesFromRoles: roles]); + [currentAce addObject: currentGrant]; + [aces addObject: davElementWithContent (@"ace", @"DAV:", currentAce)]; + [currentAce release]; + } +} + +- (void) _fillAcesWithRolesForPseudoPrincipals: (NSMutableArray *) aces +{ + NSArray *roles, *currentAce; + NSDictionary *principal, *currentGrant; + SOGoUser *user; + +// DAV:self, DAV:property(owner), DAV:authenticated + user = [context activeUser]; + roles = [user rolesForObject: self inContext: context]; + if ([roles count]) + { + principal = davElement (@"self", @"DAV:"); + currentGrant + = davElementWithContent (@"grant", @"DAV:", + [self _davPrivilegesFromRoles: roles]); + currentAce = [NSArray arrayWithObjects: + davElementWithContent (@"principal", @"DAV:", + principal), + currentGrant, nil]; + [aces addObject: davElementWithContent (@"ace", @"DAV:", currentAce)]; + } + + user = [SOGoUser userWithLogin: [self ownerInContext: context] roles: nil]; + roles = [user rolesForObject: self inContext: context]; + if ([roles count]) + { + principal = davElementWithContent (@"property", @"DAV:", + davElement (@"owner", @"DAV:")); + currentGrant + = davElementWithContent (@"grant", @"DAV:", + [self _davPrivilegesFromRoles: roles]); + currentAce = [NSArray arrayWithObjects: + davElementWithContent (@"principal", @"DAV:", + principal), + currentGrant, nil]; + [aces addObject: davElementWithContent (@"ace", @"DAV:", currentAce)]; + } + + roles = [self aclsForUser: [self defaultUserID]]; + if ([roles count]) + { + principal = davElement (@"authenticated", @"DAV:"); + currentGrant + = davElementWithContent (@"grant", @"DAV:", + [self _davPrivilegesFromRoles: roles]); + currentAce = [NSArray arrayWithObjects: + davElementWithContent (@"principal", @"DAV:", + principal), + currentGrant, nil]; + [aces addObject: davElementWithContent (@"ace", @"DAV:", currentAce)]; + } +} + +- (SOGoWebDAVValue *) davAcl +{ + NSEnumerator *uids; + NSMutableArray *aces; + NSString *currentUID; + + aces = [NSMutableArray array]; + + [self _fillAcesWithRolesForPseudoPrincipals: aces]; + uids = [[self aclUsers] objectEnumerator]; + while ((currentUID = [uids nextObject])) + [self _fillAces: aces withRolesForUID: currentUID]; + + return [davElementWithContent (@"acl", @"DAV:", aces) + asWebDAVValue]; +} + +#warning all REPORT method should be standardized... +- (NSDictionary *) _formalizePrincipalMatchResponse: (NSArray *) hrefs +{ + NSDictionary *multiStatus; + NSEnumerator *hrefList; + NSString *currentHref; + NSMutableArray *responses; + NSArray *responseElements; + + responses = [NSMutableArray new]; + + hrefList = [hrefs objectEnumerator]; + while ((currentHref = [hrefList nextObject])) + { + responseElements + = [NSArray arrayWithObjects: davElementWithContent (@"href", @"DAV:", + currentHref), + davElementWithContent (@"status", @"DAV:", + @"HTTP/1.1 200 OK"), + nil]; + [responses addObject: davElementWithContent (@"response", @"DAV:", + responseElements)]; + } + + multiStatus = davElementWithContent (@"multistatus", @"DAV:", responses); + [responses release]; + + return multiStatus; +} + +- (NSDictionary *) _handlePrincipalMatchSelf +{ + NSString *davURL, *userLogin; + NSArray *principalURL; + + davURL = [[WOApplication application] davURL]; + userLogin = [[context activeUser] login]; + principalURL + = [NSArray arrayWithObject: [NSString stringWithFormat: @"%@%@/", davURL, + userLogin]]; + return [self _formalizePrincipalMatchResponse: principalURL]; +} + +- (void) _fillArrayWithPrincipalsOwnedBySelf: (NSMutableArray *) hrefs +{ + NSString *url; + NSArray *roles; + + roles = [[context activeUser] rolesForObject: self inContext: context]; + if ([roles containsObject: SoRole_Owner]) + { + url = [[self davURL] absoluteString]; + [hrefs addObject: url]; + } +} + +- (NSDictionary *) + _handlePrincipalMatchPrincipalProperty: (id ) child +{ + NSMutableArray *hrefs; + NSDictionary *response; + + hrefs = [NSMutableArray new]; + [self _fillArrayWithPrincipalsOwnedBySelf: hrefs]; + + response = [self _formalizePrincipalMatchResponse: hrefs]; + [hrefs release]; + + return response; +} + +- (NSDictionary *) _handlePrincipalMatchReport: (id ) document +{ + NSDictionary *response; + id documentElement, queryChild; + NSArray *children; + NSString *queryTag; + + documentElement = [document documentElement]; + children = [self domNode: documentElement + getChildNodesByType: DOM_ELEMENT_NODE]; + if ([children count] == 1) + { + queryChild = [children objectAtIndex: 0]; + queryTag = [queryChild tagName]; + if ([queryTag isEqualToString: @"self"]) + response = [self _handlePrincipalMatchSelf]; + else if ([queryTag isEqualToString: @"principal-property"]) + response = [self _handlePrincipalMatchPrincipalProperty: queryChild]; + else + response = [NSException exceptionWithHTTPStatus: 400 + reason: @"Query element must be either " + @" '{DAV:}principal-property' or '{DAV:}self'"]; + } + else + response = [NSException exceptionWithHTTPStatus: 400 + reason: @"Query must have one element:" + @" '{DAV:}principal-property' or '{DAV:}self'"]; + + return response; +} + +- (WOResponse *) davPrincipalMatch: (WOContext *) localContext +{ + WOResponse *r; + id document; + NSDictionary *xmlResponse; + + r = [context response]; + + document = [[context request] contentAsDOMDocument]; + xmlResponse = [self _handlePrincipalMatchReport: document]; + if ([xmlResponse isKindOfClass: [NSException class]]) + r = (WOResponse *) xmlResponse; + else + { + [r setStatus: 207]; + [r setContentEncoding: NSUTF8StringEncoding]; + [r setHeader: @"text/xml; charset=\"utf-8\"" forKey: @"content-type"]; + [r setHeader: @"no-cache" forKey: @"pragma"]; + [r setHeader: @"no-cache" forKey: @"cache-control"]; + [r appendContentString: + @"\r\n"]; + [r appendContentString: [xmlResponse asWebDavStringWithNamespaces: nil]]; + } + + return r; +} + /* actions */ - (id) DELETEAction: (id) _ctx @@ -763,7 +805,8 @@ static NSDictionary *reportMap = nil; if ([rq isSoWebDAVRequest]) { cType = [rq headerForKey: @"content-type"]; - if ([cType isEqualToString: @"application/xml"]) + if ([cType hasPrefix: @"application/xml"] + || [cType hasPrefix: @"text/xml"]) { document = [rq contentAsDOMDocument]; command = [[self _parseXMLCommand: document] davMethodToObjC]; @@ -1188,7 +1231,8 @@ static NSDictionary *reportMap = nil; /* description */ -- (void)appendAttributesToDescription:(NSMutableString *)_ms { +- (void) appendAttributesToDescription: (NSMutableString *) _ms +{ if (nameInContainer) [_ms appendFormat:@" name=%@", nameInContainer]; if (container) @@ -1196,7 +1240,8 @@ static NSDictionary *reportMap = nil; container, [container valueForKey:@"nameInContainer"]]; } -- (NSString *)description { +- (NSString *) description +{ NSMutableString *ms; ms = [NSMutableString stringWithCapacity:64]; @@ -1227,12 +1272,6 @@ static NSDictionary *reportMap = nil; } /* dav acls */ -- (NSArray *) davNamespaces -{ - return [NSArray arrayWithObject: - @"urn:inverse:params:xml:ns:inverse-dav"]; -} - - (NSString *) davRecordForUser: (NSString *) user { NSMutableString *userRecord; @@ -1443,11 +1482,12 @@ static NSDictionary *reportMap = nil; return exception; } -- (NSArray *) davSupportedReportSet +- (SOGoWebDAVValue *) davSupportedReportSet { + NSDictionary *currentValue; NSEnumerator *reportKeys; NSMutableArray *reportSet; - NSString *currentKey, *currentValue; + NSString *currentKey; reportSet = [NSMutableArray array]; @@ -1455,13 +1495,37 @@ static NSDictionary *reportMap = nil; while ((currentKey = [reportKeys nextObject])) if ([self _reportSelector: currentKey]) { - currentValue = [[currentKey asDavInvocation] - keysWithFormat: @"<%{method} xmlns=\"%{ns}\"/>"]; - [reportSet addObject: [SoWebDAVValue valueForObject: currentValue - attributes: nil]]; + currentValue = [currentKey asDavInvocation]; + [reportSet addObject: davElementWithContent(@"report", + @"DAV:", + currentValue)]; } - return [SOGoDAVSet davSetWithArray: reportSet ofValuesTaggedAs: @"report"]; + return [davElementWithContent (@"supported-report-set", @"DAV:", reportSet) + asWebDAVValue]; } @end /* SOGoObject */ + +@implementation SOGoObject (SOGoDomHelpers) + +- (NSArray *) domNode: (id ) node + getChildNodesByType: (DOMNodeType ) type +{ + NSMutableArray *nodes; + id currentChild; + + nodes = [NSMutableArray array]; + + currentChild = [node firstChild]; + while (currentChild) + { + if ([currentChild nodeType] == type) + [nodes addObject: currentChild]; + currentChild = [currentChild nextSibling]; + } + + return nodes; +} + +@end diff --git a/SoObjects/SOGo/SOGoParentFolder.m b/SoObjects/SOGo/SOGoParentFolder.m index c7291168..af6929f6 100644 --- a/SoObjects/SOGo/SOGoParentFolder.m +++ b/SoObjects/SOGo/SOGoParentFolder.m @@ -32,9 +32,11 @@ #import #import +#import "NSObject+DAV.h" #import "SOGoGCSFolder.h" #import "SOGoPermissions.h" #import "SOGoUser.h" +#import "SOGoWebDAVAclManager.h" #import "SOGoParentFolder.h" @@ -48,6 +50,48 @@ static SoSecurityManager *sm = nil; sm = [SoSecurityManager sharedSecurityManager]; } ++ (SOGoWebDAVAclManager *) webdavAclManager +{ + SOGoWebDAVAclManager *webdavAclManager = nil; + + if (!webdavAclManager) + { + webdavAclManager = [SOGoWebDAVAclManager new]; + [webdavAclManager registerDAVPermission: davElement (@"read", @"DAV:") + abstract: YES + withEquivalent: nil + asChildOf: davElement (@"all", @"DAV:")]; + [webdavAclManager registerDAVPermission: davElement (@"read-current-user-privilege-set", @"DAV:") + abstract: NO + withEquivalent: SoPerm_WebDAVAccess + asChildOf: davElement (@"read", @"DAV:")]; + [webdavAclManager registerDAVPermission: davElement (@"write", @"DAV:") + abstract: YES + withEquivalent: nil + asChildOf: davElement (@"all", @"DAV:")]; + [webdavAclManager registerDAVPermission: davElement (@"bind", @"DAV:") + abstract: NO + withEquivalent: SoPerm_AddFolders + asChildOf: davElement (@"write", @"DAV:")]; + [webdavAclManager registerDAVPermission: davElement (@"unbind", @"DAV:") + abstract: NO + withEquivalent: SoPerm_DeleteObjects + asChildOf: davElement (@"write", @"DAV:")]; + [webdavAclManager + registerDAVPermission: davElement (@"write-properties", @"DAV:") + abstract: YES + withEquivalent: nil + asChildOf: davElement (@"write", @"DAV:")]; + [webdavAclManager + registerDAVPermission: davElement (@"write-content", @"DAV:") + abstract: YES + withEquivalent: nil + asChildOf: davElement (@"write", @"DAV:")]; + } + + return webdavAclManager; +} + - (id) init { if ((self = [super init])) diff --git a/SoObjects/SOGo/SOGoPermissions.h b/SoObjects/SOGo/SOGoPermissions.h index 7fdab2c9..b8d8422d 100644 --- a/SoObjects/SOGo/SOGoPermissions.h +++ b/SoObjects/SOGo/SOGoPermissions.h @@ -71,7 +71,6 @@ extern NSString *SOGoCalendarRole_ComponentResponder; extern NSString *SOGoPerm_AccessObject; extern NSString *SOGoPerm_ReadAcls; -extern NSString *SOGoPerm_SaveAcls; extern NSString *SOGoPerm_FreeBusyLookup; extern NSString *SOGoCalendarPerm_ViewWholePublicRecords; diff --git a/SoObjects/SOGo/SOGoPermissions.m b/SoObjects/SOGo/SOGoPermissions.m index 740ef718..3eed89f0 100644 --- a/SoObjects/SOGo/SOGoPermissions.m +++ b/SoObjects/SOGo/SOGoPermissions.m @@ -75,7 +75,6 @@ NSString *SOGoPerm_AccessObject= @"Access Object"; NSString *SOGoPerm_ReadAcls = @"ReadAcls"; /* the equivalent of "read-acl" in the WebDAV acls spec, which is currently missing from SOPE */ -NSString *SOGoPerm_SaveAcls = @"SaveAcls"; NSString *SOGoPerm_FreeBusyLookup = @"FreeBusyLookup"; NSString *SOGoCalendarPerm_ViewWholePublicRecords = @"ViewWholePublicRecords"; @@ -95,4 +94,3 @@ NSString *SOGoCalendarPerm_ViewAllComponent = @"ViewAllComponent"; NSString *SOGoCalendarPerm_ViewDAndT = @"ViewDAndT"; NSString *SOGoCalendarPerm_ModifyComponent = @"ModifyComponent"; NSString *SOGoCalendarPerm_RespondToComponent = @"RespondToComponent"; - diff --git a/SoObjects/SOGo/SOGoUserFolder.m b/SoObjects/SOGo/SOGoUserFolder.m index a7e6ba51..0bc23b53 100644 --- a/SoObjects/SOGo/SOGoUserFolder.m +++ b/SoObjects/SOGo/SOGoUserFolder.m @@ -556,106 +556,15 @@ return cos; } +- (NSString *) davDisplayName +{ + return [[LDAPUserManager sharedUserManager] + getCNForUID: nameInContainer]; +} + - (BOOL) davIsCollection { return YES; } -// /* CalDAV support */ -// - (NSArray *) davCalendarHomeSet -// { -// /* -// -// http://cal.example.com/home/bernard/calendars/ -// - -// Note: this is the *container* for calendar collections, not the -// collections itself. So for use its the home folder, the -// public folder and the groups folder. -// */ -// NSArray *tag; -// SOGoAppointmentFolders *parent; - -// parent = [self privateCalendars: @"Calendar" inContext: context]; -// tag = [NSArray arrayWithObjects: @"href", @"DAV:", @"D", -// [parent davURL], nil]; - -// return [NSArray arrayWithObject: tag]; -// } - -// - (NSArray *) davCalendarUserAddressSet -// { -// NSArray *tag, *allEmails; -// NSMutableArray *addresses; -// NSEnumerator *emails; -// NSString *currentEmail; - -// addresses = [NSMutableArray array]; - -// allEmails = [[context activeUser] allEmails]; -// emails = [allEmails objectEnumerator]; -// while ((currentEmail = [emails nextObject])) -// { -// tag = [NSArray arrayWithObjects: @"href", @"DAV:", @"D", -// [NSString stringWithFormat: @"MAILTO:%@", currentEmail], -// nil]; -// [addresses addObject: tag]; -// } - -// return addresses; -// } - -// - (NSArray *) davCalendarScheduleInboxURL -// { -// NSArray *tag; -// SOGoAppointmentFolders *parent; - -// parent = [self privateCalendars: @"Calendar" inContext: context]; -// tag = [NSArray arrayWithObjects: @"href", @"DAV:", @"D", -// [NSString stringWithFormat: @"%@personal/", [parent davURL]], -// nil]; - -// return [NSArray arrayWithObject: tag]; -// } - -// - (NSString *) davCalendarScheduleOutboxURL -// { -// NSArray *tag; -// SOGoAppointmentFolders *parent; - -// parent = [self privateCalendars: @"Calendar" inContext: context]; -// tag = [NSArray arrayWithObjects: @"href", @"DAV:", @"D", -// [NSString stringWithFormat: @"%@personal/", [parent davURL]], -// nil]; - -// return [NSArray arrayWithObject: tag]; -// } - -// - (NSString *) davDropboxHomeURL -// { -// NSArray *tag; -// SOGoAppointmentFolders *parent; - -// parent = [self privateCalendars: @"Calendar" inContext: context]; -// tag = [NSArray arrayWithObjects: @"href", @"DAV:", @"D", -// [NSString stringWithFormat: @"%@personal/", [parent davURL]], -// nil]; - -// return [NSArray arrayWithObject: tag]; -// } - -// - (NSString *) davNotificationsURL -// { -// NSArray *tag; -// SOGoAppointmentFolders *parent; - -// parent = [self privateCalendars: @"Calendar" inContext: context]; -// tag = [NSArray arrayWithObjects: @"href", @"DAV:", @"D", -// [NSString stringWithFormat: @"%@personal/", [parent davURL]], -// nil]; - -// return [NSArray arrayWithObject: tag]; -// } - @end /* SOGoUserFolder */ diff --git a/SoObjects/SOGo/SOGoWebDAVAclManager.h b/SoObjects/SOGo/SOGoWebDAVAclManager.h new file mode 100644 index 00000000..18c4c49d --- /dev/null +++ b/SoObjects/SOGo/SOGoWebDAVAclManager.h @@ -0,0 +1,53 @@ +/* SOGoWebDAVAclManager.h - this file is part of SOGo + * + * Copyright (C) 2008 Inverse groupe conseil + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef SOGOWEBDAVACLMANAGER_H +#define SOGOWEBDAVACLMANAGER_H + +#import + +@class NSDictionary; +@class NSMutableDictionary; +@class NSString; + +@class SOGoObject; +@class SOGoUser; +@class SOGoWebDAVValue; + +@interface SOGoWebDAVAclManager : NSObject +{ + NSMutableDictionary *aclTree; +} + +- (void) registerDAVPermission: (NSDictionary *) davPermission + abstract: (BOOL) abstract + withEquivalent: (NSString *) sogoPermission + asChildOf: (NSDictionary *) otherDAVPermission; + +- (NSArray *) davPermissionsForRoles: (NSArray *) roles + onObject: (SOGoObject *) object; + +- (SOGoWebDAVValue *) treeAsWebDAVValue; + +@end + +#endif /* SOGOWEBDAVACLMANAGER_H */ diff --git a/SoObjects/SOGo/SOGoWebDAVAclManager.m b/SoObjects/SOGo/SOGoWebDAVAclManager.m new file mode 100644 index 00000000..ad576d71 --- /dev/null +++ b/SoObjects/SOGo/SOGoWebDAVAclManager.m @@ -0,0 +1,262 @@ +/* SOGoWebDAVAclManager.m - this file is part of SOGo + * + * Copyright (C) 2008 Inverse groupe conseil + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#import +#import +#import + +#import +#import +#import + +#import "NSDictionary+Utilities.h" +#import "NSObject+DAV.h" +#import "SOGoObject.h" +#import "SOGoUser.h" +#import "SOGoWebDAVValue.h" + +#import "SOGoWebDAVAclManager.h" + +static NSNumber *yesObject = nil; + +@interface SoClass (SOGoDAVPermissions) + +- (BOOL) userRoles: (NSArray *) userRoles + havePermission: (NSString *) permission; + +@end + +@implementation SoClass (SOGoDAVPermissions) + +- (BOOL) userRoles: (NSArray *) userRoles + havePermission: (NSString *) permission +{ + BOOL result; + SoClass *currentClass; + NSArray *roles; + + result = NO; + + currentClass = self; + while (!result && currentClass) + { + roles = [[currentClass soClassSecurityInfo] + defaultRolesForPermission: permission]; + if ([roles firstObjectCommonWithArray: userRoles]) + { + NSLog (@"matched '%@': %@", permission, roles); + result = YES; + } + else + currentClass = [currentClass soSuperClass]; + } + + return result; +} + +@end + +@implementation SOGoWebDAVAclManager + ++ (void) initialize +{ + if (!yesObject) + { + yesObject = [NSNumber numberWithBool: YES]; + [yesObject retain]; + } +} + +- (id) init +{ + if ((self = [super init])) + { + aclTree = [NSMutableDictionary new]; + [self registerDAVPermission: davElement (@"all", @"DAV:") + abstract: YES + withEquivalent: nil + asChildOf: nil]; + } + + return self; +} + +- (void) dealloc +{ + [aclTree release]; + [super dealloc]; +} + +- (void) _registerChild: (NSMutableDictionary *) newEntry + of: (NSDictionary *) parentPermission +{ + NSString *identifier; + NSMutableDictionary *parentEntry; + NSMutableArray *children; + + identifier = [parentPermission keysWithFormat: @"{%{ns}}%{method}"]; + parentEntry = [aclTree objectForKey: identifier]; + if (!parentEntry) + [self warnWithFormat: @"parent entry '%@' does not exist in DAV" + @" permissions table", identifier]; + children = [parentEntry objectForKey: @"children"]; + if (!children) + { + children = [NSMutableArray new]; + [parentEntry setObject: children forKey: @"children"]; + [children release]; + } + [children addObject: newEntry]; + [newEntry setObject: parentEntry forKey: @"parent"]; +} + +- (void) registerDAVPermission: (NSDictionary *) davPermission + abstract: (BOOL) abstract + withEquivalent: (NSString *) sogoPermission + asChildOf: (NSDictionary *) otherDAVPermission +{ + NSMutableDictionary *newEntry; + NSString *identifier; + + newEntry = [NSMutableDictionary new]; + identifier = [davPermission keysWithFormat: @"{%{ns}}%{method}"]; + if ([aclTree objectForKey: identifier]) + [self warnWithFormat: + @"entry '%@' already exists in DAV permissions table", + identifier]; + [aclTree setObject: newEntry forKey: identifier]; + [newEntry setObject: davPermission forKey: @"permission"]; + if (abstract) + [newEntry setObject: yesObject forKey: @"abstract"]; + if (sogoPermission) + [newEntry setObject: sogoPermission forKey: @"equivalent"]; + + if (otherDAVPermission) + [self _registerChild: newEntry of: otherDAVPermission]; + + [newEntry release]; +} + +#warning this method should be simplified! +/* We add the permissions that fill those conditions: + - should match the sogo permissions implied by the user roles + If all the child permissions of a permission are included, then this + permission will be included too. Conversely, if a permission is included, + all the child permissions will be included too. */ + +- (BOOL) _fillArray: (NSMutableArray *) davPermissions + withPermission: (NSDictionary *) permission + forUserRoles: (NSArray *) userRoles + withSoClass: (SoClass *) soClass + matchSOGoPerms: (BOOL) matchSOGoPerms +{ + NSString *sogoPermission; + NSDictionary *childPermission; + NSEnumerator *children; + BOOL appended, childrenAppended; + + appended = YES; + if (matchSOGoPerms) + { + sogoPermission = [permission objectForKey: @"equivalent"]; + if (sogoPermission + && [soClass userRoles: userRoles havePermission: sogoPermission]) + { + [davPermissions + addObject: [permission objectForKey: @"permission"]]; + } + else + appended = NO; + } + else + [davPermissions + addObject: [permission objectForKey: @"permission"]]; + + children = [[permission objectForKey: @"children"] objectEnumerator]; + if (children) + { + childrenAppended = YES; + while ((childPermission = [children nextObject])) + childrenAppended = (childrenAppended + && [self _fillArray: davPermissions + withPermission: childPermission + forUserRoles: userRoles + withSoClass: soClass + matchSOGoPerms: (matchSOGoPerms && !appended)]); + if (childrenAppended && !appended) + { + [davPermissions + addObject: [permission objectForKey: @"permission"]]; + appended = YES; + } + } + + return appended; +} + +- (NSArray *) davPermissionsForRoles: (NSArray *) roles + onObject: (SOGoObject *) object +{ + NSMutableArray *davPermissions; + SoClass *soClass; + + davPermissions = [NSMutableArray array]; + soClass = [[object class] soClass]; + [self _fillArray: davPermissions + withPermission: [aclTree objectForKey: @"{DAV:}all"] + forUserRoles: roles + withSoClass: soClass + matchSOGoPerms: YES]; + + return davPermissions; +} + +- (SOGoWebDAVValue *) + _supportedPrivilegeSetFromPermission: (NSDictionary *) perm +{ + NSMutableArray *privilege; + NSEnumerator *children; + NSDictionary *currentPerm; + + privilege = [NSMutableArray array]; + [privilege addObject: + davElementWithContent (@"privilege", + @"DAV:", + [perm objectForKey: @"permission"])]; + if ([[perm objectForKey: @"abstract"] boolValue]) + [privilege addObject: davElement (@"abstract", @"DAV:")]; + children = [[perm objectForKey: @"children"] objectEnumerator]; + while ((currentPerm = [children nextObject])) + [privilege addObject: + [self _supportedPrivilegeSetFromPermission: currentPerm]]; + + return davElementWithContent (@"supported-privilege", + @"DAV:", privilege); +} + +- (SOGoWebDAVValue *) treeAsWebDAVValue +{ + return [self _supportedPrivilegeSetFromPermission: + [aclTree objectForKey: @"{DAV:}all"]]; +} + +@end diff --git a/SoObjects/SOGo/SOGoDAVRendererTypes.h b/SoObjects/SOGo/SOGoWebDAVValue.h similarity index 51% rename from SoObjects/SOGo/SOGoDAVRendererTypes.h rename to SoObjects/SOGo/SOGoWebDAVValue.h index 2fdfaa81..239abc96 100644 --- a/SoObjects/SOGo/SOGoDAVRendererTypes.h +++ b/SoObjects/SOGo/SOGoWebDAVValue.h @@ -1,6 +1,6 @@ -/* SOGoDAVRendererTypes.h - this file is part of SOGo +/* SOGoWebDAVValue.h - this file is part of SOGo * - * Copyright (C) 2006 Inverse groupe conseil + * Copyright (C) 2008 Inverse groupe conseil * * Author: Wolfgang Sourdeau * @@ -20,41 +20,21 @@ * Boston, MA 02111-1307, USA. */ -#ifndef SOGODAVRENDERERTYPES_H -#define SOGODAVRENDERERTYPES_H +#ifndef SOGOWEBDAVVALUE_H +#define SOGOWEBDAVVALUE_H #import -@class NSArray; -@class NSDictionary; @class NSString; -@interface SOGoDAVSet : SoWebDAVValue -{ - NSString *valueTag; - NSArray *values; -} +@interface SOGoWebDAVValue : SoWebDAVValue -+ (id) davSetWithArray: (NSArray *) newValues - ofValuesTaggedAs: (NSString *) newValueTag; +- (NSString *) stringForTag: (NSString *) _key + rawName: (NSString *) setTag + inContext: (id) context + prefixes: (NSDictionary *) prefixes; -- (void) setValueTag: (NSString *) newValueTag; -- (void) setValues: (NSArray *) newValues; - @end -@interface SOGoDAVDictionary : SoWebDAVValue -{ - NSString *valueTag; - NSDictionary *values; -} -+ (id) davDictionary: (NSDictionary *) newValues - taggedAs: (NSString *) newValueTag; - -- (void) setValueTag: (NSString *) newValueTag; -- (void) setValues: (NSDictionary *) newValues; - -@end - -#endif /* SOGODAVRENDERERTYPES_H */ +#endif /* SOGOWEBDAVVALUE_H */ diff --git a/SoObjects/SOGo/SOGoWebDAVValue.m b/SoObjects/SOGo/SOGoWebDAVValue.m new file mode 100644 index 00000000..913bd09d --- /dev/null +++ b/SoObjects/SOGo/SOGoWebDAVValue.m @@ -0,0 +1,37 @@ +/* SOGoWebDAVValue.m - this file is part of $PROJECT_NAME_HERE$ + * + * Copyright (C) 2008 Inverse groupe conseil + * + * Author: Wolfgang Sourdeau + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#import + +#import "SOGoWebDAVValue.h" + +@implementation SOGoWebDAVValue : SoWebDAVValue + +- (NSString *) stringForTag: (NSString *) _key + rawName: (NSString *) setTag + inContext: (id) context + prefixes: (NSDictionary *) prefixes +{ + return object; +} + +@end diff --git a/SoObjects/common.make b/SoObjects/common.make index 12400eea..89a625e9 100644 --- a/SoObjects/common.make +++ b/SoObjects/common.make @@ -18,7 +18,7 @@ ADDITIONAL_INCLUDE_DIRS += \ -I../../SOPE ADDITIONAL_LIB_DIRS += \ - -L../SOGo/$(GNUSTEP_OBJ_DIR)/ \ + -L../SOGo/SOGo.framework/ \ -L../../SOGo/$(GNUSTEP_OBJ_DIR)/ \ -L../../OGoContentStore/$(GNUSTEP_OBJ_DIR)/ \ -L../../SOPE/NGCards/$(GNUSTEP_OBJ_DIR)/ \ diff --git a/TODO b/TODO index 895f10a5..63e2dcb8 100644 --- a/TODO +++ b/TODO @@ -4,3 +4,10 @@ Rendering of multi-status responses is suboptimal in SOPE: Therefore it would be nice to refactor those things a little bit and maybe put some code from SOGo up into SOPE. -- wsourdeau@inverse.ca, Tue, 22 Apr 2008 15:21:32 -0400 + +ACL: +- the "default user" concept in the SOGo ACL paradigm should probably match +the "authenticated" role in SOGo/SOPE. Also, we should reconsider the handling +of the DAV:authenticated principal wrt the DAV ACL interface. +- we should add support for DAV privilege descriptions + -- wsourdeau@inverse.ca, Tue, 29 Apr 2008 12:05:17 -0400 diff --git a/UI/Common/UIxAclEditor.m b/UI/Common/UIxAclEditor.m index 1d0a430e..f5ae4997 100644 --- a/UI/Common/UIxAclEditor.m +++ b/UI/Common/UIxAclEditor.m @@ -193,7 +193,7 @@ mgr = [SoSecurityManager sharedSecurityManager]; - return (![mgr validatePermission: SOGoPerm_SaveAcls + return (![mgr validatePermission: SoPerm_ChangePermissions onObject: [self clientObject] inContext: context]); } diff --git a/UI/Common/product.plist b/UI/Common/product.plist index ba403b8d..670291c0 100644 --- a/UI/Common/product.plist +++ b/UI/Common/product.plist @@ -31,12 +31,12 @@ SOGoObject = { methods = { addUserInAcls = { - protectedBy = "SaveAcls"; + protectedBy = "Change Permissions"; actionClass = "UIxObjectActions"; actionName = "addUserInAcls"; }; removeUserFromAcls = { - protectedBy = "SaveAcls"; + protectedBy = "Change Permissions"; actionClass = "UIxObjectActions"; actionName = "removeUserFromAcls"; }; @@ -45,7 +45,7 @@ pageName = "UIxAclEditor"; }; saveAcls = { - protectedBy = "SaveAcls"; + protectedBy = "Change Permissions"; pageName = "UIxAclEditor"; actionName = "saveAcls"; }; @@ -54,7 +54,7 @@ pageName = "UIxUserRightsEditor"; }; saveUserRights = { - protectedBy = "SaveAcls"; + protectedBy = "Change Permissions"; pageName = "UIxUserRightsEditor"; actionName = "saveUserRights"; }; @@ -63,7 +63,7 @@ SOGoParentFolder = { methods = { createFolder = { - protectedBy = "View"; + protectedBy = "SoPerm_AddFolders"; actionClass = "UIxParentFolderActions"; actionName = "createFolder"; }; @@ -97,12 +97,12 @@ actionName = "deactivateFolder"; }; deleteFolder = { - protectedBy = "SaveAcls"; /* a hack to force "owner" */ + protectedBy = "Delete Objects"; actionClass = "UIxFolderActions"; actionName = "deleteFolder"; }; renameFolder = { - protectedBy = "SaveAcls"; + protectedBy = "Change Permissions"; actionClass = "UIxFolderActions"; actionName = "renameFolder"; }; diff --git a/UI/Contacts/product.plist b/UI/Contacts/product.plist index 8c06e706..1cebeb68 100644 --- a/UI/Contacts/product.plist +++ b/UI/Contacts/product.plist @@ -37,7 +37,7 @@ pageName = "UIxAclEditor"; }; saveAcls = { - protectedBy = "SaveAcls"; + protectedBy = "Change Permissions"; pageName = "UIxAclEditor"; actionName = "saveAcls"; }; @@ -92,7 +92,7 @@ pageName = "UIxContactsUserRightsEditor"; }; saveUserRights = { - protectedBy = "SaveAcls"; + protectedBy = "Change Permissions"; pageName = "UIxContactsUserRightsEditor"; actionName = "saveUserRights"; }; diff --git a/UI/MailPartViewers/UIxMailPartTextViewer.m b/UI/MailPartViewers/UIxMailPartTextViewer.m index e84ce944..c8d20347 100644 --- a/UI/MailPartViewers/UIxMailPartTextViewer.m +++ b/UI/MailPartViewers/UIxMailPartTextViewer.m @@ -61,13 +61,13 @@ convertChars (const char *oldString, unsigned int oldLength, iteration = 0; upperLimit = oldString + oldLength; - while ((unsigned int) currentChar < (unsigned int) upperLimit) + while (currentChar < upperLimit) { if (*currentChar != '\r') { if (*currentChar == '\n') { - length = (unsigned int) destChar - (unsigned int) newString; + length = destChar - newString; if ((length + (6 * iteration) + 500) > maxLength) { maxLength = length + (iteration * 6) + 500; @@ -93,7 +93,7 @@ convertChars (const char *oldString, unsigned int oldLength, currentChar++; } *destChar = 0; - *newLength = (unsigned int) destChar - (unsigned int) newString; + *newLength = destChar - newString; return newString; } diff --git a/UI/MailerUI/product.plist b/UI/MailerUI/product.plist index 733563be..da02d014 100644 --- a/UI/MailerUI/product.plist +++ b/UI/MailerUI/product.plist @@ -160,7 +160,7 @@ pageName = "UIxMailUserRightsEditor"; }; saveUserRights = { - protectedBy = "SaveAcls"; + protectedBy = "Change Permissions"; pageName = "UIxMailUserRightsEditor"; actionName = "saveUserRights"; }; diff --git a/UI/MainUI/GNUmakefile b/UI/MainUI/GNUmakefile index 2d0bf7f8..6ed1e7e5 100644 --- a/UI/MainUI/GNUmakefile +++ b/UI/MainUI/GNUmakefile @@ -11,9 +11,9 @@ MainUI_LANGUAGES = English French German Italian MainUI_OBJC_FILES += \ MainUIProduct.m \ SOGoRootPage.m \ - SOGoUserHomePage.m \ - SOGoGroupPage.m \ - SOGoGroupsPage.m \ + SOGoUserHomePage.m +# SOGoGroupPage.m \ +# SOGoGroupsPage.m \ MainUI_RESOURCE_FILES += \ Version \ diff --git a/UI/MainUI/product.plist b/UI/MainUI/product.plist index d00f74aa..ce67497d 100644 --- a/UI/MainUI/product.plist +++ b/UI/MainUI/product.plist @@ -26,7 +26,7 @@ "Add Documents, Images, and Files" = ( "Owner", "ObjectCreator" ); "Add Folders" = ( "Owner", "FolderCreator" ); "ReadAcls" = ( "Owner" ); - "SaveAcls" = ( "Owner" ); + "Change Permissions" = ( "Owner" ); "Delete Objects" = ( "Owner", "ObjectEraser" ); "WebDAV Access" = ( "Owner", "ObjectViewer", "ObjectEditor", "ObjectCreator", "ObjectEraser" ); }; @@ -67,6 +67,8 @@ defaultRoles = { "Access Contents Information" = ( "Authenticated" ); "WebDAV Access" = ( "Authenticated" ); + "Add Folders" = ( "Owner" ); + "Delete Objects" = ( "Owner" ); }; }; SOGoUserFolder = { @@ -136,22 +138,22 @@ }; }; }; - SOGoGroupsFolder = { - methods = { - index = { - protectedBy = "View"; - pageName = "SOGoGroupsPage"; - }; - }; - }; - SOGoGroupFolder = { - methods = { - index = { - protectedBy = "View"; - pageName = "SOGoGroupPage"; - }; - }; - }; +// SOGoGroupsFolder = { +// methods = { +// index = { +// protectedBy = "View"; +// pageName = "SOGoGroupsPage"; +// }; +// }; +// }; +// SOGoGroupFolder = { +// methods = { +// index = { +// protectedBy = "View"; +// pageName = "SOGoGroupPage"; +// }; +// }; +// }; SOGoFreeBusyObject = { methods = { ajaxRead = { @@ -161,9 +163,9 @@ }; }; }; - SOGoCustomGroupFolder = { - methods = { - }; - }; +// SOGoCustomGroupFolder = { +// methods = { +// }; +// }; }; } diff --git a/UI/SOGoUI/UIxComponent.m b/UI/SOGoUI/UIxComponent.m index 0a707bc5..9a29fe56 100644 --- a/UI/SOGoUI/UIxComponent.m +++ b/UI/SOGoUI/UIxComponent.m @@ -41,7 +41,7 @@ #import #import #import -#import +// #import #import #import "UIxJSClose.h" @@ -318,23 +318,26 @@ static BOOL uixDebugEnabled = NO; { SOGoObject *currentClient, *parent; BOOL found; - Class objectClass, groupFolderClass, userFolderClass; + Class objectClass, userFolderClass; +// , groupFolderClass currentClient = [self clientObject]; if (currentClient && [currentClient isKindOfClass: [SOGoObject class]]) { - groupFolderClass = [SOGoCustomGroupFolder class]; +// groupFolderClass = [SOGoCustomGroupFolder class]; userFolderClass = [SOGoUserFolder class]; objectClass = [currentClient class]; - found = (objectClass == groupFolderClass || objectClass == userFolderClass); +// found = (objectClass == groupFolderClass || objectClass == userFolderClass); + found = (objectClass == userFolderClass); while (!found && currentClient) { parent = [currentClient container]; objectClass = [parent class]; - if (objectClass == groupFolderClass - || objectClass == userFolderClass) + if (// objectClass == groupFolderClass +// || + objectClass == userFolderClass) found = YES; else currentClient = parent; diff --git a/UI/Scheduler/UIxComponentEditor.m b/UI/Scheduler/UIxComponentEditor.m index 27ad5be2..c53b8d7d 100644 --- a/UI/Scheduler/UIxComponentEditor.m +++ b/UI/Scheduler/UIxComponentEditor.m @@ -176,8 +176,7 @@ iRANGE(2); um = [LDAPUserManager sharedUserManager]; attendees = [[component attendees] objectEnumerator]; - currentAttendee = [attendees nextObject]; - while (currentAttendee) + while ((currentAttendee = [attendees nextObject])) { [names appendFormat: @"%@,", [currentAttendee cn]]; [emails appendFormat: @"%@,", [currentAttendee rfc822Email]]; @@ -186,8 +185,8 @@ iRANGE(2); [uids appendFormat: @"%@,", uid]; else [uids appendString: @","]; - [states appendFormat: @"%@,", [[currentAttendee partStat] lowercaseString]]; - currentAttendee = [attendees nextObject]; + [states appendFormat: @"%@,", + [[currentAttendee partStat] lowercaseString]]; } if ([names length] > 0) diff --git a/UI/Scheduler/product.plist b/UI/Scheduler/product.plist index b18b596b..0c48af66 100644 --- a/UI/Scheduler/product.plist +++ b/UI/Scheduler/product.plist @@ -1,4 +1,4 @@ -{ /* -*-javascript-*- */ +{ /* -*-java-*- */ requires = ( MAIN, MainUI, CommonUI, Appointments, Contacts, ContactsUI ); publicResources = ( @@ -99,7 +99,7 @@ pageName = "UIxCalUserRightsEditor"; }; saveUserRights = { - protectedBy = "SaveAcls"; + protectedBy = "Change Permissions"; pageName = "UIxCalUserRightsEditor"; actionName = "saveUserRights"; }; @@ -139,7 +139,7 @@ pageName = "UIxCalUserRightsEditor"; }; saveUserRights = { - protectedBy = "SaveAcls"; + protectedBy = "Change Permissions"; pageName = "UIxCalUserRightsEditor"; actionName = "saveUserRights"; }; diff --git a/UI/WebServerResources/MailerUI.js b/UI/WebServerResources/MailerUI.js index 77cf17e7..3416324f 100644 --- a/UI/WebServerResources/MailerUI.js +++ b/UI/WebServerResources/MailerUI.js @@ -1170,16 +1170,16 @@ var messageListGhost = function () { newDiv.appendChild(document.createTextNode(count + " messages...")); return newDiv; -} +}; - var messageListData = function(type) { - var rows = this.parentNode.parentNode.getSelectedRowsId(); - var msgIds = new Array(); - for (var i = 0; i < rows.length; i++) - msgIds.push(rows[i].substr(4)); +var messageListData = function(type) { + var rows = this.parentNode.parentNode.getSelectedRowsId(); + var msgIds = new Array(); + for (var i = 0; i < rows.length; i++) + msgIds.push(rows[i].substr(4)); - return msgIds; - } + return msgIds; +} /* a model for a futur refactoring of the sortable table headers mechanism */ function configureMessageListEvents(table) { @@ -1200,28 +1200,28 @@ function configureMessageListBodyEvents(table) { if ($(cell).hasClassName("tbtv_navcell")) { var anchors = $(cell).childNodesWithTag("a"); for (var i = 0; i < anchors.length; i++) - anchors[i].observe("click", - openMailboxAtIndex.bindAsEventListener(anchors[i])); + $(anchors[i]).observe("click", openMailboxAtIndex); } rows = table.tBodies[0].rows; for (var i = 0; i < rows.length; i++) { - rows[i].observe("mousedown", onRowClick); - rows[i].observe("selectstart", listRowMouseDownHandler); - rows[i].observe("contextmenu", onMessageContextMenu.bindAsEventListener(rows[i])); + var row = $(rows[i]); + row.observe("mousedown", onRowClick); + row.observe("selectstart", listRowMouseDownHandler); + row.observe("contextmenu", onMessageContextMenu); - rows[i].dndTypes = function() { return new Array("mailRow"); }; - rows[i].dndGhost = messageListGhost; - rows[i].dndDataForType = messageListData; - // document.DNDManager.registerSource(rows[i]); + row.dndTypes = function() { return new Array("mailRow"); }; + row.dndGhost = messageListGhost; + row.dndDataForType = messageListData; + // document.DNDManager.registerSource(row); - for (var j = 0; j < rows[i].cells.length; j++) { - var cell = rows[i].cells[j]; + for (var j = 0; j < row.cells.length; j++) { + var cell = $(row.cells[j]); cell.observe("mousedown", listRowMouseDownHandler); if (j == 2 || j == 3 || j == 5) cell.observe("dblclick", onMessageDoubleClick.bindAsEventListener(cell)); else if (j == 4) { - var img = cell.childNodesWithTag("img")[0]; + var img = $(cell.childNodesWithTag("img")[0]); img.observe("click", mailListMarkMessage.bindAsEventListener(img)); } } diff --git a/UI/WebServerResources/SchedulerUI.js b/UI/WebServerResources/SchedulerUI.js index ee6b067e..513f696b 100644 --- a/UI/WebServerResources/SchedulerUI.js +++ b/UI/WebServerResources/SchedulerUI.js @@ -417,8 +417,7 @@ function tasksListCallback(http) { list.appendChild(listItem); listItem.observe("mousedown", listRowMouseDownHandler); listItem.observe("click", onRowClick); - listItem.observe("dblclick", - editDoubleClickedEvent); + listItem.observe("dblclick", editDoubleClickedEvent); listItem.setAttribute("id", data[i][0]); $(listItem).addClassName(data[i][5]); $(listItem).addClassName(data[i][6]); @@ -428,7 +427,7 @@ function tasksListCallback(http) { var input = document.createElement("input"); input.setAttribute("type", "checkbox"); listItem.appendChild(input); - // input.observe("click", updateTaskStatus, true); + input.observe("click", updateTaskStatus, true); input.setAttribute("value", "1"); if (data[i][2] == 1) input.setAttribute("checked", "checked"); @@ -1598,7 +1597,7 @@ function initCalendarSelector() { var items = list.childNodesWithTag("li"); for (var i = 0; i < items.length; i++) { var input = items[i].childNodesWithTag("input")[0]; - input.observe("click", updateCalendarStatus); + $(input).observe("click", updateCalendarStatus); items[i].observe("mousedown", listRowMouseDownHandler); items[i].observe("selectstart", listRowMouseDownHandler); items[i].observe("click", onRowClick); diff --git a/UI/WebServerResources/UIxMailEditor.js b/UI/WebServerResources/UIxMailEditor.js index 3160af40..ee6a5676 100644 --- a/UI/WebServerResources/UIxMailEditor.js +++ b/UI/WebServerResources/UIxMailEditor.js @@ -261,11 +261,11 @@ function onTextFocus() { function onTextFirstFocus() { var content = this.getValue(); if (content.lastIndexOf("--") == 0) { - this.insertBefore(document.createTextNode("\r\n"), + this.insertBefore(document.createTextNode("\r"), this.lastChild); } if (signatureLength > 0) { - var length = this.getValue().length - signatureLength - 1; + var length = this.getValue().length - signatureLength - 2; this.setCaretTo(length); } Event.stopObserving(this, "focus", onTextFirstFocus); diff --git a/UI/WebServerResources/generic.js b/UI/WebServerResources/generic.js index bee04205..7c2e36b5 100644 --- a/UI/WebServerResources/generic.js +++ b/UI/WebServerResources/generic.js @@ -304,6 +304,7 @@ function onAjaxRequestStateChange(http) { log("AJAX Request, Caught Exception: " + e.name); log(e.message); log(backtrace()); + log("request url was '" + http.url + "'"); } } @@ -1387,6 +1388,16 @@ function onLoadHandler(event) { if (progressImage) progressImage.parentNode.removeChild(progressImage); $(document.body).observe("contextmenu", onBodyClickContextMenu); + /* $(document.body).observe("click", testclic); */ +} + +function testclic(event) { +log("test: " + event.target); +if (event.target) { +log("tag: " + event.target.tagName); +log("id: " + event.target.getAttribute("id")); +log("class: " + event.target.getAttribute("class")); +} } function onBodyClickContextMenu(event) { diff --git a/UI/WebServerResources/iefixes.css b/UI/WebServerResources/iefixes.css index 20709a0d..af554f48 100644 --- a/UI/WebServerResources/iefixes.css +++ b/UI/WebServerResources/iefixes.css @@ -1,4 +1,11 @@ /* SOGoRootPage */ +HTML +{ overflow: hidden; } + +FORM +{ padding: 0px; + margin: 0px; } + DIV#loginScreen { border: 2px solid #fff; border-right: 2px solid #666; @@ -293,4 +300,4 @@ TABLE#freeBusyData TD SPAN.freeBusyZoneElement { height: 103%; } TABLE -{ empty-cells: show; } \ No newline at end of file +{ empty-cells: show; } diff --git a/UI/WebServerResources/prototype.js b/UI/WebServerResources/prototype.js index 35a69137..e8a445ff 100644 --- a/UI/WebServerResources/prototype.js +++ b/UI/WebServerResources/prototype.js @@ -1275,7 +1275,7 @@ Ajax.Request = Class.create(Ajax.Base, { success: function() { var status = this.getStatus(); - return !status || (status >= 200 && status < 300); + return !status || status == 1223 || (status >= 200 && status < 300); }, getStatus: function() { diff --git a/UI/common.make b/UI/common.make index 84720619..21d53eed 100644 --- a/UI/common.make +++ b/UI/common.make @@ -20,13 +20,13 @@ ifeq ($(GNUSTEP_BUILD_DIR),) ADDITIONAL_LIB_DIRS += \ -L../../SOPE/NGCards/$(GNUSTEP_OBJ_DIR) \ -L../SOGoUI/$(GNUSTEP_OBJ_DIR) \ - -L../../SoObjects/SOGo/$(GNUSTEP_OBJ_DIR) + -L../../SoObjects/SOGo/SOGo.framework/ else RELBUILD_DIR_libNGCards = \ $(GNUSTEP_BUILD_DIR)/../../SOPE/NGCards/$(GNUSTEP_OBJ_DIR_NAME) RELBUILD_DIR_libSOGo = \ - $(GNUSTEP_BUILD_DIR)/../../SoObjects/SOGo/$(GNUSTEP_OBJ_DIR_NAME) + $(GNUSTEP_BUILD_DIR)/../../SoObjects/SOGo/SOGo.framework/ RELBUILD_DIR_libSOGoUI = \ $(GNUSTEP_BUILD_DIR)/../SOGoUI/$(GNUSTEP_OBJ_DIR_NAME) RELBUILD_DIR_libOGoContentStore = \