From 8c5ebf99b4596734302b1be7adf2a4d235589984 Mon Sep 17 00:00:00 2001 From: wolfgang Date: Sat, 23 Feb 2008 18:31:32 +0000 Subject: [PATCH] git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1374 d1b88da0-ebda-0310-925b-ed51d893ca5b --- ChangeLog | 45 ++ ...et-r1603.diff => sope-patchset-r1605.diff} | 398 ++++++++++-------- .../Appointments/SOGoAppointmentFolder.m | 7 +- SoObjects/Contacts/SOGoContactGCSFolder.m | 7 +- SoObjects/SOGo/NSArray+Utilities.h | 2 + SoObjects/SOGo/NSArray+Utilities.m | 15 + SoObjects/SOGo/SOGoDAVRendererTypes.h | 15 + SoObjects/SOGo/SOGoDAVRendererTypes.m | 106 ++++- SoObjects/SOGo/SOGoFolder.h | 1 - SoObjects/SOGo/SOGoFolder.m | 7 +- SoObjects/SOGo/SOGoGCSFolder.m | 53 ++- SoObjects/SOGo/SOGoObject.h | 7 + SoObjects/SOGo/SOGoObject.m | 255 ++++++++++- SoObjects/SOGo/SOGoUserFolder.m | 103 ++++- UI/Common/UIxObjectActions.m | 57 +-- configure | 1 + 16 files changed, 789 insertions(+), 290 deletions(-) rename SOPE/{sope-patchset-r1603.diff => sope-patchset-r1605.diff} (95%) diff --git a/ChangeLog b/ChangeLog index 38ab62f1..9a67f429 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,48 @@ +2008-02-22 Wolfgang Sourdeau + + * SoObjects/SOGo/SOGoUserFolder.m ([SOGoUserFolder + -davUserQuery:queryContext]): new method for the "user-query" + inverse DAV method. + + * SoObjects/SOGo/SOGoGCSFolder.m ([SOGoGCSFolder + -aclUsersForObjectAtPath:objectPathArray]): return unique uids. + + * SoObjects/SOGo/SOGoFolder.m ([-davNamespaces]): removed method. + + * SoObjects/SOGo/SOGoDAVRendererTypes.h (SoWebDAVValue): added + SOGoDAVDictionary webdav value class. + + * SoObjects/SOGo/NSArray+Utilities.m ([NSArray -uniqueObjects]): + new method that returns unique occurences of the objects. + + * SoObjects/Contacts/SOGoContactGCSFolder.m ([SOGoContactGCSFolder + -davNamespaces]): same as below. + + * SoObjects/Appointments/SOGoAppointmentFolder.m + ([SOGoAppointmentFolder -davNamespaces]): take the parents + namespaces into account. + + * SoObjects/SOGo/SOGoObject.m ([SOGoObject -addUserInAcls:uid]): + new method. + ([SOGoObject -removeUserFromAcls:uid]): new methods (see below). + ([SOGoObject -davNamespaces]): declare the + "urn:inverse:params:xml:ns:inverse-dav" namespace. + ([SOGoObject -davRecordForUser:user]) + ([SOGoObject -davAclQuery:queryContext]): new methods to answer to + the "user-list", "roles", "set-roles", "add-user", "remove-user" + inverse DAV methods. + + * UI/Common/UIxObjectActions.m ([UIxObjectActions -addUserInAclsAction]) + ([UIxObjectActions -removeUserFromAclsAction]): moved the core of + those methods into SOGoObject and translate its result into an + appropriate HTTP status. + +2008-02-20 Wolfgang Sourdeau + + * SoObjects/SOGo/SOGoGCSFolder.m ([SOGoGCSFolder -davInverseACL]): + first implementation of a DAV interface to SOGo roles. Returns the + result in JSON. + 2008-02-14 Wolfgang Sourdeau * GNUmakefile: migrated to GNUstep Make 2. diff --git a/SOPE/sope-patchset-r1603.diff b/SOPE/sope-patchset-r1605.diff similarity index 95% rename from SOPE/sope-patchset-r1603.diff rename to SOPE/sope-patchset-r1605.diff index 487297bf..3075615f 100644 --- a/SOPE/sope-patchset-r1603.diff +++ b/SOPE/sope-patchset-r1605.diff @@ -1,136 +1,6 @@ -Index: sope-gdl1/PostgreSQL/PostgreSQL72Channel.m -=================================================================== ---- sope-gdl1/PostgreSQL/PostgreSQL72Channel.m (révision 1603) -+++ 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 1603) -+++ 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-mime/NGImap4/NGImap4Connection.m =================================================================== ---- sope-mime/NGImap4/NGImap4Connection.m (révision 1603) +--- sope-mime/NGImap4/NGImap4Connection.m (révision 1605) +++ sope-mime/NGImap4/NGImap4Connection.m (copie de travail) @@ -381,7 +381,7 @@ @@ -143,7 +13,7 @@ Index: sope-mime/NGImap4/NGImap4Connection.m [self errorWithFormat:@"Could not list mailbox hierarchy!"]; Index: sope-mime/NGImap4/NGImap4ResponseNormalizer.m =================================================================== ---- sope-mime/NGImap4/NGImap4ResponseNormalizer.m (révision 1603) +--- sope-mime/NGImap4/NGImap4ResponseNormalizer.m (révision 1605) +++ sope-mime/NGImap4/NGImap4ResponseNormalizer.m (copie de travail) @@ -648,14 +648,13 @@ enumerator = [_flags objectEnumerator]; @@ -169,7 +39,7 @@ Index: sope-mime/NGImap4/NGImap4ResponseNormalizer.m if (objs) free(objs); Index: sope-mime/NGImap4/NGImap4ResponseParser.m =================================================================== ---- sope-mime/NGImap4/NGImap4ResponseParser.m (révision 1603) +--- sope-mime/NGImap4/NGImap4ResponseParser.m (révision 1605) +++ sope-mime/NGImap4/NGImap4ResponseParser.m (copie de travail) @@ -84,6 +84,8 @@ static NSDictionary *_parseMultipartBody(NGImap4ResponseParser *self, @@ -394,7 +264,7 @@ Index: sope-mime/NGImap4/NGImap4ResponseParser.m { Index: sope-mime/NGMail/NGSmtpClient.m =================================================================== ---- sope-mime/NGMail/NGSmtpClient.m (révision 1603) +--- sope-mime/NGMail/NGSmtpClient.m (révision 1605) +++ sope-mime/NGMail/NGSmtpClient.m (copie de travail) @@ -24,6 +24,82 @@ #include "NGSmtpReplyCodes.h" @@ -550,7 +420,7 @@ Index: sope-mime/NGMail/NGSmtpClient.m reply = [self receiveReply]; Index: sope-mime/NGMail/NGMimeMessageGenerator.m =================================================================== ---- sope-mime/NGMail/NGMimeMessageGenerator.m (révision 1603) +--- sope-mime/NGMail/NGMimeMessageGenerator.m (révision 1605) +++ sope-mime/NGMail/NGMimeMessageGenerator.m (copie de travail) @@ -86,37 +86,40 @@ char *des = NULL; @@ -616,7 +486,7 @@ Index: sope-mime/NGMail/NGMimeMessageGenerator.m unsigned isoEndLen = 2; Index: sope-mime/NGMime/NGMimeRFC822DateHeaderFieldParser.m =================================================================== ---- sope-mime/NGMime/NGMimeRFC822DateHeaderFieldParser.m (révision 1603) +--- sope-mime/NGMime/NGMimeRFC822DateHeaderFieldParser.m (révision 1605) +++ sope-mime/NGMime/NGMimeRFC822DateHeaderFieldParser.m (copie de travail) @@ -19,88 +19,45 @@ 02111-1307, USA. @@ -1011,7 +881,7 @@ Index: sope-mime/NGMime/NGMimeRFC822DateHeaderFieldParser.m #if 0 Index: sope-mime/NGMime/NGMimeHeaderFieldGeneratorSet.m =================================================================== ---- sope-mime/NGMime/NGMimeHeaderFieldGeneratorSet.m (révision 1603) +--- sope-mime/NGMime/NGMimeHeaderFieldGeneratorSet.m (révision 1605) +++ sope-mime/NGMime/NGMimeHeaderFieldGeneratorSet.m (copie de travail) @@ -77,6 +77,7 @@ [rfc822Set setGenerator:gen forField:@"bcc"]; @@ -1023,7 +893,7 @@ Index: sope-mime/NGMime/NGMimeHeaderFieldGeneratorSet.m Index: sope-mime/NGMime/NGMimeBodyPart.m =================================================================== ---- sope-mime/NGMime/NGMimeBodyPart.m (révision 1603) +--- sope-mime/NGMime/NGMimeBodyPart.m (révision 1605) +++ sope-mime/NGMime/NGMimeBodyPart.m (copie de travail) @@ -31,18 +31,6 @@ return 2; @@ -1061,7 +931,7 @@ Index: sope-mime/NGMime/NGMimeBodyPart.m - (NSString *)contentId { Index: sope-mime/NGMime/GNUmakefile.preamble =================================================================== ---- sope-mime/NGMime/GNUmakefile.preamble (révision 1603) +--- sope-mime/NGMime/GNUmakefile.preamble (révision 1605) +++ sope-mime/NGMime/GNUmakefile.preamble (copie de travail) @@ -5,6 +5,11 @@ -DLIBRARY_MINOR_VERSION=${MINOR_VERSION} \ @@ -1077,7 +947,7 @@ Index: sope-mime/NGMime/GNUmakefile.preamble -I../../sope-core/NGStreams/ \ Index: sope-mime/NGMime/NGMimeBodyParser.m =================================================================== ---- sope-mime/NGMime/NGMimeBodyParser.m (révision 1603) +--- sope-mime/NGMime/NGMimeBodyParser.m (révision 1605) +++ sope-mime/NGMime/NGMimeBodyParser.m (copie de travail) @@ -67,7 +67,10 @@ if (_data == nil) return nil; @@ -1093,7 +963,7 @@ Index: sope-mime/NGMime/NGMimeBodyParser.m Index: sope-mime/NGMime/NGMimePartParser.h =================================================================== ---- sope-mime/NGMime/NGMimePartParser.h (révision 1603) +--- sope-mime/NGMime/NGMimePartParser.h (révision 1605) +++ sope-mime/NGMime/NGMimePartParser.h (copie de travail) @@ -117,6 +117,7 @@ BOOL parserParseRawBodyDataOfPart:1; @@ -1115,7 +985,7 @@ Index: sope-mime/NGMime/NGMimePartParser.h @interface NSObject(NGMimePartParser) Index: sope-mime/NGMime/NGMimePartParser.m =================================================================== ---- sope-mime/NGMime/NGMimePartParser.m (révision 1603) +--- sope-mime/NGMime/NGMimePartParser.m (révision 1605) +++ sope-mime/NGMime/NGMimePartParser.m (copie de travail) @@ -227,7 +227,7 @@ } @@ -1140,7 +1010,7 @@ Index: sope-mime/NGMime/NGMimePartParser.m : [NGMimeType mimeType:[ctype stringValue]]; Index: sope-mime/NGMime/NGMimeAddressHeaderFieldGenerator.m =================================================================== ---- sope-mime/NGMime/NGMimeAddressHeaderFieldGenerator.m (révision 1603) +--- sope-mime/NGMime/NGMimeAddressHeaderFieldGenerator.m (révision 1605) +++ sope-mime/NGMime/NGMimeAddressHeaderFieldGenerator.m (copie de travail) @@ -130,8 +130,13 @@ @@ -1171,7 +1041,7 @@ Index: sope-mime/NGMime/NGMimeAddressHeaderFieldGenerator.m bufLen = [data length]; Index: sope-mime/NGMime/NGMimeContentDispositionHeaderFieldGenerator.m =================================================================== ---- sope-mime/NGMime/NGMimeContentDispositionHeaderFieldGenerator.m (révision 1603) +--- sope-mime/NGMime/NGMimeContentDispositionHeaderFieldGenerator.m (révision 1605) +++ sope-mime/NGMime/NGMimeContentDispositionHeaderFieldGenerator.m (copie de travail) @@ -49,80 +49,70 @@ @@ -1305,9 +1175,187 @@ Index: sope-mime/NGMime/NGMimeContentDispositionHeaderFieldGenerator.m } return data; } +Index: sope-gdl1/PostgreSQL/PostgreSQL72Channel.m +=================================================================== +--- sope-gdl1/PostgreSQL/PostgreSQL72Channel.m (révision 1605) ++++ 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 1605) ++++ 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 1605) ++++ 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/FdExt.subproj/NSString+Encoding.m =================================================================== ---- sope-core/NGExtensions/FdExt.subproj/NSString+Encoding.m (révision 1603) +--- sope-core/NGExtensions/FdExt.subproj/NSString+Encoding.m (révision 1605) +++ sope-core/NGExtensions/FdExt.subproj/NSString+Encoding.m (copie de travail) @@ -140,8 +140,12 @@ @@ -1350,7 +1398,7 @@ Index: sope-core/NGExtensions/FdExt.subproj/NSString+Encoding.m static char *iconv_wrapper(id self, char *_src, unsigned _srcLen, Index: sope-core/NGExtensions/EOExt.subproj/EOGlobalID+Ext.m =================================================================== ---- sope-core/NGExtensions/EOExt.subproj/EOGlobalID+Ext.m (révision 1603) +--- sope-core/NGExtensions/EOExt.subproj/EOGlobalID+Ext.m (révision 1605) +++ sope-core/NGExtensions/EOExt.subproj/EOGlobalID+Ext.m (copie de travail) @@ -19,6 +19,7 @@ 02111-1307, USA. @@ -1362,7 +1410,7 @@ Index: sope-core/NGExtensions/EOExt.subproj/EOGlobalID+Ext.m Index: sope-xml/libxmlSAXDriver/libxmlHTMLSAXDriver.h =================================================================== ---- sope-xml/libxmlSAXDriver/libxmlHTMLSAXDriver.h (révision 1603) +--- sope-xml/libxmlSAXDriver/libxmlHTMLSAXDriver.h (révision 1605) +++ sope-xml/libxmlSAXDriver/libxmlHTMLSAXDriver.h (copie de travail) @@ -19,6 +19,8 @@ 02111-1307, USA. @@ -1384,7 +1432,7 @@ Index: sope-xml/libxmlSAXDriver/libxmlHTMLSAXDriver.h id entityResolver; Index: sope-xml/libxmlSAXDriver/libxmlHTMLSAXDriver.m =================================================================== ---- sope-xml/libxmlSAXDriver/libxmlHTMLSAXDriver.m (révision 1603) +--- sope-xml/libxmlSAXDriver/libxmlHTMLSAXDriver.m (révision 1605) +++ sope-xml/libxmlSAXDriver/libxmlHTMLSAXDriver.m (copie de travail) @@ -30,6 +30,12 @@ #include @@ -1444,7 +1492,7 @@ Index: sope-xml/libxmlSAXDriver/libxmlHTMLSAXDriver.m - (void)tearDownParser { Index: sope-appserver/mod_ngobjweb/config.c =================================================================== ---- sope-appserver/mod_ngobjweb/config.c (révision 1603) +--- sope-appserver/mod_ngobjweb/config.c (révision 1605) +++ sope-appserver/mod_ngobjweb/config.c (copie de travail) @@ -21,7 +21,7 @@ @@ -1455,9 +1503,21 @@ Index: sope-appserver/mod_ngobjweb/config.c static char *_makeString(char *buf, char *str, int max) { if (buf == NULL) +Index: sope-appserver/mod_ngobjweb/NGBufferedDescriptor.c +=================================================================== +--- sope-appserver/mod_ngobjweb/NGBufferedDescriptor.c (révision 1605) ++++ sope-appserver/mod_ngobjweb/NGBufferedDescriptor.c (copie de travail) +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include "common.h" + #include "NGBufferedDescriptor.h" + + // returns the number of bytes which where read from the buffer Index: sope-appserver/mod_ngobjweb/GNUmakefile =================================================================== ---- sope-appserver/mod_ngobjweb/GNUmakefile (révision 1603) +--- sope-appserver/mod_ngobjweb/GNUmakefile (révision 1605) +++ sope-appserver/mod_ngobjweb/GNUmakefile (copie de travail) @@ -81,7 +81,7 @@ @@ -1468,21 +1528,9 @@ Index: sope-appserver/mod_ngobjweb/GNUmakefile LDFLAGS = $(APXS_LDFLAGS) $(APR_LDFLAGS) -shared -fPIC -Index: sope-appserver/mod_ngobjweb/NGBufferedDescriptor.c -=================================================================== ---- sope-appserver/mod_ngobjweb/NGBufferedDescriptor.c (révision 1603) -+++ sope-appserver/mod_ngobjweb/NGBufferedDescriptor.c (copie de travail) -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include "common.h" - #include "NGBufferedDescriptor.h" - - // returns the number of bytes which where read from the buffer Index: sope-appserver/mod_ngobjweb/handler.c =================================================================== ---- sope-appserver/mod_ngobjweb/handler.c (révision 1603) +--- sope-appserver/mod_ngobjweb/handler.c (révision 1605) +++ sope-appserver/mod_ngobjweb/handler.c (copie de travail) @@ -267,7 +267,7 @@ const char *uri; @@ -1610,7 +1658,7 @@ Index: sope-appserver/mod_ngobjweb/handler.c static void test(void) { Index: sope-appserver/NGObjWeb/GNUmakefile.postamble =================================================================== ---- sope-appserver/NGObjWeb/GNUmakefile.postamble (révision 1603) +--- sope-appserver/NGObjWeb/GNUmakefile.postamble (révision 1605) +++ sope-appserver/NGObjWeb/GNUmakefile.postamble (copie de travail) @@ -23,14 +23,20 @@ @@ -1639,7 +1687,7 @@ Index: sope-appserver/NGObjWeb/GNUmakefile.postamble -endif Index: sope-appserver/NGObjWeb/WOContext.m =================================================================== ---- sope-appserver/NGObjWeb/WOContext.m (révision 1603) +--- sope-appserver/NGObjWeb/WOContext.m (révision 1605) +++ sope-appserver/NGObjWeb/WOContext.m (copie de travail) @@ -64,11 +64,13 @@ static BOOL testNSURLs = NO; @@ -1679,9 +1727,9 @@ Index: sope-appserver/NGObjWeb/WOContext.m serverURL = [@"http://" stringByAppendingString:host]; Index: sope-appserver/NGObjWeb/DAVPropMap.plist =================================================================== ---- sope-appserver/NGObjWeb/DAVPropMap.plist (révision 1603) +--- sope-appserver/NGObjWeb/DAVPropMap.plist (révision 1605) +++ sope-appserver/NGObjWeb/DAVPropMap.plist (copie de travail) -@@ -123,11 +123,14 @@ +@@ -123,11 +123,18 @@ /* CalDAV */ "{urn:ietf:params:xml:ns:caldav}calendar-home-set" = davCalendarHomeSet; @@ -1697,10 +1745,14 @@ Index: sope-appserver/NGObjWeb/DAVPropMap.plist + "{http://calendarserver.org/ns/}notifications-URL" = davNotificationsURL; "{com.apple.ical:}calendarcolor" = davCalendarColor; ++ ++ /* Inverse DAV Extensions */ ++ "{urn:ietf:params:xml:ns:inverse-dav:}acl" = ++ davInverseACL; } Index: sope-appserver/NGObjWeb/WebDAV/SaxDAVHandler.m =================================================================== ---- sope-appserver/NGObjWeb/WebDAV/SaxDAVHandler.m (révision 1603) +--- sope-appserver/NGObjWeb/WebDAV/SaxDAVHandler.m (révision 1605) +++ sope-appserver/NGObjWeb/WebDAV/SaxDAVHandler.m (copie de travail) @@ -655,6 +655,7 @@ if (self->responses == nil) @@ -1712,7 +1764,7 @@ Index: sope-appserver/NGObjWeb/WebDAV/SaxDAVHandler.m case 'n': Index: sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.m =================================================================== ---- sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.m (révision 1603) +--- sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.m (révision 1605) +++ sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.m (copie de travail) @@ -216,6 +216,12 @@ assocCount++; @@ -1729,7 +1781,7 @@ Index: sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.m Index: sope-appserver/NGObjWeb/DynamicElements/_WOComplexHyperlink.m =================================================================== ---- sope-appserver/NGObjWeb/DynamicElements/_WOComplexHyperlink.m (révision 1603) +--- sope-appserver/NGObjWeb/DynamicElements/_WOComplexHyperlink.m (révision 1605) +++ sope-appserver/NGObjWeb/DynamicElements/_WOComplexHyperlink.m (copie de travail) @@ -41,6 +41,7 @@ WOAssociation *string; @@ -1762,7 +1814,7 @@ Index: sope-appserver/NGObjWeb/DynamicElements/_WOComplexHyperlink.m return NO; Index: sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.h =================================================================== ---- sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.h (révision 1603) +--- sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.h (révision 1605) +++ sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.h (copie de travail) @@ -41,7 +41,8 @@ WOAssociation *pageName; @@ -1776,7 +1828,7 @@ Index: sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.h /* 'ivar' associations */ Index: sope-appserver/NGObjWeb/SoObjects/SoObject.m =================================================================== ---- sope-appserver/NGObjWeb/SoObjects/SoObject.m (révision 1603) +--- sope-appserver/NGObjWeb/SoObjects/SoObject.m (révision 1605) +++ sope-appserver/NGObjWeb/SoObjects/SoObject.m (copie de travail) @@ -39,22 +39,34 @@ static int debugLookup = -1; @@ -1927,7 +1979,7 @@ Index: sope-appserver/NGObjWeb/SoObjects/SoObject.m Index: sope-appserver/NGObjWeb/WOHttpAdaptor/WOHttpTransaction.m =================================================================== ---- sope-appserver/NGObjWeb/WOHttpAdaptor/WOHttpTransaction.m (révision 1603) +--- sope-appserver/NGObjWeb/WOHttpAdaptor/WOHttpTransaction.m (révision 1605) +++ sope-appserver/NGObjWeb/WOHttpAdaptor/WOHttpTransaction.m (copie de travail) @@ -31,6 +31,7 @@ #include diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.m b/SoObjects/Appointments/SOGoAppointmentFolder.m index aec706ee..745e312c 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.m +++ b/SoObjects/Appointments/SOGoAppointmentFolder.m @@ -287,7 +287,12 @@ static NSNumber *sharedYes = nil; - (NSArray *) davNamespaces { - return [NSArray arrayWithObject: @"urn:ietf:params:xml:ns:caldav"]; + NSMutableArray *ns; + + ns = [NSMutableArray arrayWithArray: [super davNamespaces]]; + [ns addObjectUniquely: @"urn:ietf:params:xml:ns:caldav"]; + + return ns; } - (id) davCalendarQuery: (id) queryContext diff --git a/SoObjects/Contacts/SOGoContactGCSFolder.m b/SoObjects/Contacts/SOGoContactGCSFolder.m index dfc77cae..eff8313e 100644 --- a/SoObjects/Contacts/SOGoContactGCSFolder.m +++ b/SoObjects/Contacts/SOGoContactGCSFolder.m @@ -259,7 +259,12 @@ - (NSArray *) davNamespaces { - return [NSArray arrayWithObject: @"urn:ietf:params:xml:ns:carddav"]; + NSMutableArray *ns; + + ns = [NSMutableArray arrayWithArray: [super davNamespaces]]; + [ns addObjectUniquely: @"urn:ietf:params:xml:ns:carddav"]; + + return ns; } - (NSString *) groupDavResourceType diff --git a/SoObjects/SOGo/NSArray+Utilities.h b/SoObjects/SOGo/NSArray+Utilities.h index 181f636c..998cab7c 100644 --- a/SoObjects/SOGo/NSArray+Utilities.h +++ b/SoObjects/SOGo/NSArray+Utilities.h @@ -36,6 +36,8 @@ - (NSArray *) objectsForKey: (NSString *) key; - (NSArray *) flattenedArray; +- (NSArray *) uniqueObjects; + - (BOOL) containsCaseInsensitiveString: (NSString *) match; #ifdef GNUSTEP_BASE_LIBRARY diff --git a/SoObjects/SOGo/NSArray+Utilities.m b/SoObjects/SOGo/NSArray+Utilities.m index 3f5a78b5..1e63756b 100644 --- a/SoObjects/SOGo/NSArray+Utilities.m +++ b/SoObjects/SOGo/NSArray+Utilities.m @@ -105,6 +105,21 @@ return flattenedArray; } +- (NSArray *) uniqueObjects +{ + NSMutableArray *newArray; + NSEnumerator *objects; + id currentObject; + + newArray = [NSMutableArray array]; + + objects = [self objectEnumerator]; + while ((currentObject = [objects nextObject])) + [newArray addObjectUniquely: currentObject]; + + return newArray; +} + - (void) makeObjectsPerform: (SEL) selector withObject: (id) object1 withObject: (id) object2 diff --git a/SoObjects/SOGo/SOGoDAVRendererTypes.h b/SoObjects/SOGo/SOGoDAVRendererTypes.h index 8a4b9274..2fdfaa81 100644 --- a/SoObjects/SOGo/SOGoDAVRendererTypes.h +++ b/SoObjects/SOGo/SOGoDAVRendererTypes.h @@ -26,6 +26,7 @@ #import @class NSArray; +@class NSDictionary; @class NSString; @interface SOGoDAVSet : SoWebDAVValue @@ -42,4 +43,18 @@ @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 */ diff --git a/SoObjects/SOGo/SOGoDAVRendererTypes.m b/SoObjects/SOGo/SOGoDAVRendererTypes.m index 21a102c2..cdbb00b2 100644 --- a/SoObjects/SOGo/SOGoDAVRendererTypes.m +++ b/SoObjects/SOGo/SOGoDAVRendererTypes.m @@ -54,10 +54,8 @@ - (void) dealloc { - if (valueTag) - [valueTag release]; - if (values) - [values release]; + [valueTag release]; + [values release]; [super dealloc]; } @@ -84,10 +82,9 @@ resultString = [NSMutableString new]; [resultString autorelease]; - [resultString appendFormat: @"<%@>", setTag]; +// [resultString appendFormat: @"<%@>", setTag]; valueEnum = [values objectEnumerator]; - currentValue = [valueEnum nextObject]; - while (currentValue) + while ((currentValue = [valueEnum nextObject])) { if ([currentValue isKindOfClass: [SoWebDAVValue class]]) valueString @@ -97,13 +94,13 @@ inContext: context prefixes: prefixes]; else - valueString = currentValue; + valueString = [[currentValue description] stringByEscapingXMLString]; - [resultString appendFormat: @"<%@>%@", - valueTag, valueString, valueTag]; - currentValue = [valueEnum nextObject]; + [resultString appendFormat: valueString]; +// [resultString appendFormat: @"<%@>%@", +// valueTag, valueString, valueTag]; } - [resultString appendFormat: @"", setTag]; +// [resultString appendFormat: @"", setTag]; NSLog(@"dav rendering for key '%@' and tag '%@':\n", _key, setTag, resultString); @@ -111,4 +108,89 @@ 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.h b/SoObjects/SOGo/SOGoFolder.h index fcc61bf4..69951d95 100644 --- a/SoObjects/SOGo/SOGoFolder.h +++ b/SoObjects/SOGo/SOGoFolder.h @@ -40,7 +40,6 @@ - (NSComparisonResult) compare: (id) otherFolder; /* dav */ -- (NSArray *) davNamespaces; - (NSArray *) davResourceType; /* outlook */ diff --git a/SoObjects/SOGo/SOGoFolder.m b/SoObjects/SOGo/SOGoFolder.m index 61986119..3f404fdf 100644 --- a/SoObjects/SOGo/SOGoFolder.m +++ b/SoObjects/SOGo/SOGoFolder.m @@ -201,11 +201,6 @@ /* WebDAV */ -- (NSArray *) davNamespaces -{ - return nil; -} - - (BOOL) davIsCollection { return [self isFolderish]; @@ -257,7 +252,7 @@ { return [NSArray arrayWithObjects: SoRole_Owner, SOGoRole_ObjectViewer, SOGoRole_ObjectEditor, SOGoRole_ObjectCreator, - SOGoRole_ObjectEraser, nil]; + SOGoRole_ObjectEraser, nil]; } - (NSArray *) aclsForUser: (NSString *) uid diff --git a/SoObjects/SOGo/SOGoGCSFolder.m b/SoObjects/SOGo/SOGoGCSFolder.m index b7c81f96..3ff9e041 100644 --- a/SoObjects/SOGo/SOGoGCSFolder.m +++ b/SoObjects/SOGo/SOGoGCSFolder.m @@ -1,23 +1,28 @@ -/* - 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. -*/ +/* 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 +#import "SOGoDAVRendererTypes.h" #import #import @@ -33,6 +38,7 @@ #import #import #import +#import #import #import #import @@ -488,14 +494,15 @@ static BOOL sendFolderAdvisories = NO; { EOQualifier *qualifier; NSString *qs; - NSArray *records; + NSArray *records, *uids; qs = [NSString stringWithFormat: @"c_object = '/%@'", [objectPathArray componentsJoinedByString: @"/"]]; qualifier = [EOQualifier qualifierWithQualifierFormat: qs]; records = [[self ocsFolder] fetchAclMatchingQualifier: qualifier]; + uids = [[records valueForKey: @"c_uid"] uniqueObjects]; - return [records valueForKey: @"c_uid"]; + return uids; } - (NSArray *) _fetchAclsForUser: (NSString *) uid @@ -515,7 +522,7 @@ static BOOL sendFolderAdvisories = NO; if ([records count] > 0) [acls addObjectsFromArray: [records valueForKey: @"c_role"]]; - return acls; + return [acls uniqueObjects]; } - (void) _cacheRoles: (NSArray *) roles diff --git a/SoObjects/SOGo/SOGoObject.h b/SoObjects/SOGo/SOGoObject.h index a6ff53d2..5c8f87b1 100644 --- a/SoObjects/SOGo/SOGoObject.h +++ b/SoObjects/SOGo/SOGoObject.h @@ -113,6 +113,9 @@ - (NSArray *) subscriptionRoles; +- (BOOL) addUserInAcls: (NSString *) uid; +- (BOOL) removeUserFromAcls: (NSString *) uid; + - (NSArray *) aclUsers; - (NSArray *) aclsForUser: (NSString *) uid; - (void) setRoles: (NSArray *) roles @@ -126,6 +129,10 @@ - (NSString *) httpURLForAdvisoryToUser: (NSString *) uid; - (NSString *) resourceURLForAdvisoryToUser: (NSString *) uid; +/* dav */ +- (NSArray *) davNamespaces; +- (NSString *) davRecordForUser: (NSString *) user; + /* description */ - (void) appendAttributesToDescription:(NSMutableString *)_ms; diff --git a/SoObjects/SOGo/SOGoObject.m b/SoObjects/SOGo/SOGoObject.m index 748461d9..7fbace9f 100644 --- a/SoObjects/SOGo/SOGoObject.m +++ b/SoObjects/SOGo/SOGoObject.m @@ -46,27 +46,31 @@ #import #import #import +#import +#import #import #import #import -#import "SOGoPermissions.h" -#import "SOGoUser.h" -#import "SOGoDAVAuthenticator.h" -#import "SOGoUserFolder.h" - -#import "SOGoDAVRendererTypes.h" - +#import "LDAPUserManager.h" #import "NSArray+Utilities.h" #import "NSCalendarDate+SOGo.h" #import "NSDictionary+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 "SOGoObject.h" +static BOOL kontactGroupDAV = YES; +static BOOL sendACLAdvisories = NO; + @interface SOGoObject(Content) -- (NSString *)contentAsString; +- (NSString *) contentAsString; @end @interface SoClassSecurityInfo (SOGoAcls) @@ -160,18 +164,13 @@ @implementation SOGoObject -static BOOL kontactGroupDAV = YES; - -+ (int)version { - return 0; -} - + (void) initialize { - NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; + NSUserDefaults *ud; - kontactGroupDAV = - [ud boolForKey:@"SOGoDisableKontact34GroupDAVHack"] ? NO : YES; + ud = [NSUserDefaults standardUserDefaults]; + kontactGroupDAV = ![ud boolForKey:@"SOGoDisableKontact34GroupDAVHack"]; + sendACLAdvisories = [ud boolForKey: @"SOGoACLsSendEMailNotifications"]; // SoClass security declarations @@ -201,7 +200,7 @@ static BOOL kontactGroupDAV = YES; float f; if (pid == 0) - { /* break if we fork ;-) */ + { pid = getpid(); rndm = random(); } @@ -889,6 +888,44 @@ static BOOL kontactGroupDAV = YES; return [container subscriptionRoles]; } +- (BOOL) addUserInAcls: (NSString *) uid +{ + BOOL result; + + if ([uid length] + && ![uid isEqualToString: [self ownerInContext: nil]] + && [[LDAPUserManager sharedUserManager] + contactInfosForUserWithUIDorEmail: uid]) + { + [self setRoles: [self aclsForUser: uid] + forUser: uid]; + if (sendACLAdvisories) + [self sendACLAdditionAdvisoryToUser: uid]; + result = YES; + } + else + result = NO; + + return result; +} + +- (BOOL) removeUserFromAcls: (NSString *) uid +{ + BOOL result; + + if ([uid length]) + { + [self removeAclsForUsers: [NSArray arrayWithObject: uid]]; + if (sendACLAdvisories) + [self sendACLRemovalAdvisoryToUser: uid]; + result = YES; + } + else + result = NO; + + return result; +} + - (NSArray *) aclUsers { [self subclassResponsibility: _cmd]; @@ -1111,4 +1148,184 @@ static BOOL kontactGroupDAV = YES; return newClasses; } +/* dav acls */ +- (NSArray *) davNamespaces +{ + return [NSArray arrayWithObject: + @"urn:inverse:params:xml:ns:inverse-dav"]; +} + +- (NSString *) davRecordForUser: (NSString *) user +{ + NSMutableString *userRecord; + SOGoUser *sogoUser; + NSString *cn, *email; + + userRecord = [NSMutableString string]; + + [userRecord appendFormat: @"%@", + [user stringByEscapingXMLString]]; + sogoUser = [SOGoUser userWithLogin: user roles: nil]; + cn = [sogoUser cn]; + if (!cn) + cn = user; + [userRecord appendFormat: @"%@", + [cn stringByEscapingXMLString]]; + email = [[sogoUser allEmails] objectAtIndex: 0]; + if (email) + [userRecord appendFormat: @"%@", + [email stringByEscapingXMLString]]; + + return userRecord; +} + +- (NSString *) _davAclUserListQuery +{ + NSMutableString *userList; + NSString *defaultUserID, *currentUserID; + NSEnumerator *users; + + userList = [NSMutableString string]; + + defaultUserID = [self defaultUserID]; + if ([defaultUserID length]) + [userList appendFormat: @"%@", + [defaultUserID stringByEscapingXMLString]]; + users = [[self aclUsers] objectEnumerator]; + while ((currentUserID = [users nextObject])) + if (![currentUserID isEqualToString: defaultUserID]) + [userList appendFormat: @"%@", + [self davRecordForUser: currentUserID]]; + + return userList; +} + +- (NSString *) _davAclUserRoles: (NSString *) userName +{ + NSArray *roles; + + roles = [[self aclsForUser: userName] stringsWithFormat: @"<%@/>"]; + + return [roles componentsJoinedByString: @""]; +} + +- (NSArray *) _davGetRolesFromRequest: (id ) node +{ + NSMutableArray *roles; + id childNodes; + NSString *currentRole; + unsigned int count, max; + + roles = [NSMutableArray array]; + childNodes = [node childNodes]; + max = [childNodes length]; + for (count = 0; count < max; count++) + { + currentRole = [[childNodes objectAtIndex: count] nodeName]; + [roles addObject: currentRole]; + } + + return roles; +} + +- (NSString *) _davAclActionFromQuery: (id ) document +{ + id node, userAttr; + id attrs; + NSString *nodeName, *result, *response, *user; + + node = [[document documentElement] firstChild]; + nodeName = [node nodeName]; + if ([nodeName isEqualToString: @"user-list"]) + result = [self _davAclUserListQuery]; + else if ([nodeName isEqualToString: @"roles"]) + { + attrs = [node attributes]; + userAttr = [attrs namedItem: @"user"]; + user = [userAttr nodeValue]; + if ([user length]) + result = [self _davAclUserRoles: user]; + else + result = nil; + } + else if ([nodeName isEqualToString: @"set-roles"]) + { + attrs = [node attributes]; + userAttr = [attrs namedItem: @"user"]; + user = [userAttr nodeValue]; + if ([user length]) + { + [self setRoles: [self _davGetRolesFromRequest: node] + forUser: user]; + result = @""; + } + else + result = nil; + } + else if ([nodeName isEqualToString: @"add-user"]) + { + attrs = [node attributes]; + userAttr = [attrs namedItem: @"user"]; + user = [userAttr nodeValue]; + if ([self addUserInAcls: user]) + result = @""; + else + result = nil; + } + else if ([nodeName isEqualToString: @"remove-user"]) + { + attrs = [node attributes]; + userAttr = [attrs namedItem: @"user"]; + user = [userAttr nodeValue]; + if ([self removeUserFromAcls: user]) + result = @""; + else + result = nil; + } + else + result = nil; + + if (result) + { + if ([result length]) + response = [NSString stringWithFormat: @"<%@>%@", + nodeName, result, nodeName]; + else + response = @""; + } + else + response = nil; + + return response; +} + +- (id) davAclQuery: (WOContext *) queryContext +{ + WOResponse *r; + id document; + NSString *content; + + r = [queryContext response]; + [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"]; + + document = [[context request] contentAsDOMDocument]; + content = [self _davAclActionFromQuery: document]; + if (content) + { + [r setStatus: 207]; + if ([content length]) + { + [r appendContentString: @"\r\n"]; + [r appendContentString: content]; + } + } + else + [r setStatus: 400]; + + return r; +} + @end /* SOGoObject */ diff --git a/SoObjects/SOGo/SOGoUserFolder.m b/SoObjects/SOGo/SOGoUserFolder.m index 1df3b304..a3a6dc7d 100644 --- a/SoObjects/SOGo/SOGoUserFolder.m +++ b/SoObjects/SOGo/SOGoUserFolder.m @@ -42,6 +42,7 @@ #import #import +#import "NSArray+Utilities.h" #import "NSDictionary+Utilities.h" #import "LDAPUserManager.h" #import "SOGoPermissions.h" @@ -108,18 +109,13 @@ return self; } -- (NSArray *) davNamespaces -{ - return [NSArray arrayWithObject: @"urn:inverse:params:xml:ns:inverse-dav"]; -} - - (NSDictionary *) _parseCollectionFilters: (id ) parentNode { NSEnumerator *children; NGDOMNode *node; NSMutableDictionary *filter; NSString *componentName; - + filter = [NSMutableDictionary dictionaryWithCapacity: 2]; children = [[parentNode getElementsByTagName: @"prop-match"] objectEnumerator]; @@ -289,7 +285,7 @@ } } -- (id) davCollectionQuery: (id) queryContext +- (id) davCollectionQuery: (WOContext *) queryContext { WOResponse *r; NSDictionary *filter; @@ -314,6 +310,99 @@ return r; } +- (NSString *) _davFetchUsersMatching: (NSString *) user +{ + LDAPUserManager *um; + NSEnumerator *users; + NSMutableString *fetch; + NSDictionary *currentUser; + NSString *field; + + fetch = [NSMutableString string]; + um = [LDAPUserManager sharedUserManager]; + users = [[um fetchContactsMatching: user] objectEnumerator]; + while ((currentUser = [users nextObject])) + { + [fetch appendString: @""]; + field = [currentUser objectForKey: @"c_uid"]; + [fetch appendFormat: @"%@", + [field stringByEscapingXMLString]]; + field = [currentUser objectForKey: @"cn"]; + [fetch appendFormat: @"%@", + [field stringByEscapingXMLString]]; + field = [currentUser objectForKey: @"c_email"]; + [fetch appendFormat: @"%@", + [field stringByEscapingXMLString]]; + [fetch appendString: @""]; + } + + return fetch; +} + +- (NSString *) _davUsersFromQuery: (id ) document +{ + id node, userAttr; + id attrs; + NSString *nodeName, *result, *response, *user; + + node = [[document documentElement] firstChild]; + nodeName = [node nodeName]; + if ([nodeName isEqualToString: @"users"]) + { + attrs = [node attributes]; + userAttr = [attrs namedItem: @"match-name"]; + user = [userAttr nodeValue]; + if ([user length]) + result = [self _davFetchUsersMatching: user]; + else + result = nil; + } + else + result = nil; + + if (result) + { + if ([result length]) + response = [NSString stringWithFormat: @"<%@>%@", + nodeName, result, nodeName]; + else + response = @""; + } + else + response = nil; + + return response; +} + +- (id) davUserQuery: (WOContext *) queryContext +{ + WOResponse *r; + id document; + NSString *content; + + r = [queryContext response]; + [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"]; + + document = [[context request] contentAsDOMDocument]; + content = [self _davUsersFromQuery: document]; + if (content) + { + [r setStatus: 207]; + if ([content length]) + { + [r appendContentString: @"\r\n"]; + [r appendContentString: content]; + } + } + else + [r setStatus: 400]; + + return r; +} + // - (SOGoGroupsFolder *) lookupGroupsFolder // { // return [self lookupName: @"Groups" inContext: nil acquire: NO]; diff --git a/UI/Common/UIxObjectActions.m b/UI/Common/UIxObjectActions.m index 05dd40a2..dec91048 100644 --- a/UI/Common/UIxObjectActions.m +++ b/UI/Common/UIxObjectActions.m @@ -33,43 +33,19 @@ #import "UIxObjectActions.h" -static BOOL sendACLAdvisories = NO; - @implementation UIxObjectActions -+ (void) initialize -{ - NSUserDefaults *ud; - - ud = [NSUserDefaults standardUserDefaults]; - sendACLAdvisories = [ud boolForKey: @"SOGoACLsSendEMailNotifications"]; -} - - (WOResponse *) addUserInAclsAction { WOResponse *response; - WORequest *request; NSString *uid; unsigned int code; - LDAPUserManager *um; - SOGoObject *clientObject; - code = 403; - request = [context request]; - uid = [request formValueForKey: @"uid"]; - if ([uid length] > 0) - { - um = [LDAPUserManager sharedUserManager]; - if ([um contactInfosForUserWithUIDorEmail: uid]) - { - clientObject = [self clientObject]; - [clientObject setRoles: [clientObject aclsForUser: uid] - forUser: uid]; - if (sendACLAdvisories) - [clientObject sendACLAdditionAdvisoryToUser: uid]; - code = 204; - } - } + uid = [[context request] formValueForKey: @"uid"]; + if ([[self clientObject] addUserInAcls: uid]) + code = 204; + else + code = 403; response = [context response]; [response setStatus: code]; @@ -80,27 +56,14 @@ static BOOL sendACLAdvisories = NO; - (WOResponse *) removeUserFromAclsAction { WOResponse *response; - WORequest *request; NSString *uid; unsigned int code; - LDAPUserManager *um; - SOGoObject *co; - code = 403; - request = [context request]; - uid = [request formValueForKey: @"uid"]; - if ([uid length] > 0) - { - um = [LDAPUserManager sharedUserManager]; - if ([um contactInfosForUserWithUIDorEmail: uid]) - { - co = [self clientObject]; - [co removeAclsForUsers: [NSArray arrayWithObject: uid]]; - if (sendACLAdvisories) - [co sendACLRemovalAdvisoryToUser: uid]; - code = 204; - } - } + uid = [[context request] formValueForKey: @"uid"]; + if ([[self clientObject] removeUserFromAcls: uid]) + code = 204; + else + code = 403; response = [context response]; [response setStatus: code]; diff --git a/configure b/configure index d2cfd0fe..a56a4278 100755 --- a/configure +++ b/configure @@ -329,6 +329,7 @@ genConfigMake() { cfgwrite "" cfgwrite "# GNUstep environment variables:"; + cfgwrite "GNUSTEP_INSTALLATION_DOMAIN=LOCAL" for i in `env | grep GNUSTEP_ | sort`; do MAKE_ASSI="`echo $i | sed s/=/:=/`" cfgwrite "${MAKE_ASSI}"; -- 2.39.5