2 Copyright (C) 2000-2005 SKYRIX Software AG
4 This file is part of SOPE.
6 SOPE 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
11 SOPE 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.
16 You should have received a copy of the GNU Lesser General Public
17 License along with SOPE; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 #include "iCalPortalUser.h"
23 #include "iCalPortalDatabase.h"
24 #include "iCalPortalCalendar.h"
27 @implementation iCalPortalUser
29 - (id)initWithDatabase:(iCalPortalDatabase *)_db {
34 if ((self = [super init])) {
35 self->database = [_db retain];
37 if ((self->fileManager = [[_db fileManager] retain]) == nil) {
45 - (id)initWithPath:(NSString *)_path
46 login:(NSString *)_login
47 database:(iCalPortalDatabase *)_db;
49 if ((self = [self initWithDatabase:_db])) {
50 self->path = [_path copy];
51 self->login = [_login copy];
64 return [self initWithDatabase:nil];
68 [self->firstName release];
69 [self->lastName release];
70 [self->street release];
72 [self->email release];
73 [self->address release];
74 [self->country release];
75 [self->phone release];
76 [self->state release];
78 [self->wantIcalNews release];
79 [self->wantSkyrixNews release];
81 [self->login release];
82 [self->fileManager release];
83 [self->database release];
90 - (iCalPortalDatabase *)database {
91 return self->database;
94 - (void)setFirstName:(NSString *)_value {
95 ASSIGN(self->firstName, _value);
97 - (NSString *)firstName {
98 return self->firstName;
101 - (void)setLastName:(NSString *)_value {
102 ASSIGN(self->lastName, _value);
104 - (NSString *)lastName {
105 return self->lastName;
108 - (void)setStreet:(NSString *)_value {
109 ASSIGN(self->street, _value);
111 - (NSString *)street {
115 - (void)setCity:(NSString *)_value {
116 ASSIGN(self->city, _value);
122 - (void)setEmail:(NSString *)_value {
123 ASSIGN(self->email, _value);
125 - (NSString *)email {
129 - (void)setLogin:(NSString *)_login {
130 /* do not allow login change via KVC ! ... */
132 - (NSString *)login {
136 - (void)setAddress:(NSString *)_value {
137 ASSIGN(self->address, _value);
139 - (NSString *)address {
140 return self->address;
142 - (void)setCountry:(NSString *)_value {
143 ASSIGN(self->country, _value);
145 - (NSString *)country {
146 return self->country;
148 - (void)setPhone:(NSString *)_value {
149 ASSIGN(self->phone, _value);
151 - (NSString *)phone {
154 - (void)setState:(NSString *)_value {
155 ASSIGN(self->state, _value);
157 - (NSString *)state {
160 - (void)setZip:(NSString *)_value {
161 ASSIGN(self->zip, _value);
167 - (void)setWantIcalNews:(NSString *)_value {
168 ASSIGN(self->wantIcalNews, _value);
170 - (NSString *)wantIcalNews {
171 return self->wantIcalNews;
173 - (void)setWantSkyrixNews:(NSString *)_value {
174 ASSIGN(self->wantSkyrixNews, _value);
176 - (NSString *)wantSkyrixNews {
177 return self->wantSkyrixNews;
180 /* do not store password in process ! ... */
182 - (void)setPassword:(NSString *)_value {
184 - (NSString *)password {
187 - (void)setCryptedPassword:(NSString *)_value {
189 - (NSString *)cryptedPassword {
195 - (NSDictionary *)accountDictionary {
199 if ([self->path length] < 4) {
200 [self logWithFormat:@"tried to read an account which has no path ..."];
204 p = [self->path stringByAppendingPathComponent:@".account.plist"];
206 if ((d = [NSDictionary dictionaryWithContentsOfFile:p]) == nil) {
207 [self logWithFormat:@"couldn't load dictionary of account (%@) ...", p];
217 if ((d = [self accountDictionary]) == nil)
220 [self takeValuesFromDictionary:d];
228 /* password checking */
230 - (BOOL)authenticate:(NSString *)_pwd {
234 if ([_pwd length] < 4)
237 if ((d = [self accountDictionary]) == nil)
240 if ((tmp = [d objectForKey:@"cryptedPassword"]))
241 return [_pwd compareWithCryptedString:tmp];
243 if ((tmp = [d objectForKey:@"password"])) {
244 if ([tmp isEqualToString:_pwd]) {
245 [self logWithFormat:@"authenticated account."];
248 [self logWithFormat:@"got invalid password for account"];
257 - (BOOL)containsUnsafeChars:(NSString *)_path {
258 /* check for dangerous stuff ... */
261 if ([_path hasPrefix:@"."]) return YES;
263 r = [_path rangeOfString:@".."];
264 if (r.length > 0) return YES;
265 r = [_path rangeOfString:@"/"];
266 if (r.length > 0) return YES;
267 r = [_path rangeOfString:@"~"];
268 if (r.length > 0) return YES;
269 r = [_path rangeOfString:@"\\"];
270 if (r.length > 0) return YES;
275 - (NSString *)cleanupCalendarPath:(NSString *)_path {
276 static NSArray *validExts = nil;
280 if (validExts == nil) {
281 validExts = [[NSArray alloc] initWithObjects:
282 @"ics", @"vfb", @"ifb",
283 @"ical", @"cal", nil];
286 if ((calName = [_path lastPathComponent]) == nil)
289 ext = [calName pathExtension];
291 if ([ext length] == 0) {
292 calName = [calName stringByAppendingPathComponent:@"ics"];
294 else if (![validExts containsObject:ext]) {
295 [self logWithFormat:@"invalid calendar extension '%@': %@", ext, _path];
299 if ([self containsUnsafeChars:calName])
302 return [self->path stringByAppendingPathComponent:calName];
305 - (NSException *)invalidPathException:(NSString *)_path {
306 return [NSException exceptionWithName:@"InvalidCalendarPath"
307 reason:@"got an invalid calendar path ..."
311 - (iCalPortalCalendar *)calendarAtPath:(NSString *)_path {
314 iCalPortalCalendar *cal;
316 if ((calpath = [self cleanupCalendarPath:_path]) == nil)
319 if (![self->fileManager fileExistsAtPath:calpath isDirectory:&isDir]) {
320 [self debugWithFormat:@" cal '%@' does not exist ...", _path];
324 [self logWithFormat:@" calpath is a directory: %@ !", calpath];
328 cal = [[iCalPortalCalendar alloc] initWithUser:self path:calpath];
329 if (cal == nil) return nil;
331 return [cal autorelease];
333 - (EODataSource *)dataSourceAtPath:(NSString *)_path {
334 iCalPortalCalendar *cal;
336 if ((cal = [self calendarAtPath:_path]) == nil)
338 return [cal dataSource];
341 - (NSException *)deleteCalendarWithPath:(NSString *)_path {
345 if ((calpath = [self cleanupCalendarPath:_path]) == nil)
346 return [self invalidPathException:_path];
348 [self debugWithFormat:@"delete calendar: %@", calpath];
350 if (![self->fileManager fileExistsAtPath:calpath isDirectory:&isDir]) {
351 [self debugWithFormat:@" cal does not exist ..."];
355 [self logWithFormat:@" calpath to be deleted is a directory: %@ !",
360 /* go on, delete ... */
361 if (![self->fileManager removeFileAtPath:calpath handler:nil]) {
362 [self logWithFormat:@" failed to delete calendar %@", path];
363 return [NSException exceptionWithName:@"DeleteError"
364 reason:@"reason unknown"
371 - (NSException *)writeICalendarData:(NSData *)_data toCalendar:(NSString *)_path{
374 if ((calpath = [self cleanupCalendarPath:_path]) == nil)
375 return [self invalidPathException:_path];
377 [self debugWithFormat:@"upload calendar data: %@, size %i",
378 calpath, [_data length]];
380 if (![_data writeToFile:calpath atomically:YES]) {
381 [self logWithFormat:@" failed to write calendar of size %i to path %@",
382 [_data length], calpath];
383 return [NSException exceptionWithName:@"WriteError"
384 reason:@"reason unknown"
391 - (NSArray *)calendarNames {
392 NSAutoreleasePool *pool;
395 NSMutableArray *md = nil;
397 e = [[self->fileManager directoryContentsAtPath:self->path]
400 pool = [[NSAutoreleasePool alloc] init];
402 while ((filename = [e nextObject])) {
403 iCalPortalCalendar *cal;
405 if ([self containsUnsafeChars:filename]) continue;
407 if ((cal = [self calendarAtPath:filename]) == nil)
411 md = [[NSMutableArray alloc] initWithCapacity:16];
413 [md addObject:filename];
416 [md sortUsingSelector:@selector(compare:)];
419 return [md autorelease];
421 - (NSDictionary *)calendars {
424 NSMutableDictionary *md = nil;
426 e = [[self->fileManager directoryContentsAtPath:self->path]
429 while ((filename = [e nextObject])) {
430 iCalPortalCalendar *cal;
432 if ([self containsUnsafeChars:filename]) continue;
434 if ((cal = [self calendarAtPath:filename]) == nil)
438 md = [[NSMutableDictionary alloc] init];
440 [md setObject:cal forKey:filename];
447 - (BOOL)isDebuggingEnabled {
450 - (NSString *)loggingPrefix {
451 return [NSString stringWithFormat:@"[user:%@]",
452 self->login ? self->login : @"<new>"];
455 - (NSString *)description {
458 s = [NSMutableString stringWithCapacity:128];
459 [s appendFormat:@"<0x%08X[%@]: ", self, NSStringFromClass([self class])];
460 [s appendFormat:@" login=%@", self->login];
461 [s appendFormat:@" path=%@", self->path];
462 [s appendString:@">"];
467 @end /* iCalPortalUser */