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