Skip to content
Find file
Fetching contributors…
Cannot retrieve contributors at this time
237 lines (199 sloc) 8.29 KB
//
// ASIAuthenticationDialog.m
// Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest
//
// Created by Ben Copsey on 21/08/2009.
// Copyright 2009 All-Seeing Interactive. All rights reserved.
//
#import "ASIAuthenticationDialog.h"
#import "ASIHTTPRequest.h"
ASIAuthenticationDialog *sharedDialog = nil;
NSLock *dialogLock = nil;
@interface ASIAuthenticationDialog ()
- (void)show;
@end
@implementation ASIAuthenticationDialog
+ (void)initialize
{
if (self == [ASIAuthenticationDialog class]) {
dialogLock = [[NSLock alloc] init];
}
}
+ (void)presentProxyAuthenticationDialogForRequest:(ASIHTTPRequest *)request
{
[dialogLock lock];
[sharedDialog release];
sharedDialog = [[self alloc] init];
[sharedDialog setRequest:request];
[sharedDialog setType:ASIProxyAuthenticationType];
[sharedDialog show];
[dialogLock unlock];
}
+ (void)presentAuthenticationDialogForRequest:(ASIHTTPRequest *)request
{
[dialogLock lock];
[sharedDialog release];
sharedDialog = [[self alloc] init];
[sharedDialog setRequest:request];
[sharedDialog show];
[dialogLock unlock];
}
- (void)show
{
// Create an action sheet to show the login dialog
[self setLoginDialog:[[[UIActionSheet alloc] init] autorelease]];
[[self loginDialog] setActionSheetStyle:UIActionSheetStyleBlackOpaque];
[[self loginDialog] setDelegate:self];
// We show the login form in a table view, similar to Safari's authentication dialog
UITableView *table = [[[UITableView alloc] initWithFrame:CGRectMake(0,80,320,480) style:UITableViewStyleGrouped] autorelease];
[table setDelegate:self];
[table setDataSource:self];
[[self loginDialog] addSubview:table];
[[self loginDialog] showInView:[[[UIApplication sharedApplication] windows] objectAtIndex:0]];
[[self loginDialog] setFrame:CGRectMake(0,0,320,480)];
// Setup the title (Couldn't figure out how to put this in the same toolbar as the buttons)
UIToolbar *titleBar = [[[UIToolbar alloc] initWithFrame:CGRectMake(0,0,320,30)] autorelease];
UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(10,0,300,30)] autorelease];
if ([self type] == ASIProxyAuthenticationType) {
[label setText:@"Login to this secure proxy server."];
} else {
[label setText:@"Login to this secure server."];
}
[label setTextColor:[UIColor blackColor]];
[label setFont:[UIFont systemFontOfSize:13.0]];
[label setShadowColor:[UIColor colorWithRed:1 green:1 blue:1 alpha:0.5]];
[label setShadowOffset:CGSizeMake(0, 1.0)];
[label setOpaque:NO];
[label setBackgroundColor:nil];
[label setTextAlignment:UITextAlignmentCenter];
[titleBar addSubview:label];
[[self loginDialog] addSubview:titleBar];
// Setup the toolbar
UIToolbar *toolbar = [[[UIToolbar alloc] initWithFrame:CGRectMake(0,30,320,50)] autorelease];
NSMutableArray *items = [[[NSMutableArray alloc] init] autorelease];
UIBarButtonItem *backButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelAuthenticationFromDialog:)] autorelease];
[items addObject:backButton];
label = [[[UILabel alloc] initWithFrame:CGRectMake(0,0,170,50)] autorelease];
if ([self type] == ASIProxyAuthenticationType) {
[label setText:[[self request] proxyHost]];
} else {
[label setText:[[[self request] url] host]];
}
[label setTextColor:[UIColor whiteColor]];
[label setFont:[UIFont boldSystemFontOfSize:22.0]];
[label setShadowColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:0.5]];
[label setShadowOffset:CGSizeMake(0, -1.0)];
[label setOpaque:NO];
[label setBackgroundColor:nil];
[label setTextAlignment:UITextAlignmentCenter];
[toolbar addSubview:label];
UIBarButtonItem *labelButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:nil action:nil] autorelease];
[labelButton setCustomView:label];
[items addObject:labelButton];
[items addObject:[[[UIBarButtonItem alloc] initWithTitle:@"Login" style:UIBarButtonItemStyleDone target:self action:@selector(loginWithCredentialsFromDialog:)] autorelease]];
[toolbar setItems:items];
[[self loginDialog] addSubview:toolbar];
// Force reload the table content, and focus the first field to show the keyboard
[table reloadData];
[[[[table cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]] subviews] objectAtIndex:2] becomeFirstResponder];
}
- (void)cancelAuthenticationFromDialog:(id)sender
{
[[self request] cancelAuthentication];
[[self loginDialog] dismissWithClickedButtonIndex:0 animated:YES];
}
- (void)loginWithCredentialsFromDialog:(id)sender
{
NSString *username = [[[[[[[self loginDialog] subviews] objectAtIndex:0] cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]] subviews] objectAtIndex:2] text];
NSString *password = [[[[[[[self loginDialog] subviews] objectAtIndex:0] cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:1]] subviews] objectAtIndex:2] text];
if ([self type] == ASIProxyAuthenticationType) {
[[self request] setProxyUsername:username];
[[self request] setProxyPassword:password];
} else {
[[self request] setUsername:username];
[[self request] setPassword:password];
}
// Handle NTLM domains
NSString *scheme = ([self type] == ASIStandardAuthenticationType) ? [[self request] authenticationScheme] : [[self request] proxyAuthenticationScheme];
if ([scheme isEqualToString:(NSString *)kCFHTTPAuthenticationSchemeNTLM]) {
NSString *domain = [[[[[[[self loginDialog] subviews] objectAtIndex:0] cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:2]] subviews] objectAtIndex:2] text];
if ([self type] == ASIProxyAuthenticationType) {
[[self request] setProxyDomain:domain];
} else {
[[self request] setDomain:domain];
}
}
[[self loginDialog] dismissWithClickedButtonIndex:1 animated:YES];
[[self request] retryUsingSuppliedCredentials];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
NSString *scheme = ([self type] == ASIStandardAuthenticationType) ? [[self request] authenticationScheme] : [[self request] proxyAuthenticationScheme];
if ([scheme isEqualToString:(NSString *)kCFHTTPAuthenticationSchemeNTLM]) {
return 3;
}
return 2;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
if (section == [self numberOfSectionsInTableView:tableView]-1) {
return 30;
}
return 0;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
if (section == 0) {
return 30;
}
return 0;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if (section == 0) {
return [[self request] authenticationRealm];
}
return nil;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_3_0
UITableViewCell *cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:nil] autorelease];
#else
UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease];
#endif
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
UITextField *textField = [[[UITextField alloc] initWithFrame:CGRectMake(20,12,260,25)] autorelease];
[textField setAutocapitalizationType:UITextAutocapitalizationTypeNone];
if ([indexPath section] == 0) {
[textField setPlaceholder:@"User"];
} else if ([indexPath section] == 1) {
[textField setPlaceholder:@"Password"];
[textField setSecureTextEntry:YES];
} else if ([indexPath section] == 2) {
[textField setPlaceholder:@"Domain"];
}
[cell addSubview:textField];
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
if (section == [self numberOfSectionsInTableView:tableView]-1) {
// If we're using Basic authentication and the connection is not using SSL, we'll show the plain text message
if ([[[self request] authenticationScheme] isEqualToString:(NSString *)kCFHTTPAuthenticationSchemeBasic] && ![[[[self request] url] scheme] isEqualToString:@"https"]) {
return @"Password will be sent in the clear.";
// We are using Digest, NTLM, or any scheme over SSL
} else {
return @"Password will be sent securely.";
}
}
return nil;
}
@synthesize request;
@synthesize loginDialog;
@synthesize type;
@end
Something went wrong with that request. Please try again.