]> err.no Git - scalable-opengroupware.org/blob - SOGo/SoObjects/Mailer/SOGoMailAccounts.m
do not show Drafts folder in shared mailboxes
[scalable-opengroupware.org] / SOGo / SoObjects / Mailer / SOGoMailAccounts.m
1 /*
2   Copyright (C) 2004-2005 SKYRIX Software AG
3
4   This file is part of OpenGroupware.org.
5
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
9   later version.
10
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.
15
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
19   02111-1307, USA.
20 */
21
22 #include "SOGoMailAccounts.h"
23 #include "SOGoUser+Mail.h"
24 #include "common.h"
25 #include <NGObjWeb/SoObject+SoDAV.h>
26 #include <SOGo/WOContext+Agenor.h>
27
28 @implementation SOGoMailAccounts
29
30 static NSString *AgenorShareLoginMarker  = @".-.";
31
32 /* detect webmail being accessed from the outside */
33
34 - (BOOL)isInternetRequest {
35   return [[(WOApplication *)[WOApplication application] context] 
36             isAccessFromIntranet] ? NO : YES;
37 }
38
39 /* listing the available mailboxes */
40
41 - (BOOL)isInHomeFolderBranchOfLoggedInAccount:(id)_ctx {
42   id user;
43
44   if (_ctx == nil) _ctx = [[WOApplication application] context];
45   if (_ctx == nil) {
46     [self errorWithFormat:@"Missing context!"];
47     return NO;
48   }
49   
50   user = [_ctx activeUser];
51   return [[[self container] nameInContainer] isEqualToString:[user login]];
52 }
53
54 - (NSArray *)toManyRelationshipKeys {
55   WOContext *ctx;
56   id        user;
57   id        account;
58   NSArray   *shares;
59   
60   if ((ctx = [[WOApplication application] context]) == nil) {
61     [self logWithFormat:@"ERROR(%s): cannot procede without context!",
62             __PRETTY_FUNCTION__];
63     return nil;
64   }
65   
66   /*
67     Note: this is not strictly correct. The accounts being retrieved should be
68           the accounts based on the container object of this folder. Given
69           sufficient rights (eg delegation rights!), this would allow you to
70           browse the hierarchies of other users.
71           
72           But then, the home-folder would need to know about mail
73           functionality which isn't perfect either.
74           => TODO
75   */
76   user = [ctx activeUser];
77   
78   /* for now: return nothing if the home-folder does not belong to the login */
79   if (![self isInHomeFolderBranchOfLoggedInAccount:ctx]) {
80     [self warnWithFormat:@"User %@ tried to access mail hierarchy of %@",
81           [user login], [[self container] nameInContainer]];
82     return nil;
83   }
84   
85   account = [user valueForKey:@"primaryIMAP4AccountString"];
86   if ([account isNotNull]) account = [NSArray arrayWithObject:account];
87   
88   if ([self isInternetRequest]) /* only show primary mailbox in Internet */
89     return account;
90   
91   shares  = [user valueForKey:@"additionalIMAP4AccountStrings"];
92   return ([shares count] == 0)
93     ? account
94     : [account arrayByAddingObjectsFromArray:shares];
95 }
96
97 - (NSArray *)fetchIdentitiesWithOnlyEmitterAccess:(BOOL)_flag {
98   WOContext *ctx;
99   
100   if ((ctx = [[WOApplication application] context]) == nil) {
101     [self logWithFormat:@"ERROR(%s): cannot procede without context!",
102             __PRETTY_FUNCTION__];
103     return nil;
104   }
105   
106   if ([self isInternetRequest]) { /* only show primary mailbox in Internet */
107     // just return the primary identity
108     id identity;
109     
110     identity = [[ctx activeUser] primaryMailIdentity];
111     return [identity isNotNull] ? [NSArray arrayWithObject:identity] : nil;
112   }
113   
114   return [[ctx activeUser] fetchAllMailIdentitiesWithOnlyEmitterAccess:_flag];
115 }
116 - (NSArray *)fetchAllIdentities {
117   return [self fetchIdentitiesWithOnlyEmitterAccess:NO];
118 }
119 - (NSArray *)fetchIdentitiesWithEmitterPermissions {
120   return [self fetchIdentitiesWithOnlyEmitterAccess:YES];
121 }
122
123 /* name lookup */
124
125 - (BOOL)isValidMailAccountName:(NSString *)_key {
126   if ([_key length] == 0)
127     return NO;
128   
129   return YES;
130 }
131
132 - (id)mailAccountWithName:(NSString *)_key inContext:(id)_ctx {
133   static Class ctClass = Nil;
134   id ct;
135   
136   if (ctClass == Nil)
137     ctClass = NSClassFromString(@"SOGoMailAccount");
138   if (ctClass == Nil) {
139     [self errorWithFormat:@"missing SOGoMailAccount class!"];
140     return nil;
141   }
142   
143   ct = [[ctClass alloc] initWithName:_key inContainer:self];
144   return [ct autorelease];
145 }
146 - (id)sharedMailAccountWithName:(NSString *)_key inContext:(id)_ctx {
147   static Class ctClass = Nil;
148   id ct;
149   
150   if (ctClass == Nil)
151     ctClass = NSClassFromString(@"SOGoSharedMailAccount");
152   if (ctClass == Nil) {
153     [self errorWithFormat:@"missing SOGoSharedMailAccount class!"];
154     return nil;
155   }
156   
157   ct = [[ctClass alloc] initWithName:_key inContainer:self];
158   return [ct autorelease];
159 }
160
161 - (id)lookupName:(NSString *)_key inContext:(id)_ctx acquire:(BOOL)_flag {
162   id obj;
163   
164   /* first check attributes directly bound to the application */
165   if ((obj = [super lookupName:_key inContext:_ctx acquire:NO]))
166     return obj;
167   
168   if (![self isInHomeFolderBranchOfLoggedInAccount:_ctx]) {
169     [self warnWithFormat:@"User %@ tried to access mail hierarchy of %@",
170           [[_ctx activeUser] login], [[self container] nameInContainer]];
171     
172     return [NSException exceptionWithHTTPStatus:403 /* Forbidden */
173                         reason:@"Tried to access the mail of another user"];
174   }
175   
176   if ([self isValidMailAccountName:_key]) {
177     /* forbid shares for requests coming from the Internet */
178     BOOL isSharedKey;
179     
180     isSharedKey = [_key rangeOfString:AgenorShareLoginMarker].length > 0;
181     
182     if ([self isInternetRequest]) {
183       if (isSharedKey) {
184         return [NSException exceptionWithHTTPStatus:403 /* Forbidden */
185                             reason:
186                               @"Access to shares forbidden from the Internet"];
187       }
188     }
189     
190     return isSharedKey
191       ? [self sharedMailAccountWithName:_key inContext:_ctx]
192       : [self mailAccountWithName:_key inContext:_ctx];
193   }
194
195   /* return 404 to stop acquisition */
196   return [NSException exceptionWithHTTPStatus:404 /* Not Found */];
197 }
198
199 /* WebDAV */
200
201 - (BOOL)davIsCollection {
202   return YES;
203 }
204
205 @end /* SOGoMailAccounts */