]> err.no Git - scalable-opengroupware.org/blob - SoObjects/SOGo/SOGoUser.m
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1052 d1b88da0-ebda-0310...
[scalable-opengroupware.org] / SoObjects / SOGo / SOGoUser.m
1 /*
2   Copyright (C) 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 #import <Foundation/NSArray.h>
23 #import <Foundation/NSNull.h>
24 #import <Foundation/NSTimeZone.h>
25 #import <Foundation/NSUserDefaults.h>
26 #import <NGObjWeb/WOApplication.h>
27 #import <NGObjWeb/SoObject.h>
28 #import <NGExtensions/NSNull+misc.h>
29
30 #import "AgenorUserDefaults.h"
31 #import "LDAPUserManager.h"
32 #import "SOGoContentObject.h"
33 #import "SOGoUser.h"
34 #import "SOGoPermissions.h"
35
36 static NSTimeZone *serverTimeZone = nil;
37 static NSString *fallbackIMAP4Server = nil;
38 static NSURL *AgenorProfileURL = nil;
39
40 @interface NSObject (SOGoRoles)
41
42 - (NSArray *) rolesOfUser: (NSString *) uid;
43
44 @end
45
46 @implementation SOGoUser
47
48 + (void) initialize
49 {
50   NSString *tzName;
51   NSUserDefaults *ud;
52   NSString *profileURL;
53
54   ud = [NSUserDefaults standardUserDefaults];
55   if (!serverTimeZone)
56     {
57       tzName = [ud stringForKey: @"SOGoServerTimeZone"];
58       if (!tzName)
59         tzName = @"Canada/Eastern";
60       serverTimeZone = [NSTimeZone timeZoneWithName: tzName];
61       [serverTimeZone retain];
62     }
63   if (!AgenorProfileURL)
64     {
65       profileURL = [ud stringForKey: @"AgenorProfileURL"];
66       AgenorProfileURL = [[NSURL alloc] initWithString: profileURL];
67     }
68   if (!fallbackIMAP4Server)
69     ASSIGN (fallbackIMAP4Server, [ud stringForKey: @"SOGoFallbackIMAP4Server"]);
70 }
71
72 + (SOGoUser *) userWithLogin: (NSString *) login
73                        roles: (NSArray *) roles
74 {
75   SOGoUser *user;
76
77   user = [[self alloc] initWithLogin: login roles: roles];
78   [user autorelease];
79
80   return user;
81 }
82
83 - (id) init
84 {
85   if ((self = [super init]))
86     {
87       userDefaults = nil;
88       userSettings = nil;
89       allEmails = nil;
90     }
91
92   return self;
93 }
94
95 - (id) initWithLogin: (NSString *) newLogin
96                roles: (NSArray *) newRoles
97 {
98   LDAPUserManager *um;
99   NSDictionary *user;
100
101   if ([newLogin isEqualToString: @"anonymous"]
102       || [newLogin isEqualToString: @"freebusy"])
103     self = [super initWithLogin: newLogin roles: newRoles];
104   else
105     {
106       um = [LDAPUserManager sharedUserManager];
107       user = [um contactInfosForUserWithUIDorEmail: newLogin];
108       self = [super initWithLogin: [user objectForKey: @"c_uid"]
109                     roles: newRoles];
110     }
111
112   return self;
113 }
114
115 - (void) dealloc
116 {
117   [userDefaults release];
118   [userSettings release];
119   [super dealloc];
120 }
121
122 - (id) _fetchFieldForUser: (NSString *) field
123 {
124   NSDictionary *contactInfos;
125   LDAPUserManager *um;
126
127   um = [LDAPUserManager sharedUserManager];
128   contactInfos = [um contactInfosForUserWithUIDorEmail: login];
129
130   return [contactInfos objectForKey: field];
131 }
132
133 - (void) _fetchAllEmails
134 {
135   allEmails = [self _fetchFieldForUser: @"emails"];
136   [allEmails retain];
137 }
138
139 - (void) _fetchCN
140 {
141   cn = [self _fetchFieldForUser: @"cn"];
142   [cn retain];
143 }
144
145 /* properties */
146
147 - (NSString *) primaryEmail
148 {
149   if (!allEmails)
150     [self _fetchAllEmails];
151
152   return [allEmails objectAtIndex: 0];
153 }
154
155 - (NSString *) systemEmail
156 {
157   if (!allEmails)
158     [self _fetchAllEmails];
159
160   return [allEmails lastObject];
161 }
162
163 - (NSArray *) allEmails
164 {
165   if (!allEmails)
166     [self _fetchAllEmails];
167
168   return allEmails;  
169 }
170
171 - (BOOL) hasEmail: (NSString *) email
172 {
173   BOOL hasEmail;
174   NSString *currentEmail, *cmpEmail;
175   NSEnumerator *emails;
176
177   hasEmail = NO;
178   if (!allEmails)
179     [self _fetchAllEmails];
180   cmpEmail = [email lowercaseString];
181   emails = [allEmails objectEnumerator];
182   currentEmail = [emails nextObject];
183   while (currentEmail && !hasEmail)
184     if ([[currentEmail lowercaseString] isEqualToString: cmpEmail])
185       hasEmail = YES;
186     else
187       currentEmail = [emails nextObject];
188
189   return hasEmail;
190 }
191
192 - (NSString *) cn
193 {
194   if (!cn)
195     [self _fetchCN];
196
197   return cn;
198 }
199
200 - (NSString *) primaryIMAP4AccountString
201 {
202   return [NSString stringWithFormat: @"%@@%@", login, fallbackIMAP4Server];
203 }
204
205 // - (NSString *) primaryMailServer
206 // {
207 //   return [[self userManager] getServerForUID: [self login]];
208 // }
209
210 // - (NSArray *) additionalIMAP4AccountStrings
211 // {
212 //   return [[self userManager]getSharedMailboxAccountStringsForUID: [self login]];
213 // }
214
215 // - (NSArray *) additionalEMailAddresses
216 // {
217 //   return [[self userManager] getSharedMailboxEMailsForUID: [self login]];
218 // }
219
220 // - (NSDictionary *) additionalIMAP4AccountsAndEMails
221 // {
222 //   return [[self userManager] getSharedMailboxesAndEMailsForUID: [self login]];
223 // }
224
225 - (NSURL *) freeBusyURL
226 {
227   return nil;
228 }
229
230 /* defaults */
231
232 - (NSUserDefaults *) userDefaults
233 {
234   if (!userDefaults)
235     userDefaults = [[AgenorUserDefaults alloc] initWithTableURL: AgenorProfileURL
236                                                uid: login
237                                                fieldName: @"defaults"];
238
239   return userDefaults;
240 }
241
242 - (NSUserDefaults *) userSettings
243 {
244   if (!userSettings)
245     userSettings = [[AgenorUserDefaults alloc] initWithTableURL: AgenorProfileURL
246                                                uid: login
247                                                fieldName: @"settings"];
248
249   return userSettings;
250 }
251
252 - (NSTimeZone *) timeZone
253 {
254   NSString *timeZoneName;
255
256   if (!userTimeZone)
257     {
258       timeZoneName = [[self userDefaults] stringForKey: @"TimeZone"];
259       if ([timeZoneName length] > 0)
260         userTimeZone = [NSTimeZone timeZoneWithName: timeZoneName];
261       if (!userTimeZone)
262         userTimeZone = serverTimeZone;
263       [userTimeZone retain];
264     }
265
266   return userTimeZone;
267 }
268
269 - (NSTimeZone *) serverTimeZone
270 {
271   return serverTimeZone;
272 }
273
274 /* folders */
275
276 // TODO: those methods should check whether the traversal stack in the context
277 //       already contains proper folders to improve caching behaviour
278
279 - (id) homeFolderInContext: (id) _ctx
280 {
281   /* Note: watch out for cyclic references */
282   // TODO: maybe we should add an [activeUser reset] method to SOPE
283   id folder;
284   
285   folder = [(WOContext *)_ctx objectForKey:@"ActiveUserHomeFolder"];
286   if (folder != nil)
287     return [folder isNotNull] ? folder : nil;
288   
289   folder = [[WOApplication application] lookupName:[self login]
290                                         inContext:_ctx acquire:NO];
291   if ([folder isKindOfClass:[NSException class]])
292     return folder;
293   
294   [(WOContext *)_ctx setObject:folder ? folder : [NSNull null] 
295                 forKey: @"ActiveUserHomeFolder"];
296   return folder;
297 }
298
299 // - (id) schedulingCalendarInContext: (id) _ctx
300 // {
301 //   /* Note: watch out for cyclic references */
302 //   id folder;
303
304 //   folder = [(WOContext *)_ctx objectForKey:@"ActiveUserCalendar"];
305 //   if (folder != nil)
306 //     return [folder isNotNull] ? folder : nil;
307
308 //   folder = [self homeFolderInContext:_ctx];
309 //   if ([folder isKindOfClass:[NSException class]])
310 //     return folder;
311   
312 //   folder = [folder lookupName:@"Calendar" inContext:_ctx acquire:NO];
313 //   if ([folder isKindOfClass:[NSException class]])
314 //     return folder;
315   
316 //   [(WOContext *)_ctx setObject:folder ? folder : [NSNull null] 
317 //                 forKey:@"ActiveUserCalendar"];
318 //   return folder;
319 // }
320
321 - (NSArray *) rolesForObject: (NSObject *) object
322                    inContext: (WOContext *) context
323 {
324   NSMutableArray *rolesForObject;
325   NSArray *sogoRoles;
326
327   rolesForObject = [NSMutableArray new];
328   [rolesForObject autorelease];
329
330   sogoRoles = [super rolesForObject: object inContext: context];
331   if (sogoRoles)
332     [rolesForObject addObjectsFromArray: sogoRoles];
333
334   if ([[object ownerInContext: context] isEqualToString: [self login]])
335     [rolesForObject addObject: SoRole_Owner];
336   if ([object isKindOfClass: [SOGoObject class]])
337     {
338       sogoRoles = [(SOGoObject *) object aclsForUser: login];
339       if (sogoRoles)
340         [rolesForObject addObjectsFromArray: sogoRoles];
341     }
342
343   return rolesForObject;
344 }
345
346 @end /* SOGoUser */