Ben Copsey

ASIAuthenticationDialog now remembers all requests that have asked for credentia…

…ls, and is smart enough to recognise ones asking for the same set of credentials
Simplfy auth dialog api - we now look at the authenticationNeeded property of a request to determine if this is a proxy dialog or not
... ... @@ -25,8 +25,6 @@ typedef enum _ASIAuthenticationType {
BOOL didEnableRotationNotifications;
}
+ (void)presentAuthenticationDialogForRequest:(ASIHTTPRequest *)request;
+ (void)presentProxyAuthenticationDialogForRequest:(ASIHTTPRequest *)request;
+ (void)dismiss;
@property (retain) ASIHTTPRequest *request;
... ...
... ... @@ -11,8 +11,8 @@
#import <CoreGraphics/CoreGraphics.h>
ASIAuthenticationDialog *sharedDialog = nil;
NSLock *dialogLock = nil;
BOOL isDismissing = NO;
static NSMutableArray *requestsNeedingAuthentication = nil;
static const NSUInteger kUsernameRow = 0;
static const NSUInteger kUsernameSection = 0;
... ... @@ -35,6 +35,8 @@ static const NSUInteger kDomainSection = 1;
@interface ASIAuthenticationDialog ()
- (void)showTitle;
- (void)show;
- (NSArray *)requestsRequiringTheseCredentials;
- (void)presentNextDialog;
@property (retain) UITableView *tableView;
@end
... ... @@ -45,31 +47,25 @@ static const NSUInteger kDomainSection = 1;
+ (void)initialize
{
if (self == [ASIAuthenticationDialog class]) {
dialogLock = [[NSLock alloc] init];
requestsNeedingAuthentication = [[NSMutableArray array] retain];
}
}
+ (void)presentProxyAuthenticationDialogForRequest:(ASIHTTPRequest *)request
{
[dialogLock lock];
if (!sharedDialog) {
sharedDialog = [[self alloc] init];
}
[sharedDialog setRequest:request];
[sharedDialog setType:ASIProxyAuthenticationType];
[sharedDialog show];
[dialogLock unlock];
}
+ (void)presentAuthenticationDialogForRequest:(ASIHTTPRequest *)request
{
[dialogLock lock];
// No need for a lock here, this will always be called on the main thread
if (!sharedDialog) {
sharedDialog = [[self alloc] init];
[sharedDialog setRequest:request];
if ([request authenticationNeeded] == ASIProxyAuthenticationNeeded) {
[sharedDialog setType:ASIProxyAuthenticationType];
} else {
[sharedDialog setType:ASIStandardAuthenticationType];
}
[sharedDialog show];
} else {
[requestsNeedingAuthentication addObject:request];
}
[sharedDialog setRequest:request];
[sharedDialog show];
[dialogLock unlock];
}
- (id)init
... ... @@ -199,11 +195,9 @@ static const NSUInteger kDomainSection = 1;
+ (void)dismiss
{
[dialogLock lock];
[[sharedDialog parentViewController] dismissModalViewControllerAnimated:YES];
[sharedDialog release];
sharedDialog = nil;
[dialogLock unlock];
}
- (void)dismiss
... ... @@ -294,38 +288,71 @@ static const NSUInteger kDomainSection = 1;
- (void)cancelAuthenticationFromDialog:(id)sender
{
[[self request] cancelAuthentication];
for (ASIHTTPRequest *theRequest in [self requestsRequiringTheseCredentials]) {
[theRequest cancelAuthentication];
[requestsNeedingAuthentication removeObject:theRequest];
}
[self dismiss];
[self performSelector:@selector(presentNextDialog) withObject:nil afterDelay:1];
}
- (NSArray *)requestsRequiringTheseCredentials
{
NSMutableArray *requestsRequiringTheseCredentials = [NSMutableArray array];
NSURL *requestURL = [[self request] url];
for (ASIHTTPRequest *otherRequest in requestsNeedingAuthentication) {
NSURL *theURL = [otherRequest url];
if (([otherRequest authenticationNeeded] == [[self request] authenticationNeeded]) && [[theURL host] isEqualToString:[requestURL host]] && ([theURL port] == [requestURL port] || ([requestURL port] && [[theURL port] isEqualToNumber:[requestURL port]])) && [[theURL scheme] isEqualToString:[requestURL scheme]] && ((![otherRequest authenticationRealm] && ![[self request] authenticationRealm]) || ([otherRequest authenticationRealm] && [[self request] authenticationRealm] && [[[self request] authenticationRealm] isEqualToString:[otherRequest authenticationRealm]]))) {
[requestsRequiringTheseCredentials addObject:otherRequest];
}
}
[requestsRequiringTheseCredentials addObject:[self request]];
return requestsRequiringTheseCredentials;
}
- (void)presentNextDialog
{
if ([requestsNeedingAuthentication count]) {
ASIHTTPRequest *nextRequest = [requestsNeedingAuthentication objectAtIndex:0];
[requestsNeedingAuthentication removeObjectAtIndex:0];
[[self class] presentAuthenticationDialogForRequest:nextRequest];
}
}
- (void)loginWithCredentialsFromDialog:(id)sender
{
NSString *username = [[self usernameField] text];
NSString *password = [[self passwordField] text];
for (ASIHTTPRequest *theRequest in [self requestsRequiringTheseCredentials]) {
if (username == nil) { username = @""; }
if (password == nil) { password = @""; }
NSString *username = [[self usernameField] text];
NSString *password = [[self passwordField] text];
if ([self type] == ASIProxyAuthenticationType) {
[[self request] setProxyUsername:username];
[[self request] setProxyPassword:password];
} else {
[[self request] setUsername:username];
[[self request] setPassword:password];
}
if (username == nil) { username = @""; }
if (password == nil) { password = @""; }
// Handle NTLM domains
NSString *scheme = ([self type] == ASIStandardAuthenticationType) ? [[self request] authenticationScheme] : [[self request] proxyAuthenticationScheme];
if ([scheme isEqualToString:(NSString *)kCFHTTPAuthenticationSchemeNTLM]) {
NSString *domain = [[self domainField] text];
if ([self type] == ASIProxyAuthenticationType) {
[[self request] setProxyDomain:domain];
[theRequest setProxyUsername:username];
[theRequest setProxyPassword:password];
} else {
[[self request] setDomain:domain];
[theRequest setUsername:username];
[theRequest setPassword:password];
}
}
[[self request] retryUsingSuppliedCredentials];
// Handle NTLM domains
NSString *scheme = ([self type] == ASIStandardAuthenticationType) ? [[self request] authenticationScheme] : [[self request] proxyAuthenticationScheme];
if ([scheme isEqualToString:(NSString *)kCFHTTPAuthenticationSchemeNTLM]) {
NSString *domain = [[self domainField] text];
if ([self type] == ASIProxyAuthenticationType) {
[theRequest setProxyDomain:domain];
} else {
[theRequest setDomain:domain];
}
}
[theRequest retryUsingSuppliedCredentials];
[requestsNeedingAuthentication removeObject:theRequest];
}
[self performSelector:@selector(presentNextDialog) withObject:nil afterDelay:1];
}
#pragma mark table view data source
... ...
... ... @@ -23,7 +23,7 @@
// Automatically set on build
NSString *ASIHTTPRequestVersion = @"v1.6.2-25 2010-06-23";
NSString *ASIHTTPRequestVersion = @"v1.6.2-36 2010-06-23";
NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain";
... ... @@ -2022,7 +2022,7 @@ static BOOL isiPhoneOS2;
// Mac authentication dialog coming soon!
#if TARGET_OS_IPHONE
if ([self shouldPresentProxyAuthenticationDialog]) {
[ASIAuthenticationDialog performSelectorOnMainThread:@selector(presentProxyAuthenticationDialogForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]];
[ASIAuthenticationDialog performSelectorOnMainThread:@selector(presentAuthenticationDialogForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]];
return YES;
}
return NO;
... ...
... ... @@ -23,11 +23,19 @@
[request setDidFinishSelector:@selector(topSecretFetchComplete:)];
[request setDidFailSelector:@selector(topSecretFetchFailed:)];
[request startAsynchronous];
[self setRequest:[ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/digest_authentication"]]];
[request setUseKeychainPersistence:[useKeychain isOn]];
[request setDelegate:self];
[request setShouldPresentAuthenticationDialog:[useBuiltInDialog isOn]];
[request setDidFinishSelector:@selector(topSecretFetchComplete:)];
[request setDidFailSelector:@selector(topSecretFetchFailed:)];
[request startAsynchronous];
}
- (IBAction)topSecretFetchFailed:(ASIHTTPRequest *)theRequest
{
NSLog(@"%@",theRequest);
[responseField setText:[[request error] localizedDescription]];
[responseField setFont:[UIFont boldSystemFontOfSize:12]];
}
... ...