Merge branch 'master' of https://code.grnet.gr/git/pithos-ios
[pithos-ios] / Classes / AccountSettingsViewController.m
index ce9752b..848f626 100755 (executable)
@@ -8,6 +8,7 @@
 
 #import "AccountSettingsViewController.h"
 #import "OpenStackAccount.h"
+#import "ActivityIndicatorView.h"
 #import "Provider.h"
 #import "RSTextFieldCell.h"
 #import "UIColor+MoreColors.h"
 #import "OpenStackRequest.h"
 
 #define kUsername 0
-#define kAPIKey 1
+#define kAuthToken 1
 
 @implementation AccountSettingsViewController
 
-@synthesize account, userName, apiKey, activityIndicatorView;
+@synthesize account, username, authToken;
 
-- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
-    return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
-}
-
-#pragma mark -
-#pragma mark HTTP Response Handlers
-
-- (void)authenticationSucceded:(OpenStackRequest *)request {
-    
-    [self.activityIndicatorView removeFromSuperview];
+#pragma mark - View lifecycle
 
-    if ([request isSuccess]) {        
-        account.authToken = [[request responseHeaders] objectForKey:@"X-Auth-Token"];
-        account.serversURL = [NSURL URLWithString:[[request responseHeaders] objectForKey:@"X-Server-Management-Url"]];
-        
-        NSString *filesStorageURL;
-        if (![[request responseHeaders] objectForKey:@"X-Storage-URL"]) {
-            filesStorageURL = [NSString stringWithFormat:@"%@/v1/%@",
-                               [account.hostURL absoluteString],
-                               [account username]];
-            account.filesURL = [NSURL URLWithString:filesStorageURL];
-        }
-        else {
-            account.filesURL = [NSURL URLWithString:[[request responseHeaders] objectForKey:@"X-Storage-Url"]];
-        }
-        
-        account.pithosPublicLinkURLPrefix = account.hostURL;
-        account.pithosLoginURLPrefix = [NSURL URLWithString:
-                                        [[account.hostURL absoluteString]
-                                         stringByAppendingString:@"/login"]];
-
-        NSString *cdnStr = [[request responseHeaders] objectForKey:@"X-Cdn-Management-Url"];
-        if (!cdnStr) {
-            cdnStr = [[request responseHeaders] objectForKey:@"X-CDN-Management-Url"];
-        }
-        if (cdnStr) {
-            account.cdnURL = [NSURL URLWithString:cdnStr];
-        }
-        [account persist];
-        [account refreshCollections];
-        [self.navigationController dismissModalViewControllerAnimated:YES];
-    } else {
-        self.navigationItem.rightBarButtonItem.enabled = NO;
-        [self alert:@"Authentication Failure" message:@"Please check your User Name and Token."];
-    }
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
+    return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
 }
 
-- (void)authenticationFailed:(OpenStackRequest *)request {
-    [self.activityIndicatorView removeFromSuperview];
-    self.navigationItem.rightBarButtonItem.enabled = YES;
-    self.account.containers = nil;
-    if ([request responseStatusCode] == 401) {
-        [self alert:@"Authentication Failure" message:@"Please check your User Name and Token."];
-    } else {
-        [self failOnBadConnection];
-    }
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    self.navigationItem.title = @"Authentication";
+    userDetailsSection = 0;
+    getTokenSection = 1;
+    [self addSaveButton];
+    self.navigationItem.rightBarButtonItem.enabled = NO;
 }
 
+#pragma mark - Memory management
 
-- (void)authenticate {
-    
-    BOOL valid = YES;
-    
-        valid = valid && usernameTextField.text && ![@"" isEqualToString:usernameTextField.text];
-        if (!valid) {
-            [self alert:nil message:@"Please enter your username."];
-            [usernameTextField becomeFirstResponder];
-        } else {
-            valid = valid && apiKeyTextField.text && ![@"" isEqualToString:apiKeyTextField.text];
-            if (!valid) {
-                [self alert:nil message:@"Please enter your token."];
-                [apiKeyTextField becomeFirstResponder];
-            } else {
-                account.username = usernameTextField.text;
-                account.apiKey = apiKeyTextField.text;                        
-                
-                self.activityIndicatorView = [[[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:@"Authenticating..."] text:@"Authenticating..."] autorelease];
-                [self.activityIndicatorView addToView:self.view];
-                
-                OpenStackRequest *request = [OpenStackRequest authenticationRequest:account];
-                request.delegate = self;
-                request.didFinishSelector = @selector(authenticationSucceded:);
-                request.didFailSelector = @selector(authenticationFailed:);
-                [request startAsynchronous];
-            }
-        }
+- (void)dealloc {
+    [username release];
+    [authToken release];
+    [account release];
+    [super dealloc];
 }
 
+#pragma mark - Internal
 
-
-#pragma mark -
-#pragma mark Button Handlers
-
-- (void)saveButtonPressed:(id)sender {
-    [self authenticate];
+- (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
 
-#pragma mark - View lifecycle
+- (void)setUsername:(NSString *)aUsername {
+    [username release];
+    username = [aUsername retain];
+    [self updateSaveButtonForUsername:username andAuthToken:authTokenTextField.text];
+}
 
-- (void)viewDidLoad {
-    [super viewDidLoad];
-    self.navigationItem.title = @"API Account Info";
-    userDetailsSection = 0;
-    if ([self.account.provider isGRNet])
-        getTokenSection = 1;
-    else
-        getTokenSection = -1;
-    
-    /*if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
-        UIView *backgroundContainer = [[UIView alloc] init];
-        backgroundContainer.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
-        backgroundContainer.backgroundColor = [UIColor iPadTableBackgroundColor];
-        NSString *logoFilename = @"account-settings-icon-large.png";
-        UIImageView *osLogo = [[UIImageView alloc] initWithImage:[UIImage imageNamed:logoFilename]];
-        osLogo.contentMode = UIViewContentModeScaleAspectFit;
-        osLogo.frame = CGRectMake(100.0, 100.0, 1000.0, 1000.0);
-        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
-            osLogo.alpha = 0.3;
-        }
-        [backgroundContainer addSubview:osLogo];
-        [osLogo release];
-        self.tableView.backgroundView = backgroundContainer;
-        [backgroundContainer release];
-    }   */ 
-    
-    [self addSaveButton];
+- (void)setAuthToken:(NSString *)anAuthToken {
+    [authToken release];
+    authToken = [anAuthToken retain];
+    [self updateSaveButtonForUsername:usernameTextField.text andAuthToken:authToken];
 }
 
+#pragma mark - Actions
 
-- (void)viewDidAppear:(BOOL)animated {
-    [super viewDidAppear:animated];    
-    //[usernameTextField becomeFirstResponder];
+- (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 - Table view data source
+#pragma mark - UITableViewDataSource
 
 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
-    if (getTokenSection > 0)
-        return 2;
-    else
-        return 1;
+    return 2;
 }
 
 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
 - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
     if (section == userDetailsSection)
         return [NSString stringWithFormat:@"%@ Login", self.account.provider.name];
-    else 
+    else
         return nil;
 }
 
 - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
     if (section == userDetailsSection)
-        return [NSString stringWithFormat:@"API Version %@", self.account.apiVersion];
+        return @"API Version 1.0";
     else
         return nil;
 }
 
-// Customize the appearance of table view cells.
 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
-    
     static NSString *CellIdentifier = @"Cell";
     RSTextFieldCell *cell = nil;
     if (indexPath.section == userDetailsSection) {
             cell = [[[RSTextFieldCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
             cell.selectionStyle = UITableViewCellSelectionStyleNone;
         }
-    
-        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
+        
+        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;
-            usernameTextField.text = self.account.username;
-            usernameTextField.placeholder = @"username";
-            if (userName)
-                usernameTextField.text = userName;
-        } else if (indexPath.row == kAPIKey) {
+            if (username) {
+                usernameTextField.text = username;
+            } else {
+                usernameTextField.text = self.account.username;
+            }
+        } else if (indexPath.row == kAuthToken) {
             cell.textLabel.text = @"Token";
-            apiKeyTextField = cell.textField;
-            apiKeyTextField.secureTextEntry = YES;
-            apiKeyTextField.delegate = self;
-            apiKeyTextField.returnKeyType = UIReturnKeyDone;
-            apiKeyTextField.text = self.account.apiKey;
-            if (apiKey)
-                apiKeyTextField.text = apiKey;
+            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 = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
+            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 *loginURL = [NSString stringWithFormat:@"%@?next=pithos://login", account.pithosLoginURLPrefix]; 
-        
+        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 - Text Field Delegate
+#pragma mark - UITextFieldDelegate
 
-- (BOOL)textFieldShouldReturn:(UITextField *)textField {    
-    [textField resignFirstResponder];    
+- (BOOL)textFieldShouldReturn:(UITextField *)textField {
+    [textField resignFirstResponder];
     if ([textField isEqual:usernameTextField]) {
-        [apiKeyTextField becomeFirstResponder];
+        [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.account.username = result;
-    } else if ([textField isEqual:apiKeyTextField]) {
-        self.account.apiKey = result;
+        self.username = result;
+    } else if ([textField isEqual:authTokenTextField]) {
+        self.authToken = result;
     }
-    self.account.authToken = @"";
-    self.account.hasBeenRefreshed = NO;
-    [self.account persist];
-    
     return YES;
 }
 
-#pragma mark - Memory management
+#pragma mark - Button Handlers
 
-- (void)dealloc {
-    [userName release];
-    [apiKey release];
-    [activityIndicatorView release];
-    [account release];
-    [super dealloc];
+- (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