2 // AccountSettingsViewController.m
5 // Created by Mike Mayo on 12/14/10.
6 // The OpenStack project is provided under the Apache 2.0 license.
9 #import "AccountSettingsViewController.h"
10 #import "OpenStackAccount.h"
12 #import "RSTextFieldCell.h"
13 #import "UIColor+MoreColors.h"
14 #import "OpenStackAppDelegate.h"
15 #import "UIViewController+Conveniences.h"
16 #import "OpenStackRequest.h"
21 @implementation AccountSettingsViewController
23 @synthesize account, userName, apiKey, activityIndicatorView;
25 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
26 return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || (toInterfaceOrientation == UIInterfaceOrientationPortrait);
30 #pragma mark HTTP Response Handlers
32 - (void)authenticationSucceded:(OpenStackRequest *)request {
34 [self.activityIndicatorView removeFromSuperview];
36 if ([request isSuccess]) {
37 account.authToken = [[request responseHeaders] objectForKey:@"X-Auth-Token"];
39 NSString *filesStorageURL;
40 if (![[request responseHeaders] objectForKey:@"X-Storage-URL"]) {
41 filesStorageURL = [NSString stringWithFormat:@"%@/v1/%@",
42 [account.hostURL absoluteString],
44 account.filesURL = [NSURL URLWithString:filesStorageURL];
47 account.filesURL = [NSURL URLWithString:[[request responseHeaders] objectForKey:@"X-Storage-Url"]];
50 account.pithosPublicLinkURLPrefix = account.hostURL;
51 account.pithosLoginURLPrefix = [NSURL URLWithString:
52 [[account.hostURL absoluteString]
53 stringByAppendingString:@"/login"]];
56 [account refreshCollections];
57 [self.navigationController dismissModalViewControllerAnimated:YES];
59 self.navigationItem.rightBarButtonItem.enabled = NO;
60 [self alert:@"Authentication Failure" message:@"Please check your User Name and Token."];
64 - (void)authenticationFailed:(OpenStackRequest *)request {
65 [self.activityIndicatorView removeFromSuperview];
66 self.navigationItem.rightBarButtonItem.enabled = YES;
67 self.account.containers = nil;
68 if ([request responseStatusCode] == 401) {
69 [self alert:@"Authentication Failure" message:@"Please check your User Name and Token."];
71 [self failOnBadConnection];
76 - (void)authenticate {
80 valid = valid && usernameTextField.text && ![@"" isEqualToString:usernameTextField.text];
82 [self alert:nil message:@"Please enter your username."];
83 [usernameTextField becomeFirstResponder];
85 valid = valid && apiKeyTextField.text && ![@"" isEqualToString:apiKeyTextField.text];
87 [self alert:nil message:@"Please enter your token."];
88 [apiKeyTextField becomeFirstResponder];
90 account.username = usernameTextField.text;
91 account.apiKey = apiKeyTextField.text;
93 self.activityIndicatorView = [[[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:@"Authenticating..."] text:@"Authenticating..."] autorelease];
94 [self.activityIndicatorView addToView:self.view];
96 OpenStackRequest *request = [OpenStackRequest authenticationRequest:account];
97 request.delegate = self;
98 request.didFinishSelector = @selector(authenticationSucceded:);
99 request.didFailSelector = @selector(authenticationFailed:);
100 [request startAsynchronous];
108 #pragma mark Button Handlers
110 - (void)saveButtonPressed:(id)sender {
115 #pragma mark - View lifecycle
117 - (void)viewDidLoad {
119 self.navigationItem.title = @"API Account Info";
120 userDetailsSection = 0;
123 /*if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
124 UIView *backgroundContainer = [[UIView alloc] init];
125 backgroundContainer.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
126 backgroundContainer.backgroundColor = [UIColor iPadTableBackgroundColor];
127 NSString *logoFilename = @"account-settings-icon-large.png";
128 UIImageView *osLogo = [[UIImageView alloc] initWithImage:[UIImage imageNamed:logoFilename]];
129 osLogo.contentMode = UIViewContentModeScaleAspectFit;
130 osLogo.frame = CGRectMake(100.0, 100.0, 1000.0, 1000.0);
131 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
134 [backgroundContainer addSubview:osLogo];
136 self.tableView.backgroundView = backgroundContainer;
137 [backgroundContainer release];
140 [self addSaveButton];
144 - (void)viewDidAppear:(BOOL)animated {
145 [super viewDidAppear:animated];
146 //[usernameTextField becomeFirstResponder];
149 #pragma mark - Table view data source
151 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
155 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
156 if (section == userDetailsSection)
162 - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
163 if (section == userDetailsSection)
164 return [NSString stringWithFormat:@"%@ Login", self.account.provider.name];
169 - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
170 if (section == userDetailsSection)
171 return @"API Version 1.0";
176 // Customize the appearance of table view cells.
177 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
179 static NSString *CellIdentifier = @"Cell";
180 RSTextFieldCell *cell = nil;
181 if (indexPath.section == userDetailsSection) {
182 cell = (RSTextFieldCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
184 cell = [[[RSTextFieldCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
185 cell.selectionStyle = UITableViewCellSelectionStyleNone;
188 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
189 cell.backgroundColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:0.8];
192 [cell.textLabel setBackgroundColor:[UIColor clearColor]];
194 if (indexPath.row == kUsername) {
195 cell.textLabel.text = @"Username";
196 usernameTextField = cell.textField;
197 usernameTextField.delegate = self;
198 usernameTextField.secureTextEntry = NO;
199 usernameTextField.returnKeyType = UIReturnKeyNext;
200 usernameTextField.text = self.account.username;
201 usernameTextField.placeholder = @"username";
203 usernameTextField.text = userName;
204 } else if (indexPath.row == kAPIKey) {
205 cell.textLabel.text = @"Token";
206 apiKeyTextField = cell.textField;
207 apiKeyTextField.secureTextEntry = YES;
208 apiKeyTextField.delegate = self;
209 apiKeyTextField.returnKeyType = UIReturnKeyDone;
210 apiKeyTextField.text = self.account.apiKey;
212 apiKeyTextField.text = apiKey;
215 cell = (RSTextFieldCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
217 cell = [[[RSTextFieldCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
220 cell.textLabel.text = @"Get Token";
225 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
226 if (indexPath.section == getTokenSection) {
227 NSString *loginURL = [NSString stringWithFormat:@"%@?next=pithos://login&force=", account.pithosLoginURLPrefix];
228 [[UIApplication sharedApplication] openURL:[NSURL URLWithString:loginURL]];
229 [tableView deselectRowAtIndexPath:indexPath animated:NO];
233 #pragma mark - Text Field Delegate
235 - (BOOL)textFieldShouldReturn:(UITextField *)textField {
236 [textField resignFirstResponder];
237 if ([textField isEqual:usernameTextField]) {
238 [apiKeyTextField becomeFirstResponder];
243 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
244 NSString *result = [textField.text stringByReplacingCharactersInRange:range withString:string];
245 if ([textField isEqual:usernameTextField]) {
246 self.account.username = result;
247 } else if ([textField isEqual:apiKeyTextField]) {
248 self.account.apiKey = result;
250 self.account.authToken = @"";
251 self.account.hasBeenRefreshed = NO;
252 [self.account persist];
257 #pragma mark - Memory management
262 [activityIndicatorView release];