root / Classes / EditPermissionsViewController.m @ 3e581f16
History | View | Annotate | Download (18.3 kB)
1 |
// |
---|---|
2 |
// EditPermissionsViewController.m |
3 |
// pithos-ios |
4 |
// |
5 |
// Copyright 2011 GRNET S.A. All rights reserved. |
6 |
// |
7 |
// Redistribution and use in source and binary forms, with or |
8 |
// without modification, are permitted provided that the following |
9 |
// conditions are met: |
10 |
// |
11 |
// 1. Redistributions of source code must retain the above |
12 |
// copyright notice, this list of conditions and the following |
13 |
// disclaimer. |
14 |
// |
15 |
// 2. Redistributions in binary form must reproduce the above |
16 |
// copyright notice, this list of conditions and the following |
17 |
// disclaimer in the documentation and/or other materials |
18 |
// provided with the distribution. |
19 |
// |
20 |
// THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
21 |
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
22 |
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
23 |
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
24 |
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
25 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
26 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
27 |
// USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
28 |
// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
29 |
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
30 |
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
31 |
// POSSIBILITY OF SUCH DAMAGE. |
32 |
// |
33 |
// The views and conclusions contained in the software and |
34 |
// documentation are those of the authors and should not be |
35 |
// interpreted as representing official policies, either expressed |
36 |
// or implied, of GRNET S.A. |
37 |
|
38 |
#import "EditPermissionsViewController.h" |
39 |
#import "AccountManager.h" |
40 |
#import "UIViewController+Conveniences.h" |
41 |
#import "FolderViewController.h" |
42 |
#import "OpenStackAccount.h" |
43 |
#import "Container.h" |
44 |
#import "Folder.h" |
45 |
#import "StorageObject.h" |
46 |
#import "ActivityIndicatorView.h" |
47 |
#import "PithosUtilities.h" |
48 |
#import "APICallback.h" |
49 |
|
50 |
#define kUser 0 |
51 |
#define kPermissions 1 |
52 |
#define kSavePermissions 2 |
53 |
#define kRemovePermissions 3 |
54 |
|
55 |
@implementation EditPermissionsViewController |
56 |
|
57 |
@synthesize account, container, object, folderViewController; |
58 |
@synthesize permissionUser, readPermissionSelected, writePermissionSelected, permissions; |
59 |
@synthesize currentUUID; |
60 |
@synthesize oldSharing, removePermissionsEnabled, objectIsFolder; |
61 |
@synthesize userTextField, groupTextField, readPermissionsCell, writePermissionsCell; |
62 |
|
63 |
#pragma mark - View lifecycle |
64 |
|
65 |
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { |
66 |
return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait); |
67 |
} |
68 |
|
69 |
#pragma mark - Memory management |
70 |
|
71 |
- (void)dealloc { |
72 |
[account release]; |
73 |
[container release]; |
74 |
[object release]; |
75 |
[permissionUser release]; |
76 |
[permissions release]; |
77 |
[oldSharing release]; |
78 |
[currentUUID release]; |
79 |
[userTextField release]; |
80 |
[groupTextField release]; |
81 |
[readPermissionsCell release]; |
82 |
[writePermissionsCell release]; |
83 |
[super dealloc]; |
84 |
} |
85 |
|
86 |
#pragma mark - Internal |
87 |
|
88 |
- (BOOL)userIsValid:(NSString *)input { |
89 |
if (!input.length) { |
90 |
[self alert:@"Invalid input" message:@"User cannot be empty."]; |
91 |
return NO; |
92 |
} |
93 |
return YES; |
94 |
} |
95 |
|
96 |
- (BOOL)groupIsValid:(NSString *)input { |
97 |
if (input && ([input rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"=,;"]].location != NSNotFound)) { |
98 |
[self alert:@"Invalid input" message:@"Group cannot contain '=', ',' or ';'."]; |
99 |
return NO; |
100 |
} |
101 |
return YES; |
102 |
} |
103 |
|
104 |
- (void)applyPermissions { |
105 |
[permissions removeObjectForKey:permissionUser]; |
106 |
NSString *newPermissionUser = ((groupTextField.text && groupTextField.text.length) ? |
107 |
[NSString stringWithFormat:@"%@:%@", currentUUID, groupTextField.text] : |
108 |
currentUUID); |
109 |
[permissions setObject:(writePermissionSelected ? @"write" : @"read") forKey:newPermissionUser]; |
110 |
self.oldSharing = object.sharing; |
111 |
[object setPermissions:permissions]; |
112 |
__block ActivityIndicatorView *activityIndicatorView = [ActivityIndicatorView activityIndicatorViewWithText:@"Applying permissions..." |
113 |
andAddToView:self.view]; |
114 |
[[self.account.manager writeObjectMetadata:container object:object] |
115 |
success:^(OpenStackRequest *request) { |
116 |
self.permissionUser = newPermissionUser; |
117 |
|
118 |
[activityIndicatorView removeFromSuperview]; |
119 |
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES]; |
120 |
if (!removePermissionsEnabled) { |
121 |
removePermissionsEnabled = YES; |
122 |
self.navigationItem.title = @"Edit Permission"; |
123 |
[self.tableView reloadData]; |
124 |
} |
125 |
|
126 |
if (objectIsFolder || (account.shared && ![oldSharing isEqualToString:object.sharing])) { |
127 |
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) { |
128 |
[self.folderViewController refreshButtonPressed:nil]; |
129 |
} else { |
130 |
self.folderViewController.needsRefreshing = YES; |
131 |
self.folderViewController.refreshWhenAppeared = YES; |
132 |
} |
133 |
} |
134 |
} |
135 |
failure:^(OpenStackRequest *request) { |
136 |
object.sharing = self.oldSharing; |
137 |
self.permissions = object.permissions; |
138 |
[activityIndicatorView removeFromSuperview]; |
139 |
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES]; |
140 |
[self alert:@"There was a problem applying the permissions." request:request]; |
141 |
}]; |
142 |
} |
143 |
|
144 |
- (void)createNewFolder { |
145 |
__block ActivityIndicatorView *activityIndicatorView = [ActivityIndicatorView activityIndicatorViewWithText:@"Creating folder..." |
146 |
andAddToView:self.view]; |
147 |
object.contentType = @"application/directory"; |
148 |
object.data = [NSData data]; |
149 |
[[self.account.manager writeObject:self.container object:object downloadProgressDelegate:nil] |
150 |
success:^(OpenStackRequest *request) { |
151 |
Folder *newFolder = [[Folder alloc] init]; |
152 |
newFolder.name = [[object.name componentsSeparatedByString:@"/"] lastObject]; |
153 |
newFolder.parent = folderViewController.folder; |
154 |
newFolder.sharing = folderViewController.folder.sharing; |
155 |
[folderViewController.folder addFolder:newFolder]; |
156 |
[newFolder release]; |
157 |
|
158 |
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) { |
159 |
[self.folderViewController refreshButtonPressed:nil]; |
160 |
} else { |
161 |
self.folderViewController.needsRefreshing = YES; |
162 |
self.folderViewController.refreshWhenAppeared = YES; |
163 |
} |
164 |
[self applyPermissions]; |
165 |
} |
166 |
failure:^(OpenStackRequest *request) { |
167 |
[activityIndicatorView removeFromSuperview]; |
168 |
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES]; |
169 |
[self alert:@"There was a problem creating the folder." request:request]; |
170 |
}]; |
171 |
} |
172 |
|
173 |
|
174 |
#pragma mark - UITableViewDataSource |
175 |
|
176 |
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { |
177 |
return (removePermissionsEnabled ? 4 : 3); |
178 |
} |
179 |
|
180 |
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { |
181 |
if ((section == kUser) || (section == kPermissions)) { |
182 |
return 2; |
183 |
} |
184 |
return 1; |
185 |
} |
186 |
|
187 |
- (UITextField *)textFieldForCell:(UITableViewCell *)cell { |
188 |
CGRect rect = CGRectInset(cell.contentView.bounds, 10.0, 10.0); |
189 |
UITextField *textField = [[[UITextField alloc] initWithFrame:rect] autorelease]; |
190 |
textField.frame = rect; |
191 |
textField.clearButtonMode = UITextFieldViewModeWhileEditing; |
192 |
textField.backgroundColor = [UIColor clearColor]; |
193 |
textField.opaque = YES; |
194 |
textField.autocorrectionType = UITextAutocorrectionTypeNo; |
195 |
textField.autocapitalizationType = UITextAutocapitalizationTypeNone; |
196 |
textField.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; |
197 |
return textField; |
198 |
} |
199 |
|
200 |
- (UITextField *)textFieldForCell:(UITableViewCell *)cell withIndexPath:(NSIndexPath *)indexPath { |
201 |
if (indexPath.row == 0) { |
202 |
if (!userTextField) { |
203 |
self.userTextField = [self textFieldForCell:cell]; |
204 |
userTextField.returnKeyType = UIReturnKeyNext; |
205 |
userTextField.placeholder = @"User"; |
206 |
NSRange rangeOfColumn = [permissionUser rangeOfString:@":"]; |
207 |
userTextField.text = [self.account displaynameForUUID:((rangeOfColumn.location == NSNotFound) ? permissionUser : [permissionUser substringToIndex:rangeOfColumn.location]) |
208 |
safe:YES]; |
209 |
userTextField.delegate = self; |
210 |
} |
211 |
return userTextField; |
212 |
} else if (indexPath.row == 1) { |
213 |
if (!groupTextField) { |
214 |
self.groupTextField = [self textFieldForCell:cell]; |
215 |
groupTextField.returnKeyType = UIReturnKeyDefault; |
216 |
groupTextField.placeholder = @"Group (optional)"; |
217 |
NSRange rangeOfColumn = [permissionUser rangeOfString:@":"]; |
218 |
groupTextField.text = ((rangeOfColumn.location == NSNotFound) || (rangeOfColumn.location == permissionUser.length - 1)) ? nil : [permissionUser substringFromIndex:(rangeOfColumn.location + 1)]; |
219 |
groupTextField.delegate = self; |
220 |
} |
221 |
return groupTextField; |
222 |
} |
223 |
return nil; |
224 |
} |
225 |
|
226 |
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ |
227 |
if (indexPath.section == kUser) { |
228 |
static NSString *CellIdentifier = @"TextFieldCell"; |
229 |
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; |
230 |
if (cell == nil) { |
231 |
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; |
232 |
} |
233 |
cell.textLabel.text = nil; |
234 |
cell.accessoryType = UITableViewCellAccessoryNone; |
235 |
cell.selectionStyle = UITableViewCellSelectionStyleNone; |
236 |
for (UIView *view in cell.contentView.subviews) { |
237 |
[view removeFromSuperview]; |
238 |
} |
239 |
[cell.contentView addSubview:[self textFieldForCell:cell withIndexPath:indexPath]]; |
240 |
return cell; |
241 |
} |
242 |
|
243 |
static NSString *CellIdentifier = @"Cell"; |
244 |
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; |
245 |
if (cell == nil) { |
246 |
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; |
247 |
} |
248 |
|
249 |
if (indexPath.section == kPermissions) { |
250 |
if (indexPath.row == 0) { |
251 |
cell.textLabel.text = @"Read Only"; |
252 |
cell.accessoryType = (readPermissionSelected ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone); |
253 |
self.readPermissionsCell = cell; |
254 |
} else { |
255 |
cell.textLabel.text = @"Read/Write"; |
256 |
cell.accessoryType = (writePermissionSelected ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone); |
257 |
self.writePermissionsCell = cell; |
258 |
} |
259 |
cell.selectionStyle = UITableViewCellSelectionStyleNone; |
260 |
} else if (indexPath.section == kSavePermissions) { |
261 |
cell.textLabel.text = @"Save"; |
262 |
cell.accessoryType = UITableViewCellAccessoryNone; |
263 |
cell.selectionStyle = UITableViewCellSelectionStyleBlue; |
264 |
} else if (indexPath.section == kRemovePermissions) { |
265 |
cell.textLabel.text = @"Remove"; |
266 |
cell.accessoryType = UITableViewCellAccessoryNone; |
267 |
cell.selectionStyle = UITableViewCellSelectionStyleBlue; |
268 |
} |
269 |
|
270 |
return cell; |
271 |
} |
272 |
|
273 |
#pragma mark - UITableViewDelegate |
274 |
|
275 |
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { |
276 |
if (indexPath.section != kUser) |
277 |
[self.view endEditing:YES]; |
278 |
|
279 |
if (indexPath.section == kPermissions) { |
280 |
if ((indexPath.row == 0) && !readPermissionSelected) { |
281 |
readPermissionSelected = YES; |
282 |
if (writePermissionSelected) { |
283 |
writePermissionSelected = FALSE; |
284 |
writePermissionsCell.accessoryType = UITableViewCellAccessoryNone; |
285 |
} |
286 |
readPermissionsCell.accessoryType = UITableViewCellAccessoryCheckmark; |
287 |
} else if ((indexPath.row == 1) && !writePermissionSelected) { |
288 |
writePermissionSelected = YES; |
289 |
if (readPermissionSelected) { |
290 |
readPermissionSelected = FALSE; |
291 |
readPermissionsCell.accessoryType = UITableViewCellAccessoryNone; |
292 |
} |
293 |
writePermissionsCell.accessoryType = UITableViewCellAccessoryCheckmark; |
294 |
} |
295 |
} else if (indexPath.section == kSavePermissions) { |
296 |
if (![self userIsValid:userTextField.text] || ![self groupIsValid:groupTextField.text]) { |
297 |
[self.tableView deselectRowAtIndexPath:indexPath animated:YES]; |
298 |
} else if (!readPermissionSelected && !writePermissionSelected) { |
299 |
[self alert:@"Cannot save permissions" message:@"Please select a permission type."]; |
300 |
[self.tableView deselectRowAtIndexPath:indexPath animated:YES]; |
301 |
} else { |
302 |
__block ActivityIndicatorView *activityIndicatorView = [ActivityIndicatorView activityIndicatorViewWithText:@"Checking user..." |
303 |
andAddToView:self.view]; |
304 |
[[self.account.manager userCatalogForDisplaynames:[NSArray arrayWithObject:userTextField.text] UUIDs:nil] |
305 |
success:^(OpenStackRequest *request) { |
306 |
[activityIndicatorView removeFromSuperview]; |
307 |
self.currentUUID = [[request displaynameCatalog] objectForKey:userTextField.text]; |
308 |
if (currentUUID) { |
309 |
if (objectIsFolder && ![PithosUtilities isContentTypeDirectory:object.contentType]) { |
310 |
if ((([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) && |
311 |
[folderViewController.parentFolderViewController.folder.objects objectForKey:object.name]) || |
312 |
(([UIDevice currentDevice].userInterfaceIdiom != UIUserInterfaceIdiomPad) && |
313 |
[folderViewController.folder.objects objectForKey:object.name])) { |
314 |
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"Apply changes" |
315 |
message:[NSString stringWithFormat:@"In order to apply the changes to folder '%@', the file at the same path must be replaced. Continue?", object.name] |
316 |
delegate:self |
317 |
cancelButtonTitle:@"Cancel" |
318 |
otherButtonTitles:@"OK", nil] autorelease]; |
319 |
[alert show]; |
320 |
} else { |
321 |
[self createNewFolder]; |
322 |
} |
323 |
} else { |
324 |
[self applyPermissions]; |
325 |
} |
326 |
} else { |
327 |
[self.tableView deselectRowAtIndexPath:indexPath animated:YES]; |
328 |
[self alert:@"Invalid user" message:[NSString stringWithFormat:@"User '%@' doesn't exist.", userTextField.text]]; |
329 |
} |
330 |
} |
331 |
failure:^(OpenStackRequest *request) { |
332 |
[activityIndicatorView removeFromSuperview]; |
333 |
[self.tableView deselectRowAtIndexPath:indexPath animated:YES]; |
334 |
[self alert:@"There was a problem checking the user." request:request]; |
335 |
}]; |
336 |
} |
337 |
} else if (indexPath.section == kRemovePermissions) { |
338 |
__block ActivityIndicatorView *activityIndicatorView = [ActivityIndicatorView activityIndicatorViewWithText:@"Removing permissions..." |
339 |
andAddToView:self.view]; |
340 |
[permissions removeObjectForKey:permissionUser]; |
341 |
self.oldSharing = object.sharing; |
342 |
[object setPermissions:permissions]; |
343 |
[[self.account.manager writeObjectMetadata:container object:object] |
344 |
success:^(OpenStackRequest *request) { |
345 |
[activityIndicatorView removeFromSuperview]; |
346 |
[self.tableView deselectRowAtIndexPath:indexPath animated:YES]; |
347 |
self.permissionUser = @""; |
348 |
self.readPermissionSelected = FALSE; |
349 |
self.writePermissionSelected = FALSE; |
350 |
removePermissionsEnabled = NO; |
351 |
self.navigationItem.title = @"Add Permission"; |
352 |
[self.tableView reloadData]; |
353 |
|
354 |
if (objectIsFolder || (account.shared && ![oldSharing isEqualToString:object.sharing])) { |
355 |
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) { |
356 |
[self.folderViewController refreshButtonPressed:nil]; |
357 |
} else { |
358 |
self.folderViewController.needsRefreshing = YES; |
359 |
self.folderViewController.refreshWhenAppeared = YES; |
360 |
} |
361 |
} |
362 |
} |
363 |
failure:^(OpenStackRequest *request) { |
364 |
object.sharing = self.oldSharing; |
365 |
self.permissions = object.permissions; |
366 |
[activityIndicatorView removeFromSuperview]; |
367 |
[self.tableView deselectRowAtIndexPath:indexPath animated:YES]; |
368 |
[self alert:@"There was a problem removing the permissions." request:request]; |
369 |
}]; |
370 |
} |
371 |
} |
372 |
|
373 |
#pragma mark - UITextFieldDelegate |
374 |
|
375 |
- (BOOL)textFieldShouldReturn:(UITextField *)textField { |
376 |
if (textField == userTextField) { |
377 |
if (![self userIsValid:textField.text]) { |
378 |
return NO; |
379 |
} |
380 |
[groupTextField becomeFirstResponder]; |
381 |
} else if (textField == groupTextField) { |
382 |
if (![self groupIsValid:textField.text]) { |
383 |
return NO; |
384 |
} |
385 |
[groupTextField resignFirstResponder]; |
386 |
} |
387 |
return YES; |
388 |
} |
389 |
|
390 |
#pragma mark - UIAlertViewDelegate |
391 |
|
392 |
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { |
393 |
if (buttonIndex == 1) { |
394 |
[self createNewFolder]; |
395 |
} else { |
396 |
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES]; |
397 |
} |
398 |
} |
399 |
|
400 |
@end |