]> err.no Git - sope/commitdiff
added support for some ACL IMAP4 commands
authorhelge <helge@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Tue, 5 Jul 2005 14:21:13 +0000 (14:21 +0000)
committerhelge <helge@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Tue, 5 Jul 2005 14:21:13 +0000 (14:21 +0000)
git-svn-id: http://svn.opengroupware.org/SOPE/trunk@866 e4a50df8-12e2-0310-a44c-efbce7f8a7e3

12 files changed:
sope-mime/ChangeLog
sope-mime/NGImap4/NGImap4Client.h
sope-mime/NGImap4/NGImap4Client.m
sope-mime/NGImap4/NGImap4ResponseNormalizer.h
sope-mime/NGImap4/NGImap4ResponseNormalizer.m
sope-mime/NGImap4/NGImap4ResponseParser.m
sope-mime/Version
sope-mime/samples/ChangeLog
sope-mime/samples/GNUmakefile
sope-mime/samples/ImapQuotaTool.m
sope-mime/samples/imapacl.m [new file with mode: 0644]
sope-mime/samples/imapquota.m

index 5f4a738083025137b1c7abd97e4aeb854e52b742..9ec18c8b9eb793fc2cd40c5a657d1ab1215f2b34 100644 (file)
@@ -1,3 +1,8 @@
+2005-07-05  Helge Hess  <helge.hess@opengroupware.org>
+
+       * NGImap4ResponseNormalizer.[hm], NGImap4Client.[hm],
+         NGImap4ResponseParser.m: added some ACL related commands (v4.5.221)
+
 2005-04-24  Helge Hess  <helge.hess@opengroupware.org>
 
        * NGMime, NGImap4, NGMail: fixed gcc 4.0 warnings (v4.5.220)
index e3e7e6a4238618e0f0feaeb9e5b2534e668673e2..52106a3cc563173da589a9497bcf3eb485b854e3 100644 (file)
@@ -152,6 +152,15 @@ typedef enum {
 
 - (NSDictionary *)searchWithQualifier:(EOQualifier *)_qualifier;
 
+/* ACLs */
+
+- (NSDictionary *)getACL:(NSString *)_folder;
+- (NSDictionary *)setACL:(NSString *)_folder rights:(NSString *)_r
+  uid:(NSString *)_uid;
+- (NSDictionary *)deleteACL:(NSString *)_folder uid:(NSString *)_uid;
+- (NSDictionary *)listRights:(NSString *)_folder uid:(NSString *)_uid;
+- (NSDictionary *)myRights:(NSString *)_folder;
+
 /* context accessors (DEPRECATED) */
 
 - (void)setContext:(NGImap4Context *)_ctx;
index 71bf137b067d84623b921738cd2121a65da58efe..551678f2aa811f06025cda24c24ddfd810133f86 100644 (file)
@@ -1108,24 +1108,82 @@ static BOOL         ImapDebugEnabled   = NO;
   return [self->normer normalizeSearchResponse:[self processCommand:s]];
 }
 
+/* ACLs */
+
+- (NSDictionary *)getACL:(NSString *)_folder {
+  NSString *cmd;
+
+  if ((_folder = [self _folder2ImapFolder:_folder]) == nil)
+    return nil;
+  
+  cmd = [NSString stringWithFormat:@"getacl \"%@\"", _folder];
+  return [self->normer normalizeGetACLResponse:[self processCommand:cmd]];
+}
+
+- (NSDictionary *)setACL:(NSString *)_folder rights:(NSString *)_r
+  uid:(NSString *)_uid
+{
+  NSString *cmd;
+  
+  if ((_folder = [self _folder2ImapFolder:_folder]) == nil)
+    return nil;
+  
+  cmd = [NSString stringWithFormat:@"setacl \"%@\" \"%@\" \"%@\"",
+                 _folder, _uid, _r];
+  return [self->normer normalizeResponse:[self processCommand:cmd]];
+}
+
+- (NSDictionary *)deleteACL:(NSString *)_folder uid:(NSString *)_uid {
+  NSString *cmd;
+
+  if ((_folder = [self _folder2ImapFolder:_folder]) == nil)
+    return nil;
+  
+  cmd = [NSString stringWithFormat:@"deleteacl \"%@\" \"%@\"",
+                 _folder, _uid];
+  return [self->normer normalizeResponse:[self processCommand:cmd]];
+}
+
+- (NSDictionary *)listRights:(NSString *)_folder uid:(NSString *)_uid {
+  NSString *cmd;
+
+  if ((_folder = [self _folder2ImapFolder:_folder]) == nil)
+    return nil;
+  
+  cmd = [NSString stringWithFormat:@"listrights \"%@\" \"%@\"",
+                 _folder, _uid];
+  return [self->normer normalizeListRightsResponse:[self processCommand:cmd]];
+}
+
+- (NSDictionary *)myRights:(NSString *)_folder {
+  NSString *cmd;
+
+  if ((_folder = [self _folder2ImapFolder:_folder]) == nil)
+    return nil;
+  
+  cmd = [NSString stringWithFormat:@"myrights \"%@\"", _folder];
+  return [self->normer normalizeMyRightsResponse:[self processCommand:cmd]];
+}
+
 /* Private Methods */
 
 - (NSException *)_processCommandParserException:(NSException *)_exception {
-  NSLog(@"ERROR(%s): catched IMAP4 parser exception %@: %@",
-       __PRETTY_FUNCTION__, [_exception name], [_exception reason]);
+  [self logWithFormat:@"ERROR(%s): catched IMAP4 parser exception %@: %@",
+       __PRETTY_FUNCTION__, [_exception name], [_exception reason]];
   [self closeConnection];
   [self->context setLastException:_exception];
   return nil;
 }
 - (NSException *)_processUnknownCommandParserException:(NSException *)_ex {
-  NSLog(@"ERROR(%s): catched non-IMAP4 parsing exception %@: %@",
-       __PRETTY_FUNCTION__, [_ex name], [_ex reason]);
+  [self logWithFormat:@"ERROR(%s): catched non-IMAP4 parsing exception %@: %@",
+       __PRETTY_FUNCTION__, [_ex name], [_ex reason]];
   return nil;
 }
 
 - (NSException *)_handleShutdownDuringCommandException:(NSException *)_ex {
-  NSLog(@"ERROR(%s): IMAP4 socket was shut down by server %@: %@",
-       __PRETTY_FUNCTION__, [_ex name], [_ex reason]);
+  [self logWithFormat:
+         @"ERROR(%s): IMAP4 socket was shut down by server %@: %@",
+         __PRETTY_FUNCTION__, [_ex name], [_ex reason]];
   [self closeConnection];
   [self->context setLastException:_ex];
   return nil;
index c0c5b5a89a66506e18e3775abb6eed9bd661facb..d3bbc931e3b2a65a23e81296a4b4cfb49beda62b 100644 (file)
 - (NSDictionary *)normalizeCapabilityRespone:(NGHashMap *)_map;
 - (NSDictionary *)normalizeQuotaResponse:(NGHashMap *)_map;
 
+/* ACL */
+
+- (NSDictionary *)normalizeGetACLResponse:(NGHashMap *)_map;
+- (NSDictionary *)normalizeListRightsResponse:(NGHashMap *)_map;
+- (NSDictionary *)normalizeMyRightsResponse:(NGHashMap *)_map;
+
 @end
 
 #endif /* __NGImap4_NGImap4ResponseNormalizer_H__ */
index 8863cac120b948c8d8e4faabd043bb42861d8081..ffff8b1b73f2d1aede1508ecefe305e100a5a408 100644 (file)
@@ -150,7 +150,7 @@ static int      LogImapEnabled = -1;
 
   result = [self normalizeResponse:_map];
   
-  if ((obj = [[_map objectEnumeratorForKey:@"sort"] nextObject]))
+  if ((obj = [[_map objectEnumeratorForKey:@"sort"] nextObject]) != nil)
     [result setObject:obj forKey:@"sort"];
   
   return result;
@@ -642,4 +642,66 @@ _imapFlags2Flags(NGImap4ResponseNormalizer *self, NSArray *_flags)
   return result;
 }
 
+/* ACL */
+
+- (NSDictionary *)normalizeGetACLResponse:(NGHashMap *)_map {
+  /*
+    Raw Sample (Cyrus):
+      21 GETACL INBOX
+      * ACL INBOX test.et.di.cete-lyon lrswipcda helge lrwip
+      21 OK Completed
+  */
+  NSMutableDictionary *result;
+  id obj;
+  
+  result = [self normalizeResponse:_map];
+  if ((obj = [[_map objectEnumeratorForKey:@"acl"] nextObject]) != nil)
+    [result setObject:obj forKey:@"acl"];
+  if ((obj = [[_map objectEnumeratorForKey:@"mailbox"] nextObject]) != nil)
+    [result setObject:obj forKey:@"mailbox"];
+  return result;
+}
+
+- (NSDictionary *)normalizeListRightsResponse:(NGHashMap *)_map {
+  /*
+    Raw Sample (Cyrus):
+      16 listrights INBOX anyone
+      * LISTRIGHTS INBOX anyone "" l r s w i p c d a 0 1 2 3 4 5 6 7 8 9
+      16 OK Completed
+  */
+  NSMutableDictionary *result;
+  id obj;
+
+  result = [self normalizeResponse:_map];
+
+  if ((obj = [[_map objectEnumeratorForKey:@"listrights"] nextObject]))
+    [result setObject:obj forKey:@"listrights"];
+  if ((obj = [[_map objectEnumeratorForKey:@"requiredRights"] nextObject]))
+    [result setObject:obj forKey:@"requiredRights"];
+
+  if ((obj = [[_map objectEnumeratorForKey:@"mailbox"] nextObject]) != nil)
+    [result setObject:obj forKey:@"mailbox"];
+  if ((obj = [[_map objectEnumeratorForKey:@"uid"] nextObject]) != nil)
+    [result setObject:obj forKey:@"uid"];
+  return result;
+}
+
+- (NSDictionary *)normalizeMyRightsResponse:(NGHashMap *)_map {
+  /*
+    Raw Sample (Cyrus):
+      18 myrights INBOX
+      * MYRIGHTS INBOX lrswipcda
+      18 OK Completed
+  */
+  NSMutableDictionary *result;
+  id obj;
+
+  result = [self normalizeResponse:_map];
+  if ((obj = [[_map objectEnumeratorForKey:@"myrights"] nextObject]) != nil)
+    [result setObject:obj forKey:@"myrights"];
+  if ((obj = [[_map objectEnumeratorForKey:@"mailbox"] nextObject]) != nil)
+    [result setObject:obj forKey:@"mailbox"];
+  return result;
+}
+
 @end /* NGImap4ResponseNormalizer */
index 270a59c6378d8e79dca7e7c5eedc53e57300fd41..dfa7a5330b97397d3fabde56c1237b8625e48de4 100644 (file)
@@ -43,6 +43,9 @@
 - (BOOL)_parseQuotaRootResponseIntoHashMap:(NGMutableHashMap *)result_;
 - (BOOL)_parseStatusResponseIntoHashMap:(NGMutableHashMap *)result_;
 - (BOOL)_parseByeUntaggedResponseIntoHashMap:(NGMutableHashMap *)result_;
+- (BOOL)_parseACLResponseIntoHashMap:(NGMutableHashMap *)result_;
+- (BOOL)_parseMyRightsResponseIntoHashMap:(NGMutableHashMap *)result_;
+- (BOOL)_parseListRightsResponseIntoHashMap:(NGMutableHashMap *)result_;
 
 - (NSArray *)_parseThread;
 
@@ -538,6 +541,11 @@ static void _parseUntaggedResponse(NGImap4ResponseParser *self,
   
   l0 = _la(self, 0);
   switch (l0) {
+  case 'A':
+    if ([self _parseACLResponseIntoHashMap:result_])
+      return;
+    break;
+    
   case 'B':
     l1 = _la(self, 1);
     if (l1 == 'A' && _parseBadUntaggedResponse(self, result_))    // la: 3
@@ -555,12 +563,21 @@ static void _parseUntaggedResponse(NGImap4ResponseParser *self,
     if (_parseFlagsUntaggedResponse(self, result_))  // la: 5
       return;
     break;
-
+    
   case 'L':
+    if (_matchesString(self, "LISTRIGHTS")) {
+      if ([self _parseListRightsResponseIntoHashMap:result_])
+       return;
+    }
     if ([self _parseListOrLSubResponseIntoHashMap:result_])       // la: 4
       return;
     break;
 
+  case 'M':
+    if ([self _parseMyRightsResponseIntoHashMap:result_])
+      return;
+    break;
+
   case 'N':
     if (_parseNoUntaggedResponse(self, result_))     // la: 2
       return;
@@ -615,6 +632,7 @@ static void _parseUntaggedResponse(NGImap4ResponseParser *self,
   
   // TODO: what if none matches?
   [self logWithFormat:@"%s: no matching tag specifier?", __PRETTY_FUNCTION__];
+  [self logWithFormat:@"  line: '%@'", _parseUntil(self, '\n')];
 }
 
 - (void)_parseContinuationResponseIntoHashMap:(NGMutableHashMap *)result_ {
@@ -700,6 +718,99 @@ static void _parseUntaggedResponse(NGImap4ResponseParser *self,
   return YES;
 }
 
+- (BOOL)_parseACLResponseIntoHashMap:(NGMutableHashMap *)result_ {
+  /*
+    21 GETACL INBOX
+    * ACL INBOX test.et.di.cete-lyon lrswipcda helge lrwip
+  */
+  NSString       *acls;
+  NSEnumerator   *enumerator;
+  id             obj;
+  NSMutableArray *uids;
+  NSMutableArray *rights;
+  NSDictionary   *result;
+  
+  if (!_matchesString(self, "ACL "))
+    return NO;
+  _consume(self, 4);
+  
+  if ((obj = _parseUntil(self, ' ')) != nil)
+    [result_ setObject:obj forKey:@"mailbox"];
+  
+  acls = _parseUntil(self, '\n');
+  
+  uids   = [[NSMutableArray alloc] initWithCapacity:8];
+  rights = [[NSMutableArray alloc] initWithCapacity:8];
+  
+  enumerator = [[acls componentsSeparatedByString:@" "] objectEnumerator];
+  while ((obj = [enumerator nextObject]) != nil) {
+    [uids  addObject:obj];
+    obj = [enumerator nextObject];
+    [rights addObject:(obj ? obj : @"")];
+  }
+  
+  result = [[NSDictionary alloc] initWithObjects:rights forKeys:uids];
+  [result_ addObject:result forKey:@"acl"];
+  
+  [uids   release]; uids   = nil;
+  [rights release]; rights = nil;
+  [result release]; result = nil;
+  return YES;
+}
+
+- (BOOL)_parseMyRightsResponseIntoHashMap:(NGMutableHashMap *)result_ {
+  /*
+    Raw Sample (Cyrus):
+      18 myrights INBOX
+      * MYRIGHTS INBOX lrswipcda
+      18 OK Completed
+  */
+  NSString *rights;
+  id obj;
+  
+  if (!_matchesString(self, "MYRIGHTS "))
+    return NO;
+  _consume(self, 9);
+  
+  if ((obj = _parseUntil(self, ' ')) != nil)
+    [result_ setObject:obj forKey:@"mailbox"];
+  
+  rights = _parseUntil(self, '\n');
+  [result_ setObject:rights forKey:@"myrights"];
+  return YES;
+}
+
+- (BOOL)_parseListRightsResponseIntoHashMap:(NGMutableHashMap *)result_ {
+  /*
+    Raw Sample (Cyrus):
+      22 LISTRIGHTS INBOX helge
+      * LISTRIGHTS INBOX helge "" l r s w i p c d a 0 1 2 3 4 5 6 7 8 9
+      22 OK Completed
+ */
+  NSString *rights;
+  id obj;
+  
+  if (!_matchesString(self, "LISTRIGHTS "))
+    return NO;
+  _consume(self, 11);
+  
+  if ((obj = _parseUntil(self, ' ')) != nil)
+    [result_ setObject:obj forKey:@"mailbox"];
+  if ((obj = _parseUntil(self, ' ')) != nil)
+    [result_ setObject:obj forKey:@"uid"];
+  
+  if ((obj = _parseUntil(self, ' ')) != nil) {
+    if ([obj isEqual:@"\"\""])
+      obj = @"";
+    [result_ setObject:obj forKey:@"requiredRights"];
+  }
+  
+  rights = _parseUntil(self, '\n');
+  [result_ setObject:[rights componentsSeparatedByString:@" "]
+          forKey:@"listrights"];
+  return YES;
+}
+
 - (BOOL)_parseSearchResponseIntoHashMap:(NGMutableHashMap *)result_ {
   NSMutableArray *msn = nil;
   
@@ -749,8 +860,8 @@ static void _parseUntaggedResponse(NGImap4ResponseParser *self,
   _consume(self, 6);
 
   quota = [result_ objectForKey:@"quota"];
-
-  if (!quota) {
+  
+  if (quota == nil) {
       quota = [NSMutableDictionary dictionaryWithCapacity:2];
       [result_ setObject:quota forKey:@"quota"];
   }
index 02b9ee5d4e4791086dad67d4a7ec135bf8ae3111..a2300f74fdf1facae61f1265e8c1e0537ad7d45c 100644 (file)
@@ -2,7 +2,7 @@
 
 MAJOR_VERSION:=4
 MINOR_VERSION:=5
-SUBMINOR_VERSION:=220
+SUBMINOR_VERSION:=221
 
 # v4.5.214 requires libNGExtensions v4.5.146
 # v4.2.149 requires libNGStreams    v4.2.34
index 024ae5bdf760bc33e39190d7d0e3077c3d0dd2e4..51a889d0e2359f29f79478003be1ffef989f2a47 100644 (file)
@@ -1,3 +1,7 @@
+2005-07-05  Helge Hess  <helge.hess@opengroupware.org>
+
+       * added imapacl tool to test ACL related IMAP4 commands
+
 2005-03-03  Helge Hess  <helge.hess@opengroupware.org>
 
        * ImapListTool.m: improved output with directories
index 08a12f41ba58f8e650961a817376be6ea6fd2d60..c6c223659677e8ec6d0a16e41baf41d63ea5aa34 100644 (file)
@@ -8,10 +8,12 @@ TOOL_NAME = \
        imapls          \
        test_qpdecode   \
        imapquota       \
+       imapacl         \
        imap_tool       \
        sievetool
 
 imapquota_OBJC_FILES     = ImapQuotaTool.m ImapTool.m imapquota.m
+imapacl_OBJC_FILES       = ImapQuotaTool.m ImapTool.m imapacl.m
 imapget_OBJC_FILES       = ImapTool.m imapget.m
 imap_tool_OBJC_FILES     = imap_tool.m
 mime2xml_OBJC_FILES      = Mime2XmlTool.m mime2xml.m
index 4a3d5584ba4497f9fce4e7e00ec3e8e804daba8d..bb4ec978156b7810bc16be56190a39e5fbf84f30 100644 (file)
@@ -35,7 +35,6 @@
   client = [[fm imapContext] client];
 
   return [[client getQuotaRoot:_folder] objectForKey:@"quotas"];
-  
 }
 
 @end /* ImapQuotaTool */
diff --git a/sope-mime/samples/imapacl.m b/sope-mime/samples/imapacl.m
new file mode 100644 (file)
index 0000000..ebac621
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+  Copyright (C) 2000-2005 SKYRIX Software AG
+
+  This file is part of SOPE.
+
+  SOPE 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.
+
+  SOPE 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 SOPE; see the file COPYING.  If not, write to the
+  Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+  02111-1307, USA.
+*/
+
+#include <NGImap4/NGImap4Client.h>
+#include <NGImap4/NGImap4FileManager.h>
+#include <NGImap4/NGImap4Context.h>
+#include "ImapQuotaTool.h"
+#include "common.h"
+
+int main(int argc, char **argv, char **env) {
+  NSAutoreleasePool *pool;
+  ImapQuotaTool *tool;
+  int res = 0;
+  
+  pool = [NSAutoreleasePool new];
+  
+#if LIB_FOUNDATION_LIBRARY  
+  [NSProcessInfo initializeWithArguments:argv count:argc environment:env];
+#endif
+  
+  tool = [[ImapQuotaTool alloc] init];
+
+  {
+    NGImap4Client *client;
+    NSString *mailbox;
+    
+    client = [[[tool fileManager] imapContext] client];
+    
+    mailbox = [[NSUserDefaults standardUserDefaults] objectForKey:@"path"];
+    NSLog(@"acl test on path: %@", mailbox);
+    NSLog(@"  acl %@", [[client getACL:mailbox] valueForKey:@"acl"]);
+    
+    NSLog(@"  set urks 'lr' %@", 
+         [[client setACL:mailbox rights:@"lr" uid:@"urks"] 
+           valueForKey:@"result"]);
+    NSLog(@"  acl %@", [[client getACL:mailbox] valueForKey:@"acl"]);
+    
+    NSLog(@"  rm urks %@", 
+         [[client deleteACL:mailbox uid:@"urks"] valueForKey:@"result"]);
+    NSLog(@"  acl %@", [[client getACL:mailbox] valueForKey:@"acl"]);
+    
+    
+    NSLog(@"  my rights: '%@'",
+         [[client myRights:mailbox] valueForKey:@"myrights"]);
+    
+    NSLog(@"  list rights: %@",
+         [[[client listRights:mailbox uid:@"urks"] 
+            valueForKey:@"listrights"] componentsJoinedByString:@","]);
+  }  
+  [tool release];
+  
+  [pool release];
+  exit(res);
+  /* static linking */
+  [NGExtensions class];
+  return res;
+}
index 3192714305228f027d408741b6e99213f70fd8b2..76282de01174573a43cf0246f756ff98635bb915 100644 (file)
@@ -37,7 +37,7 @@ int main(int argc, char **argv, char **env) {
 
   {
     NSString *str;
-
+    
     str = [[NSUserDefaults standardUserDefaults] objectForKey:@"path"];
     NSLog(@"quota for path: %@", str);
     NSLog(@"result %@", [tool getQuotaRoot:str]);