Ben Copsey

Start auth dialog work

  1 +//
  2 +// ASIAuthenticationDialog.h
  3 +// iPhone
  4 +//
  5 +// Created by Ben Copsey on 21/08/2009.
  6 +// Copyright 2009 All-Seeing Interactive. All rights reserved.
  7 +//
  8 +
  9 +#import <Foundation/Foundation.h>
  10 +@class ASIHTTPRequest;
  11 +
  12 +typedef enum _ASIAuthenticationType {
  13 + ASIStandardAuthenticationType = 0,
  14 + ASIProxyAuthenticationType = 1
  15 +} ASIAuthenticationType;
  16 +
  17 +@interface ASIAuthenticationDialog : NSObject <UIActionSheetDelegate, UITableViewDelegate, UITableViewDataSource> {
  18 + ASIHTTPRequest *request;
  19 + UIActionSheet *loginDialog;
  20 + ASIAuthenticationType type;
  21 +}
  22 ++ (void)presentAuthenticationDialogForRequest:(ASIHTTPRequest *)request;
  23 ++ (void)presentProxyAuthenticationDialogForRequest:(ASIHTTPRequest *)request;
  24 +
  25 +@property (retain) ASIHTTPRequest *request;
  26 +@property (retain) UIActionSheet *loginDialog;
  27 +@property (assign) ASIAuthenticationType type;
  28 +@end
  1 +//
  2 +// ASIAuthenticationDialog.m
  3 +// iPhone
  4 +//
  5 +// Created by Ben Copsey on 21/08/2009.
  6 +// Copyright 2009 All-Seeing Interactive. All rights reserved.
  7 +//
  8 +
  9 +#import "ASIAuthenticationDialog.h"
  10 +#import "ASIHTTPRequest.h"
  11 +
  12 +ASIAuthenticationDialog *sharedDialog = nil;
  13 +NSLock *dialogLock = nil;
  14 +
  15 +@interface ASIAuthenticationDialog ()
  16 +- (void)show;
  17 +@end
  18 +
  19 +@implementation ASIAuthenticationDialog
  20 +
  21 ++ (void)initialize
  22 +{
  23 + if (self == [ASIAuthenticationDialog class]) {
  24 + dialogLock = [[NSLock alloc] init];
  25 + }
  26 +}
  27 +
  28 ++ (void)presentProxyAuthenticationDialogForRequest:(ASIHTTPRequest *)request
  29 +{
  30 + [dialogLock lock];
  31 + [sharedDialog release];
  32 + sharedDialog = [[self alloc] init];
  33 + [sharedDialog setRequest:request];
  34 + [sharedDialog setType:ASIProxyAuthenticationType];
  35 + [sharedDialog show];
  36 + [dialogLock unlock];
  37 +}
  38 +
  39 ++ (void)presentAuthenticationDialogForRequest:(ASIHTTPRequest *)request
  40 +{
  41 + [dialogLock lock];
  42 + [sharedDialog release];
  43 + sharedDialog = [[self alloc] init];
  44 + [sharedDialog setRequest:request];
  45 + [sharedDialog show];
  46 + [dialogLock unlock];
  47 +
  48 +}
  49 +
  50 +- (void)show
  51 +{
  52 + // Create an action sheet to show the login dialog
  53 + [self setLoginDialog:[[[UIActionSheet alloc] init] autorelease]];
  54 + [[self loginDialog] setActionSheetStyle:UIActionSheetStyleBlackOpaque];
  55 + [[self loginDialog] setDelegate:self];
  56 +
  57 + // We show the login form in a table view, similar to Safari's authentication dialog
  58 + UITableView *table = [[[UITableView alloc] initWithFrame:CGRectMake(0,50,320,480) style:UITableViewStyleGrouped] autorelease];
  59 + [table setDelegate:self];
  60 + [table setDataSource:self];
  61 + [[self loginDialog] addSubview:table];
  62 + [[self loginDialog] showInView:[[[UIApplication sharedApplication] windows] objectAtIndex:0]];
  63 + [[self loginDialog] setFrame:CGRectMake(0,0,320,480)];
  64 +
  65 + UIToolbar *toolbar = [[[UIToolbar alloc] initWithFrame:CGRectMake(0,0,320,80)] autorelease];
  66 + //[toolbar setFrame:CGRectMake(0,20,320,50)];
  67 + NSMutableArray *items = [[[NSMutableArray alloc] init] autorelease];
  68 + UIBarButtonItem *backButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelAuthenticationFromDialog:)] autorelease];
  69 + //[backButton setContentEdgeInsets:UIEdgeInsetsMake(0,20,0,0)];
  70 + [items addObject:backButton];
  71 +
  72 + UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0,0,170,50)];
  73 + [label setText:[[[self request] url] host]];
  74 + [label setTextColor:[UIColor whiteColor]];
  75 + [label setFont:[UIFont boldSystemFontOfSize:22.0]];
  76 + [label setShadowColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:0.5]];
  77 + [label setShadowOffset:CGSizeMake(0, -1.0)];
  78 + [label setOpaque:NO];
  79 + [label setBackgroundColor:nil];
  80 + [label setTextAlignment:UITextAlignmentCenter];
  81 +
  82 + [toolbar addSubview:label];
  83 +
  84 + UIBarButtonItem *labelButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:nil action:nil] autorelease];
  85 +
  86 + //[labelButton setCustomView:label];
  87 + //[items addObject:labelButton];
  88 + [items addObject:[[[UIBarButtonItem alloc] initWithTitle:@"Login" style:UIBarButtonItemStyleDone target:self action:@selector(loginWithCredentialsFromDialog:)] autorelease]];
  89 + [toolbar setItems:items];
  90 + [[self loginDialog] addSubview:toolbar];
  91 +}
  92 +
  93 +- (void)cancelAuthenticationFromDialog:(id)sender
  94 +{
  95 + [[self request] cancelAuthentication];
  96 + [[self loginDialog] dismissWithClickedButtonIndex:0 animated:YES];
  97 +}
  98 +
  99 +- (void)loginWithCredentialsFromDialog:(id)sender
  100 +{
  101 + [[self request] setUsername:[[[[[[[self loginDialog] subviews] objectAtIndex:0] cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]] subviews] objectAtIndex:2] text]];
  102 + [[self request] setPassword:[[[[[[[self loginDialog] subviews] objectAtIndex:0] cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:1]] subviews] objectAtIndex:2] text]];
  103 + [[self loginDialog] dismissWithClickedButtonIndex:1 animated:YES];
  104 + [[self request] retryWithAuthentication];
  105 +}
  106 +
  107 +
  108 +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
  109 +{
  110 + NSString *scheme = ([self type] == ASIStandardAuthenticationType) ? [[self request] authenticationScheme] : [[self request] proxyAuthenticationScheme];
  111 + if ([scheme isEqualToString:(NSString *)kCFHTTPAuthenticationSchemeNTLM]) {
  112 + return 3;
  113 + }
  114 + return 2;
  115 +}
  116 +
  117 +- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
  118 +{
  119 + if (section == [self numberOfSectionsInTableView:tableView]-1) {
  120 + return 30;
  121 + }
  122 + return 0;
  123 +}
  124 +
  125 +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
  126 +{
  127 + if (section == 0) {
  128 + return 30;
  129 + }
  130 + return 0;
  131 +}
  132 +
  133 +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
  134 +{
  135 + if (section == 0) {
  136 + return [[self request] authenticationRealm];
  137 + }
  138 + return nil;
  139 +}
  140 +
  141 +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  142 +{
  143 + UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease];
  144 + [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
  145 + UITextField *textField = [[[UITextField alloc] initWithFrame:CGRectMake(20,12,260,25)] autorelease];
  146 + if ([indexPath section] == 0) {
  147 + [textField setPlaceholder:@"User"];
  148 + } else if ([indexPath section] == 1) {
  149 + [textField setPlaceholder:@"Password"];
  150 + } else if ([indexPath section] == 2) {
  151 + [textField setPlaceholder:@"Domain"];
  152 + }
  153 + [cell addSubview:textField];
  154 +
  155 + return cell;
  156 +}
  157 +
  158 +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
  159 +{
  160 + return 1;
  161 +}
  162 +
  163 +
  164 +- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
  165 +{
  166 + if (section == [self numberOfSectionsInTableView:tableView]-1) {
  167 + if ([[[[self request] url] scheme] isEqualToString:@"https"]) {
  168 + return @"Password will be sent securely.";
  169 + } else {
  170 + return @"Password will be sent in the clear.";
  171 + }
  172 + }
  173 + return nil;
  174 +}
  175 +
  176 +@synthesize request;
  177 +@synthesize loginDialog;
  178 +@synthesize type;
  179 +@end
@@ -160,8 +160,8 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; @@ -160,8 +160,8 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount;
160 // Used during NTLM authentication 160 // Used during NTLM authentication
161 int authenticationRetryCount; 161 int authenticationRetryCount;
162 162
163 - // Authentication method (Basic, Digest, NTLM) 163 + // Authentication scheme (Basic, Digest, NTLM)
164 - NSString *authenticationMethod; 164 + NSString *authenticationScheme;
165 165
166 // Realm for authentication when credentials are required 166 // Realm for authentication when credentials are required
167 NSString *authenticationRealm; 167 NSString *authenticationRealm;
@@ -169,6 +169,16 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; @@ -169,6 +169,16 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount;
169 // And now, the same thing, but for authenticating proxies 169 // And now, the same thing, but for authenticating proxies
170 BOOL needsProxyAuthentication; 170 BOOL needsProxyAuthentication;
171 171
  172 + // When YES, ASIHTTPRequest will present a dialog allowing users to enter credentials when no-matching credentials were found for a server that requires authentication
  173 + // The dialog will not be shown if your delegate responds to authenticationNeededForRequest:
  174 + // Default is NO.
  175 + BOOL shouldPresentAuthenticationDialog;
  176 +
  177 + // When YES, ASIHTTPRequest will present a dialog allowing users to enter credentials when no-matching credentials were found for a proxy server that requires authentication
  178 + // The dialog will not be shown if your delegate responds to proxyAuthenticationNeededForRequest:
  179 + // Default is YES (basically, because most people won't want the hassle of adding support for authenticating proxies to their apps)
  180 + BOOL shouldPresentProxyAuthenticationDialog;
  181 +
172 // Used for proxy authentication 182 // Used for proxy authentication
173 CFHTTPAuthenticationRef proxyAuthentication; 183 CFHTTPAuthenticationRef proxyAuthentication;
174 NSMutableDictionary *proxyCredentials; 184 NSMutableDictionary *proxyCredentials;
@@ -176,8 +186,8 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; @@ -176,8 +186,8 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount;
176 // Used during authentication with an NTLM proxy 186 // Used during authentication with an NTLM proxy
177 int proxyAuthenticationRetryCount; 187 int proxyAuthenticationRetryCount;
178 188
179 - // Authentication method for the proxy (Basic, Digest, NTLM) 189 + // Authentication scheme for the proxy (Basic, Digest, NTLM)
180 - NSString *proxyAuthenticationMethod; 190 + NSString *proxyAuthenticationScheme;
181 191
182 // Realm for proxy authentication when credentials are required 192 // Realm for proxy authentication when credentials are required
183 NSString *proxyAuthenticationRealm; 193 NSString *proxyAuthenticationRealm;
@@ -378,6 +388,9 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; @@ -378,6 +388,9 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount;
378 // Should be called by delegates when they have populated the authentication information after an authentication challenge 388 // Should be called by delegates when they have populated the authentication information after an authentication challenge
379 - (void)retryWithAuthentication; 389 - (void)retryWithAuthentication;
380 390
  391 +// Should be called by delegates when they wish to cancel authentication and stop
  392 +- (void)cancelAuthentication;
  393 +
381 // Apply authentication information and resume the request after an authentication challenge 394 // Apply authentication information and resume the request after an authentication challenge
382 - (void)attemptToApplyCredentialsAndResume; 395 - (void)attemptToApplyCredentialsAndResume;
383 - (void)attemptToApplyProxyCredentialsAndResume; 396 - (void)attemptToApplyProxyCredentialsAndResume;
@@ -484,6 +497,10 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; @@ -484,6 +497,10 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount;
484 + (void)reachabilityChanged:(NSNotification *)note; 497 + (void)reachabilityChanged:(NSNotification *)note;
485 #endif 498 #endif
486 499
  500 +
  501 +- (BOOL)showProxyAuthenticationDialog;
  502 +- (BOOL)showAuthenticationDialog;
  503 +
487 + (unsigned long)maxUploadReadLength; 504 + (unsigned long)maxUploadReadLength;
488 505
489 @property (retain) NSString *username; 506 @property (retain) NSString *username;
@@ -546,4 +563,8 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount; @@ -546,4 +563,8 @@ extern unsigned long const ASIWWANBandwidthThrottleAmount;
546 @property (assign) BOOL shouldCompressRequestBody; 563 @property (assign) BOOL shouldCompressRequestBody;
547 @property (assign) BOOL needsProxyAuthentication; 564 @property (assign) BOOL needsProxyAuthentication;
548 @property (retain) NSURL *PACurl; 565 @property (retain) NSURL *PACurl;
  566 +@property (retain) NSString *authenticationScheme;
  567 +@property (retain) NSString *proxyAuthenticationScheme;
  568 +@property (assign) BOOL shouldPresentAuthenticationDialog;
  569 +@property (assign) BOOL shouldPresentProxyAuthenticationDialog;
549 @end 570 @end
@@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
18 #import <SystemConfiguration/SystemConfiguration.h> 18 #import <SystemConfiguration/SystemConfiguration.h>
19 #endif 19 #endif
20 #import "ASIInputStream.h" 20 #import "ASIInputStream.h"
  21 +#import "ASIAuthenticationDialog.h"
21 22
22 // We use our own custom run loop mode as CoreAnimation seems to want to hijack our threads otherwise 23 // We use our own custom run loop mode as CoreAnimation seems to want to hijack our threads otherwise
23 static CFStringRef ASIHTTPRequestRunMode = CFSTR("ASIHTTPRequest"); 24 static CFStringRef ASIHTTPRequestRunMode = CFSTR("ASIHTTPRequest");
@@ -77,6 +78,8 @@ BOOL shouldThrottleBandwithForWWANOnly = NO; @@ -77,6 +78,8 @@ BOOL shouldThrottleBandwithForWWANOnly = NO;
77 78
78 static NSLock *sessionCookiesLock = nil; 79 static NSLock *sessionCookiesLock = nil;
79 80
  81 +UIActionSheet *loginDialog = nil;
  82 +
80 // Private stuff 83 // Private stuff
81 @interface ASIHTTPRequest () 84 @interface ASIHTTPRequest ()
82 85
@@ -196,14 +199,14 @@ static NSLock *sessionCookiesLock = nil; @@ -196,14 +199,14 @@ static NSLock *sessionCookiesLock = nil;
196 [password release]; 199 [password release];
197 [domain release]; 200 [domain release];
198 [authenticationRealm release]; 201 [authenticationRealm release];
199 - [authenticationMethod release]; 202 + [authenticationScheme release];
200 [requestCredentials release]; 203 [requestCredentials release];
201 [proxyHost release]; 204 [proxyHost release];
202 [proxyUsername release]; 205 [proxyUsername release];
203 [proxyPassword release]; 206 [proxyPassword release];
204 [proxyDomain release]; 207 [proxyDomain release];
205 [proxyAuthenticationRealm release]; 208 [proxyAuthenticationRealm release];
206 - [proxyAuthenticationMethod release]; 209 + [proxyAuthenticationScheme release];
207 [proxyCredentials release]; 210 [proxyCredentials release];
208 [url release]; 211 [url release];
209 [authenticationLock release]; 212 [authenticationLock release];
@@ -1401,24 +1404,44 @@ static NSLock *sessionCookiesLock = nil; @@ -1401,24 +1404,44 @@ static NSLock *sessionCookiesLock = nil;
1401 return nil; 1404 return nil;
1402 } 1405 }
1403 1406
1404 -// Called by delegate to resume loading once authentication info has been populated 1407 +// Called by delegate or authentication dialog to resume loading once authentication info has been populated
1405 - (void)retryWithAuthentication 1408 - (void)retryWithAuthentication
1406 { 1409 {
1407 [[self authenticationLock] lockWhenCondition:1]; 1410 [[self authenticationLock] lockWhenCondition:1];
1408 [[self authenticationLock] unlockWithCondition:2]; 1411 [[self authenticationLock] unlockWithCondition:2];
1409 } 1412 }
1410 1413
  1414 +// Called by delegate or authentication dialog to cancel authentication
  1415 +- (void)cancelAuthentication
  1416 +{
  1417 + [self failWithError:ASIAuthenticationError];
  1418 + [[self authenticationLock] lockWhenCondition:1];
  1419 + [[self authenticationLock] unlockWithCondition:2];
  1420 +}
  1421 +
  1422 +- (BOOL)showProxyAuthenticationDialog
  1423 +{
  1424 + if ([self shouldPresentProxyAuthenticationDialog]) {
  1425 + [ASIAuthenticationDialog performSelectorOnMainThread:@selector(presentProxyAuthenticationDialogForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]];
  1426 + [[self authenticationLock] lockWhenCondition:2];
  1427 + [[self authenticationLock] unlockWithCondition:1];
  1428 + return YES;
  1429 + }
  1430 + return NO;
  1431 +}
  1432 +
  1433 +
1411 - (BOOL)askDelegateForProxyCredentials 1434 - (BOOL)askDelegateForProxyCredentials
1412 { 1435 {
1413 - // If we have a delegate, we'll see if it can handle proxyAuthorizationNeededForRequest:. 1436 + // If we have a delegate, we'll see if it can handle proxyAuthenticationNeededForRequest:.
1414 // Otherwise, we'll try the queue (if this request is part of one) and it will pass the message on to its own delegate 1437 // Otherwise, we'll try the queue (if this request is part of one) and it will pass the message on to its own delegate
1415 - id authorizationDelegate = [self delegate]; 1438 + id authenticationDelegate = [self delegate];
1416 - if (!authorizationDelegate) { 1439 + if (!authenticationDelegate) {
1417 - authorizationDelegate = [self queue]; 1440 + authenticationDelegate = [self queue];
1418 } 1441 }
1419 1442
1420 - if ([authorizationDelegate respondsToSelector:@selector(proxyAuthorizationNeededForRequest:)]) { 1443 + if ([authenticationDelegate respondsToSelector:@selector(proxyAuthenticationNeededForRequest:)]) {
1421 - [authorizationDelegate performSelectorOnMainThread:@selector(proxyAuthorizationNeededForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]]; 1444 + [authenticationDelegate performSelectorOnMainThread:@selector(proxyAuthenticationNeededForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]];
1422 [[self authenticationLock] lockWhenCondition:2]; 1445 [[self authenticationLock] lockWhenCondition:2];
1423 [[self authenticationLock] unlockWithCondition:1]; 1446 [[self authenticationLock] unlockWithCondition:1];
1424 1447
@@ -1430,12 +1453,16 @@ static NSLock *sessionCookiesLock = nil; @@ -1430,12 +1453,16 @@ static NSLock *sessionCookiesLock = nil;
1430 - (void)attemptToApplyProxyCredentialsAndResume 1453 - (void)attemptToApplyProxyCredentialsAndResume
1431 { 1454 {
1432 1455
  1456 + if ([self error]) {
  1457 + return;
  1458 + }
  1459 +
1433 // Read authentication data 1460 // Read authentication data
1434 if (!proxyAuthentication) { 1461 if (!proxyAuthentication) {
1435 CFHTTPMessageRef responseHeader = (CFHTTPMessageRef) CFReadStreamCopyProperty(readStream,kCFStreamPropertyHTTPResponseHeader); 1462 CFHTTPMessageRef responseHeader = (CFHTTPMessageRef) CFReadStreamCopyProperty(readStream,kCFStreamPropertyHTTPResponseHeader);
1436 proxyAuthentication = CFHTTPAuthenticationCreateFromResponse(NULL, responseHeader); 1463 proxyAuthentication = CFHTTPAuthenticationCreateFromResponse(NULL, responseHeader);
1437 CFRelease(responseHeader); 1464 CFRelease(responseHeader);
1438 - proxyAuthenticationMethod = (NSString *)CFHTTPAuthenticationCopyMethod(proxyAuthentication); 1465 + [self setProxyAuthenticationScheme:[(NSString *)CFHTTPAuthenticationCopyMethod(proxyAuthentication) autorelease]];
1439 } 1466 }
1440 1467
1441 // If we haven't got a CFHTTPAuthenticationRef by now, something is badly wrong, so we'll have to give up 1468 // If we haven't got a CFHTTPAuthenticationRef by now, something is badly wrong, so we'll have to give up
@@ -1472,11 +1499,11 @@ static NSLock *sessionCookiesLock = nil; @@ -1472,11 +1499,11 @@ static NSLock *sessionCookiesLock = nil;
1472 if (proxyCredentials) { 1499 if (proxyCredentials) {
1473 1500
1474 // We use startRequest rather than starting all over again in load request because NTLM requires we reuse the request 1501 // We use startRequest rather than starting all over again in load request because NTLM requires we reuse the request
1475 - if (((proxyAuthenticationMethod != (NSString *)kCFHTTPAuthenticationSchemeNTLM) || proxyAuthenticationRetryCount < 2) && [self applyCredentials:proxyCredentials]) { 1502 + if ((([self proxyAuthenticationScheme] != (NSString *)kCFHTTPAuthenticationSchemeNTLM) || proxyAuthenticationRetryCount < 2) && [self applyCredentials:proxyCredentials]) {
1476 [self startRequest]; 1503 [self startRequest];
1477 1504
1478 // We've failed NTLM authentication twice, we should assume our credentials are wrong 1505 // We've failed NTLM authentication twice, we should assume our credentials are wrong
1479 - } else if (proxyAuthenticationMethod == (NSString *)kCFHTTPAuthenticationSchemeNTLM && proxyAuthenticationRetryCount == 2) { 1506 + } else if ([self proxyAuthenticationScheme] == (NSString *)kCFHTTPAuthenticationSchemeNTLM && proxyAuthenticationRetryCount == 2) {
1480 [self failWithError:ASIAuthenticationError]; 1507 [self failWithError:ASIAuthenticationError];
1481 1508
1482 // Something went wrong, we'll have to give up 1509 // Something went wrong, we'll have to give up
@@ -1505,24 +1532,39 @@ static NSLock *sessionCookiesLock = nil; @@ -1505,24 +1532,39 @@ static NSLock *sessionCookiesLock = nil;
1505 return; 1532 return;
1506 } 1533 }
1507 1534
1508 - // The delegate isn't interested, we'll have to give up 1535 + if ([self showProxyAuthenticationDialog]) {
  1536 + [self attemptToApplyProxyCredentialsAndResume];
  1537 + }
  1538 +
  1539 + // The delegate isn't interested and we aren't showing the authentication dialog, we'll have to give up
1509 [self failWithError:ASIAuthenticationError]; 1540 [self failWithError:ASIAuthenticationError];
1510 return; 1541 return;
1511 } 1542 }
1512 1543
1513 } 1544 }
1514 1545
  1546 +- (BOOL)showAuthenticationDialog
  1547 +{
  1548 + if ([self shouldPresentAuthenticationDialog]) {
  1549 + [ASIAuthenticationDialog performSelectorOnMainThread:@selector(presentAuthenticationDialogForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]];
  1550 + [[self authenticationLock] lockWhenCondition:2];
  1551 + [[self authenticationLock] unlockWithCondition:1];
  1552 + return YES;
  1553 + }
  1554 + return NO;
  1555 +}
  1556 +
1515 - (BOOL)askDelegateForCredentials 1557 - (BOOL)askDelegateForCredentials
1516 { 1558 {
1517 - // If we have a delegate, we'll see if it can handle proxyAuthorizationNeededForRequest:. 1559 + // If we have a delegate, we'll see if it can handle proxyAuthenticationNeededForRequest:.
1518 // Otherwise, we'll try the queue (if this request is part of one) and it will pass the message on to its own delegate 1560 // Otherwise, we'll try the queue (if this request is part of one) and it will pass the message on to its own delegate
1519 - id authorizationDelegate = [self delegate]; 1561 + id authenticationDelegate = [self delegate];
1520 - if (!authorizationDelegate) { 1562 + if (!authenticationDelegate) {
1521 - authorizationDelegate = [self queue]; 1563 + authenticationDelegate = [self queue];
1522 } 1564 }
1523 1565
1524 - if ([authorizationDelegate respondsToSelector:@selector(authorizationNeededForRequest:)]) { 1566 + if ([authenticationDelegate respondsToSelector:@selector(authenticationNeededForRequest:)]) {
1525 - [authorizationDelegate performSelectorOnMainThread:@selector(authorizationNeededForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]]; 1567 + [authenticationDelegate performSelectorOnMainThread:@selector(authenticationNeededForRequest:) withObject:self waitUntilDone:[NSThread isMainThread]];
1526 [[self authenticationLock] lockWhenCondition:2]; 1568 [[self authenticationLock] lockWhenCondition:2];
1527 [[self authenticationLock] unlockWithCondition:1]; 1569 [[self authenticationLock] unlockWithCondition:1];
1528 1570
@@ -1533,6 +1575,10 @@ static NSLock *sessionCookiesLock = nil; @@ -1533,6 +1575,10 @@ static NSLock *sessionCookiesLock = nil;
1533 1575
1534 - (void)attemptToApplyCredentialsAndResume 1576 - (void)attemptToApplyCredentialsAndResume
1535 { 1577 {
  1578 + if ([self error]) {
  1579 + return;
  1580 + }
  1581 +
1536 if ([self needsProxyAuthentication]) { 1582 if ([self needsProxyAuthentication]) {
1537 [self attemptToApplyProxyCredentialsAndResume]; 1583 [self attemptToApplyProxyCredentialsAndResume];
1538 return; 1584 return;
@@ -1543,7 +1589,7 @@ static NSLock *sessionCookiesLock = nil; @@ -1543,7 +1589,7 @@ static NSLock *sessionCookiesLock = nil;
1543 CFHTTPMessageRef responseHeader = (CFHTTPMessageRef) CFReadStreamCopyProperty(readStream,kCFStreamPropertyHTTPResponseHeader); 1589 CFHTTPMessageRef responseHeader = (CFHTTPMessageRef) CFReadStreamCopyProperty(readStream,kCFStreamPropertyHTTPResponseHeader);
1544 requestAuthentication = CFHTTPAuthenticationCreateFromResponse(NULL, responseHeader); 1590 requestAuthentication = CFHTTPAuthenticationCreateFromResponse(NULL, responseHeader);
1545 CFRelease(responseHeader); 1591 CFRelease(responseHeader);
1546 - authenticationMethod = (NSString *)CFHTTPAuthenticationCopyMethod(requestAuthentication); 1592 + [self setAuthenticationScheme:[(NSString *)CFHTTPAuthenticationCopyMethod(requestAuthentication) autorelease]];
1547 } 1593 }
1548 1594
1549 if (!requestAuthentication) { 1595 if (!requestAuthentication) {
@@ -1570,6 +1616,9 @@ static NSLock *sessionCookiesLock = nil; @@ -1570,6 +1616,9 @@ static NSLock *sessionCookiesLock = nil;
1570 [self attemptToApplyCredentialsAndResume]; 1616 [self attemptToApplyCredentialsAndResume];
1571 return; 1617 return;
1572 } 1618 }
  1619 + if ([self showAuthenticationDialog]) {
  1620 + [self attemptToApplyCredentialsAndResume];
  1621 + }
1573 } 1622 }
1574 [self cancelLoad]; 1623 [self cancelLoad];
1575 [self failWithError:ASIAuthenticationError]; 1624 [self failWithError:ASIAuthenticationError];
@@ -1580,11 +1629,11 @@ static NSLock *sessionCookiesLock = nil; @@ -1580,11 +1629,11 @@ static NSLock *sessionCookiesLock = nil;
1580 1629
1581 if (requestCredentials) { 1630 if (requestCredentials) {
1582 1631
1583 - if (((authenticationMethod != (NSString *)kCFHTTPAuthenticationSchemeNTLM) || authenticationRetryCount < 2) && [self applyCredentials:requestCredentials]) { 1632 + if ((([self authenticationScheme] != (NSString *)kCFHTTPAuthenticationSchemeNTLM) || authenticationRetryCount < 2) && [self applyCredentials:requestCredentials]) {
1584 [self startRequest]; 1633 [self startRequest];
1585 1634
1586 // We've failed NTLM authentication twice, we should assume our credentials are wrong 1635 // We've failed NTLM authentication twice, we should assume our credentials are wrong
1587 - } else if (authenticationMethod == (NSString *)kCFHTTPAuthenticationSchemeNTLM && authenticationRetryCount == 2) { 1636 + } else if ([self authenticationScheme] == (NSString *)kCFHTTPAuthenticationSchemeNTLM && authenticationRetryCount == 2) {
1588 [self failWithError:ASIAuthenticationError]; 1637 [self failWithError:ASIAuthenticationError];
1589 1638
1590 } else { 1639 } else {
@@ -1612,8 +1661,9 @@ static NSLock *sessionCookiesLock = nil; @@ -1612,8 +1661,9 @@ static NSLock *sessionCookiesLock = nil;
1612 return; 1661 return;
1613 } 1662 }
1614 1663
1615 - // The delegate isn't interested, we'll have to give up 1664 + if ([self showAuthenticationDialog]) {
1616 - [self failWithError:ASIAuthenticationError]; 1665 + [self attemptToApplyCredentialsAndResume];
  1666 + }
1617 return; 1667 return;
1618 } 1668 }
1619 1669
@@ -2498,6 +2548,7 @@ static NSLock *sessionCookiesLock = nil; @@ -2498,6 +2548,7 @@ static NSLock *sessionCookiesLock = nil;
2498 return toRead; 2548 return toRead;
2499 } 2549 }
2500 2550
  2551 +
2501 @synthesize username; 2552 @synthesize username;
2502 @synthesize password; 2553 @synthesize password;
2503 @synthesize domain; 2554 @synthesize domain;
@@ -2572,6 +2623,10 @@ static NSLock *sessionCookiesLock = nil; @@ -2572,6 +2623,10 @@ static NSLock *sessionCookiesLock = nil;
2572 @synthesize proxyHost; 2623 @synthesize proxyHost;
2573 @synthesize proxyPort; 2624 @synthesize proxyPort;
2574 @synthesize PACurl; 2625 @synthesize PACurl;
  2626 +@synthesize authenticationScheme;
  2627 +@synthesize proxyAuthenticationScheme;
  2628 +@synthesize shouldPresentAuthenticationDialog;
  2629 +@synthesize shouldPresentProxyAuthenticationDialog;
2575 @end 2630 @end
2576 2631
2577 2632
@@ -13,6 +13,7 @@ @@ -13,6 +13,7 @@
13 @interface AuthenticationViewController : UIViewController { 13 @interface AuthenticationViewController : UIViewController {
14 ASINetworkQueue *networkQueue; 14 ASINetworkQueue *networkQueue;
15 IBOutlet UISwitch *useKeychain; 15 IBOutlet UISwitch *useKeychain;
  16 + IBOutlet UISwitch *useBuiltInDialog;
16 IBOutlet UILabel *topSecretInfo; 17 IBOutlet UILabel *topSecretInfo;
17 ASIHTTPRequest *requestRequiringAuthentication; 18 ASIHTTPRequest *requestRequiringAuthentication;
18 ASIHTTPRequest *requestRequiringProxyAuthentication; 19 ASIHTTPRequest *requestRequiringProxyAuthentication;
@@ -27,6 +27,7 @@ @@ -27,6 +27,7 @@
27 27
28 ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/top_secret/"]]; 28 ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://allseeing-i.com/top_secret/"]];
29 [request setUseKeychainPersistance:[useKeychain isOn]]; 29 [request setUseKeychainPersistance:[useKeychain isOn]];
  30 + [request setShouldPresentAuthenticationDialog:[useBuiltInDialog isOn]];
30 [networkQueue addOperation:request]; 31 [networkQueue addOperation:request];
31 [networkQueue go]; 32 [networkQueue go];
32 33
@@ -44,28 +45,31 @@ @@ -44,28 +45,31 @@
44 [topSecretInfo setFont:[UIFont boldSystemFontOfSize:12]]; 45 [topSecretInfo setFont:[UIFont boldSystemFontOfSize:12]];
45 } 46 }
46 47
47 -- (void)authorizationNeededForRequest:(ASIHTTPRequest *)request 48 +//- (void)authorizationNeededForRequest:(ASIHTTPRequest *)request
48 -{ 49 +//{
49 - // Why oh why is there no contextInfo for alertView like on Mac OS ?! 50 +// // Why oh why is there no contextInfo for alertView like on Mac OS ?!
50 - [self setRequestRequiringProxyAuthentication:nil]; 51 +// [self setRequestRequiringProxyAuthentication:nil];
51 - [self setRequestRequiringAuthentication:request]; 52 +// [self setRequestRequiringAuthentication:request];
52 - UIAlertView *alertView = [[[UIAlertView alloc] initWithTitle:@"Please Login" message:[request authenticationRealm] delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK",nil] autorelease]; 53 +//
53 - // These are undocumented, use at your own risk! 54 +// [ASIHTTPRequest showAuthenticationDialogForRequest:request];
54 - // A better general approach would be to subclass UIAlertView 55 +//
55 - [alertView addTextFieldWithValue:@"" label:@"Username"]; 56 +// //UIAlertView *alertView = [[[UIAlertView alloc] initWithTitle:@"Please Login" message:[request authenticationRealm] delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK",nil] autorelease];
56 - [alertView addTextFieldWithValue:@"" label:@"Password"]; 57 +// // These are undocumented, use at your own risk!
57 - [alertView show]; 58 +// // A better general approach would be to subclass UIAlertView
58 -} 59 +// //[alertView addTextFieldWithValue:@"" label:@"Username"];
59 - 60 +// //[alertView addTextFieldWithValue:@"" label:@"Password"];
60 -- (void)proxyAuthorizationNeededForRequest:(ASIHTTPRequest *)request 61 +//
61 -{ 62 +//}
62 - [self setRequestRequiringAuthentication:nil]; 63 +//
63 - [self setRequestRequiringProxyAuthentication:request]; 64 +//- (void)proxyAuthorizationNeededForRequest:(ASIHTTPRequest *)request
64 - UIAlertView *alertView = [[[UIAlertView alloc] initWithTitle:@"Please Login to proxy" message:[request authenticationRealm] delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK",nil] autorelease]; 65 +//{
65 - [alertView addTextFieldWithValue:@"" label:@"Username"]; 66 +// [self setRequestRequiringAuthentication:nil];
66 - [alertView addTextFieldWithValue:@"" label:@"Password"]; 67 +// [self setRequestRequiringProxyAuthentication:request];
67 - [alertView show]; 68 +// UIAlertView *alertView = [[[UIAlertView alloc] initWithTitle:@"Please Login to proxy" message:[request authenticationRealm] delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK",nil] autorelease];
68 -} 69 +// [alertView addTextFieldWithValue:@"" label:@"Username"];
  70 +// [alertView addTextFieldWithValue:@"" label:@"Password"];
  71 +// [alertView show];
  72 +//}
69 73
70 74
71 75
This diff is collapsed. Click to expand it.
This diff was suppressed by a .gitattributes entry.