-
Notifications
You must be signed in to change notification settings - Fork 3
/
ASIAuthenticationDialog.m
executable file
·240 lines (199 loc) · 8.18 KB
/
ASIAuthenticationDialog.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
//
// 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.
//
// Modifyed for ARC by Jayesh on 19/06/14.
// Copyright (c) 2012 [email protected].
#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 = [[self alloc] init];
[sharedDialog setRequest:request];
[sharedDialog setType:ASIProxyAuthenticationType];
[sharedDialog show];
[dialogLock unlock];
}
+ (void)presentAuthenticationDialogForRequest:(ASIHTTPRequest *)request
{
[dialogLock lock];
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] ];
[[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] ;
[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)] ;
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10,0,300,30)] ;
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:NSTextAlignmentCenter];
[titleBar addSubview:label];
[[self loginDialog] addSubview:titleBar];
// Setup the toolbar
UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0,30,320,50)] ;
NSMutableArray *items = [[NSMutableArray alloc] init] ;
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelAuthenticationFromDialog:)] ;
[items addObject:backButton];
label = [[UILabel alloc] initWithFrame:CGRectMake(0,0,170,50)] ;
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:NSTextAlignmentCenter];
[toolbar addSubview:label];
UIBarButtonItem *labelButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:nil action:nil] ;
[labelButton setCustomView:label];
[items addObject:labelButton];
[items addObject:[[UIBarButtonItem alloc] initWithTitle:@"Login" style:UIBarButtonItemStyleDone target:self action:@selector(loginWithCredentialsFromDialog:)] ];
[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] ;
#endif
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(20,12,260,25)] ;
[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