2 Copyright (C) 2004-2005 SKYRIX Software AG
4 This file is part of OpenGroupware.org.
6 OGo is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 OGo is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with OGo; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 #include "SOGoMailAccount.h"
23 #include "SOGoMailFolder.h"
24 #include "SOGoMailManager.h"
25 #include "SOGoDraftsFolder.h"
26 #include <NGObjWeb/SoHTTPAuthenticator.h>
29 @implementation SOGoMailAccount
31 static NSArray *rootFolderNames = nil;
32 static NSString *inboxFolderName = @"INBOX";
33 static NSString *draftsFolderName = @"Drafts";
34 static NSString *sieveFolderName = @"Filters";
37 NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
39 if ([ud boolForKey:@"SOGoEnableSieveFolder"]) {
40 rootFolderNames = [[NSArray alloc] initWithObjects:
47 rootFolderNames = [[NSArray alloc] initWithObjects:
54 /* listing the available folders */
56 - (NSArray *)toManyRelationshipKeys {
57 // TODO: hardcoded, if we want to support shared fldrs, this needs to change
58 return rootFolderNames;
63 - (SOGoMailAccount *)mailAccountFolder {
67 - (NSArray *)allFolderPathes {
70 pathes = [[self mailManager] allFoldersForURL:[self imap4URL]
71 password:[self imap4Password]];
72 pathes = [pathes sortedArrayUsingSelector:@selector(compare:)];
82 - (NSString *)imap4LoginFromHTTP {
87 rq = [[(WOApplication *)[WOApplication application] context] request];
89 s = [rq headerForKey:@"x-webobjects-remote-user"];
93 if ((s = [rq headerForKey:@"authorization"]) == nil) {
98 creds = [SoHTTPAuthenticator parseCredentials:s];
99 if ([creds count] < 2)
100 /* somehow invalid */
103 return [creds objectAtIndex:0]; /* the user */
106 - (NSURL *)imap4URL {
107 /* imap://agenortest@mail.opengroupware.org/INBOX/withsubdirs/subdir1 */
111 if (self->imap4URL != nil)
112 return self->imap4URL;
114 s = [self nameInContainer];
115 r = [s rangeOfString:@"@"];
119 u = [self imap4LoginFromHTTP];
120 if ([u length] == 0) {
121 [self errorWithFormat:@"missing login in account folder name: %@", s];
124 s = [[u stringByAppendingString:@"@"] stringByAppendingString:s];
126 if ([s hasSuffix:@":80"]) { // HACK
127 [self logWithFormat:@"WARNING: incorrect value for IMAP4 URL: '%@'", s];
128 s = [s substringToIndex:([s length] - 3)];
131 s = [([self useSSL] ? @"imaps://" : @"imap://") stringByAppendingString:s];
132 s = [s stringByAppendingString:@"/"];
134 self->imap4URL = [[NSURL alloc] initWithString:s];
135 return self->imap4URL;
138 - (NSString *)imap4Login {
139 return [[self imap4URL] user];
144 - (id)lookupFolder:(NSString *)_key ofClassNamed:(NSString *)_cn
149 if ((clazz = NSClassFromString(_cn)) == Nil) {
150 [self logWithFormat:@"ERROR: did not find class '%@' for key: '%@'",
152 return [NSException exceptionWithHTTPStatus:500 /* server error */
153 reason:@"did not find mail folder class!"];
155 return [[[clazz alloc] initWithName:_key inContainer:self] autorelease];
158 - (id)lookupImap4Folder:(NSString *)_key inContext:(id)_cx {
159 return [self lookupFolder:_key ofClassNamed:@"SOGoMailFolder" inContext:_cx];
161 - (id)lookupDraftsFolder:(NSString *)_key inContext:(id)_ctx {
162 return [self lookupFolder:_key ofClassNamed:@"SOGoDraftsFolder"
165 - (id)lookupFiltersFolder:(NSString *)_key inContext:(id)_ctx {
166 return [self lookupFolder:_key ofClassNamed:@"SOGoSieveScriptsFolder"
170 - (id)lookupName:(NSString *)_key inContext:(id)_ctx acquire:(BOOL)_flag {
173 /* first check attributes directly bound to the application */
174 if ((obj = [super lookupName:_key inContext:_ctx acquire:NO]) != nil)
177 // TODO: those should be product.plist bindings? (can't be class bindings
178 // though because they are 'per-account')
179 if ([_key isEqualToString:draftsFolderName]) {
180 if ((obj = [self lookupDraftsFolder:_key inContext:_ctx]) != nil)
183 if ([_key isEqualToString:sieveFolderName]) {
184 if ((obj = [self lookupFiltersFolder:_key inContext:_ctx]) != nil)
188 if ((obj = [self lookupImap4Folder:_key inContext:_ctx]) != nil)
191 /* return 404 to stop acquisition */
192 return [NSException exceptionWithHTTPStatus:404 /* Not Found */];
195 /* special folders */
197 - (NSString *)inboxFolderNameInContext:(id)_ctx {
198 return inboxFolderName; /* cannot be changed in Cyrus ? */
200 - (NSString *)draftsFolderNameInContext:(id)_ctx {
201 return draftsFolderName; /* SOGo managed folder */
203 - (NSString *)sieveFolderNameInContext:(id)_ctx {
204 return sieveFolderName; /* SOGo managed folder */
206 - (NSString *)sentFolderNameInContext:(id)_ctx {
207 /* OGo issue #1225 */
208 static NSString *s = nil;
213 ud = [NSUserDefaults standardUserDefaults];
214 s = [[ud stringForKey:@"SOGoSentFolderName"] copy];
215 if ([s length] == 0) s = @"Sent";
216 NSLog(@"Note: using SOGoSentFolderName: '%@'", s);
220 - (NSString *)trashFolderNameInContext:(id)_ctx {
221 /* OGo issue #1225 */
222 static NSString *s = nil;
227 ud = [NSUserDefaults standardUserDefaults];
228 s = [[ud stringForKey:@"SOGoTrashFolderName"] copy];
229 if ([s length] == 0) s = @"Trash";
230 NSLog(@"Note: using SOGoTrashFolderName: '%@'", s);
235 - (SOGoMailFolder *)inboxFolderInContext:(id)_ctx {
236 // TODO: use some profile to determine real location, use a -traverse lookup
237 SOGoMailFolder *folder;
239 if (self->inboxFolder != nil)
240 return self->inboxFolder;
242 folder = [self lookupName:[self inboxFolderNameInContext:_ctx]
243 inContext:_ctx acquire:NO];
244 if ([folder isKindOfClass:[NSException class]]) return folder;
246 return ((self->inboxFolder = [folder retain]));
249 - (SOGoMailFolder *)sentFolderInContext:(id)_ctx {
250 // TODO: use some profile to determine real location, use a -traverse lookup
251 SOGoMailFolder *folder;
253 if (self->sentFolder != nil)
254 return self->sentFolder;
256 folder = [self inboxFolderInContext:_ctx];
257 if ([folder isKindOfClass:[NSException class]]) return folder;
259 folder = [folder lookupName:[self sentFolderNameInContext:_ctx]
260 inContext:_ctx acquire:NO];
261 if ([folder isKindOfClass:[NSException class]]) return folder;
263 if (![folder isNotNull]) {
264 return [NSException exceptionWithHTTPStatus:404 /* not found */
265 reason:@"did not find Sent folder!"];
268 return ((self->sentFolder = [folder retain]));
271 - (SOGoMailFolder *)trashFolderInContext:(id)_ctx {
272 // TODO: use some profile to determine real location
273 SOGoMailFolder *folder;
275 if (self->trashFolder != nil)
276 return self->trashFolder;
278 folder = [self inboxFolderInContext:_ctx];
279 if ([folder isKindOfClass:[NSException class]]) return folder;
281 folder = [folder lookupName:[self trashFolderNameInContext:_ctx]
282 inContext:_ctx acquire:NO];
283 if ([folder isKindOfClass:[NSException class]]) return folder;
285 if (![folder isNotNull]) {
286 return [NSException exceptionWithHTTPStatus:404 /* not found */
287 reason:@"did not find Trash folder!"];
290 return ((self->trashFolder = [folder retain]));
295 - (BOOL)davIsCollection {
299 - (NSString *)shortTitle {
300 NSString *s, *login, *host;
303 s = [self nameInContainer];
305 r = [s rangeOfString:@"@"];
307 login = [s substringToIndex:r.location];
308 host = [s substringFromIndex:(r.location + r.length)];
315 r = [host rangeOfString:@"."];
317 host = [host substringToIndex:r.location];
319 if ([login length] == 0)
322 r = [login rangeOfString:@"."];
324 login = [login substringToIndex:r.location];
326 return [NSString stringWithFormat:@"%@@%@", login, host];
329 - (NSString *)davDisplayName {
330 return [self shortTitle];
333 @end /* SOGoMailAccount */