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"];
38 account.serversURL = [NSURL URLWithString:[[request responseHeaders] objectForKey:@"X-Server-Management-Url"]];
40 NSString *filesStorageURL;
41 if (![[request responseHeaders] objectForKey:@"X-Storage-URL"]) {
42 filesStorageURL = [NSString stringWithFormat:@"%@/v1/%@",
43 [account.hostURL absoluteString],
45 account.filesURL = [NSURL URLWithString:filesStorageURL];
48 account.filesURL = [NSURL URLWithString:[[request responseHeaders] objectForKey:@"X-Storage-Url"]];
51 account.pithosPublicLinkURLPrefix = account.hostURL;
52 account.pithosLoginURLPrefix = [NSURL URLWithString:
53 [[account.hostURL absoluteString]
54 stringByAppendingString:@"/login"]];
56 NSString *cdnStr = [[request responseHeaders] objectForKey:@"X-Cdn-Management-Url"];
58 cdnStr = [[request responseHeaders] objectForKey:@"X-CDN-Management-Url"];
61 account.cdnURL = [NSURL URLWithString:cdnStr];
64 [account refreshCollections];
65 [self.navigationController dismissModalViewControllerAnimated:YES];
67 self.navigationItem.rightBarButtonItem.enabled = NO;
68 [self alert:@"Authentication Failure" message:@"Please check your User Name and Token."];
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."];
79 [self failOnBadConnection];
84 - (void)authenticate {
88 valid = valid && usernameTextField.text && ![@"" isEqualToString:usernameTextField.text];
90 [self alert:nil message:@"Please enter your username."];
91 [usernameTextField becomeFirstResponder];
93 valid = valid && apiKeyTextField.text && ![@"" isEqualToString:apiKeyTextField.text];
95 [self alert:nil message:@"Please enter your token."];
96 [apiKeyTextField becomeFirstResponder];
98 account.username = usernameTextField.text;
99 account.apiKey = apiKeyTextField.text;
101 self.activityIndicatorView = [[[ActivityIndicatorView alloc] initWithFrame:[ActivityIndicatorView frameForText:@"Authenticating..."] text:@"Authenticating..."] autorelease];
102 [self.activityIndicatorView addToView:self.view];
104 OpenStackRequest *request = [OpenStackRequest authenticationRequest:account];
105 request.delegate = self;
106 request.didFinishSelector = @selector(authenticationSucceded:);
107 request.didFailSelector = @selector(authenticationFailed:);
108 [request startAsynchronous];
116 #pragma mark Button Handlers
118 - (void)saveButtonPressed:(id)sender {
123 #pragma mark - View lifecycle
125 - (void)viewDidLoad {
127 self.navigationItem.title = @"API Account Info";
128 userDetailsSection = 0;
129 if ([self.account.provider isGRNet])
132 getTokenSection = -1;
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) {
145 [backgroundContainer addSubview:osLogo];
147 self.tableView.backgroundView = backgroundContainer;
148 [backgroundContainer release];
151 [self addSaveButton];
155 - (void)viewDidAppear:(BOOL)animated {
156 [super viewDidAppear:animated];
157 //[usernameTextField becomeFirstResponder];
160 #pragma mark - Table view data source
162 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
163 if (getTokenSection > 0)
169 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
170 if (section == userDetailsSection)
176 - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
177 if (section == userDetailsSection)
178 return [NSString stringWithFormat:@"%@ Login", self.account.provider.name];
183 - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
184 if (section == userDetailsSection)
185 return [NSString stringWithFormat:@"API Version %@", self.account.apiVersion];
190 // Customize the appearance of table view cells.
191 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
193 static NSString *CellIdentifier = @"Cell";
194 RSTextFieldCell *cell = nil;
195 if (indexPath.section == userDetailsSection) {
196 cell = (RSTextFieldCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
198 cell = [[[RSTextFieldCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
199 cell.selectionStyle = UITableViewCellSelectionStyleNone;
202 if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
203 cell.backgroundColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:0.8];
206 [cell.textLabel setBackgroundColor:[UIColor clearColor]];
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";
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;
226 apiKeyTextField.text = apiKey;
229 cell = (RSTextFieldCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
231 cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
234 cell.textLabel.text = @"Get Token";
239 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
240 if (indexPath.section == getTokenSection) {
241 NSString *loginURL = [NSString stringWithFormat:@"%@?next=pithos://login", account.pithosLoginURLPrefix];
243 [[UIApplication sharedApplication] openURL:[NSURL URLWithString:loginURL]];
244 [tableView deselectRowAtIndexPath:indexPath animated:NO];
248 #pragma mark - Text Field Delegate
250 - (BOOL)textFieldShouldReturn:(UITextField *)textField {
251 [textField resignFirstResponder];
252 if ([textField isEqual:usernameTextField]) {
253 [apiKeyTextField becomeFirstResponder];
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;
265 self.account.authToken = @"";
266 self.account.hasBeenRefreshed = NO;
267 [self.account persist];
272 #pragma mark - Memory management
277 [activityIndicatorView release];