1 /* UIxContactFoldersView.m - this file is part of SOGo
3 * Copyright (C) 2006 Inverse groupe conseil
5 * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
7 * This file is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
12 * This file is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; see the file COPYING. If not, write to
19 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
23 #import <Foundation/NSString.h>
25 #import <NGObjWeb/NSException+HTTP.h>
26 #import <NGObjWeb/SoObject.h>
27 #import <NGObjWeb/WOResponse.h>
28 #import <NGObjWeb/WOContext.h>
30 #import <GDLContentStore/GCSFolder.h>
31 #import <GDLContentStore/GCSFolderManager.h>
33 #import <SoObjects/SOGo/SOGoUser.h>
34 #import <SoObjects/SOGo/NSString+Utilities.h>
35 #import <SoObjects/Contacts/SOGoContactFolders.h>
36 #import <SoObjects/Contacts/SOGoContactFolder.h>
37 #import <SoObjects/Contacts/SOGoContactGCSFolder.h>
38 #import <SoObjects/Contacts/SOGoContactLDAPFolder.h>
42 #import "UIxContactFoldersView.h"
44 @implementation UIxContactFoldersView
46 - (id) _selectActionForApplication: (NSString *) actionName
48 SOGoContactFolders *folders;
49 NSString *url, *action;
52 folders = [self clientObject];
53 action = [NSString stringWithFormat: @"../%@/%@",
54 [folders defaultSourceName],
57 request = [[self context] request];
59 url = [[request uri] composeURLWithAction: action
60 parameters: [self queryParameters]
63 return [self redirectToLocation: url];
68 return [self _selectActionForApplication: @"view"];
73 return [self _selectActionForApplication: @"new"];
76 - (id <WOActionResults>) newAbAction
78 id <WOActionResults> response;
81 name = [self queryParameterForKey: @"name"];
82 if ([name length] > 0)
83 response = [[self clientObject] newFolderWithName: name];
85 response = [NSException exceptionWithHTTPStatus: 400
86 reason: @"The name is missing"];
91 - (id) selectForMailerAction
93 return [self _selectActionForApplication: @"mailer-contacts"];
96 - (NSArray *) _searchResults: (NSString *) contact
97 ldapFoldersOnly: (BOOL) ldapFoldersOnly
99 NSMutableArray *results;
100 SOGoContactFolders *topFolder;
101 NSEnumerator *sogoContactFolders;
102 id <SOGoContactFolder> currentFolder;
104 results = [NSMutableArray new];
105 [results autorelease];
107 topFolder = [self clientObject];
108 sogoContactFolders = [[topFolder contactFolders] objectEnumerator];
109 currentFolder = [sogoContactFolders nextObject];
110 while (currentFolder)
113 || [currentFolder isKindOfClass: [SOGoContactLDAPFolder class]])
114 [results addObjectsFromArray: [currentFolder
115 lookupContactsWithFilter: contact
117 ordering: NSOrderedAscending]];
118 currentFolder = [sogoContactFolders nextObject];
125 - (NSString *) _emailForResult: (NSDictionary *) result
127 NSMutableString *email;
128 NSString *name, *mail;
130 email = [NSMutableString string];
131 name = [result objectForKey: @"displayName"];
133 name = [result objectForKey: @"cn"];
134 mail = [result objectForKey: @"mail"];
136 [email appendFormat: @"%@ <%@>", name, mail];
138 [email appendString: mail];
143 - (NSDictionary *) _nextResultWithUid: (NSEnumerator *) results
145 NSDictionary *result, *possibleResult;
148 possibleResult = [results nextObject];
149 while (possibleResult && !result)
150 if ([[possibleResult objectForKey: @"c_uid"] length])
151 result = possibleResult;
153 possibleResult = [results nextObject];
158 - (WOResponse *) _responseForResults: (NSArray *) results
160 WOResponse *response;
161 NSString *email, *responseString, *uid;
162 NSDictionary *result;
164 response = [context response];
168 result = [self _nextResultWithUid: [results objectEnumerator]];
170 result = [results objectAtIndex: 0];
171 email = [self _emailForResult: result];
172 uid = [result objectForKey: @"c_uid"];
173 if ([uid length] == 0)
175 responseString = [NSString stringWithFormat: @"%@:%@",
177 [response setStatus: 200];
178 [response setHeader: @"text/plain; charset=iso-8859-1"
179 forKey: @"Content-Type"];
180 [response appendContentString: responseString];
183 [response setStatus: 404];
188 - (id <WOActionResults>) contactSearchAction
191 id <WOActionResults> result;
192 BOOL ldapFoldersOnly;
194 contact = [self queryParameterForKey: @"search"];
195 ldapFoldersOnly = [[self queryParameterForKey: @"ldap-only"] boolValue];
196 if ([contact length] > 0)
198 = [self _responseForResults: [self _searchResults: contact
199 ldapFoldersOnly: ldapFoldersOnly]];
201 result = [NSException exceptionWithHTTPStatus: 400
202 reason: @"missing 'search' parameter"];
207 - (NSArray *) _gcsFoldersFromFolder: (SOGoContactFolders *) contactFolders
209 NSMutableArray *gcsFolders;
210 NSEnumerator *contactSubfolders;
211 SOGoContactGCSFolder *currentContactFolder;
212 NSString *folderName, *displayName;
213 NSMutableDictionary *currentDictionary;
215 gcsFolders = [NSMutableArray new];
216 [gcsFolders autorelease];
218 contactSubfolders = [[contactFolders contactFolders] objectEnumerator];
219 currentContactFolder = [contactSubfolders nextObject];
220 while (currentContactFolder)
222 if ([currentContactFolder
223 isKindOfClass: [SOGoContactGCSFolder class]])
225 folderName = [NSString stringWithFormat: @"/Contacts/%@",
226 [currentContactFolder nameInContainer]];
227 currentDictionary = [NSMutableDictionary new];
228 [currentDictionary autorelease];
229 displayName = [[currentContactFolder ocsFolder] folderName];
230 [currentDictionary setObject: displayName forKey: @"displayName"];
231 [currentDictionary setObject: folderName forKey: @"name"];
232 [currentDictionary setObject: @"contact" forKey: @"type"];
233 [gcsFolders addObject: currentDictionary];
235 currentContactFolder = [contactSubfolders nextObject];
241 - (NSArray *) _foldersForUID: (NSString *) uid
242 ofType: (NSString *) folderType
244 NSObject *topFolder, *userFolder;
245 SOGoContactFolders *contactFolders;
246 NSMutableArray *folders;
247 NSMutableDictionary *currentDictionary;
249 folders = [NSMutableArray new];
250 [folders autorelease];
252 topFolder = [[[self clientObject] container] container];
253 userFolder = [topFolder lookupName: uid inContext: context acquire: NO];
255 /* FIXME: should be moved in the SOGo* classes. Maybe by having a SOGoFolderManager. */
256 #warning this might need adjustments whenever we permit multiple calendar folders per-user
257 if ([folderType length] == 0 || [folderType isEqualToString: @"calendar"])
259 currentDictionary = [NSMutableDictionary new];
260 [currentDictionary autorelease];
261 [currentDictionary setObject: [self labelForKey: @"Calendar"]
262 forKey: @"displayName"];
263 [currentDictionary setObject: @"/Calendar" forKey: @"name"];
264 [currentDictionary setObject: @"calendar" forKey: @"type"];
265 [folders addObject: currentDictionary];
267 if ([folderType length] == 0 || [folderType isEqualToString: @"contact"])
269 contactFolders = [userFolder lookupName: @"Contacts"
270 inContext: context acquire: NO];
272 addObjectsFromArray: [self _gcsFoldersFromFolder: contactFolders]];
278 - (NSString *) _foldersStringForFolders: (NSEnumerator *) folders
280 NSMutableString *foldersString;
281 NSDictionary *currentFolder;
283 foldersString = [NSMutableString new];
284 [foldersString autorelease];
286 currentFolder = [folders nextObject];
287 while (currentFolder)
289 [foldersString appendFormat: @";%@:%@:%@",
290 [currentFolder objectForKey: @"displayName"],
291 [currentFolder objectForKey: @"name"],
292 [currentFolder objectForKey: @"type"]];
293 currentFolder = [folders nextObject];
296 return foldersString;
299 - (WOResponse *) _foldersResponseForResults: (NSArray *) results
300 withType: (NSString *) folderType
302 WOResponse *response;
303 NSString *uid, *foldersString;
304 NSMutableString *responseString;
305 NSDictionary *result;
306 NSEnumerator *resultsEnum;
309 response = [context response];
313 [response setStatus: 200];
314 [response setHeader: @"text/plain; charset=iso-8859-1"
315 forKey: @"Content-Type"];
317 responseString = [NSMutableString new];
318 resultsEnum = [results objectEnumerator];
319 result = [resultsEnum nextObject];
322 uid = [result objectForKey: @"c_uid"];
323 folders = [self _foldersForUID: uid ofType: folderType];
325 = [self _foldersStringForFolders: [folders objectEnumerator]];
326 [responseString appendFormat: @"%@:%@%@\n",
327 uid, [self _emailForResult: result], foldersString];
328 result = [resultsEnum nextObject];
330 [response appendContentString: responseString];
331 [responseString release];
334 [response setStatus: 404];
339 - (id <WOActionResults>) foldersSearchAction
341 NSString *contact, *folderType;
342 id <WOActionResults> result;
345 contact = [self queryParameterForKey: @"search"];
346 if ([contact length] > 0)
348 ldapOnly = [[self queryParameterForKey: @"ldap-only"] boolValue];
349 folderType = [self queryParameterForKey: @"type"];
350 result = [self _foldersResponseForResults:
351 [self _searchResults: contact
352 ldapFoldersOnly: ldapOnly]
353 withType: folderType];
356 result = [NSException exceptionWithHTTPStatus: 400
357 reason: @"missing 'search' parameter"];
362 - (SOGoContactGCSFolder *) contactFolderForUID: (NSString *) uid
364 SOGoFolder *upperContainer;
365 SOGoUserFolder *userFolder;
366 SOGoContactFolders *contactFolders;
367 SOGoContactGCSFolder *contactFolder;
368 SoSecurityManager *securityManager;
370 upperContainer = [[[self clientObject] container] container];
371 userFolder = [SOGoUserFolder objectWithName: uid
372 inContainer: upperContainer];
373 contactFolders = [SOGoContactFolders objectWithName: @"Contacts"
374 inContainer: userFolder];
375 contactFolder = [SOGoContactGCSFolder objectWithName: @"personal"
376 inContainer: contactFolders];
378 setOCSPath: [NSString stringWithFormat: @"/Users/%@/Contacts/personal", uid]];
379 [contactFolder setOwner: uid];
381 securityManager = [SoSecurityManager sharedSecurityManager];
383 return (([securityManager validatePermission: SoPerm_AccessContentsInformation
384 onObject: contactFolder
385 inContext: context] == nil)
386 ? contactFolder : nil);