1/* UIxUserRightsEditor.m - this file is part of SOGo
2 *
3 * Copyright (C) 2007-2015 Inverse inc.
4 *
5 * This file is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This file is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; see the file COPYING.  If not, write to
17 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
19 */
20
21
22#import <NGObjWeb/NSException+HTTP.h>
23#import <NGObjWeb/WOApplication.h>
24#import <NGObjWeb/WOResponse.h>
25#import <NGObjWeb/WORequest.h>
26
27#import <SOGo/NSDictionary+Utilities.h>
28#import <SOGo/NSString+Utilities.h>
29#import <SOGo/SOGoDomainDefaults.h>
30#import <SOGo/SOGoUser.h>
31#import <SOGo/SOGoUserManager.h>
32
33#import <UI/SOGoUI/SOGoACLAdvisory.h>
34
35#import "UIxUserRightsEditor.h"
36
37@implementation UIxUserRightsEditor
38
39- (id) init
40{
41  if ((self = [super init]))
42    {
43      uid = nil;
44      userRights = [NSMutableArray new];
45      defaultUserID = nil;
46    }
47
48  return self;
49}
50
51- (void) dealloc
52{
53  [uid release];
54  [userRights release];
55  [defaultUserID release];
56  [super dealloc];
57}
58
59- (void) setUid: (NSString *) _uid
60{
61  ASSIGNCOPY (self->uid, _uid);
62}
63
64- (NSString *) uid
65{
66  return uid;
67}
68
69- (NSString *) folderName
70{
71  id folder;
72
73  folder = [context clientObject];
74
75  return [folder displayName];
76}
77
78- (BOOL) userIsDefaultUser
79{
80  if (!defaultUserID)
81    ASSIGN (defaultUserID, [[self clientObject] defaultUserID]);
82
83  return [uid isEqualToString: defaultUserID];
84}
85
86- (BOOL) userIsAnonymousUser
87{
88  return [uid isEqualToString: @"anonymous"];
89}
90
91- (NSString *) userDisplayName
92{
93  NSDictionary *infos;
94  SOGoUserManager *um;
95
96  if ([self userIsAnonymousUser])
97    {
98      return [self labelForKey: @"Public Access"];
99    }
100  else if ([self userIsDefaultUser])
101    {
102      return [self labelForKey: @"Any Authenticated User"];
103    }
104  else
105    {
106      um = [SOGoUserManager sharedUserManager];
107      infos = [um contactInfosForUserWithUIDorEmail: uid inDomain: [[context activeUser] domain]];
108      if (infos)
109        {
110          return [NSString stringWithFormat: @"%@ <%@>",
111                        [infos objectForKey: @"cn"],
112                        [infos objectForKey: @"c_email"]];
113        }
114      else
115        return uid;
116    }
117}
118
119- (BOOL) _initRights
120{
121  BOOL response;
122  NSString *newUID;
123  SOGoUserManager *um;
124  SOGoObject *clientObject;
125  NSDictionary *dict;
126
127  response = NO;
128
129  newUID = [[context request] formValueForKey: @"uid"];
130  if ([newUID length] > 0)
131    {
132      if (!defaultUserID)
133        ASSIGN (defaultUserID, [[self clientObject] defaultUserID]);
134
135      um = [SOGoUserManager sharedUserManager];
136      if ([newUID isEqualToString: defaultUserID]
137          || [newUID isEqualToString: @"anonymous"]
138          || [[um getEmailForUID: newUID] length] > 0)
139        {
140          if (![newUID hasPrefix: @"@"])
141            {
142              dict = [[SOGoUserManager sharedUserManager] contactInfosForUserWithUIDorEmail: newUID];
143              if (dict && [[dict objectForKey: @"isGroup"] boolValue])
144                newUID = [NSString stringWithFormat: @"@%@", newUID];
145            }
146          ASSIGN (uid, newUID);
147          clientObject = [self clientObject];
148          [userRights addObjectsFromArray: [clientObject aclsForUser: uid]];
149
150          response = YES;
151        }
152    }
153
154  return response;
155}
156- (BOOL) _initRightsForUserID:(NSString *) newUID
157{
158  BOOL response;
159  SOGoUserManager *um;
160  SOGoObject *clientObject;
161  NSDictionary *dict;
162
163  response = NO;
164
165  if ([newUID length] > 0)
166    {
167      if (!defaultUserID)
168        ASSIGN (defaultUserID, [[self clientObject] defaultUserID]);
169
170      um = [SOGoUserManager sharedUserManager];
171      if ([newUID isEqualToString: defaultUserID] || [newUID isEqualToString: @"anonymous"]
172                                                  || [[um getEmailForUID: newUID] length] > 0)
173        {
174#warning Duplicated code from _initRights
175          if (![newUID hasPrefix: @"@"])
176            {
177              dict = [[SOGoUserManager sharedUserManager] contactInfosForUserWithUIDorEmail: newUID];
178              if (dict && [[dict objectForKey: @"isGroup"] boolValue])
179                newUID = [NSString stringWithFormat: @"@%@", newUID];
180            }
181          ASSIGN (uid, newUID);
182          clientObject = [self clientObject];
183          [userRights addObjectsFromArray: [clientObject aclsForUser: uid]];
184
185          response = YES;
186        }
187    }
188  return response;
189}
190
191/**
192 * @api {get} /so/:username/:folderPath/userRights?uid=:uid Get user's rights
193 * @apiVersion 1.0.0
194 * @apiName GetUserRights
195 * @apiGroup Common
196 * @apiExample {curl} Example usage:
197 *     curl -i http://localhost/SOGo/so/sogo1/Calendar/personal/userRights?uid=sogo2
198 *
199 * @apiSuccess (Success 200) {String} [Public]            Calendar: either None, DAndTViewer, Viewer, Responder, or Modifier
200 * @apiSuccess (Success 200) {String} [Confidential]      Calendar: either None, DAndTViewer, Viewer, Responder, or Modifier
201 * @apiSuccess (Success 200) {Number} [Private]           Calendar: either None, DAndTViewer, Viewer, Responder, or Modifier
202 * @apiSuccess (Success 200) {Number} [canCreateObjects]  Calendar: can create events and tasks
203 * @apiSuccess (Success 200) {Number} [canEraseObjects]   Calendar: can erase events and tasks
204 * @apiSuccess (Success 200) {Number} [canCreateObjects]  Address Book: can create cards
205 * @apiSuccess (Success 200) {Number} [canEraseObjects]   Address Book: can erase cards
206 * @apiSuccess (Success 200) {Number} [canViewObjects]    Address Book: can view cards
207 * @apiSuccess (Success 200) {Number} [canEditObjects]    Address Book: can modify cards
208 */
209- (id <WOActionResults>) userRightsAction
210{
211  id <WOActionResults> response;
212  NSDictionary *jsonResponse;
213
214  if (![self _initRights])
215    {
216      jsonResponse = [NSDictionary dictionaryWithObject: [self labelForKey: @"No such user."]
217                                                 forKey: @"message"];
218      response = [self responseWithStatus: 403
219                                andString: [jsonResponse jsonRepresentation]];
220    }
221  else
222    {
223      jsonResponse = [self userRightsForObject];
224      response = [self responseWithStatus: 200
225                                andString: [jsonResponse jsonRepresentation]];
226    }
227  return response;
228}
229
230- (void) sendACLAdvisoryTemplateForObject: (id) theObject
231{
232  NSString *language, *pageName;
233  SOGoUserDefaults *ud;
234  SOGoACLAdvisory *page;
235  WOApplication *app;
236
237  if (!([self userIsDefaultUser] || [self userIsAnonymousUser]))
238    {
239      ud = [[SOGoUser userWithLogin: uid roles: nil] userDefaults];
240      language = [ud language];
241      pageName = [NSString stringWithFormat: @"SOGoACL%@ModificationAdvisory",
242                           language];
243
244      app = [WOApplication application];
245      page = [app pageWithName: pageName inContext: context];
246      [page setACLObject: theObject];
247      [page setRecipientUID: uid];
248      [page send];
249    }
250}
251
252- (id <WOActionResults>) saveUserRightsAction
253{
254  id <WOActionResults> response;
255  WORequest *request;
256  SOGoDomainDefaults *dd;
257  NSArray *users;
258  NSDictionary *currentUser, *jsonResponse;;
259  NSEnumerator *usersList;
260  NSString *currentUid;
261  NSArray *o;
262
263  request = [[self context] request];
264  response = [self responseWithStatus: 200];
265  users = [[request contentAsString] objectFromJSONString];
266  usersList = [users objectEnumerator];
267
268  while ((currentUser = [usersList nextObject]))
269    {
270      currentUid = [currentUser objectForKey: @"uid"];
271      if (!([self _initRightsForUserID: currentUid]))
272        {
273          jsonResponse = [NSDictionary dictionaryWithObject: [self labelForKey: @"No such user."]
274                                                     forKey: @"message"];
275          response = [self responseWithStatus: 403
276                                    andString: [jsonResponse jsonRepresentation]];
277          break;
278        }
279      else
280        {
281          o = [NSArray arrayWithArray: userRights];
282          [self updateRights: [currentUser objectForKey: @"rights"]];
283          [[self clientObject] setRoles: userRights forUser: currentUid];
284
285          dd = [[context activeUser] domainDefaults];
286          if (![o isEqualToArray: userRights] && [dd aclSendEMailNotifications])
287            [self sendACLAdvisoryTemplateForObject: [self clientObject]];
288        }
289    }
290  return response;
291}
292
293- (void) appendRight: (NSString *) newRight
294{
295  if (![userRights containsObject: newRight])
296    [userRights addObject: newRight];
297}
298
299- (void) removeRight: (NSString *) right
300{
301  if ([userRights containsObject: right])
302    [userRights removeObject: right];
303}
304
305- (void) appendExclusiveRight: (NSString *) newRight
306		     fromList: (NSArray *) list
307{
308  [userRights removeObjectsInArray: list];
309  [self appendRight: newRight];
310}
311
312- (void) removeAllRightsFromList: (NSArray *) list
313{
314  [userRights removeObjectsInArray: list];
315}
316
317- (NSDictionary *) userRightsForObject
318{
319  return [self subclassResponsibility: _cmd];
320}
321
322- (void) updateRights: (NSDictionary *) newRights
323{
324  [self subclassResponsibility: _cmd];
325}
326
327@end
328