Merge branch 'feature/#19-verifyBetaUsers' into develop

meh, always update before doing work…
Conflicts:
	Classes/BITAuthenticator.m
	Classes/HockeySDK.h
This commit is contained in:
Stephan Diederich 2013-09-12 22:23:03 +02:00
commit b23d4f3eb4
3 changed files with 98 additions and 87 deletions

View File

@ -130,9 +130,9 @@ static NSString* const kBITAuthenticatorDidSkipOptionalLogin = @"BITAuthenticato
__weak typeof (self) weakSelf = self; __weak typeof (self) weakSelf = self;
[self.hockeyAppClient getPath:validationPath [self.hockeyAppClient getPath:validationPath
parameters:[self validationParameters] parameters:[self validationParameters]
completion:^(BITHTTPOperation *operation, id response, NSError *error) { completion:^(BITHTTPOperation *operation, NSData* responseData, NSError *error) {
typeof (self) strongSelf = weakSelf; typeof (self) strongSelf = weakSelf;
if(nil == response) { if(nil == responseData) {
NSDictionary *userInfo = nil; NSDictionary *userInfo = nil;
if(error) { if(error) {
userInfo = @{NSUnderlyingErrorKey : error}; userInfo = @{NSUnderlyingErrorKey : error};
@ -143,7 +143,7 @@ static NSString* const kBITAuthenticatorDidSkipOptionalLogin = @"BITAuthenticato
[strongSelf validationFailedWithError:error completion:completion]; [strongSelf validationFailedWithError:error completion:completion];
} else { } else {
NSError *validationParseError = nil; NSError *validationParseError = nil;
BOOL isValidated = [strongSelf.class isValidationResponseValid:response error:&validationParseError]; BOOL isValidated = [strongSelf.class isValidationResponseValid:responseData error:&validationParseError];
if(isValidated) { if(isValidated) {
[strongSelf validationSucceededWithCompletion:completion]; [strongSelf validationSucceededWithCompletion:completion];
} else { } else {
@ -171,7 +171,7 @@ static NSString* const kBITAuthenticatorDidSkipOptionalLogin = @"BITAuthenticato
if(error) { if(error) {
*error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain *error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain
code:BITAuthenticatorAPIServerReturnedInvalidResponse code:BITAuthenticatorAPIServerReturnedInvalidResponse
userInfo:(jsonParseError ? @{NSUnderlyingErrorKey : jsonParseError} : nil)]; userInfo:@{NSLocalizedDescriptionKey : BITHockeyLocalizedString(@"Failed to authenticate. Please try again later.")}];
} }
return NO; return NO;
} }
@ -179,7 +179,7 @@ static NSString* const kBITAuthenticatorDidSkipOptionalLogin = @"BITAuthenticato
if(error) { if(error) {
*error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain *error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain
code:BITAuthenticatorAPIServerReturnedInvalidResponse code:BITAuthenticatorAPIServerReturnedInvalidResponse
userInfo:nil]; userInfo:@{NSLocalizedDescriptionKey : BITHockeyLocalizedString(@"Failed to authenticate. Please try again later.")}];
} }
return NO; return NO;
} }
@ -189,14 +189,14 @@ static NSString* const kBITAuthenticatorDidSkipOptionalLogin = @"BITAuthenticato
if(error) { if(error) {
*error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain *error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain
code:BITAuthenticatorNotAuthorized code:BITAuthenticatorNotAuthorized
userInfo:nil]; userInfo:@{NSLocalizedDescriptionKey : BITHockeyLocalizedString(@"You are not authorized to use this app. Please check that you are a member of this app.")}];
} }
return NO; return NO;
} else if([status isEqualToString:@"not found"]) { } else if([status isEqualToString:@"not found"]) {
if(error) { if(error) {
*error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain *error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain
code:BITAuthenticatorNotAuthorized code:BITAuthenticatorUnknownApplicationID
userInfo:nil]; userInfo:@{NSLocalizedDescriptionKey : BITHockeyLocalizedString(@"Authorization error. Please contact the developer of the app.")}];
} }
return NO; return NO;
} else if([status isEqualToString:@"validated"]) { } else if([status isEqualToString:@"validated"]) {
@ -205,7 +205,7 @@ static NSString* const kBITAuthenticatorDidSkipOptionalLogin = @"BITAuthenticato
if(error) { if(error) {
*error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain *error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain
code:BITAuthenticatorAPIServerReturnedInvalidResponse code:BITAuthenticatorAPIServerReturnedInvalidResponse
userInfo:nil]; userInfo:@{NSLocalizedDescriptionKey : BITHockeyLocalizedString(@"Failed to authenticate. Please try again later.")}];
} }
return NO; return NO;
} }
@ -317,51 +317,18 @@ static NSString* const kBITAuthenticatorDidSkipOptionalLogin = @"BITAuthenticato
NSURLRequest* request = [self requestForAuthenticationEmail:email password:password]; NSURLRequest* request = [self requestForAuthenticationEmail:email password:password];
__weak typeof (self) weakSelf = self; __weak typeof (self) weakSelf = self;
BITHTTPOperation *operation = [self.hockeyAppClient operationWithURLRequest:request BITHTTPOperation *operation = [self.hockeyAppClient operationWithURLRequest:request
completion:^(BITHTTPOperation *operation, id response, NSError *error) { completion:^(BITHTTPOperation *operation, NSData* responseData, NSError *error) {
typeof (self) strongSelf = weakSelf; typeof (self) strongSelf = weakSelf;
if(nil == response) { NSError *authParseError = nil;
NSError *error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain NSString *authToken = [strongSelf.class authenticationTokenFromURLResponse:operation.response
code:BITAuthenticatorAPIServerReturnedInvalidResponse data:responseData
userInfo:@{ error:&authParseError];
NSLocalizedDescriptionKey : BITHockeyLocalizedString(@"HockeyAuthenticationViewControllerNetworkError") if(nil == authToken) {
}]; completion(NO, authParseError);
completion(NO, error); } else {
} else if(401 == operation.response.statusCode) { //no need to call completion, we're dismissing it anyways
NSError *error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain [self didAuthenticateWithToken:authToken];
code:BITAuthenticatorNotAuthorized }}];
userInfo:@{
NSLocalizedDescriptionKey : BITHockeyLocalizedString(@"HockeyAuthenticationViewControllerNotauthorized")
}];
completion(NO, error);
} else {
NSError *authParseError = nil;
NSString *authToken = [strongSelf.class authenticationTokenFromReponse:response
error:&authParseError];
NSError *error = nil;
if(nil == authToken) {
if([authParseError.domain isEqualToString:kBITAuthenticatorErrorDomain] &&
authParseError.code == BITAuthenticatorNotAuthorized) {
error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain
code:BITAuthenticatorNotAuthorized
userInfo:@{
NSLocalizedDescriptionKey : BITHockeyLocalizedString(@"HockeyAuthenticationViewControllerNotauthorized"),
NSUnderlyingErrorKey : authParseError
}];
} else {
error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain
code:BITAuthenticatorErrorUnknown
userInfo:@{
NSLocalizedDescriptionKey : BITHockeyLocalizedString(@"HockeyAuthenticationViewControllerNetworkError"),
NSUnderlyingErrorKey : authParseError
}];
}
completion(NO, error);
} else {
//no need to call completion, we're dismissing it anyways
[self didAuthenticateWithToken:authToken];
}
}
}];
[self.hockeyAppClient enqeueHTTPOperation:operation]; [self.hockeyAppClient enqeueHTTPOperation:operation];
} }
@ -400,52 +367,91 @@ static NSString* const kBITAuthenticatorDidSkipOptionalLogin = @"BITAuthenticato
} }
+ (NSString *) authenticationTokenFromReponse:(id) response error:(NSError **) error { + (NSString *) authenticationTokenFromURLResponse:(NSHTTPURLResponse*) urlResponse data:(NSData*) data error:(NSError **) error {
NSParameterAssert(response); NSParameterAssert(urlResponse);
if(nil == urlResponse) {
if(error) {
*error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain
code:BITAuthenticatorAPIServerReturnedInvalidResponse
userInfo:@{ NSLocalizedDescriptionKey : BITHockeyLocalizedString(@"Failed to authenticate. Please try again later.")}];
}
return nil;
}
switch (urlResponse.statusCode) {
case 404:
if(error) {
*error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain
code:BITAuthenticatorUnknownApplicationID
userInfo:@{
NSLocalizedDescriptionKey : BITHockeyLocalizedString(@"Authorization error. Please contact the developer of the app.")
}];
}
break;
case 401:
if(error) {
*error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain
code:BITAuthenticatorNotAuthorized
userInfo:@{
NSLocalizedDescriptionKey : BITHockeyLocalizedString(@"Wrong email or password. Please check your credentials and try again.")
}];
}
break;
case 200:
//Do nothing, handled below
break;
default:
if(error) {
*error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain
code:BITAuthenticatorAPIServerReturnedInvalidResponse
userInfo:@{ NSLocalizedDescriptionKey : BITHockeyLocalizedString(@"Failed to authenticate. Please try again later.")}];
}
return nil;
break;
}
if(200 != urlResponse.statusCode) {
//make sure we have an error created if user wanted to have one
NSParameterAssert(0 == error || *error);
return nil;
}
NSAssert(urlResponse.statusCode == 200, @"Should be 200 now. Everything else should've been handled above");
NSError *jsonParseError = nil; NSError *jsonParseError = nil;
id jsonObject = [NSJSONSerialization JSONObjectWithData:response id jsonObject = [NSJSONSerialization JSONObjectWithData:data
options:0 options:0
error:&jsonParseError]; error:&jsonParseError];
if(nil == jsonObject) { //no json or unexpected json
if(nil == jsonObject || ![jsonObject isKindOfClass:[NSDictionary class]]) {
if(error) { if(error) {
NSDictionary *userInfo = @{NSLocalizedDescriptionKey: BITHockeyLocalizedString(@"Failed to authenticate. Please try again later.")};
if(jsonParseError) {
NSMutableDictionary *userInfoMutable = [userInfo mutableCopy];
userInfoMutable[NSUnderlyingErrorKey] = jsonParseError;
userInfo = userInfoMutable;
}
*error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain *error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain
code:BITAuthenticatorAPIServerReturnedInvalidResponse code:BITAuthenticatorAPIServerReturnedInvalidResponse
userInfo:(jsonParseError ? @{NSUnderlyingErrorKey : jsonParseError} : nil)]; userInfo:userInfo];
}
return nil;
}
if(![jsonObject isKindOfClass:[NSDictionary class]]) {
if(error) {
*error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain
code:BITAuthenticatorAPIServerReturnedInvalidResponse
userInfo:nil];
} }
return nil; return nil;
} }
NSString *status = jsonObject[@"status"]; NSString *status = jsonObject[@"status"];
if(nil == status) { NSString *authToken = nil;
if(error) { if([status isEqualToString:@"identified"]) {
*error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain authToken = jsonObject[@"iuid"];
code:BITAuthenticatorAPIServerReturnedInvalidResponse
userInfo:nil];
}
return nil;
} else if([status isEqualToString:@"identified"]) {
return jsonObject[@"iuid"];
} else if([status isEqualToString:@"authorized"]) { } else if([status isEqualToString:@"authorized"]) {
return jsonObject[@"auid"]; authToken = jsonObject[@"auid"];
} else {
if(error) {
*error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain
code:BITAuthenticatorNotAuthorized
userInfo:nil];
}
return nil;
} }
if(nil == authToken && error) {
*error = [NSError errorWithDomain:kBITAuthenticatorErrorDomain
code:BITAuthenticatorAPIServerReturnedInvalidResponse
userInfo:@{NSLocalizedDescriptionKey: BITHockeyLocalizedString(@"Failed to authenticate. Please try again later.")}];
}
return authToken;
} }
- (void)authenticationViewControllerDidTapWebButton:(UIViewController *)viewController { - (void)authenticationViewControllerDidTapWebButton:(UIViewController *)viewController {
NSURL *hockeyWebbasedLoginURL = [self.webpageURL URLByAppendingPathComponent:[NSString stringWithFormat:@"apps/%@/authorize", self.encodedAppIdentifier]]; NSURL *hockeyWebbasedLoginURL = [self.webpageURL URLByAppendingPathComponent:[NSString stringWithFormat:@"apps/%@/authorize", self.encodedAppIdentifier]];
[[UIApplication sharedApplication] openURL:hockeyWebbasedLoginURL]; [[UIApplication sharedApplication] openURL:hockeyWebbasedLoginURL];

View File

@ -29,7 +29,7 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
@class BITHTTPOperation; @class BITHTTPOperation;
typedef void (^BITNetworkCompletionBlock)(BITHTTPOperation* operation, id response, NSError* error); typedef void (^BITNetworkCompletionBlock)(BITHTTPOperation* operation, NSData* data, NSError* error);
@interface BITHTTPOperation : NSOperation @interface BITHTTPOperation : NSOperation

View File

@ -165,6 +165,7 @@ typedef NS_ENUM(NSInteger, BITAuthenticatorReason) {
* Network error * Network error
*/ */
BITAuthenticatorNetworkError, BITAuthenticatorNetworkError,
/** /**
* API Server returned invalid response * API Server returned invalid response
*/ */
@ -178,7 +179,11 @@ typedef NS_ENUM(NSInteger, BITAuthenticatorReason) {
*/ */
BITAuthenticatorAuthenticationCancelled, BITAuthenticatorAuthenticationCancelled,
/** /**
* Authoraization secret missing * Unknown Application ID (configuration error)
*/
BITAuthenticatorUnknownApplicationID,
/**
* Authorization secret missing
*/ */
BITAuthenticatorAuthorizationSecretMissing, BITAuthenticatorAuthorizationSecretMissing,
}; };