Renamed target to "Pithos+". Login uses url "pithos://login". Bug fixes. Removed...
[pithos-ios] / Classes / AccountSettingsViewController.m
1 //
2 //  AccountSettingsViewController.m
3 //  OpenStack
4 //
5 //  Created by Mike Mayo on 12/14/10.
6 //  The OpenStack project is provided under the Apache 2.0 license.
7 //
8
9 #import "AccountSettingsViewController.h"
10 #import "OpenStackAccount.h"
11 #import "Provider.h"
12 #import "RSTextFieldCell.h"
13 #import "UIColor+MoreColors.h"
14 #import "OpenStackAppDelegate.h"
15 #import "UIViewController+Conveniences.h"
16 #import "OpenStackRequest.h"
17
18 #define kUsername 0
19 #define kAPIKey 1
20
21 @implementation AccountSettingsViewController
22
23 @synthesize account, userName, apiKey, activityIndicatorView;
24
25 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
26     return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
27 }
28
29 #pragma mark -
30 #pragma mark HTTP Response Handlers
31
32 - (void)authenticationSucceded:(OpenStackRequest *)request {
33     
34     [self.activityIndicatorView removeFromSuperview];
35
36     if ([request isSuccess]) {        
37         account.authToken = [[request responseHeaders] objectForKey:@"X-Auth-Token"];
38         account.serversURL = [NSURL URLWithString:[[request responseHeaders] objectForKey:@"X-Server-Management-Url"]];
39         
40         NSString *filesStorageURL;
41         if (![[request responseHeaders] objectForKey:@"X-Storage-URL"]) {
42             filesStorageURL = [NSString stringWithFormat:@"%@/v1/%@",
43                                [account.hostURL absoluteString],
44                                [account username]];
45             account.filesURL = [NSURL URLWithString:filesStorageURL];
46         }
47         else {
48             account.filesURL = [NSURL URLWithString:[[request responseHeaders] objectForKey:@"X-Storage-Url"]];
49         }
50         
51         account.pithosPublicLinkURLPrefix = account.hostURL;
52         account.pithosLoginURLPrefix = [NSURL URLWithString:
53                                         [[account.hostURL absoluteString]
54                                          stringByAppendingString:@"/login"]];
55
56         NSString *cdnStr = [[request responseHeaders] objectForKey:@"X-Cdn-Management-Url"];
57         if (!cdnStr) {
58             cdnStr = [[request responseHeaders] objectForKey:@"X-CDN-Management-Url"];
59         }
60         if (cdnStr) {
61             account.cdnURL = [NSURL URLWithString:cdnStr];
62         }
63         [account persist];
64         [account refreshCollections];
65         [self.navigationController dismissModalViewControllerAnimated:YES];
66     } else {
67         self.navigationItem.rightBarButtonItem.enabled = NO;
68         [self alert:@"Authentication Failure" message:@"Please check your User Name and Token."];
69     }
70 }
71
72 - (void)authenticationFailed:(OpenStackRequest *)request {
73     [self.activityIndicatorView removeFromSuperview];
74     self.navigationItem.rightBarButtonItem.enabled = YES;
75     self.account.containers = nil;
76     if ([request responseStatusCode] == 401) {
77         [self alert:@"Authentication Failure" message:@"Please check your User Name and Token."];
78     } else {
79         [self failOnBadConnection];
80     }
81 }
82
83
84 - (void)authenticate {
85     
86     BOOL valid = YES;
87     
88         valid = valid && usernameTextField.text && ![@"" isEqualToString:usernameTextField.text];
89         if (!valid) {
90             [self alert:nil message:@"Please enter your username."];
91             [usernameTextField becomeFirstResponder];
92         } else {
93             valid = valid && apiKeyTextField.text && ![@"" isEqualToString:apiKeyTextField.text];
94             if (!valid) {
95                 [self alert:nil message:@"Please enter your token."];
96                 [apiKeyTextField becomeFirstResponder];
97             } else {
98                 account.username = usernameTextField.text;
99                 account.apiKey = apiKeyTextField.text;                        
100                 
101                 self.activityIndicatorView = [[[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:@"Authenticating..."] text:@"Authenticating..."] autorelease];
102                 [self.activityIndicatorView addToView:self.view];
103                 
104                 OpenStackRequest *request = [OpenStackRequest authenticationRequest:account];
105                 request.delegate = self;
106                 request.didFinishSelector = @selector(authenticationSucceded:);
107                 request.didFailSelector = @selector(authenticationFailed:);
108                 [request startAsynchronous];
109             }
110         }
111 }
112
113
114
115 #pragma mark -
116 #pragma mark Button Handlers
117
118 - (void)saveButtonPressed:(id)sender {
119     [self authenticate];
120 }
121
122
123 #pragma mark - View lifecycle
124
125 - (void)viewDidLoad {
126     [super viewDidLoad];
127     self.navigationItem.title = @"API Account Info";
128     userDetailsSection = 0;
129     if ([self.account.provider isGRNet])
130         getTokenSection = 1;
131     else
132         getTokenSection = -1;
133     
134     /*if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
135         UIView *backgroundContainer = [[UIView alloc] init];
136         backgroundContainer.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
137         backgroundContainer.backgroundColor = [UIColor iPadTableBackgroundColor];
138         NSString *logoFilename = @"account-settings-icon-large.png";
139         UIImageView *osLogo = [[UIImageView alloc] initWithImage:[UIImage imageNamed:logoFilename]];
140         osLogo.contentMode = UIViewContentModeScaleAspectFit;
141         osLogo.frame = CGRectMake(100.0, 100.0, 1000.0, 1000.0);
142         if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
143             osLogo.alpha = 0.3;
144         }
145         [backgroundContainer addSubview:osLogo];
146         [osLogo release];
147         self.tableView.backgroundView = backgroundContainer;
148         [backgroundContainer release];
149     }   */ 
150     
151     [self addSaveButton];
152 }
153
154
155 - (void)viewDidAppear:(BOOL)animated {
156     [super viewDidAppear:animated];    
157     //[usernameTextField becomeFirstResponder];
158 }
159
160 #pragma mark - Table view data source
161
162 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
163     if (getTokenSection > 0)
164         return 2;
165     else
166         return 1;
167 }
168
169 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
170     if (section == userDetailsSection)
171         return 2;
172     else
173         return 1;
174 }
175
176 - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
177     if (section == userDetailsSection)
178         return [NSString stringWithFormat:@"%@ Login", self.account.provider.name];
179     else 
180         return nil;
181 }
182
183 - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
184     if (section == userDetailsSection)
185         return [NSString stringWithFormat:@"API Version %@", self.account.apiVersion];
186     else
187         return nil;
188 }
189
190 // Customize the appearance of table view cells.
191 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
192     
193     static NSString *CellIdentifier = @"Cell";
194     RSTextFieldCell *cell = nil;
195     if (indexPath.section == userDetailsSection) {
196         cell = (RSTextFieldCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
197         if (cell == nil) {
198             cell = [[[RSTextFieldCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
199             cell.selectionStyle = UITableViewCellSelectionStyleNone;
200         }
201     
202         if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
203             cell.backgroundColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:0.8];
204         }
205
206         [cell.textLabel setBackgroundColor:[UIColor clearColor]];
207
208         if (indexPath.row == kUsername) {
209             cell.textLabel.text = @"Username";
210             usernameTextField = cell.textField;
211             usernameTextField.delegate = self;
212             usernameTextField.secureTextEntry = NO;
213             usernameTextField.returnKeyType = UIReturnKeyNext;
214             usernameTextField.text = self.account.username;
215             usernameTextField.placeholder = @"username";
216             if (userName)
217                 usernameTextField.text = userName;
218         } else if (indexPath.row == kAPIKey) {
219             cell.textLabel.text = @"Token";
220             apiKeyTextField = cell.textField;
221             apiKeyTextField.secureTextEntry = YES;
222             apiKeyTextField.delegate = self;
223             apiKeyTextField.returnKeyType = UIReturnKeyDone;
224             apiKeyTextField.text = self.account.apiKey;
225             if (apiKey)
226                 apiKeyTextField.text = apiKey;
227         }
228     } else {
229         cell = (RSTextFieldCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
230         if (cell == nil) {
231             cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
232         }
233         
234         cell.textLabel.text = @"Get Token";
235     }
236     return cell;
237 }
238
239 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
240     if (indexPath.section == getTokenSection) {
241         NSString *loginURL = [NSString stringWithFormat:@"%@?next=pithos://login", account.pithosLoginURLPrefix]; 
242         
243         [[UIApplication sharedApplication] openURL:[NSURL URLWithString:loginURL]];
244         [tableView deselectRowAtIndexPath:indexPath animated:NO];
245     }
246 }
247
248 #pragma mark - Text Field Delegate
249
250 - (BOOL)textFieldShouldReturn:(UITextField *)textField {    
251     [textField resignFirstResponder];    
252     if ([textField isEqual:usernameTextField]) {
253         [apiKeyTextField becomeFirstResponder];
254     }
255     return NO;
256 }
257
258 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
259     NSString *result = [textField.text stringByReplacingCharactersInRange:range withString:string];
260     if ([textField isEqual:usernameTextField]) {
261         self.account.username = result;
262     } else if ([textField isEqual:apiKeyTextField]) {
263         self.account.apiKey = result;
264     }
265     self.account.authToken = @"";
266     self.account.hasBeenRefreshed = NO;
267     [self.account persist];
268     
269     return YES;
270 }
271
272 #pragma mark - Memory management
273
274 - (void)dealloc {
275     [userName release];
276     [apiKey release];
277     [activityIndicatorView release];
278     [account release];
279     [super dealloc];
280 }
281
282
283 @end
284