Fix bugs in account creation or account settings, and remove code of rackspace specific functionality.
@interface AccountDetailsViewController : UITableViewController <UITextFieldDelegate> {
Provider *provider;
UITextField *usernameTextField;
- UITextField *apiKeyTextField;
+ UITextField *authTokenTextField;
UITextField *providerNameTextField;
UITextField *apiEndpointTextField;
RootViewController *rootViewController;
- NSString *userName;
- NSString *apiKey;
+ NSString *username;
+ NSString *authToken;
BOOL customProvider;
NSInteger authenticationSection;
NSInteger providerSection;
NSInteger getTokenSection;
- BOOL tableShrunk;
-
OpenStackAccount *account;
}
@property (nonatomic, retain) RootViewController *rootViewController;
@property (nonatomic, retain) ActivityIndicatorView *activityIndicatorView;
-@property (nonatomic, retain) NSString *userName;
-@property (nonatomic, retain) NSString *apiKey;
+@property (nonatomic, retain) NSString *username;
+@property (nonatomic, retain) NSString *authToken;
- (void)saveButtonPressed:(id)sender;
#import "OpenStackAppDelegate.h"
#import "UIColor+MoreColors.h"
-
#define kUsername 0
-#define kAPIKey 1
+#define kAuthToken 1
#define kProviderName 0
#define kAuthEndpoint 1
@implementation AccountDetailsViewController
@synthesize provider, rootViewController, activityIndicatorView;
-@synthesize userName, apiKey;
+@synthesize username, authToken;
#pragma mark - View lifecycle
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[usernameTextField resignFirstResponder];
- [apiKeyTextField resignFirstResponder];
+ [authTokenTextField resignFirstResponder];
[providerNameTextField resignFirstResponder];
[apiEndpointTextField resignFirstResponder];
- tableShrunk = NO;
- CGRect rect = self.tableView.frame;
- rect.size.height = 416.0;
- self.tableView.frame = rect;
}
#pragma mark - Memory management
[provider release];
[rootViewController release];
[activityIndicatorView release];
- [userName release];
- [apiKey release];
+ [username release];
+ [authToken release];
[super dealloc];
}
((UITextField *)*textField).delegate = self;
((UITextField *)*textField).secureTextEntry = secure;
((UITextField *)*textField).returnKeyType = returnKeyType;
- if ([labelText isEqualToString:@"Username"])
- (*textField).text = userName;
- else if ([labelText isEqualToString:@"Token"])
- (*textField).text = apiKey;
}
return cell;
if (indexPath.section == authenticationSection) {
if (indexPath.row == kUsername) {
- if (userName)
- usernameTextField.text = userName;
cell = [self textCell:@"Username" textField:&usernameTextField secure:NO returnKeyType:UIReturnKeyNext];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
CGRect rect = usernameTextField.frame;
CGFloat offset = 19.0;
usernameTextField.frame = CGRectMake(rect.origin.x + offset, rect.origin.y, rect.size.width - offset, rect.size.height);
}
- } else if (indexPath.row == kAPIKey) {
- if (apiKey)
- apiKeyTextField.text = apiKey;
- cell = [self textCell:@"Token" textField:&apiKeyTextField secure:YES returnKeyType:UIReturnKeyDone];
+ if (username)
+ usernameTextField.text = username;
+ } else if (indexPath.row == kAuthToken) {
+ cell = [self textCell:@"Token" textField:&authTokenTextField secure:NO returnKeyType:UIReturnKeyDone];
+ if (authToken)
+ authTokenTextField.text = authToken;
}
} else if (indexPath.section == providerSection) {
if (indexPath.row == kProviderName) {
cell = [self textCell:@"Name" textField:&providerNameTextField secure:NO returnKeyType:UIReturnKeyNext];
- providerNameTextField.placeholder = @"Ex: Pithos";
+ providerNameTextField.placeholder = @"E.g.: pithos";
} else if (indexPath.row == kAuthEndpoint) {
cell = [self textCell:@"API URL" textField:&apiEndpointTextField secure:NO returnKeyType:UIReturnKeyNext];
- apiEndpointTextField.placeholder = @"Type server's url here";
+ apiEndpointTextField.placeholder = @"Type server's URL here";
}
} else if (indexPath.section == getTokenSection) {
static NSString *CellIdentifier = @"Cell";
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == getTokenSection) {
- NSString *loginURLPrefix = nil;
+ NSURL *loginURLPrefix = nil;
if (customProvider) {
- if (!apiEndpointTextField.text || ![apiEndpointTextField.text isURL])
- [self alert:@"No API URL" message:@"Please enter an API URL"];
- else
- loginURLPrefix = [apiEndpointTextField.text stringByAppendingString:@"/login"];
+ if (!apiEndpointTextField.text || ![apiEndpointTextField.text isURL]) {
+ [self alert:@"No API URL" message:@"Please enter an API Authentication URL"];
+ } else {
+ loginURLPrefix = [[NSURL URLWithString:apiEndpointTextField.text] URLByAppendingPathComponent:@"login"];
+ }
} else {
- loginURLPrefix = [[provider.authEndpointURL absoluteString] stringByReplacingOccurrencesOfString:@"/v1" withString:@"/login"];
- }
-
- if (loginURLPrefix) {
- NSString *loginURL = [NSString stringWithFormat:@"%@?next=pithos://login&force=", loginURLPrefix];
- [[UIApplication sharedApplication] openURL:[NSURL URLWithString:loginURL]];
+ loginURLPrefix = [[provider.authEndpointURL URLByDeletingLastPathComponent] URLByAppendingPathComponent:@"login"];
}
+ NSString *loginURL = [NSString stringWithFormat:@"%@?next=pithos://login&force=", loginURLPrefix];
+ [[UIApplication sharedApplication] openURL:[NSURL URLWithString:loginURL]];
[tableView deselectRowAtIndexPath:indexPath animated:NO];
- if (tableShrunk) {
- tableShrunk = NO;
- CGRect rect = self.tableView.frame;
- rect.size.height = 416.0;
- self.tableView.frame = rect;
- }
}
}
#pragma mark - UITextFieldDelegate
-- (void)tableShrinkAnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
- UITextField *textField = ((UITextField *)context);
- if ([textField isEqual:apiKeyTextField] || [textField isEqual:usernameTextField]) {
- [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:kAPIKey inSection:authenticationSection] atScrollPosition:UITableViewScrollPositionNone animated:NO];
- }
-}
-
-- (void)textFieldDidBeginEditing:(UITextField *)textField {
- if (!tableShrunk) {
- if (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPad) {
- [UIView beginAnimations:nil context:textField];
- [UIView setAnimationDuration:0.35];
- [UIView setAnimationDelegate:self];
- [UIView setAnimationDidStopSelector:@selector(tableShrinkAnimationDidStop:finished:context:)];
- CGRect rect = self.tableView.frame;
- rect.size.height = 200.0;
- self.tableView.frame = rect;
- [UIView commitAnimations];
- tableShrunk = YES;
- }
- }
-}
-
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
if ([textField isEqual:providerNameTextField]) {
[apiEndpointTextField becomeFirstResponder];
} else if ([textField isEqual:apiEndpointTextField]) {
[usernameTextField becomeFirstResponder];
- [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:kAPIKey inSection:authenticationSection] atScrollPosition:UITableViewScrollPositionNone animated:YES];
+ [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:kAuthToken inSection:authenticationSection] atScrollPosition:UITableViewScrollPositionNone animated:YES];
} else if ([textField isEqual:usernameTextField]) {
- [apiKeyTextField becomeFirstResponder];
- [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:kAPIKey inSection:authenticationSection] atScrollPosition:UITableViewScrollPositionNone animated:YES];
+ [authTokenTextField becomeFirstResponder];
+ [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:kAuthToken inSection:authenticationSection] atScrollPosition:UITableViewScrollPositionNone animated:YES];
} else {
[textField resignFirstResponder];
- self.navigationItem.rightBarButtonItem.enabled = NO;
- tableShrunk = NO;
- CGRect rect = self.tableView.frame;
- rect.size.height = 416.0;
- self.tableView.frame = rect;
- [self authenticate];
+ [self saveButtonPressed:self];
}
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;
- tableShrunk = NO;
- CGRect rect = self.tableView.frame;
- rect.size.height = 416.0;
- self.tableView.frame = rect;
[self authenticate];
}
- (void)authenticationSucceded:(OpenStackRequest *)request {
[self.activityIndicatorView removeFromSuperview];
-
- if ([request isSuccess]) {
- account.authToken = [[request responseHeaders] objectForKey:@"X-Auth-Token"];
- NSString *storageURLString = [[request responseHeaders] objectForKey:@"X-Storage-URL"];
+ if ([request isSuccess]) {
+ 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.filesURL = [[account.hostURL URLByAppendingPathComponent:@"v1"] URLByAppendingPathComponent:account.username];
}
- account.pithosPublicLinkURLPrefix = account.hostURL;
- account.pithosLoginURLPrefix = [account.hostURL URLByAppendingPathComponent:@"/login"];
-
[account persist];
[rootViewController.tableView reloadData];
- [account refreshCollections];
-
[self.navigationController dismissModalViewControllerAnimated:YES];
} else {
- self.navigationItem.rightBarButtonItem.enabled = NO;
+ self.navigationItem.rightBarButtonItem.enabled = YES;
[self alert:@"Authentication Failure" message:@"Please check your Username and Token."];
}
}
[self alert:nil message:@"Please enter your Username."];
self.navigationItem.rightBarButtonItem.enabled = YES;
[usernameTextField becomeFirstResponder];
- } else if (!apiKeyTextField.text || [apiKeyTextField.text isEqualToString:@""]) {
+ } else if (!authTokenTextField.text || [authTokenTextField.text isEqualToString:@""]) {
[self alert:nil message:@"Please enter your Token."];
self.navigationItem.rightBarButtonItem.enabled = YES;
- [apiKeyTextField becomeFirstResponder];
+ [authTokenTextField becomeFirstResponder];
} else {
account = [[OpenStackAccount alloc] init];
if (customProvider) {
account.provider = [[[Provider alloc] init] autorelease];
account.provider.name = providerNameTextField.text;
- account.provider.authEndpointURL = [[NSURL URLWithString:apiEndpointTextField.text] URLByAppendingPathComponent:@"/v1"];
+ account.provider.authEndpointURL = [[NSURL URLWithString:apiEndpointTextField.text] URLByAppendingPathComponent:@"v1"];
} else {
account.provider = provider;
}
account.username = usernameTextField.text;
- account.apiKey = apiKeyTextField.text;
+ account.authToken = authTokenTextField.text;
account.hostURL = [account.provider.authEndpointURL URLByDeletingLastPathComponent];
-
+
self.activityIndicatorView = [[[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:@"Authenticating..."] text:@"Authenticating..."] autorelease];
[self.activityIndicatorView addToView:self.view];
NSInteger refreshCount;
- NSInteger totalRows;
NSInteger storageRow;
- NSInteger accountSettingsRow;
- NSInteger accountMetadataRow;
NSInteger mySharedRow;
NSInteger othersSharedRow;
-
- IBOutlet UIBarButtonItem *refreshButton;
+ NSInteger accountSettingsRow;
+ NSInteger accountMetadataRow;
}
@property (nonatomic, retain) OpenStackAccount *account;
@property (nonatomic, retain) RootViewController *rootViewController;
@property (nonatomic, retain) IBOutlet UITableView *tableView;
-- (void)refreshButtonPressed:(id)sender;
-
@end
@synthesize account, rootViewController, tableView;
-#pragma mark -
-#pragma mark View lifecycle
+#pragma mark - View lifecycle
-- (void)incrementRefreshCount {
- refreshCount++;
- //if (refreshCount == 2) {
- self.account.hasBeenRefreshed = YES;
- [self hideToolbarActivityMessage];
- refreshButton.enabled = YES;
- //}
-}
- (void)viewDidLoad {
[super viewDidLoad];
-
+
Reachability *reachability = [Reachability reachabilityForInternetConnection];
if ([reachability currentReachabilityStatus] == kNotReachable) {
self.account.hasBeenRefreshed = YES;
[self hideToolbarActivityMessage];
- refreshButton.enabled = YES;
[self failOnBadConnection];
}
+ storageRow = 0;
mySharedRow = 0;
othersSharedRow = 1;
accountSettingsRow = 0;
accountMetadataRow = 1;
-
-
-
- id getContainersObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"getContainersSucceeded" object:self.account
- queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
- {
+ id getContainersObserver = [[NSNotificationCenter defaultCenter]
+ addObserverForName:@"getContainersSucceeded"
+ object:self.account
+ queue:[NSOperationQueue mainQueue]
+ usingBlock:^(NSNotification *notification) {
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:storageRow inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
[self incrementRefreshCount];
}];
- id getContainersFailedObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"getContainersFailed" object:self.account
- queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
- {
+ id getContainersFailedObserver = [[NSNotificationCenter defaultCenter]
+ addObserverForName:@"getContainersFailed"
+ object:self.account
+ queue:[NSOperationQueue mainQueue]
+ usingBlock:^(NSNotification *notification) {
[self incrementRefreshCount];
}];
- id createContainerObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"createContainerSucceeded" object:self.account
- queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
- {
+ id createContainerObserver = [[NSNotificationCenter defaultCenter]
+ addObserverForName:@"createContainerSucceeded"
+ object:self.account
+ queue:[NSOperationQueue mainQueue]
+ usingBlock:^(NSNotification *notification) {
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:storageRow inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
}];
- id deleteContainerObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"deleteContainerSucceeded" object:self.account
- queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification)
- {
+ id deleteContainerObserver = [[NSNotificationCenter defaultCenter]
+ addObserverForName:@"deleteContainerSucceeded"
+ object:self.account
+ queue:[NSOperationQueue mainQueue]
+ usingBlock:^(NSNotification *notification) {
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:storageRow inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
}];
observers = [[NSArray alloc] initWithObjects: getContainersObserver, getContainersFailedObserver, createContainerObserver, deleteContainerObserver, nil];
-
-
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
- self.navigationItem.title = self.account.username;
-
+
+ self.navigationItem.title = self.account.username;
account.shared = NO;
account.sharingAccount = nil;
-
- totalRows = 0;
- storageRow = (self.account.filesURL && [self.account.filesURL host]) ? totalRows++ : -1;
-
+
[self.tableView reloadData];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
}
}
-- (void)viewDidAppear:(BOOL)animated {
- [super viewDidAppear:animated];
- if (!self.account.hasBeenRefreshed) {
- [self.account refreshCollections];
- }
-}
-
- (void)viewDidUnload {
for (id observer in observers) {
[[NSNotificationCenter defaultCenter] removeObserver:observer];
[super viewDidUnload];
}
-- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
- return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
+
+#pragma mark - Memory management
+
+- (void)dealloc {
+ [account release];
+ [rootViewController release];
+ [observers release];
+ [tableView release];
+ [super dealloc];
}
-#pragma mark -
-#pragma mark Table view data source
+#pragma mark - Internal
+
+- (void)incrementRefreshCount {
+ refreshCount++;
+ self.account.hasBeenRefreshed = YES;
+ [self hideToolbarActivityMessage];
+}
+
+#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 3;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
- if (section == kObjectStorage)
- return totalRows;
- else
+ if (section == kObjectStorage) {
+ return 1;
+ } else {
return 2;
+ }
}
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
-
static NSString *CellIdentifier = @"Cell";
-
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
-
cell.imageView.image = nil;
if (indexPath.section == kObjectStorage) {
if (indexPath.row == accountSettingsRow) {
cell.textLabel.text = @"Account Token";
cell.imageView.image = [UIImage imageNamed:@"account-settings-icon.png"];
- if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
- cell.accessoryType = UITableViewCellAccessoryNone;
- } else {
- cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
- }
} else if (indexPath.row == accountMetadataRow) {
cell.textLabel.text = @"Account Metadata";
cell.imageView.image = [UIImage imageNamed:@"account-settings-icon.png"];
- if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
- cell.accessoryType = UITableViewCellAccessoryNone;
- } else {
- cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
- }
+ }
+ if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
+ cell.accessoryType = UITableViewCellAccessoryNone;
+ } else {
+ cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
}
-
+
return cell;
}
-#pragma mark -
-#pragma mark Table view delegate
+#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[super tableView:aTableView didSelectRowAtIndexPath:indexPath];
[app.rootViewController.popoverController dismissPopoverAnimated:YES];
}
-#pragma mark -
-#pragma mark Button Handlers
-
-- (void)refreshButtonPressed:(id)sender {
- refreshCount = 0;
- [self.account refreshCollections];
-}
-
-#pragma mark -
-#pragma mark Memory management
-
-- (void)dealloc {
- [account release];
- [rootViewController release];
- [observers release];
- [tableView release];
- [super dealloc];
-}
-
@end
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.10">
<data>
- <int key="IBDocument.SystemTarget">1280</int>
- <string key="IBDocument.SystemVersion">10K549</string>
- <string key="IBDocument.InterfaceBuilderVersion">1938</string>
- <string key="IBDocument.AppKitVersion">1038.36</string>
- <string key="IBDocument.HIToolboxVersion">461.00</string>
+ <int key="IBDocument.SystemTarget">1536</int>
+ <string key="IBDocument.SystemVersion">11G63</string>
+ <string key="IBDocument.InterfaceBuilderVersion">2843</string>
+ <string key="IBDocument.AppKitVersion">1138.51</string>
+ <string key="IBDocument.HIToolboxVersion">569.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
- <string key="NS.object.0">933</string>
+ <string key="NS.object.0">1929</string>
</object>
<object class="NSArray" key="IBDocument.IntegratedClassDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
- <string>IBUIBarButtonItem</string>
- <string>IBUIToolbar</string>
+ <string>IBProxyObject</string>
<string>IBUITableView</string>
<string>IBUIView</string>
- <string>IBProxyObject</string>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
<int key="NSvFlags">292</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
- <object class="IBUIToolbar" id="302743223">
- <reference key="NSNextResponder" ref="1064914977"/>
- <int key="NSvFlags">266</int>
- <string key="NSFrame">{{0, 416}, {320, 44}}</string>
- <reference key="NSSuperview" ref="1064914977"/>
- <reference key="NSWindow"/>
- <reference key="NSNextKeyView"/>
- <bool key="IBUIOpaque">NO</bool>
- <bool key="IBUIClearsContextBeforeDrawing">NO</bool>
- <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
- <object class="NSMutableArray" key="IBUIItems">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="IBUIBarButtonItem" id="1057849967">
- <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
- <reference key="IBUIToolbar" ref="302743223"/>
- <int key="IBUISystemItemIdentifier">5</int>
- </object>
- <object class="IBUIBarButtonItem" id="589134056">
- <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
- <reference key="IBUIToolbar" ref="302743223"/>
- <int key="IBUISystemItemIdentifier">5</int>
- </object>
- <object class="IBUIBarButtonItem" id="261181725">
- <string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
- <float key="IBUIWidth">33</float>
- <reference key="IBUIToolbar" ref="302743223"/>
- <int key="IBUISystemItemIdentifier">6</int>
- </object>
- </object>
- <object class="NSColor" key="IBUITintColor">
- <int key="NSColorSpace">2</int>
- <bytes key="NSRGB">MC44MDc4NDMyMDgzIDAuMjAwMDAwMDE3OSAwLjE0OTAxOTYxMzkAA</bytes>
- </object>
- </object>
<object class="IBUITableView" id="638451124">
<reference key="NSNextResponder" ref="1064914977"/>
<int key="NSvFlags">274</int>
- <string key="NSFrameSize">{320, 416}</string>
+ <string key="NSFrameSize">{320, 460}</string>
<reference key="NSSuperview" ref="1064914977"/>
- <reference key="NSWindow"/>
- <reference key="NSNextKeyView" ref="302743223"/>
+ <reference key="NSNextKeyView"/>
<object class="NSColor" key="IBUIBackgroundColor">
- <int key="NSColorSpace">10</int>
- <object class="NSImage" key="NSImage">
- <int key="NSImageFlags">549453824</int>
- <string key="NSSize">{512, 1}</string>
- <object class="NSMutableArray" key="NSReps">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <integer value="0"/>
- <object class="NSBitmapImageRep">
- <object class="NSData" key="NSTIFFRepresentation">
- <bytes key="NS.bytes">TU0AKgAACAjFzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/
-y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/
-xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/
-xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/
-xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/
-xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/
-xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/
-y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/
-y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/
-xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/
-xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/
-xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/
-xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/
-xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/
-y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/
-y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/
-xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/
-xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/
-xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/
-xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/
-xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/
-y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/
-y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/
-xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/
-xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/
-xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/
-xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/
-xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/
-y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/
-y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/
-xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/
-xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/
-xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/xczS/8vS2P/L0tj/xczU/8XM1P/FzNT/
-xczU/8XM0v/L0tj/y9LY/8XM1P/FzNT/xczU/8XM1P/FzNL/y9LY/8vS2P/FzNT/xczU/8XM1P/FzNT/
-xczS/8vS2P/L0tj/xczU/wANAQAAAwAAAAECAAAAAQEAAwAAAAEAAQAAAQIAAwAAAAQAAAiqAQMAAwAA
-AAEAAQAAAQYAAwAAAAEAAgAAAREABAAAAAEAAAAIARIAAwAAAAEAAQAAARUAAwAAAAEABAAAARYAAwAA
-AAEAAQAAARcABAAAAAEAAAgAARwAAwAAAAEAAQAAAVIAAwAAAAEAAQAAAVMAAwAAAAQAAAiyAAAAAAAI
-AAgACAAIAAEAAQABAAE</bytes>
- </object>
- </object>
- </object>
- </object>
- <object class="NSColor" key="NSColor">
- <int key="NSColorSpace">3</int>
- <bytes key="NSWhite">MCAwAA</bytes>
- </object>
- </object>
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MCAwIDAgMAA</bytes>
<string key="IBUIColorCocoaTouchKeyPath">groupTableViewBackgroundColor</string>
</object>
<bool key="IBUIOpaque">NO</bool>
</object>
<string key="NSFrameSize">{320, 460}</string>
<reference key="NSSuperview"/>
- <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="638451124"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
- <string key="label">toolbar</string>
- <reference key="source" ref="372490531"/>
- <reference key="destination" ref="302743223"/>
- </object>
- <int key="connectionID">14</int>
- </object>
- <object class="IBConnectionRecord">
- <object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">tableView</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="638451124"/>
<reference key="object" ref="1064914977"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
- <reference ref="302743223"/>
<reference ref="638451124"/>
</object>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
- <int key="objectID">9</int>
- <reference key="object" ref="302743223"/>
- <object class="NSMutableArray" key="children">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <reference ref="1057849967"/>
- <reference ref="589134056"/>
- <reference ref="261181725"/>
- </object>
- <reference key="parent" ref="1064914977"/>
- <string key="objectName">Toolbar</string>
- </object>
- <object class="IBObjectRecord">
<int key="objectID">10</int>
<reference key="object" ref="638451124"/>
<reference key="parent" ref="1064914977"/>
</object>
- <object class="IBObjectRecord">
- <int key="objectID">11</int>
- <reference key="object" ref="1057849967"/>
- <reference key="parent" ref="302743223"/>
- </object>
- <object class="IBObjectRecord">
- <int key="objectID">12</int>
- <reference key="object" ref="589134056"/>
- <reference key="parent" ref="302743223"/>
- </object>
- <object class="IBObjectRecord">
- <int key="objectID">18</int>
- <reference key="object" ref="261181725"/>
- <reference key="parent" ref="302743223"/>
- </object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
<string>-2.CustomClassName</string>
<string>-2.IBPluginDependency</string>
<string>10.IBPluginDependency</string>
- <string>11.IBPluginDependency</string>
- <string>12.IBPluginDependency</string>
- <string>18.IBPluginDependency</string>
<string>8.IBPluginDependency</string>
- <string>9.IBPluginDependency</string>
</object>
- <object class="NSMutableArray" key="dict.values">
+ <object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>AccountHomeViewController</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
- <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
- <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
- <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
- <string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</object>
</object>
<object class="NSMutableDictionary" key="unlocalizedProperties">
<nil key="sourceID"/>
<int key="maxID">21</int>
</object>
- <object class="IBClassDescriber" key="IBDocument.Classes">
- <object class="NSMutableArray" key="referencedPartialClassDescriptions">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="IBPartialClassDescription">
- <string key="className">AccountHomeViewController</string>
- <string key="superclassName">OpenStackViewController</string>
- <object class="NSMutableDictionary" key="outlets">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>refreshButton</string>
- <string>tableView</string>
- </object>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>UIBarButtonItem</string>
- <string>UITableView</string>
- </object>
- </object>
- <object class="NSMutableDictionary" key="toOneOutletInfosByName">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSArray" key="dict.sortedKeys">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <string>refreshButton</string>
- <string>tableView</string>
- </object>
- <object class="NSMutableArray" key="dict.values">
- <bool key="EncodedWithXMLCoder">YES</bool>
- <object class="IBToOneOutletInfo">
- <string key="name">refreshButton</string>
- <string key="candidateClassName">UIBarButtonItem</string>
- </object>
- <object class="IBToOneOutletInfo">
- <string key="name">tableView</string>
- <string key="candidateClassName">UITableView</string>
- </object>
- </object>
- </object>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBProjectSource</string>
- <string key="minorKey">./Classes/AccountHomeViewController.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
- <string key="className">OpenStackViewController</string>
- <string key="superclassName">UIViewController</string>
- <object class="NSMutableDictionary" key="outlets">
- <string key="NS.key.0">toolbar</string>
- <string key="NS.object.0">UIToolbar</string>
- </object>
- <object class="NSMutableDictionary" key="toOneOutletInfosByName">
- <string key="NS.key.0">toolbar</string>
- <object class="IBToOneOutletInfo" key="NS.object.0">
- <string key="name">toolbar</string>
- <string key="candidateClassName">UIToolbar</string>
- </object>
- </object>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBProjectSource</string>
- <string key="minorKey">./Classes/OpenStackViewController.h</string>
- </object>
- </object>
- </object>
- </object>
+ <object class="IBClassDescriber" key="IBDocument.Classes"/>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
- <real value="1280" key="NS.object.0"/>
+ <real value="1536" key="NS.object.0"/>
</object>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDevelopmentDependencies">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3</string>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
- <string key="IBCocoaTouchPluginVersion">933</string>
+ <string key="IBCocoaTouchPluginVersion">1929</string>
</data>
</archive>
- (NSString *)notificationName:(NSString *)key identifier:(NSString *)identifier;
- (void)notify:(NSString *)name request:(OpenStackRequest *)request;
- (void)notify:(NSString *)name request:(OpenStackRequest *)request object:(id)object;
-
-- (APICallback *)authenticate;
// object storage
return [self callbackWithRequest:request];
}
-- (APICallback *)authenticate {
- __block OpenStackRequest *request = [OpenStackRequest authenticationRequest:self.account];
- return [self callbackWithRequest:request success:^(OpenStackRequest *request) {
- if ([request isSuccess]) {
- self.account.authToken = [[request responseHeaders] objectForKey:@"X-Auth-Token"];
-
-
- if (![[request responseHeaders] objectForKey:@"X-Storage-URL"]) {
- NSString *filesStorageURL = [NSString stringWithFormat:@"%@/v1/%@",
- [self.account.hostURL absoluteString],
- [self.account username]];
-
- self.account.filesURL = [NSURL URLWithString:filesStorageURL];
- } else {
- self.account.filesURL = [NSURL URLWithString:[[request responseHeaders] objectForKey:@"X-Storage-Url"]];
- }
-
- self.account.pithosPublicLinkURLPrefix = self.account.hostURL;
- self.account.pithosLoginURLPrefix = [NSURL URLWithString:[[self.account.hostURL absoluteString] stringByAppendingString:@"/login"]];
-
- [self.account persist];
- }
- }];
-}
-
#pragma mark -
#pragma mark Memory Management
@interface AccountSettingsViewController : UITableViewController <UITextFieldDelegate> {
UITextField *usernameTextField;
- UITextField *apiKeyTextField;
+ UITextField *authTokenTextField;
NSInteger userDetailsSection;
NSInteger getTokenSection;
- NSString *userName;
- NSString *apiKey;
+ NSString *username;
+ NSString *authToken;
ActivityIndicatorView *activityIndicatorView;
}
@property (nonatomic, retain) OpenStackAccount *account;
-@property (nonatomic, retain) NSString *userName;
-@property (nonatomic, retain) NSString *apiKey;
+@property (nonatomic, retain) NSString *username;
+@property (nonatomic, retain) NSString *authToken;
@property (nonatomic, retain) ActivityIndicatorView *activityIndicatorView;
- (void)saveButtonPressed:(id)sender;
#import "OpenStackRequest.h"
#define kUsername 0
-#define kAPIKey 1
+#define kAuthToken 1
@implementation AccountSettingsViewController
-@synthesize account, userName, apiKey, activityIndicatorView;
+@synthesize account, username, authToken, activityIndicatorView;
+
+#pragma mark - View lifecycle
- (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];
-
- if ([request isSuccess]) {
- account.authToken = [[request responseHeaders] objectForKey:@"X-Auth-Token"];
-
- 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"]];
-
- [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."];
- }
-}
-
-- (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 = @"API Account Info";
+ 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];
+ [activityIndicatorView 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.length && checkAuthToken.length &&
+ (![checkUsername isEqualToString:account.username] ||
+ ![checkAuthToken isEqualToString:account.authToken]));
}
+#pragma mark - Properties
-#pragma mark - View lifecycle
-
-- (void)viewDidLoad {
- [super viewDidLoad];
- self.navigationItem.title = @"API Account Info";
- userDetailsSection = 0;
- 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)setUsername:(NSString *)aUsername {
+ [username release];
+ username = [aUsername retain];
+ if (username)
+ [self updateSaveButtonForUsername:username andAuthToken:authTokenTextField.text];
}
-
-- (void)viewDidAppear:(BOOL)animated {
- [super viewDidAppear:animated];
- //[usernameTextField becomeFirstResponder];
+- (void)setAuthToken:(NSString *)anAuthToken {
+ [authToken release];
+ authToken = [anAuthToken retain];
+ if (authToken)
+ [self updateSaveButtonForUsername:usernameTextField.text andAuthToken:authToken];
}
-#pragma mark - Table view data source
+#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if (section == userDetailsSection)
return [NSString stringWithFormat:@"%@ Login", self.account.provider.name];
- else
+ else
return nil;
}
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) {
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];
return cell;
}
+#pragma mark - UITableViewDelegate
+
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == getTokenSection) {
- NSString *loginURL = [NSString stringWithFormat:@"%@?next=pithos://login&force=", account.pithosLoginURLPrefix];
+ NSString *loginURL = [NSString stringWithFormat:@"%@?next=pithos://login&force=", account.pithosLoginURLPrefix];
[[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 - HTTP Response Handlers
+
+- (void)authenticationSucceded:(OpenStackRequest *)request {
+ [self.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."];
+ }
+}
+
+- (void)authenticationFailed:(OpenStackRequest *)request {
+ [self.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];
+ }
}
+- (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;
+
+ self.activityIndicatorView = [[[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:@"Authenticating..."] text:@"Authenticating..."] autorelease];
+ [self.activityIndicatorView addToView:self.view];
+
+ OpenStackRequest *request = [OpenStackRequest authenticationRequest:temporaryAccount];
+ request.delegate = self;
+ request.didFinishSelector = @selector(authenticationSucceded:);
+ request.didFailSelector = @selector(authenticationFailed:);
+ [request startAsynchronous];
+ }
+}
@end
@implementation NSString (Conveniences)
- (BOOL)isURL {
- return [self hasPrefix:@"http://"] || [self hasPrefix:@"https://"];
+// return [self hasPrefix:@"http://"] || [self hasPrefix:@"https://"];
+ return [[NSPredicate predicateWithFormat:@"SELF MATCHES %@",
+ @"(http|https)://((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+"]
+ evaluateWithObject:self];
}
- (NSString *)replace:(NSString *)s with:(NSString *)r {
@property (nonatomic, retain) NSString *authToken;
@property (nonatomic, retain) NSURL *hostURL;
@property (nonatomic, retain) NSURL *filesURL;
-@property (nonatomic, retain) NSURL *pithosPublicLinkURLPrefix;
-@property (nonatomic, retain) NSURL *pithosLoginURLPrefix;
+@property (nonatomic, readonly) NSURL *pithosPublicLinkURLPrefix;
+@property (nonatomic, readonly) NSURL *pithosLoginURLPrefix;
@property (nonatomic, retain) AccountManager *manager;
@property (nonatomic, assign) NSInteger containerCount;
@property (nonatomic, assign) unsigned long long totalBytesUsed;
+ (NSArray *)accounts;
- (void)persist;
+ (void)persist:(NSArray *)accountArray;
-- (void)refreshCollections;
- (NSArray *)pithosSortedContainers;
return pithosSortedContainers;
}
-#pragma mark -
-#pragma mark Collections API Management
+#pragma mark - Properties
-- (void)refreshCollections {
- if (!self.manager) {
- self.manager = [[[AccountManager alloc] init] autorelease];
- self.manager.account = self;
- }
+-(NSURL *)pithosPublicLinkURLPrefix {
+ return self.hostURL;
+}
- // XXX check if the following is needed
- [[self.manager authenticate] success:^(OpenStackRequest *request){
- } failure:^(OpenStackRequest *request){
- }];
+-(NSURL *)pithosLoginURLPrefix {
+ return [self.hostURL URLByAppendingPathComponent:@"login"];
}
-#pragma mark -
-#pragma mark Serialization
+#pragma mark - Serialization
- (id)copyWithZone:(NSZone *)zone {
OpenStackAccount *copy = [[OpenStackAccount allocWithZone:zone] init];
[filesURL release];
[containers release];
[sharingAccount release];
- [pithosLoginURLPrefix release];
- [pithosPublicLinkURLPrefix release];
[super dealloc];
}
if (vc) {
gotToken = YES;
if (authToken)
- [vc setValue:authToken forKey:@"apiKey"];
+ [vc setValue:authToken forKey:@"authToken"];
if (authUser)
- [vc setValue:authUser forKey:@"userName"];
+ [vc setValue:authUser forKey:@"username"];
[((UITableViewController *)vc).tableView reloadData];
}
}
OpenStackRequest *request = [[[OpenStackRequest alloc] initWithURL:account.provider.authEndpointURL] autorelease];
request.account = account;
[request addRequestHeader:@"X-Auth-User" value:account.username];
- if (account.apiKey) {
- [request addRequestHeader:@"X-Auth-Key" value:account.apiKey];
+ if (account.authToken) {
+ [request addRequestHeader:@"X-Auth-Token" value:account.authToken];
} else {
- [request addRequestHeader:@"X-Auth-Key" value:@""];
+ [request addRequestHeader:@"X-Auth-Token" value:@""];
}
return request;