2006-06-15 21:34:10 +02:00
|
|
|
/*
|
|
|
|
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.
|
|
|
|
*/
|
|
|
|
|
2007-05-19 02:46:16 +02:00
|
|
|
#import <Foundation/NSUserDefaults.h>
|
|
|
|
|
|
|
|
#import <NGObjWeb/NSException+HTTP.h>
|
|
|
|
#import <NGExtensions/NSNull+misc.h>
|
|
|
|
#import <NGExtensions/NSURL+misc.h>
|
|
|
|
#import <NGExtensions/NSObject+Logs.h>
|
2007-05-30 22:23:54 +02:00
|
|
|
#import <NGExtensions/NSString+misc.h>
|
2007-05-19 02:46:16 +02:00
|
|
|
|
|
|
|
#import <NGImap4/NGImap4Connection.h>
|
|
|
|
#import <NGImap4/NGImap4Client.h>
|
|
|
|
|
|
|
|
#import <SoObjects/SOGo/SOGoPermissions.h>
|
2007-05-30 22:23:54 +02:00
|
|
|
#import <SoObjects/SOGo/SOGoUser.h>
|
2007-05-19 02:46:16 +02:00
|
|
|
#import <SoObjects/SOGo/NSArray+Utilities.h>
|
|
|
|
|
|
|
|
#import "SOGoMailObject.h"
|
|
|
|
#import "SOGoMailAccount.h"
|
|
|
|
#import "SOGoMailManager.h"
|
|
|
|
#import "SOGoMailFolderDataSource.h"
|
|
|
|
#import "SOGoMailFolder.h"
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2007-05-22 21:16:07 +02:00
|
|
|
static NSString *defaultUserID = @"anyone";
|
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
@implementation SOGoMailFolder
|
|
|
|
|
|
|
|
static BOOL useAltNamespace = NO;
|
|
|
|
|
2007-05-28 21:07:21 +02:00
|
|
|
+ (int) version
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
return [super version] + 0 /* v1 */;
|
|
|
|
}
|
|
|
|
|
2007-05-28 21:07:21 +02:00
|
|
|
+ (void) initialize
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
|
|
|
|
|
|
|
NSAssert2([super version] == 1,
|
|
|
|
@"invalid superclass (%@) version %i !",
|
|
|
|
NSStringFromClass([self superclass]), [super version]);
|
|
|
|
|
|
|
|
useAltNamespace = [ud boolForKey:@"SOGoSpecialFoldersInRoot"];
|
|
|
|
}
|
|
|
|
|
2007-06-01 07:45:12 +02:00
|
|
|
- (void) _adjustOwner
|
|
|
|
{
|
|
|
|
SOGoMailAccount *mailAccount;
|
|
|
|
NSString *path;
|
|
|
|
NSArray *names;
|
|
|
|
|
|
|
|
mailAccount = [self mailAccountFolder];
|
|
|
|
path = [[self imap4Connection] imap4FolderNameForURL: [self imap4URL]];
|
|
|
|
|
|
|
|
if ([path hasPrefix: [mailAccount sharedFolderName]])
|
|
|
|
owner = @"anyone";
|
|
|
|
else if ([path hasPrefix: [mailAccount otherUsersFolderName]])
|
|
|
|
{
|
|
|
|
names = [path componentsSeparatedByString: @"/"];
|
|
|
|
if ([names count] > 1)
|
|
|
|
owner = [names objectAtIndex: 1];
|
|
|
|
else
|
|
|
|
owner = @"anyone";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) initWithName: (NSString *) newName
|
|
|
|
inContainer: (id) newContainer
|
|
|
|
{
|
|
|
|
if ((self = [super initWithName: newName
|
|
|
|
inContainer: newContainer]))
|
|
|
|
{
|
|
|
|
[self _adjustOwner];
|
|
|
|
}
|
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2007-05-28 21:07:21 +02:00
|
|
|
- (void) dealloc
|
|
|
|
{
|
2007-05-22 21:17:45 +02:00
|
|
|
[filenames release];
|
|
|
|
[folderType release];
|
2006-06-15 21:34:10 +02:00
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* IMAP4 */
|
|
|
|
|
2007-05-28 21:07:21 +02:00
|
|
|
- (NSString *) relativeImap4Name
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
return [self nameInContainer];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* listing the available folders */
|
|
|
|
|
2007-05-28 21:07:21 +02:00
|
|
|
- (NSArray *) toManyRelationshipKeys
|
|
|
|
{
|
|
|
|
return [self subfolders];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSArray *) subfolders
|
|
|
|
{
|
|
|
|
return [[self imap4Connection] subfoldersForURL: [self imap4URL]];
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
2006-07-13 00:03:05 +02:00
|
|
|
|
2007-05-28 21:07:21 +02:00
|
|
|
- (NSArray *) subfoldersURL
|
|
|
|
{
|
|
|
|
NSURL *selfURL, *currentURL;
|
|
|
|
NSMutableArray *subfoldersURL;
|
|
|
|
NSEnumerator *subfolders;
|
|
|
|
NSString *selfPath, *currentFolder;
|
|
|
|
|
|
|
|
subfoldersURL = [NSMutableArray array];
|
|
|
|
selfURL = [self imap4URL];
|
|
|
|
selfPath = [selfURL path];
|
|
|
|
subfolders = [[self subfolders] objectEnumerator];
|
|
|
|
currentFolder = [subfolders nextObject];
|
|
|
|
while (currentFolder)
|
|
|
|
{
|
|
|
|
currentURL = [[NSURL alloc]
|
|
|
|
initWithScheme: [selfURL scheme]
|
|
|
|
host: [selfURL host]
|
|
|
|
path: [selfPath stringByAppendingPathComponent:
|
|
|
|
currentFolder]];
|
|
|
|
[currentURL autorelease];
|
|
|
|
[subfoldersURL addObject: currentURL];
|
|
|
|
currentFolder = [subfolders nextObject];
|
|
|
|
}
|
|
|
|
|
|
|
|
return subfoldersURL;
|
|
|
|
}
|
|
|
|
|
2007-06-01 07:45:12 +02:00
|
|
|
- (NSString *) davContentType
|
|
|
|
{
|
|
|
|
return @"httpd/unix-directory";
|
|
|
|
}
|
|
|
|
|
2007-05-28 21:07:21 +02:00
|
|
|
- (NSArray *) toOneRelationshipKeys
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
NSArray *uids;
|
|
|
|
unsigned count;
|
|
|
|
|
2007-05-22 21:17:45 +02:00
|
|
|
if (filenames != nil)
|
|
|
|
return [filenames isNotNull] ? filenames : nil;
|
2006-06-15 21:34:10 +02:00
|
|
|
|
|
|
|
uids = [self fetchUIDsMatchingQualifier:nil sortOrdering:@"DATE"];
|
|
|
|
if ([uids isKindOfClass:[NSException class]])
|
|
|
|
return nil;
|
|
|
|
|
|
|
|
if ((count = [uids count]) == 0) {
|
2007-05-22 21:17:45 +02:00
|
|
|
filenames = [[NSArray alloc] init];
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
NSMutableArray *keys;
|
|
|
|
unsigned i;
|
|
|
|
|
|
|
|
keys = [[NSMutableArray alloc] initWithCapacity:count];
|
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
NSString *k;
|
|
|
|
|
|
|
|
k = [[uids objectAtIndex:i] stringValue];
|
|
|
|
k = [k stringByAppendingString:@".mail"];
|
|
|
|
[keys addObject:k];
|
|
|
|
}
|
2007-05-22 21:17:45 +02:00
|
|
|
filenames = [keys copy];
|
2006-06-15 21:34:10 +02:00
|
|
|
[keys release];
|
|
|
|
}
|
2007-05-22 21:17:45 +02:00
|
|
|
return filenames;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2007-05-28 21:07:21 +02:00
|
|
|
- (EODataSource *) contentDataSourceInContext: (id) _ctx
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
SOGoMailFolderDataSource *ds;
|
|
|
|
|
|
|
|
ds = [[SOGoMailFolderDataSource alloc] initWithImap4URL:[self imap4URL]
|
|
|
|
imap4Password:[self imap4Password]];
|
|
|
|
return [ds autorelease];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* messages */
|
|
|
|
|
2007-05-28 21:07:21 +02:00
|
|
|
- (NSArray *) fetchUIDsMatchingQualifier: (id) _q
|
|
|
|
sortOrdering: (id) _so
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
/* seems to return an NSArray of NSNumber's */
|
|
|
|
return [[self imap4Connection] fetchUIDsInURL:[self imap4URL]
|
|
|
|
qualifier:_q sortOrdering:_so];
|
|
|
|
}
|
|
|
|
|
2007-05-28 21:07:21 +02:00
|
|
|
- (NSArray *) fetchUIDs: (NSArray *) _uids
|
|
|
|
parts: (NSArray *) _parts
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
return [[self imap4Connection] fetchUIDs:_uids inURL:[self imap4URL]
|
|
|
|
parts:_parts];
|
|
|
|
}
|
|
|
|
|
2007-05-28 21:07:21 +02:00
|
|
|
- (NSException *) postData: (NSData *) _data
|
|
|
|
flags: (id) _flags
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
return [[self imap4Connection] postData:_data flags:_flags
|
|
|
|
toFolderURL:[self imap4URL]];
|
|
|
|
}
|
|
|
|
|
2007-05-28 21:07:21 +02:00
|
|
|
- (NSException *) expunge
|
|
|
|
{
|
|
|
|
return [[self imap4Connection] expungeAtURL: [self imap4URL]];
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
|
2007-05-28 21:07:21 +02:00
|
|
|
- (NSException *) addFlagsToAllMessages: (id) _f
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
return [[self imap4Connection] addFlags:_f
|
2007-05-28 21:07:21 +02:00
|
|
|
toAllMessagesInURL: [self imap4URL]];
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* name lookup */
|
|
|
|
|
2007-05-28 21:07:21 +02:00
|
|
|
- (BOOL) isMessageKey: (NSString *) _key
|
|
|
|
inContext: (id) _ctx
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
/*
|
|
|
|
Every key starting with a digit is consider an IMAP4 message key. This is
|
|
|
|
not entirely correct since folders could also start with a number.
|
|
|
|
|
|
|
|
If we want to support folders beginning with numbers, we would need to
|
|
|
|
scan the folder list for the _key, which would make everything quite a bit
|
|
|
|
slower.
|
|
|
|
TODO: support this mode using a default.
|
|
|
|
*/
|
|
|
|
if ([_key length] == 0)
|
|
|
|
return NO;
|
|
|
|
|
|
|
|
if (isdigit([_key characterAtIndex:0]))
|
|
|
|
return YES;
|
|
|
|
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
2007-05-28 21:07:21 +02:00
|
|
|
- (id) lookupImap4Folder: (NSString *) _key
|
|
|
|
inContext: (id) _ctx
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
// TODO: we might want to check for existence prior controller creation
|
|
|
|
NSURL *sf;
|
|
|
|
|
|
|
|
/* check whether URL exists */
|
|
|
|
|
|
|
|
sf = [self imap4URL];
|
|
|
|
sf = [NSURL URLWithString:[[sf path] stringByAppendingPathComponent:_key]
|
|
|
|
relativeToURL:sf];
|
|
|
|
|
|
|
|
if (![[self imap4Connection] doesMailboxExistAtURL:sf]) {
|
|
|
|
/*
|
|
|
|
We may not return 404, confuses path traversal - but we still do in the
|
|
|
|
calling method. Probably the traversal process should be fixed to
|
|
|
|
support 404 exceptions (as stop traversal _and_ acquisition).
|
|
|
|
*/
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* create object */
|
|
|
|
|
|
|
|
return [[[SOGoMailFolder alloc] initWithName:_key
|
|
|
|
inContainer:self] autorelease];
|
|
|
|
}
|
|
|
|
|
2007-05-28 21:07:21 +02:00
|
|
|
- (id) lookupImap4Message: (NSString *) _key
|
|
|
|
inContext: (id) _ctx
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
// TODO: we might want to check for existence prior controller creation
|
|
|
|
return [[[SOGoMailObject alloc] initWithName:_key
|
|
|
|
inContainer:self] autorelease];
|
|
|
|
}
|
|
|
|
|
2007-05-28 21:07:21 +02:00
|
|
|
- (id) lookupName: (NSString *) _key
|
|
|
|
inContext: (id)_ctx
|
|
|
|
acquire: (BOOL) _acquire
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
id obj;
|
|
|
|
|
|
|
|
if ([self isMessageKey:_key inContext:_ctx]) {
|
|
|
|
/*
|
|
|
|
We assume here that _key is a number and methods are not and this is
|
|
|
|
moved above the super lookup since the super checks the
|
|
|
|
-toOneRelationshipKeys which in turn loads the message ids.
|
|
|
|
*/
|
|
|
|
return [self lookupImap4Message:_key inContext:_ctx];
|
|
|
|
}
|
2007-02-08 22:55:47 +01:00
|
|
|
|
|
|
|
obj = [self lookupImap4Folder:_key inContext:_ctx];
|
|
|
|
if (obj != nil)
|
|
|
|
return obj;
|
2006-06-15 21:34:10 +02:00
|
|
|
|
|
|
|
/* check attributes directly bound to the app */
|
|
|
|
if ((obj = [super lookupName:_key inContext:_ctx acquire:NO]))
|
|
|
|
return obj;
|
|
|
|
|
|
|
|
/* return 404 to stop acquisition */
|
|
|
|
return _acquire
|
|
|
|
? [NSException exceptionWithHTTPStatus:404 /* Not Found */]
|
|
|
|
: nil; /* hack to work with WebDAV move */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* WebDAV */
|
|
|
|
|
2007-05-28 21:07:21 +02:00
|
|
|
- (BOOL) davIsCollection
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
2007-05-28 21:07:21 +02:00
|
|
|
- (NSException *) davCreateCollection: (NSString *) _name
|
|
|
|
inContext: (id) _ctx
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
return [[self imap4Connection] createMailbox:_name atURL:[self imap4URL]];
|
|
|
|
}
|
|
|
|
|
2007-05-28 21:07:21 +02:00
|
|
|
- (NSException *) delete
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
/* Note: overrides SOGoObject -delete */
|
|
|
|
return [[self imap4Connection] deleteMailboxAtURL:[self imap4URL]];
|
|
|
|
}
|
|
|
|
|
2007-05-28 21:07:21 +02:00
|
|
|
- (NSException *) davMoveToTargetObject: (id) _target
|
|
|
|
newName: (NSString *) _name
|
|
|
|
inContext: (id)_ctx
|
2006-06-15 21:34:10 +02:00
|
|
|
{
|
|
|
|
NSURL *destImapURL;
|
|
|
|
|
|
|
|
if ([_name length] == 0) { /* target already exists! */
|
|
|
|
// TODO: check the overwrite request field (should be done by dispatcher)
|
|
|
|
return [NSException exceptionWithHTTPStatus:412 /* Precondition Failed */
|
|
|
|
reason:@"target already exists"];
|
|
|
|
}
|
|
|
|
if (![_target respondsToSelector:@selector(imap4URL)]) {
|
|
|
|
return [NSException exceptionWithHTTPStatus:502 /* Bad Gateway */
|
|
|
|
reason:@"target is not an IMAP4 folder"];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* build IMAP4 URL for target */
|
|
|
|
|
|
|
|
destImapURL = [_target imap4URL];
|
|
|
|
destImapURL = [NSURL URLWithString:[[destImapURL path]
|
|
|
|
stringByAppendingPathComponent:_name]
|
|
|
|
relativeToURL:destImapURL];
|
|
|
|
|
|
|
|
[self logWithFormat:@"TODO: should move collection as '%@' to: %@",
|
|
|
|
[[self imap4URL] absoluteString],
|
|
|
|
[destImapURL absoluteString]];
|
|
|
|
|
|
|
|
return [[self imap4Connection] moveMailboxAtURL:[self imap4URL]
|
|
|
|
toURL:destImapURL];
|
|
|
|
}
|
2007-05-28 21:07:21 +02:00
|
|
|
|
|
|
|
- (NSException *) davCopyToTargetObject: (id) _target
|
|
|
|
newName: (NSString *) _name
|
|
|
|
inContext: (id) _ctx
|
2006-06-15 21:34:10 +02:00
|
|
|
{
|
|
|
|
[self logWithFormat:@"TODO: should copy collection as '%@' to: %@",
|
|
|
|
_name, _target];
|
|
|
|
return [NSException exceptionWithHTTPStatus:501 /* Not Implemented */
|
|
|
|
reason:@"not implemented"];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* folder type */
|
2007-05-30 22:23:54 +02:00
|
|
|
- (NSString *) folderType
|
|
|
|
{
|
|
|
|
return @"Mail";
|
|
|
|
}
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2007-05-28 21:07:21 +02:00
|
|
|
- (NSString *) outlookFolderClass
|
|
|
|
{
|
2006-06-15 21:34:10 +02:00
|
|
|
// TODO: detect Trash/Sent/Drafts folders
|
|
|
|
SOGoMailAccount *account;
|
|
|
|
NSString *n;
|
|
|
|
|
2007-05-22 21:17:45 +02:00
|
|
|
if (folderType != nil)
|
|
|
|
return folderType;
|
2006-06-15 21:34:10 +02:00
|
|
|
|
|
|
|
account = [self mailAccountFolder];
|
|
|
|
n = [self nameInContainer];
|
|
|
|
|
|
|
|
if ([n isEqualToString:[account trashFolderNameInContext:nil]])
|
2007-05-22 21:17:45 +02:00
|
|
|
folderType = @"IPF.Trash";
|
2006-06-15 21:34:10 +02:00
|
|
|
else if ([n isEqualToString:[account inboxFolderNameInContext:nil]])
|
2007-05-22 21:17:45 +02:00
|
|
|
folderType = @"IPF.Inbox";
|
2006-06-15 21:34:10 +02:00
|
|
|
else if ([n isEqualToString:[account sentFolderNameInContext:nil]])
|
2007-05-22 21:17:45 +02:00
|
|
|
folderType = @"IPF.Sent";
|
2006-06-15 21:34:10 +02:00
|
|
|
else
|
2007-05-22 21:17:45 +02:00
|
|
|
folderType = @"IPF.Folder";
|
2006-06-15 21:34:10 +02:00
|
|
|
|
2007-05-22 21:17:45 +02:00
|
|
|
return folderType;
|
2006-06-15 21:34:10 +02:00
|
|
|
}
|
|
|
|
|
2007-05-19 02:46:16 +02:00
|
|
|
/* acls */
|
|
|
|
|
|
|
|
- (NSArray *) _imapAclsToSOGoAcls: (NSString *) imapAcls
|
|
|
|
{
|
|
|
|
unsigned int count, max;
|
|
|
|
NSMutableArray *SOGoAcls;
|
|
|
|
|
|
|
|
SOGoAcls = [NSMutableArray array];
|
|
|
|
max = [imapAcls length];
|
|
|
|
for (count = 0; count < max; count++)
|
|
|
|
{
|
|
|
|
switch ([imapAcls characterAtIndex: count])
|
|
|
|
{
|
|
|
|
case 'l':
|
2007-05-22 20:33:45 +02:00
|
|
|
[SOGoAcls addObjectUniquely: SOGoRole_ObjectViewer];
|
2007-05-19 02:46:16 +02:00
|
|
|
break;
|
|
|
|
case 'r':
|
|
|
|
[SOGoAcls addObjectUniquely: SOGoRole_ObjectReader];
|
|
|
|
break;
|
|
|
|
case 's':
|
|
|
|
[SOGoAcls addObjectUniquely: SOGoMailRole_SeenKeeper];
|
|
|
|
break;
|
|
|
|
case 'w':
|
|
|
|
[SOGoAcls addObjectUniquely: SOGoMailRole_Writer];
|
|
|
|
break;
|
|
|
|
case 'i':
|
|
|
|
[SOGoAcls addObjectUniquely: SOGoRole_ObjectCreator];
|
|
|
|
break;
|
|
|
|
case 'p':
|
|
|
|
[SOGoAcls addObjectUniquely: SOGoMailRole_Poster];
|
|
|
|
break;
|
|
|
|
case 'k':
|
|
|
|
[SOGoAcls addObjectUniquely: SOGoRole_FolderCreator];
|
|
|
|
break;
|
|
|
|
case 'x':
|
2007-05-22 20:33:45 +02:00
|
|
|
[SOGoAcls addObjectUniquely: SOGoRole_ObjectEraser];
|
2007-05-19 02:46:16 +02:00
|
|
|
break;
|
|
|
|
case 't':
|
2007-05-22 20:33:45 +02:00
|
|
|
[SOGoAcls addObjectUniquely: SOGoMailRole_MessageEraser];
|
2007-05-19 02:46:16 +02:00
|
|
|
break;
|
|
|
|
case 'e':
|
|
|
|
[SOGoAcls addObjectUniquely: SOGoMailRole_Expunger];
|
|
|
|
break;
|
|
|
|
case 'a':
|
|
|
|
[SOGoAcls addObjectUniquely: SOGoMailRole_Administrator];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return SOGoAcls;
|
|
|
|
}
|
|
|
|
|
2007-05-22 20:33:45 +02:00
|
|
|
- (NSString *) _sogoAclsToImapAcls: (NSArray *) sogoAcls
|
|
|
|
{
|
|
|
|
NSMutableString *imapAcls;
|
|
|
|
NSEnumerator *acls;
|
|
|
|
NSString *currentAcl;
|
|
|
|
char character;
|
|
|
|
|
|
|
|
imapAcls = [NSMutableString string];
|
|
|
|
acls = [sogoAcls objectEnumerator];
|
|
|
|
currentAcl = [acls nextObject];
|
|
|
|
while (currentAcl)
|
|
|
|
{
|
|
|
|
if ([currentAcl isEqualToString: SOGoRole_ObjectViewer])
|
|
|
|
character = 'l';
|
|
|
|
else if ([currentAcl isEqualToString: SOGoRole_ObjectReader])
|
|
|
|
character = 'r';
|
|
|
|
else if ([currentAcl isEqualToString: SOGoMailRole_SeenKeeper])
|
|
|
|
character = 's';
|
|
|
|
else if ([currentAcl isEqualToString: SOGoMailRole_Writer])
|
|
|
|
character = 'w';
|
|
|
|
else if ([currentAcl isEqualToString: SOGoRole_ObjectCreator])
|
|
|
|
character = 'i';
|
|
|
|
else if ([currentAcl isEqualToString: SOGoMailRole_Poster])
|
|
|
|
character = 'p';
|
|
|
|
else if ([currentAcl isEqualToString: SOGoRole_FolderCreator])
|
|
|
|
character = 'k';
|
|
|
|
else if ([currentAcl isEqualToString: SOGoRole_ObjectEraser])
|
|
|
|
character = 'x';
|
|
|
|
else if ([currentAcl isEqualToString: SOGoMailRole_MessageEraser])
|
|
|
|
character = 't';
|
|
|
|
else if ([currentAcl isEqualToString: SOGoMailRole_Expunger])
|
|
|
|
character = 'e';
|
|
|
|
else if ([currentAcl isEqualToString: SOGoMailRole_Administrator])
|
|
|
|
character = 'a';
|
|
|
|
else
|
|
|
|
character = 0;
|
|
|
|
|
|
|
|
if (character)
|
|
|
|
[imapAcls appendFormat: @"%c", character];
|
|
|
|
|
|
|
|
currentAcl = [acls nextObject];
|
|
|
|
}
|
|
|
|
|
|
|
|
return imapAcls;
|
|
|
|
}
|
|
|
|
|
2007-05-19 02:46:16 +02:00
|
|
|
- (NSArray *) aclUsers
|
|
|
|
{
|
2007-05-25 23:26:01 +02:00
|
|
|
NSArray *users;
|
2007-05-19 02:46:16 +02:00
|
|
|
NSDictionary *imapAcls;
|
|
|
|
|
2007-05-30 22:23:54 +02:00
|
|
|
imapAcls = [[self imap4Connection] aclForMailboxAtURL: [self imap4URL]];
|
2007-05-25 23:26:01 +02:00
|
|
|
if ([imapAcls isKindOfClass: [NSDictionary class]])
|
|
|
|
users = [imapAcls allKeys];
|
|
|
|
else
|
|
|
|
users = nil;
|
|
|
|
|
|
|
|
return users;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSMutableArray *) _sharesACLs
|
|
|
|
{
|
|
|
|
NSMutableArray *acls;
|
|
|
|
SOGoMailAccount *mailAccount;
|
2007-05-30 22:23:54 +02:00
|
|
|
NSString *path;
|
2007-05-25 23:26:01 +02:00
|
|
|
NSArray *names;
|
|
|
|
unsigned int count;
|
|
|
|
|
|
|
|
acls = [NSMutableArray array];
|
|
|
|
|
|
|
|
mailAccount = [self mailAccountFolder];
|
2007-05-30 22:23:54 +02:00
|
|
|
path = [[self imap4Connection] imap4FolderNameForURL: [self imap4URL]];
|
2007-05-25 23:26:01 +02:00
|
|
|
names = [path componentsSeparatedByString: @"/"];
|
|
|
|
count = [names count];
|
|
|
|
|
2007-05-30 22:23:54 +02:00
|
|
|
if ([path hasPrefix: [mailAccount sharedFolderName]])
|
|
|
|
[acls addObject: SOGoRole_ObjectViewer];
|
|
|
|
else if ([path hasPrefix: [mailAccount otherUsersFolderName]])
|
|
|
|
[acls addObject: SOGoRole_ObjectViewer];
|
2007-05-25 23:26:01 +02:00
|
|
|
else
|
|
|
|
[acls addObject: SoRole_Owner];
|
2007-05-19 02:46:16 +02:00
|
|
|
|
2007-05-25 23:26:01 +02:00
|
|
|
return acls;
|
2007-05-19 02:46:16 +02:00
|
|
|
}
|
|
|
|
|
2007-05-22 20:33:45 +02:00
|
|
|
- (NSArray *) aclsForUser: (NSString *) uid
|
|
|
|
{
|
|
|
|
NSDictionary *imapAcls;
|
2007-05-25 23:26:01 +02:00
|
|
|
NSMutableArray *acls;
|
2007-05-22 21:30:36 +02:00
|
|
|
NSString *userAcls;
|
2007-05-22 20:33:45 +02:00
|
|
|
|
2007-05-25 23:26:01 +02:00
|
|
|
acls = [self _sharesACLs];
|
2007-05-30 22:23:54 +02:00
|
|
|
imapAcls = [[self imap4Connection] aclForMailboxAtURL: [self imap4URL]];
|
2007-05-25 23:26:01 +02:00
|
|
|
if ([imapAcls isKindOfClass: [NSDictionary class]])
|
|
|
|
{
|
|
|
|
userAcls = [imapAcls objectForKey: uid];
|
|
|
|
if (!([userAcls length] || [uid isEqualToString: defaultUserID]))
|
|
|
|
userAcls = [imapAcls objectForKey: defaultUserID];
|
|
|
|
if ([userAcls length])
|
|
|
|
[acls addObjectsFromArray: [self _imapAclsToSOGoAcls: userAcls]];
|
|
|
|
}
|
2007-05-22 20:33:45 +02:00
|
|
|
|
2007-05-25 23:26:01 +02:00
|
|
|
return acls;
|
2007-05-22 20:33:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) removeAclsForUsers: (NSArray *) users
|
|
|
|
{
|
|
|
|
NSEnumerator *uids;
|
|
|
|
NSString *currentUID;
|
|
|
|
NSString *folderName;
|
|
|
|
NGImap4Client *client;
|
|
|
|
|
2007-05-30 22:23:54 +02:00
|
|
|
folderName = [[self imap4Connection] imap4FolderNameForURL: [self imap4URL]];
|
2007-05-22 20:33:45 +02:00
|
|
|
client = [imap4 client];
|
|
|
|
|
|
|
|
uids = [users objectEnumerator];
|
|
|
|
currentUID = [uids nextObject];
|
|
|
|
while (currentUID)
|
|
|
|
{
|
|
|
|
[client deleteACL: folderName uid: currentUID];
|
|
|
|
currentUID = [uids nextObject];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setRoles: (NSArray *) roles
|
|
|
|
forUser: (NSString *) uid
|
|
|
|
{
|
|
|
|
NSString *acls, *folderName;
|
|
|
|
|
|
|
|
acls = [self _sogoAclsToImapAcls: roles];
|
2007-05-30 22:23:54 +02:00
|
|
|
folderName = [[self imap4Connection] imap4FolderNameForURL: [self imap4URL]];
|
2007-05-22 20:33:45 +02:00
|
|
|
[[imap4 client] setACL: folderName rights: acls uid: uid];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) defaultUserID
|
|
|
|
{
|
2007-05-22 21:16:07 +02:00
|
|
|
return defaultUserID;
|
2007-05-22 20:33:45 +02:00
|
|
|
}
|
|
|
|
|
2007-05-30 22:23:54 +02:00
|
|
|
- (NSString *) otherUsersPathToFolder
|
|
|
|
{
|
|
|
|
NSString *userPath, *selfPath, *otherUsers, *sharedFolders;
|
|
|
|
SOGoMailAccount *account;
|
|
|
|
|
|
|
|
account = [self mailAccountFolder];
|
|
|
|
otherUsers = [account otherUsersFolderName];
|
|
|
|
sharedFolders = [account sharedFolderName];
|
|
|
|
|
|
|
|
selfPath = [[self imap4URL] path];
|
|
|
|
if ([selfPath hasPrefix: [NSString stringWithFormat: @"/%@", otherUsers]]
|
|
|
|
|| [selfPath hasPrefix:
|
|
|
|
[NSString stringWithFormat: @"/%@", sharedFolders]])
|
|
|
|
userPath = selfPath;
|
|
|
|
else
|
|
|
|
userPath = [NSString stringWithFormat: @"/%@/%@%@",
|
|
|
|
[otherUsers stringByEscapingURL],
|
2007-06-01 07:45:12 +02:00
|
|
|
owner, selfPath];
|
2007-05-30 22:23:54 +02:00
|
|
|
|
|
|
|
return userPath;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) httpURLForAdvisoryToUser: (NSString *) uid;
|
|
|
|
{
|
|
|
|
SOGoUser *user;
|
|
|
|
|
|
|
|
user = [SOGoUser userWithLogin: uid roles: nil];
|
|
|
|
|
|
|
|
return [NSString stringWithFormat: @"%@/%@%@",
|
|
|
|
[self soURLToBaseContainerForUser: uid],
|
|
|
|
[user primaryIMAP4AccountString],
|
|
|
|
[self otherUsersPathToFolder]];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) resourceURLForAdvisoryToUser: (NSString *) uid;
|
|
|
|
{
|
|
|
|
NSURL *selfURL, *userURL;
|
|
|
|
|
|
|
|
selfURL = [self imap4URL];
|
|
|
|
userURL = [[NSURL alloc] initWithScheme: [selfURL scheme]
|
|
|
|
host: [selfURL host]
|
|
|
|
path: [self otherUsersPathToFolder]];
|
|
|
|
[userURL autorelease];
|
|
|
|
|
|
|
|
return [userURL absoluteString];
|
|
|
|
}
|
|
|
|
|
2006-06-15 21:34:10 +02:00
|
|
|
@end /* SOGoMailFolder */
|