// // AccountSettingsViewController.m // OpenStack // // Created by Mike Mayo on 12/14/10. // The OpenStack project is provided under the Apache 2.0 license. // #import "AccountSettingsViewController.h" #import "OpenStackAccount.h" #import "ActivityIndicatorView.h" #import "Provider.h" #import "RSTextFieldCell.h" #import "UIColor+MoreColors.h" #import "OpenStackAppDelegate.h" #import "UIViewController+Conveniences.h" #import "OpenStackRequest.h" #define kUsername 0 #define kAuthToken 1 @implementation AccountSettingsViewController @synthesize account, username, authToken; #pragma mark - View lifecycle - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait); } - (void)viewDidLoad { [super viewDidLoad]; self.navigationItem.title = @"Authentication"; userDetailsSection = 0; getTokenSection = 1; [self addSaveButton]; self.navigationItem.rightBarButtonItem.enabled = NO; } #pragma mark - Memory management - (void)dealloc { [username release]; [authToken release]; [account release]; [super dealloc]; } #pragma mark - Internal - (void) updateSaveButtonForUsername:(NSString *)checkUsername andAuthToken:(NSString *)checkAuthToken { self.navigationItem.rightBarButtonItem.enabled = (checkUsername && checkUsername.length && checkAuthToken &&checkAuthToken.length && (![checkUsername isEqualToString:account.username] || ![checkAuthToken isEqualToString:account.authToken])); } #pragma mark - Properties - (void)setUsername:(NSString *)aUsername { [username release]; username = [aUsername retain]; [self updateSaveButtonForUsername:username andAuthToken:authTokenTextField.text]; } - (void)setAuthToken:(NSString *)anAuthToken { [authToken release]; authToken = [anAuthToken retain]; [self updateSaveButtonForUsername:usernameTextField.text andAuthToken:authToken]; } #pragma mark - Actions - (void)setUsername:(NSString *)aUsername andAuthToken:(NSString *)anAuthToken { if (aUsername) { [username release]; username = [aUsername retain]; } if (anAuthToken) { [authToken release]; authToken = [anAuthToken retain]; } [self updateSaveButtonForUsername:username andAuthToken:authToken]; } #pragma mark - UITableViewDataSource - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 2; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { if (section == userDetailsSection) return 2; else return 1; } - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { if (section == userDetailsSection) return [NSString stringWithFormat:@"%@ Login", self.account.provider.name]; else return nil; } - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section { if (section == userDetailsSection) return @"API Version 1.0"; else return nil; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; RSTextFieldCell *cell = nil; if (indexPath.section == userDetailsSection) { cell = (RSTextFieldCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[RSTextFieldCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease]; cell.selectionStyle = UITableViewCellSelectionStyleNone; } if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) { cell.backgroundColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:0.8]; } [cell.textLabel setBackgroundColor:[UIColor clearColor]]; if (indexPath.row == kUsername) { cell.textLabel.text = @"Username"; usernameTextField = cell.textField; usernameTextField.delegate = self; usernameTextField.secureTextEntry = NO; usernameTextField.returnKeyType = UIReturnKeyNext; if (username) { usernameTextField.text = username; } else { usernameTextField.text = self.account.username; } } else if (indexPath.row == kAuthToken) { cell.textLabel.text = @"Token"; authTokenTextField = cell.textField; authTokenTextField.secureTextEntry = NO; authTokenTextField.delegate = self; authTokenTextField.returnKeyType = UIReturnKeyDone; if (authToken) { authTokenTextField.text = authToken; } else { authTokenTextField.text = self.account.authToken; } } } else { cell = (RSTextFieldCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[RSTextFieldCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; } cell.textLabel.text = @"Get Token"; } return cell; } #pragma mark - UITableViewDelegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.section == getTokenSection) { NSString *protocol = [[[[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleURLTypes"] objectAtIndex:0] objectForKey:@"CFBundleURLSchemes"] objectAtIndex:0]; NSString *loginURL = [NSString stringWithFormat:@"%@?next=%@://login&force=", account.pithosLoginURLPrefix, protocol]; [[UIApplication sharedApplication] openURL:[NSURL URLWithString:loginURL]]; [tableView deselectRowAtIndexPath:indexPath animated:NO]; } } #pragma mark - UITextFieldDelegate - (BOOL)textFieldShouldReturn:(UITextField *)textField { [textField resignFirstResponder]; if ([textField isEqual:usernameTextField]) { [authTokenTextField becomeFirstResponder]; } return NO; } - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { NSString *result = [textField.text stringByReplacingCharactersInRange:range withString:string]; if ([textField isEqual:usernameTextField]) { self.username = result; } else if ([textField isEqual:authTokenTextField]) { self.authToken = result; } return YES; } #pragma mark - Button Handlers - (void)saveButtonPressed:(id)sender { self.navigationItem.rightBarButtonItem.enabled = NO; [self authenticate]; } #pragma mark - Authentication - (void)authenticate { if (!usernameTextField.text || [usernameTextField.text isEqualToString:@""]) { [self alert:nil message:@"Please enter your Username."]; self.navigationItem.rightBarButtonItem.enabled = YES; [usernameTextField becomeFirstResponder]; } else if (!authTokenTextField.text || [authTokenTextField.text isEqualToString:@""]) { [self alert:nil message:@"Please enter your Token."]; self.navigationItem.rightBarButtonItem.enabled = YES; [authTokenTextField becomeFirstResponder]; } else { OpenStackAccount *temporaryAccount = [[[OpenStackAccount alloc] init] autorelease]; temporaryAccount.provider = account.provider; temporaryAccount.username = usernameTextField.text; temporaryAccount.authToken = authTokenTextField.text; __block ActivityIndicatorView *activityIndicatorView = [ActivityIndicatorView activityIndicatorViewWithText:@"Authenticating..." andAddToView:self.view]; OpenStackRequest *request = [OpenStackRequest authenticationRequest:temporaryAccount]; request.completionBlock = ^{ [activityIndicatorView removeFromSuperview]; if ([request isSuccess]) { account.username = request.account.username; account.authToken = request.account.authToken; NSString *storageURLString = [[request responseHeaders] objectForKey:@"X-Storage-Url"]; if (storageURLString) { account.filesURL = [NSURL URLWithString:storageURLString]; } else { account.filesURL = [[account.hostURL URLByAppendingPathComponent:@"v1"] URLByAppendingPathComponent:account.username]; } [account persist]; } else { self.navigationItem.rightBarButtonItem.enabled = YES; [self alert:@"Authentication Failure" message:@"Please check your Username and Token."]; } }; request.failedBlock = ^{ [activityIndicatorView removeFromSuperview]; self.navigationItem.rightBarButtonItem.enabled = YES; if ([request responseStatusCode] == 401) { [self alert:@"Authentication Failure" message:@"Please check your Username and Token."]; } else { [self failOnBadConnection]; } }; [request startAsynchronous]; } } @end