Statistics
| Branch: | Tag: | Revision:

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