]> err.no Git - scalable-opengroupware.org/blobdiff - SOGo/SoObjects/Mailer/SOGoMailAccount.m
do not show Drafts folder in shared mailboxes
[scalable-opengroupware.org] / SOGo / SoObjects / Mailer / SOGoMailAccount.m
index 68c6ca8e348125137f3394eab2fbd86f95e0ca04..bcb0ea6b74958530a92f0b7777a28b380031cdc2 100644 (file)
 #include "SOGoMailFolder.h"
 #include "SOGoMailManager.h"
 #include "SOGoDraftsFolder.h"
+#include <NGObjWeb/SoHTTPAuthenticator.h>
 #include "common.h"
 
 @implementation SOGoMailAccount
 
-static NSArray  *rootFolderNames  = nil;
-static NSString *inboxFolderName  = @"INBOX";
-static NSString *draftsFolderName = @"Drafts";
-static NSString *sieveFolderName  = @"Filters";
+static NSArray  *rootFolderNames      = nil;
+static NSString *inboxFolderName      = @"INBOX";
+static NSString *draftsFolderName     = @"Drafts";
+static NSString *sieveFolderName      = @"Filters";
+static NSString *sharedFolderName     = @""; // TODO: add English default
+static NSString *otherUsersFolderName = @""; // TODO: add English default
+static BOOL     useAltNamespace       = NO;
+
++ (int)version {
+  return [super version] + 0 /* v1 */;
+}
 
 + (void)initialize {
   NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
 
+  NSAssert2([super version] == 1,
+            @"invalid superclass (%@) version %i !",
+            NSStringFromClass([self superclass]), [super version]);
+  
+  useAltNamespace = [ud boolForKey:@"SOGoSpecialFoldersInRoot"];
+  
+  sharedFolderName     = [ud stringForKey:@"SOGoSharedFolderName"];
+  otherUsersFolderName = [ud stringForKey:@"SOGoOtherUsersFolderName"];
+  
+  NSLog(@"Note: using shared-folders name:      '%@'", sharedFolderName);
+  NSLog(@"Note: using other-users-folders name: '%@'", otherUsersFolderName);
+  
   if ([ud boolForKey:@"SOGoEnableSieveFolder"]) {
     rootFolderNames = [[NSArray alloc] initWithObjects:
-                                       inboxFolderName, 
                                        draftsFolderName, 
                                        sieveFolderName, 
                                      nil];
   }
   else {
     rootFolderNames = [[NSArray alloc] initWithObjects:
-                                       inboxFolderName, 
                                        draftsFolderName, 
                                      nil];
   }
 }
 
+/* shared accounts */
+
+- (BOOL)isSharedAccount {
+  NSString *s;
+  NSRange  r;
+  
+  s = [self nameInContainer];
+  r = [s rangeOfString:@"@"];
+  if (r.length == 0) /* regular HTTP logins are never a shared mailbox */
+    return NO;
+  
+  s = [s substringToIndex:r.location];
+  return [s rangeOfString:@".-."].length > 0 ? YES : NO;
+}
+
+- (NSString *)sharedAccountName {
+  return nil;
+}
+
 /* listing the available folders */
 
-- (NSArray *)toManyRelationshipKeys {
-  // TODO: hardcoded, if we want to support shared fldrs, this needs to change
+- (NSArray *)additionalRootFolderNames {
   return rootFolderNames;
 }
 
+- (NSArray *)toManyRelationshipKeys {
+  NSArray *a, *b;
+  
+  a = [self additionalRootFolderNames];
+  b = [[self imap4Connection] subfoldersForURL:[self imap4URL]];
+  return [b count] > 0 ? [b arrayByAddingObjectsFromArray:a] : a;
+}
+
 /* hierarchy */
 
 - (SOGoMailAccount *)mailAccountFolder {
@@ -66,8 +110,7 @@ static NSString *sieveFolderName  = @"Filters";
 - (NSArray *)allFolderPathes {
   NSArray *pathes;
   
-  pathes = [[self mailManager] allFoldersForURL:[self imap4URL] 
-                              password:[self imap4Password]];
+  pathes = [[self imap4Connection] allFoldersForURL:[self imap4URL] ];
   pathes = [pathes sortedArrayUsingSelector:@selector(compare:)];
   return pathes;
 }
@@ -78,19 +121,46 @@ static NSString *sieveFolderName  = @"Filters";
   return NO;
 }
 
-- (NSURL *)imap4URL {
-  /* imap://agenortest@mail.opengroupware.org/INBOX/withsubdirs/subdir1 */
+- (NSString *)imap4LoginFromHTTP {
+  WORequest *rq;
+  NSString  *s;
+  NSArray   *creds;
+  
+  rq = [[(WOApplication *)[WOApplication application] context] request];
+  
+  s = [rq headerForKey:@"x-webobjects-remote-user"];
+  if ([s length] > 0)
+    return s;
+  
+  if ((s = [rq headerForKey:@"authorization"]) == nil) {
+    /* no basic auth */
+    return nil;
+  }
+  
+  creds = [SoHTTPAuthenticator parseCredentials:s];
+  if ([creds count] < 2)
+    /* somehow invalid */
+    return nil;
+  
+  return [creds objectAtIndex:0]; /* the user */
+}
+
+- (NSString *)imap4URLString {
+  /* private, overridden by SOGoSharedMailAccount */
   NSString *s;
   NSRange  r;
-
-  if (self->imap4URL != nil)
-    return self->imap4URL;
   
   s = [self nameInContainer];
   r = [s rangeOfString:@"@"];
   if (r.length == 0) {
-    [self errorWithFormat:@"missing login in account folder name: %@", s];
-    return nil;
+    NSString *u;
+    
+    u = [self imap4LoginFromHTTP];
+    if ([u length] == 0) {
+      [self errorWithFormat:@"missing login in account folder name: %@", s];
+      return nil;
+    }
+    s = [[u stringByAppendingString:@"@"] stringByAppendingString:s];
   }
   if ([s hasSuffix:@":80"]) { // HACK
     [self logWithFormat:@"WARNING: incorrect value for IMAP4 URL: '%@'", s];
@@ -99,11 +169,27 @@ static NSString *sieveFolderName  = @"Filters";
   
   s = [([self useSSL] ? @"imaps://" : @"imap://") stringByAppendingString:s];
   s = [s stringByAppendingString:@"/"];
+  return s;
+}
+
+- (NSURL *)imap4URL {
+  /* imap://agenortest@mail.opengroupware.org/ */
+  NSString *s;
+  
+  if (self->imap4URL != nil)
+    return self->imap4URL;
+
+  if ((s = [self imap4URLString]) == nil)
+    return nil;
   
   self->imap4URL = [[NSURL alloc] initWithString:s];
   return self->imap4URL;
 }
 
+- (NSString *)imap4Login {
+  return [[self imap4URL] user];
+}
+
 /* name lookup */
 
 - (id)lookupFolder:(NSString *)_key ofClassNamed:(NSString *)_cn
@@ -121,8 +207,14 @@ static NSString *sieveFolderName  = @"Filters";
 }
 
 - (id)lookupImap4Folder:(NSString *)_key inContext:(id)_cx {
-  return [self lookupFolder:_key ofClassNamed:@"SOGoMailFolder" inContext:_cx];
+  NSString *s;
+
+  s = [_key isEqualToString:[self trashFolderNameInContext:_cx]]
+    ? @"SOGoTrashFolder" : @"SOGoMailFolder";
+  
+  return [self lookupFolder:_key ofClassNamed:s inContext:_cx];
 }
+
 - (id)lookupDraftsFolder:(NSString *)_key inContext:(id)_ctx {
   return [self lookupFolder:_key ofClassNamed:@"SOGoDraftsFolder" 
               inContext:_ctx];
@@ -178,7 +270,7 @@ static NSString *sieveFolderName  = @"Filters";
     ud = [NSUserDefaults standardUserDefaults];
     s = [[ud stringForKey:@"SOGoSentFolderName"] copy];
     if ([s length] == 0) s = @"Sent";
-    NSLog(@"Note: using SOGoSentFolderName: '%@'", s);
+    [self logWithFormat:@"Note: using SOGoSentFolderName: '%@'", s];
   }
   return s;
 }
@@ -218,7 +310,7 @@ static NSString *sieveFolderName  = @"Filters";
   if (self->sentFolder != nil)
     return self->sentFolder;
   
-  folder = [self inboxFolderInContext:_ctx];
+  folder = useAltNamespace ? (id)self : [self inboxFolderInContext:_ctx];
   if ([folder isKindOfClass:[NSException class]]) return folder;
   
   folder = [folder lookupName:[self sentFolderNameInContext:_ctx]
@@ -239,8 +331,8 @@ static NSString *sieveFolderName  = @"Filters";
   
   if (self->trashFolder != nil)
     return self->trashFolder;
-
-  folder = [self inboxFolderInContext:_ctx];
+  
+  folder = useAltNamespace ? (id)self : [self inboxFolderInContext:_ctx];
   if ([folder isKindOfClass:[NSException class]]) return folder;
   
   folder = [folder lookupName:[self trashFolderNameInContext:_ctx]
@@ -261,6 +353,10 @@ static NSString *sieveFolderName  = @"Filters";
   return YES;
 }
 
+- (NSException *)davCreateCollection:(NSString *)_name inContext:(id)_ctx {
+  return [[self imap4Connection] createMailbox:_name atURL:[self imap4URL]];
+}
+
 - (NSString *)shortTitle {
   NSString *s, *login, *host;
   NSRange r;
@@ -284,7 +380,11 @@ static NSString *sieveFolderName  = @"Filters";
   if ([login length] == 0)
     return host;
   
-  return [NSString stringWithFormat:@"%@ (%@)", host, login];
+  r = [login rangeOfString:@"."];
+  if (r.length > 0)
+    login = [login substringToIndex:r.location];
+  
+  return [NSString stringWithFormat:@"%@@%@", login, host];
 }
 
 - (NSString *)davDisplayName {