mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-07-30 15:10:56 +00:00
add some code to BITAuthenticatorViewController
and let it perform authentication. Still some TODOs to do.
This commit is contained in:
parent
2a3a8d62cb
commit
d7f45267dd
@ -8,8 +8,24 @@
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
@protocol BITAuthenticationViewControllerDelegate;
|
||||
@class BITAuthenticator;
|
||||
|
||||
@interface BITAuthenticationViewController : UIViewController
|
||||
@interface BITAuthenticationViewController : UITableViewController
|
||||
|
||||
/**
|
||||
* can be set to YES to also require the users password
|
||||
*
|
||||
* defaults to NO
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL requirePassword;
|
||||
|
||||
/**
|
||||
* TODO: instead of passing the whole authenticator, we actually only need
|
||||
* something to create and enqueue BITHTTPOperations
|
||||
*/
|
||||
@property (nonatomic, weak) BITAuthenticator *authenticator;
|
||||
|
||||
@property (nonatomic, weak) id<BITAuthenticationViewControllerDelegate> delegate;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -7,32 +7,280 @@
|
||||
//
|
||||
|
||||
#import "BITAuthenticationViewController.h"
|
||||
#import "BITAuthenticator_Private.h"
|
||||
#import "HockeySDKPrivate.h"
|
||||
#import "HockeySDK.h"
|
||||
|
||||
@interface BITAuthenticationViewController ()
|
||||
@interface BITAuthenticationViewController ()<UITextFieldDelegate> {
|
||||
UIStatusBarStyle _statusBarStyle;
|
||||
}
|
||||
|
||||
@property (nonatomic, copy) NSString *email;
|
||||
@property (nonatomic, copy) NSString *password;
|
||||
|
||||
@end
|
||||
|
||||
@implementation BITAuthenticationViewController
|
||||
|
||||
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
|
||||
{
|
||||
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
|
||||
if (self) {
|
||||
// Custom initialization
|
||||
- (id)initWithStyle:(UITableViewStyle)style {
|
||||
self = [super initWithStyle:style];
|
||||
if (self) {
|
||||
self.title = BITHockeyLocalizedString(@"HockeyAuthenticatorViewControllerTitle");
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
[self.tableView setScrollEnabled:NO];
|
||||
}
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated {
|
||||
[super viewWillAppear:animated];
|
||||
|
||||
_statusBarStyle = [[UIApplication sharedApplication] statusBarStyle];
|
||||
[[UIApplication sharedApplication] setStatusBarStyle:(self.navigationController.navigationBar.barStyle == UIBarStyleDefault) ? UIStatusBarStyleDefault : UIStatusBarStyleBlackOpaque];
|
||||
|
||||
// Do any additional setup after loading the view.
|
||||
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
|
||||
target:self
|
||||
action:@selector(dismissAction:)];
|
||||
|
||||
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave
|
||||
target:self
|
||||
action:@selector(saveAction:)];
|
||||
|
||||
self.navigationItem.rightBarButtonItem.enabled = [self allRequiredFieldsEntered];
|
||||
}
|
||||
|
||||
- (void)viewWillDisappear:(BOOL)animated {
|
||||
[super viewWillDisappear:animated];
|
||||
|
||||
[[UIApplication sharedApplication] setStatusBarStyle:_statusBarStyle];
|
||||
}
|
||||
|
||||
#pragma mark - UIViewController Rotation
|
||||
|
||||
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation {
|
||||
return YES;
|
||||
}
|
||||
|
||||
#pragma mark - Private methods
|
||||
|
||||
//TODO: extract from feedbackviewcontroller and move to common place
|
||||
- (BOOL)validateEmail {
|
||||
NSString *emailRegex =
|
||||
@"(?:[a-z0-9!#$%\\&'*+/=?\\^_`{|}~-]+(?:\\.[a-z0-9!#$%\\&'*+/=?\\^_`{|}"
|
||||
@"~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\"
|
||||
@"x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-"
|
||||
@"z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5"
|
||||
@"]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-"
|
||||
@"9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21"
|
||||
@"-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])";
|
||||
NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES[c] %@", emailRegex];
|
||||
|
||||
return [emailTest evaluateWithObject:self.email];
|
||||
}
|
||||
|
||||
- (BOOL)allRequiredFieldsEntered {
|
||||
if (self.requirePassword && [self.password length] == 0)
|
||||
return NO;
|
||||
|
||||
if ([self.email length] > 0 && ![self validateEmail])
|
||||
return NO;
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
#pragma mark - Table view data source
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
|
||||
return 1;
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||
NSInteger rows = 1;
|
||||
|
||||
if ([self requirePassword]) rows ++;
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
|
||||
if (section == 0) {
|
||||
return BITHockeyLocalizedString(@"HockeyAuthenticationDataDescription");
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
static NSString *CellIdentifier = @"InputCell";
|
||||
|
||||
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
|
||||
if (cell == nil) {
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
|
||||
|
||||
cell.accessoryType = UITableViewCellAccessoryNone;
|
||||
cell.selectionStyle = UITableViewCellSelectionStyleNone;
|
||||
cell.backgroundColor = [UIColor whiteColor];
|
||||
|
||||
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, self.view.frame.size.width - 110 - 35, 30)];
|
||||
if (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPad) {
|
||||
textField.autoresizingMask = UIViewAutoresizingFlexibleWidth;
|
||||
}
|
||||
return self;
|
||||
textField.adjustsFontSizeToFitWidth = YES;
|
||||
textField.textColor = [UIColor blackColor];
|
||||
textField.backgroundColor = [UIColor lightGrayColor];
|
||||
|
||||
if (0 == [indexPath row]) {
|
||||
textField.placeholder = BITHockeyLocalizedString(@"HockeyFeedbackUserDataEmailPlaceholder");
|
||||
textField.text = self.email;
|
||||
|
||||
textField.keyboardType = UIKeyboardTypeEmailAddress;
|
||||
if ([self requirePassword])
|
||||
textField.returnKeyType = UIReturnKeyNext;
|
||||
else
|
||||
textField.returnKeyType = UIReturnKeyDone;
|
||||
|
||||
[textField addTarget:self action:@selector(userEmailEntered:) forControlEvents:UIControlEventEditingChanged];
|
||||
[textField becomeFirstResponder];
|
||||
} else {
|
||||
textField.placeholder = BITHockeyLocalizedString(@"HockeyAuthenticatorViewControllerPasswordPlaceHolder");
|
||||
textField.text = self.password;
|
||||
|
||||
textField.keyboardType = UIKeyboardTypeDefault;
|
||||
textField.returnKeyType = UIReturnKeyDone;
|
||||
textField.secureTextEntry = YES;
|
||||
[textField addTarget:self action:@selector(userPasswordEntered:) forControlEvents:UIControlEventEditingChanged];
|
||||
}
|
||||
|
||||
textField.backgroundColor = [UIColor whiteColor];
|
||||
textField.autocorrectionType = UITextAutocorrectionTypeNo;
|
||||
textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
|
||||
textField.textAlignment = kBITTextLabelAlignmentLeft;
|
||||
textField.delegate = self;
|
||||
textField.tag = indexPath.row;
|
||||
|
||||
textField.clearButtonMode = UITextFieldViewModeWhileEditing;
|
||||
[textField setEnabled: YES];
|
||||
|
||||
[cell addSubview:textField];
|
||||
}
|
||||
|
||||
if (0 == [indexPath row]) {
|
||||
cell.textLabel.text = BITHockeyLocalizedString(@"HockeyFeedbackUserDataEmail");
|
||||
} else {
|
||||
cell.textLabel.text = BITHockeyLocalizedString(@"HockeyAuthenticationViewControllerPassword");
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
// Do any additional setup after loading the view.
|
||||
|
||||
- (void)userEmailEntered:(id)sender {
|
||||
self.email = [(UITextField *)sender text];
|
||||
|
||||
self.navigationItem.rightBarButtonItem.enabled = [self allRequiredFieldsEntered];
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning
|
||||
{
|
||||
[super didReceiveMemoryWarning];
|
||||
// Dispose of any resources that can be recreated.
|
||||
- (void)userPasswordEntered:(id)sender {
|
||||
self.password = [(UITextField *)sender text];
|
||||
|
||||
self.navigationItem.rightBarButtonItem.enabled = [self allRequiredFieldsEntered];
|
||||
}
|
||||
|
||||
#pragma mark - UITextFieldDelegate
|
||||
|
||||
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
|
||||
NSInteger nextTag = textField.tag + 1;
|
||||
|
||||
UIResponder* nextResponder = [self.view viewWithTag:nextTag];
|
||||
if (nextResponder) {
|
||||
[nextResponder becomeFirstResponder];
|
||||
} else {
|
||||
if ([self allRequiredFieldsEntered]) {
|
||||
if ([textField isFirstResponder])
|
||||
[textField resignFirstResponder];
|
||||
|
||||
[self saveAction:nil];
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
#pragma mark - Actions
|
||||
- (void)dismissAction:(id)sender {
|
||||
[self.delegate authenticationViewControllerDidCancel:self];
|
||||
}
|
||||
|
||||
- (void)saveAction:(id)sender {
|
||||
[self showLoginUI:YES];
|
||||
|
||||
NSString *authenticationEndpoint = @"authenticate";
|
||||
__weak typeof (self) weakSelf = self;
|
||||
|
||||
[self.authenticator getPath:authenticationEndpoint
|
||||
completion:^(BITHTTPOperation *operation, id response, NSError *error) {
|
||||
typeof (self) strongSelf = weakSelf;
|
||||
if(nil == response) {
|
||||
//TODO think about alertview messages
|
||||
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil
|
||||
message:@"Failed to authenticate"
|
||||
delegate:nil
|
||||
cancelButtonTitle:BITHockeyLocalizedString(@"OK")
|
||||
otherButtonTitles:nil];
|
||||
[alert show];
|
||||
} else {
|
||||
NSError *authParseError = nil;
|
||||
NSString *authToken = [strongSelf.class authenticationTokenFromReponse:response
|
||||
error:&authParseError];
|
||||
if(nil == authToken) {
|
||||
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil
|
||||
message:@"Failed to authenticate"
|
||||
delegate:nil
|
||||
cancelButtonTitle:BITHockeyLocalizedString(@"OK")
|
||||
otherButtonTitles:nil];
|
||||
[alert show];
|
||||
} else {
|
||||
[strongSelf.delegate authenticationViewController:strongSelf authenticatedWithToken:authToken];
|
||||
}
|
||||
}
|
||||
[self showLoginUI:NO];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void) showLoginUI:(BOOL) enableLoginUI {
|
||||
self.navigationItem.rightBarButtonItem.enabled = !enableLoginUI;
|
||||
self.tableView.userInteractionEnabled = !enableLoginUI;
|
||||
}
|
||||
|
||||
+ (NSString *) authenticationTokenFromReponse:(id) response error:(NSError **) error {
|
||||
NSParameterAssert(response);
|
||||
|
||||
NSError *jsonParseError = nil;
|
||||
id jsonObject = [NSJSONSerialization JSONObjectWithData:response
|
||||
options:0
|
||||
error:&jsonParseError];
|
||||
if(nil == jsonObject) {
|
||||
if(error) {
|
||||
*error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain
|
||||
code:BITAuthenticatorAPIServerReturnedInvalidRespone
|
||||
userInfo:(jsonParseError ? @{NSUnderlyingErrorKey : jsonParseError} : nil)];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
if(![jsonObject isKindOfClass:[NSDictionary class]]) {
|
||||
if(error) {
|
||||
*error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain
|
||||
code:BITAuthenticatorAPIServerReturnedInvalidRespone
|
||||
userInfo:nil];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
//TODO: add proper validation
|
||||
return jsonObject[@"authToken"];
|
||||
}
|
||||
@end
|
||||
|
@ -159,12 +159,16 @@ static NSString* const kBITAuthenticatorLastAuthenticatedVersionKey = @"BITAuthe
|
||||
BITHockeyLog(@"Already authenticating. Ignoring request");
|
||||
return;
|
||||
}
|
||||
UIViewController *viewController = nil;
|
||||
|
||||
BITAuthenticationViewController *viewController = [[BITAuthenticationViewController alloc] initWithStyle:UITableViewStyleGrouped];
|
||||
viewController.delegate = self;
|
||||
viewController.authenticator = self;
|
||||
switch (self.authenticationType) {
|
||||
case BITAuthenticatorAuthTypeEmail:
|
||||
case BITAuthenticatorAuthTypeEmailAndPassword:
|
||||
viewController = [UIViewController new];
|
||||
//TODO
|
||||
viewController.requirePassword = YES;
|
||||
break;
|
||||
case BITAuthenticatorAuthTypeEmail:
|
||||
viewController.requirePassword = NO;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -173,13 +177,16 @@ static NSString* const kBITAuthenticatorLastAuthenticatedVersionKey = @"BITAuthe
|
||||
_authenticationController = viewController;
|
||||
_authenticationCompletionBlock = completion;
|
||||
UIViewController *rootViewController = [self.findVisibleWindow rootViewController];
|
||||
[rootViewController presentModalViewController:_authenticationController
|
||||
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController];
|
||||
[rootViewController presentModalViewController:navController
|
||||
animated:YES];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - AuthenticationViewControllerDelegate
|
||||
- (void) authenticationViewControllerDidCancel:(UIViewController*) viewController {
|
||||
[viewController dismissModalViewControllerAnimated:YES];
|
||||
|
||||
_authenticationController = nil;
|
||||
self.authenticationToken = nil;
|
||||
NSError *error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain
|
||||
|
Loading…
x
Reference in New Issue
Block a user