]> err.no Git - scalable-opengroupware.org/blob - SoObjects/SOGo/SOGoUser.m
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1163 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 <Foundation/NSValue.h>
27 #import <NGObjWeb/WOApplication.h>
28 #import <NGObjWeb/WOContext.h>
29 #import <NGObjWeb/WORequest.h>
30 #import <NGObjWeb/SoObject.h>
31 #import <NGExtensions/NSNull+misc.h>
32
33 #import "AgenorUserDefaults.h"
34 #import "LDAPUserManager.h"
35 #import "SOGoDateFormatter.h"
36 #import "SOGoObject.h"
37 #import "SOGoPermissions.h"
38 #import "NSArray+Utilities.h"
39
40 #import "SOGoUser.h"
41
42 static NSTimeZone *serverTimeZone = nil;
43 static NSString *fallbackIMAP4Server = nil;
44 static NSString *defaultLanguage = nil;
45 static NSString *superUsername = nil;
46 static NSURL *AgenorProfileURL = nil;
47 static BOOL acceptAnyUser = NO;
48
49 NSString *SOGoWeekStartHideWeekNumbers = @"HideWeekNumbers";
50 NSString *SOGoWeekStartJanuary1 = @"January1";
51 NSString *SOGoWeekStartFirst4DayWeek = @"First4DayWeek";
52 NSString *SOGoWeekStartFirstFullWeek = @"FirstFullWeek";
53
54 @interface NSObject (SOGoRoles)
55
56 - (NSArray *) rolesOfUser: (NSString *) uid;
57
58 @end
59
60 @implementation SOGoUser
61
62 + (void) initialize
63 {
64   NSString *tzName, *nsUsername;
65   NSUserDefaults *ud;
66   NSString *profileURL;
67
68   ud = [NSUserDefaults standardUserDefaults];
69   if (!serverTimeZone)
70     {
71       tzName = [ud stringForKey: @"SOGoServerTimeZone"];
72       if (!tzName)
73         tzName = @"UTC";
74       serverTimeZone = [NSTimeZone timeZoneWithName: tzName];
75       [serverTimeZone retain];
76     }
77   if (!AgenorProfileURL)
78     {
79       profileURL = [ud stringForKey: @"AgenorProfileURL"];
80       AgenorProfileURL = [[NSURL alloc] initWithString: profileURL];
81     }
82   if (!fallbackIMAP4Server)
83     ASSIGN (fallbackIMAP4Server,
84             [ud stringForKey: @"SOGoFallbackIMAP4Server"]);
85   if (!defaultLanguage)
86     {
87       ASSIGN (defaultLanguage, [ud stringForKey: @"SOGoDefaultLanguage"]);
88       if (!defaultLanguage)
89         ASSIGN (defaultLanguage, @"English");
90     }
91   if (!superUsername)
92     {
93       nsUsername = [ud stringForKey: @"SOGoSuperUsername"];
94       if ([nsUsername length] > 0)
95         ASSIGN (superUsername, nsUsername);
96     }
97
98   acceptAnyUser = ([[ud stringForKey: @"SOGoAuthentificationMethod"]
99                      isEqualToString: @"bypass"]);
100 }
101
102 + (SOGoUser *) userWithLogin: (NSString *) newLogin
103                        roles: (NSArray *) newRoles
104 {
105   SOGoUser *user;
106
107   user = [[self alloc] initWithLogin: newLogin roles: newRoles];
108   [user autorelease];
109
110   return user;
111 }
112
113 - (id) init
114 {
115   if ((self = [super init]))
116     {
117       userDefaults = nil;
118       userSettings = nil;
119       allEmails = nil;
120       language = nil;
121       currentPassword = nil;
122       dateFormatter = nil;
123     }
124
125   return self;
126 }
127
128 - (id) initWithLogin: (NSString *) newLogin
129                roles: (NSArray *) newRoles
130 {
131   LDAPUserManager *um;
132   NSString *realUID;
133
134   if (acceptAnyUser
135       || [newLogin isEqualToString: @"anonymous"]
136       || [newLogin isEqualToString: @"freebusy"])
137     realUID = newLogin;
138   else
139     {
140       um = [LDAPUserManager sharedUserManager];
141       realUID = [[um contactInfosForUserWithUIDorEmail: newLogin]
142                   objectForKey: @"c_uid"];
143     }
144   self = [super initWithLogin: realUID roles: newRoles];
145
146   return self;
147 }
148
149 - (void) dealloc
150 {
151   [currentPassword release];
152   [userDefaults release];
153   [userSettings release];
154   [allEmails release];
155   [language release];
156   [dateFormatter release];
157   [super dealloc];
158 }
159
160 - (void) setCurrentPassword: (NSString *) newPassword
161 {
162   ASSIGN (currentPassword, newPassword);
163 }
164
165 - (NSString *) currentPassword
166 {
167   return currentPassword;
168 }
169
170 - (id) _fetchFieldForUser: (NSString *) field
171 {
172   NSDictionary *contactInfos;
173   LDAPUserManager *um;
174
175   um = [LDAPUserManager sharedUserManager];
176   contactInfos = [um contactInfosForUserWithUIDorEmail: login];
177
178   return [contactInfos objectForKey: field];
179 }
180
181 - (void) _fetchAllEmails
182 {
183   allEmails = [self _fetchFieldForUser: @"emails"];
184   [allEmails retain];
185 }
186
187 - (void) _fetchCN
188 {
189   cn = [self _fetchFieldForUser: @"cn"];
190   [cn retain];
191 }
192
193 /* properties */
194
195 // - (NSString *) fullEmail
196 // {
197 //   return [[LDAPUserManager sharedUserManager] getFullEmailForUID: login];
198 // }
199
200 // - (NSString *) primaryEmail
201 // {
202 //   if (!allEmails)
203 //     [self _fetchAllEmails];
204
205 //   return [allEmails objectAtIndex: 0];
206 // }
207
208 - (NSArray *) allEmails
209 {
210   if (!allEmails)
211     [self _fetchAllEmails];
212
213   return allEmails;  
214 }
215
216 - (NSString *) systemEmail
217 {
218   if (!allEmails)
219     [self _fetchAllEmails];
220
221   return [allEmails lastObject];
222 }
223
224 - (BOOL) hasEmail: (NSString *) email
225 {
226   if (!allEmails)
227     [self _fetchAllEmails];
228   
229   return [allEmails containsCaseInsensitiveString: email];
230 }
231
232 - (NSString *) cn
233 {
234   if (!cn)
235     [self _fetchCN];
236
237   return cn;
238 }
239
240 // - (NSString *) primaryMailServer
241 // {
242 //   return [[self userManager] getServerForUID: [self login]];
243 // }
244
245 // - (NSArray *) additionalIMAP4AccountStrings
246 // {
247 //   return [[self userManager]getSharedMailboxAccountStringsForUID: [self login]];
248 // }
249
250 // - (NSArray *) additionalEMailAddresses
251 // {
252 //   return [[self userManager] getSharedMailboxEMailsForUID: [self login]];
253 // }
254
255 // - (NSDictionary *) additionalIMAP4AccountsAndEMails
256 // {
257 //   return [[self userManager] getSharedMailboxesAndEMailsForUID: [self login]];
258 // }
259
260 - (NSURL *) freeBusyURL
261 {
262   return nil;
263 }
264
265 - (SOGoDateFormatter *) dateFormatterInContext: (WOContext *) context
266 {
267   NSString *format;
268   NSUserDefaults *ud;
269
270   if (!dateFormatter)
271     {
272       dateFormatter = [SOGoDateFormatter new];
273       [dateFormatter setLocale: [context valueForKey: @"locale"]];
274       ud = [self userDefaults];
275       format = [ud stringForKey: @"ShortDateFormat"];
276       if (format)
277         [dateFormatter setShortDateFormat: format];
278       format = [ud stringForKey: @"LongDateFormat"];
279       if (format)
280         [dateFormatter setLongDateFormat: format];
281       format = [ud stringForKey: @"TimeFormat"];
282       if (format)
283         [dateFormatter setTimeFormat: format];
284     }
285
286   return dateFormatter;
287 }
288
289 /* defaults */
290
291 - (NSUserDefaults *) userDefaults
292 {
293   if (!userDefaults)
294     userDefaults
295       = [[AgenorUserDefaults alloc] initWithTableURL: AgenorProfileURL
296                                     uid: login
297                                     fieldName: @"c_defaults"];
298
299   return userDefaults;
300 }
301
302 - (NSUserDefaults *) userSettings
303 {
304   if (!userSettings)
305     userSettings
306       = [[AgenorUserDefaults alloc] initWithTableURL: AgenorProfileURL
307                                     uid: login
308                                     fieldName: @"c_settings"];
309
310   return userSettings;
311 }
312
313 - (NSString *) language
314 {
315   NSArray *bLanguages;
316   WOContext *context;
317
318   if (!language)
319     {
320       language = [[self userDefaults] stringForKey: @"Language"];
321       if (![language length])
322         {
323           context = [[WOApplication application] context];
324           bLanguages = [[context request] browserLanguages];
325           if ([bLanguages count] > 0)
326             language = [bLanguages objectAtIndex: 0];
327         }
328       if (![language length])
329         language = defaultLanguage;
330       [language retain];
331     }
332
333   return language;
334 }
335
336 - (NSTimeZone *) timeZone
337 {
338   NSString *timeZoneName;
339
340   if (!userTimeZone)
341     {
342       timeZoneName = [[self userDefaults] stringForKey: @"TimeZone"];
343       if ([timeZoneName length] > 0)
344         userTimeZone = [NSTimeZone timeZoneWithName: timeZoneName];
345       if (!userTimeZone)
346         userTimeZone = serverTimeZone;
347       [userTimeZone retain];
348     }
349
350   return userTimeZone;
351 }
352
353 - (NSTimeZone *) serverTimeZone
354 {
355   return serverTimeZone;
356 }
357
358 /* mail */
359 - (NSArray *) mailAccounts
360 {
361 #warning should be implemented with the user defaults interfaces
362   NSMutableDictionary *mailAccount, *identity;
363   NSMutableArray *identities;
364   NSString *name, *fullName;
365
366   if (!mailAccounts)
367     {
368       mailAccount = [NSMutableDictionary dictionary];
369       name = [NSString stringWithFormat: @"%@@%@", login, fallbackIMAP4Server];
370       [mailAccount setObject: login forKey: @"userName"];
371       [mailAccount setObject: fallbackIMAP4Server forKey: @"serverName"];
372       [mailAccount setObject: name forKey: @"name"];
373
374       identity = [NSMutableDictionary dictionary];
375       fullName = [self cn];
376       if (![fullName length])
377         fullName = login;
378       [identity setObject: fullName forKey: @"fullName"];
379       [identity setObject: [self systemEmail] forKey: @"email"];
380       [identity setObject: [NSNumber numberWithBool: YES] forKey: @"isDefault"];
381
382       identities = [NSMutableArray array];
383       [identities addObject: identity];
384       [mailAccount setObject: identities forKey: @"identities"];
385
386       mailAccounts = [NSMutableArray new];
387       [mailAccounts addObject: mailAccount];
388     }
389
390   return mailAccounts;
391 }
392
393 /*
394 @interface SOGoMailIdentity : NSObject
395 {
396   NSString *name;
397   NSString *email;
398   NSString *replyTo;
399   NSString *organization;
400   NSString *signature;
401   NSString *vCard;
402   NSString *sentFolderName;
403   NSString *sentBCC;
404   NSString *draftsFolderName;
405   NSString *templatesFolderName;
406   struct
407   {
408     int composeHTML:1;
409     int reserved:31;
410   } idFlags;
411 }
412
413 - (void) setName: (NSString *) _value;
414 - (NSString *) name;
415
416 - (void) setEmail: (NSString *) _value;
417 - (NSString *) email;
418
419 - (void) setReplyTo: (NSString *) _value;
420 - (NSString *) replyTo;
421
422 - (void) setOrganization: (NSString *) _value;
423 - (NSString *) organization;
424
425 - (void) setSignature: (NSString *) _value;
426 - (NSString *) signature;
427 - (BOOL) hasSignature;
428
429 - (void) setVCard: (NSString *) _value;
430 - (NSString *) vCard;
431 - (BOOL) hasVCard;
432
433 - (void) setSentFolderName: (NSString *) _value;
434 - (NSString *) sentFolderName;
435
436 - (void) setSentBCC: (NSString *) _value;
437 - (NSString *) sentBCC;
438
439 - (void) setDraftsFolderName: (NSString *) _value;
440 - (NSString *) draftsFolderName;
441
442 - (void) setTemplatesFolderName: (NSString *) _value;
443 - (NSString *) templatesFolderName;
444
445 @end */
446
447 - (NSArray *) allIdentities
448 {
449   NSArray *identities;
450
451   [self mailAccounts];
452   identities = [mailAccounts objectsForKey: @"identities"];
453
454   return [identities flattenedArray];
455 }
456
457 - (NSDictionary *) primaryIdentity
458 {
459   NSDictionary *defaultAccount;
460
461   [self mailAccounts];
462   defaultAccount = [mailAccounts objectAtIndex: 0];
463
464   return [[defaultAccount objectForKey: @"identities"] objectAtIndex: 0];
465 }
466
467 - (NSString *) messageForwarding
468 {
469   NSString *messageForwarding;
470
471   messageForwarding
472     = [[self userDefaults] stringForKey: @"MessageForwarding"];
473   if (![messageForwarding length])
474     messageForwarding = @"attached";
475
476   return messageForwarding;
477 }
478
479 /* folders */
480
481 // TODO: those methods should check whether the traversal stack in the context
482 //       already contains proper folders to improve caching behaviour
483
484 - (id) homeFolderInContext: (id) _ctx
485 {
486   /* Note: watch out for cyclic references */
487   // TODO: maybe we should add an [activeUser reset] method to SOPE
488   id folder;
489   
490   folder = [(WOContext *)_ctx objectForKey:@"ActiveUserHomeFolder"];
491   if (folder != nil)
492     return [folder isNotNull] ? folder : nil;
493   
494   folder = [[WOApplication application] lookupName: [self login]
495                                         inContext: _ctx
496                                         acquire: NO];
497   if ([folder isKindOfClass:[NSException class]])
498     return folder;
499   
500   [(WOContext *)_ctx setObject: ((folder)
501                                  ? folder
502                                  : [NSNull null])
503                 forKey: @"ActiveUserHomeFolder"];
504   return folder;
505 }
506
507 // - (id) schedulingCalendarInContext: (id) _ctx
508 // {
509 //   /* Note: watch out for cyclic references */
510 //   id folder;
511
512 //   folder = [(WOContext *)_ctx objectForKey:@"ActiveUserCalendar"];
513 //   if (folder != nil)
514 //     return [folder isNotNull] ? folder : nil;
515
516 //   folder = [self homeFolderInContext:_ctx];
517 //   if ([folder isKindOfClass:[NSException class]])
518 //     return folder;
519   
520 //   folder = [folder lookupName:@"Calendar" inContext:_ctx acquire:NO];
521 //   if ([folder isKindOfClass:[NSException class]])
522 //     return folder;
523   
524 //   [(WOContext *)_ctx setObject:folder ? folder : [NSNull null] 
525 //                 forKey:@"ActiveUserCalendar"];
526 //   return folder;
527 // }
528
529 - (NSArray *) rolesForObject: (NSObject *) object
530                    inContext: (WOContext *) context
531 {
532   NSMutableArray *rolesForObject;
533   NSArray *sogoRoles;
534
535   rolesForObject = [NSMutableArray new];
536   [rolesForObject autorelease];
537
538   sogoRoles = [super rolesForObject: object inContext: context];
539   if (sogoRoles)
540     [rolesForObject addObjectsFromArray: sogoRoles];
541
542   if ((superUsername && [login isEqualToString: superUsername])
543       || [[object ownerInContext: context] isEqualToString: login])
544     [rolesForObject addObject: SoRole_Owner];
545   if ([object isKindOfClass: [SOGoObject class]])
546     {
547       sogoRoles = [(SOGoObject *) object aclsForUser: login];
548       if (sogoRoles)
549         [rolesForObject addObjectsFromArray: sogoRoles];
550     }
551
552   return rolesForObject;
553 }
554
555 @end /* SOGoUser */