]> err.no Git - scalable-opengroupware.org/blob - SoObjects/Mailer/SOGoMailAccounts.m
initial sync
[scalable-opengroupware.org] / 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
117 - (NSArray *)fetchAllIdentities {
118   return [self fetchIdentitiesWithOnlyEmitterAccess:NO];
119 }
120
121 - (NSArray *)fetchIdentitiesWithEmitterPermissions {
122   return [self fetchIdentitiesWithOnlyEmitterAccess:YES];
123 }
124
125 /* name lookup */
126
127 - (BOOL)isValidMailAccountName:(NSString *)_key {
128   if ([_key length] == 0)
129     return NO;
130   
131   return YES;
132 }
133
134 - (id)mailAccountWithName:(NSString *)_key inContext:(id)_ctx {
135   static Class ctClass = Nil;
136   id ct;
137   
138   if (ctClass == Nil)
139     ctClass = NSClassFromString(@"SOGoMailAccount");
140   if (ctClass == Nil) {
141     [self errorWithFormat:@"missing SOGoMailAccount class!"];
142     return nil;
143   }
144   
145   ct = [[ctClass alloc] initWithName:_key inContainer:self];
146   return [ct autorelease];
147 }
148
149 - (id)sharedMailAccountWithName:(NSString *)_key inContext:(id)_ctx {
150   static Class ctClass = Nil;
151   id ct;
152   
153   if (ctClass == Nil)
154     ctClass = NSClassFromString(@"SOGoSharedMailAccount");
155   if (ctClass == Nil) {
156     [self errorWithFormat:@"missing SOGoSharedMailAccount class!"];
157     return nil;
158   }
159   
160   ct = [[ctClass alloc] initWithName:_key inContainer:self];
161   return [ct autorelease];
162 }
163
164 - (id)lookupName:(NSString *)_key inContext:(id)_ctx acquire:(BOOL)_flag {
165   id obj;
166   
167   /* first check attributes directly bound to the application */
168   if ((obj = [super lookupName:_key inContext:_ctx acquire:NO]))
169     return obj;
170   
171   if (![self isInHomeFolderBranchOfLoggedInAccount:_ctx]) {
172     [self warnWithFormat:@"User %@ tried to access mail hierarchy of %@",
173           [[_ctx activeUser] login], [[self container] nameInContainer]];
174     
175     return [NSException exceptionWithHTTPStatus:403 /* Forbidden */
176                         reason:@"Tried to access the mail of another user"];
177   }
178   
179   if ([self isValidMailAccountName:_key]) {
180     /* forbid shares for requests coming from the Internet */
181     BOOL isSharedKey;
182     
183     isSharedKey = [_key rangeOfString:AgenorShareLoginMarker].length > 0;
184     
185     if ([self isInternetRequest]) {
186       if (isSharedKey) {
187         return [NSException exceptionWithHTTPStatus:403 /* Forbidden */
188                             reason:
189                               @"Access to shares forbidden from the Internet"];
190       }
191     }
192     
193     return isSharedKey
194       ? [self sharedMailAccountWithName:_key inContext:_ctx]
195       : [self mailAccountWithName:_key inContext:_ctx];
196   }
197
198   /* return 404 to stop acquisition */
199   return [NSException exceptionWithHTTPStatus:404 /* Not Found */];
200 }
201
202 /* WebDAV */
203
204 - (BOOL)davIsCollection {
205   return YES;
206 }
207
208 @end /* SOGoMailAccounts */