From 5851287ec2531b5d0bbdb0eb3972fd22e1bf33cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=CC=88ller?= Date: Tue, 9 Sep 2014 15:56:36 +0200 Subject: [PATCH 1/9] added header fields to request class --- Sources/OAuth2Client/NXOAuth2Request.h | 10 ++++++++++ Sources/OAuth2Client/NXOAuth2Request.m | 26 ++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/Sources/OAuth2Client/NXOAuth2Request.h b/Sources/OAuth2Client/NXOAuth2Request.h index 3bc2c270..7f605a73 100644 --- a/Sources/OAuth2Client/NXOAuth2Request.h +++ b/Sources/OAuth2Client/NXOAuth2Request.h @@ -20,6 +20,7 @@ @interface NXOAuth2Request : NSObject { @private NSDictionary *parameters; + NSDictionary *headerFields; NSURL *resource; NSString *requestMethod; NXOAuth2Account *account; @@ -37,6 +38,14 @@ sendProgressHandler:(NXOAuth2ConnectionSendingProgressHandler)progressHandler responseHandler:(NXOAuth2ConnectionResponseHandler)responseHandler; ++ (void)performMethod:(NSString *)method + onResource:(NSURL *)resource + usingParameters:(NSDictionary *)parameters + headerFields:(NSDictionary *)headerFields + withAccount:(NXOAuth2Account *)account + sendProgressHandler:(NXOAuth2ConnectionSendingProgressHandler)progressHandler + responseHandler:(NXOAuth2ConnectionResponseHandler)responseHandler; + #pragma mark Lifecycle @@ -50,6 +59,7 @@ @property (nonatomic, strong, readwrite) NSString *requestMethod; @property (nonatomic, strong, readwrite) NSURL *resource; @property (nonatomic, strong, readwrite) NSDictionary *parameters; +@property (nonatomic, strong, readwrite) NSDictionary *headerFields; #pragma mark Signed NSURLRequest diff --git a/Sources/OAuth2Client/NXOAuth2Request.m b/Sources/OAuth2Client/NXOAuth2Request.m index e44589fd..c9934926 100644 --- a/Sources/OAuth2Client/NXOAuth2Request.m +++ b/Sources/OAuth2Client/NXOAuth2Request.m @@ -37,6 +37,7 @@ @implementation NXOAuth2Request + (void)performMethod:(NSString *)aMethod onResource:(NSURL *)aResource usingParameters:(NSDictionary *)someParameters + headerFields:(NSDictionary *)headerFields withAccount:(NXOAuth2Account *)anAccount sendProgressHandler:(NXOAuth2ConnectionSendingProgressHandler)progressHandler responseHandler:(NXOAuth2ConnectionResponseHandler)responseHandler; @@ -45,9 +46,24 @@ + (void)performMethod:(NSString *)aMethod method:aMethod parameters:someParameters]; request.account = anAccount; + request.headerFields = headerFields; [request performRequestWithSendingProgressHandler:progressHandler responseHandler:responseHandler]; } ++ (void)performMethod:(NSString *)aMethod + onResource:(NSURL *)aResource + usingParameters:(NSDictionary *)someParameters + withAccount:(NXOAuth2Account *)anAccount + sendProgressHandler:(NXOAuth2ConnectionSendingProgressHandler)progressHandler + responseHandler:(NXOAuth2ConnectionResponseHandler)responseHandler; +{ + [self performMethod:aMethod + onResource:aResource + usingParameters:someParameters + withAccount:anAccount + sendProgressHandler:progressHandler + responseHandler:responseHandler]; +} #pragma mark Lifecycle @@ -66,6 +82,7 @@ - (id)initWithResource:(NSURL *)aResource method:(NSString *)aMethod parameters: #pragma mark Accessors @synthesize parameters; +@synthesize headerFields; @synthesize resource; @synthesize requestMethod; @synthesize account; @@ -105,6 +122,15 @@ - (void)performRequestWithSendingProgressHandler:(NXOAuth2ConnectionSendingProgr NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:self.resource]; [request setHTTPMethod:self.requestMethod]; + + if (self.headerFields) { + [self.headerFields enumerateKeysAndObjectsUsingBlock:^(NSString *field, NSString *value, BOOL *stop) { + if ([field isKindOfClass:NSString.class] && [value isKindOfClass:NSString.class]) { + [request setValue:value forHTTPHeaderField:field]; + } + }]; + } + self.connection = [[NXOAuth2Connection alloc] initWithRequest:request requestParameters:self.parameters oauthClient:self.account.oauthClient From ad83f965ada6f2e7db0fde7948cceacdf3b1897d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=CC=88ller?= Date: Thu, 11 Sep 2014 09:40:46 +0200 Subject: [PATCH 2/9] fixes for token refresh --- Sources/OAuth2Client/NXOAuth2Client.m | 5 +++++ Sources/OAuth2Client/NXOAuth2Connection.m | 12 +++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Sources/OAuth2Client/NXOAuth2Client.m b/Sources/OAuth2Client/NXOAuth2Client.m index 2dfa0f6e..d8c07f8d 100644 --- a/Sources/OAuth2Client/NXOAuth2Client.m +++ b/Sources/OAuth2Client/NXOAuth2Client.m @@ -474,6 +474,11 @@ - (void)refreshAccessTokenAndRetryConnection:(NXOAuth2Connection *)retryConnecti clientSecret, @"client_secret", accessToken.refreshToken, @"refresh_token", nil]; + + if (self.additionalAuthenticationParameters) { + [parameters addEntriesFromDictionary:self.additionalAuthenticationParameters]; + } + if (self.desiredScope) { [parameters setObject:[[self.desiredScope allObjects] componentsJoinedByString:@" "] forKey:@"scope"]; } diff --git a/Sources/OAuth2Client/NXOAuth2Connection.m b/Sources/OAuth2Client/NXOAuth2Connection.m index a324850b..96de8ee7 100644 --- a/Sources/OAuth2Client/NXOAuth2Connection.m +++ b/Sources/OAuth2Client/NXOAuth2Connection.m @@ -163,9 +163,7 @@ - (NSURLConnection *)createConnection; ![[requestParameters objectForKey:@"grant_type"] isEqualToString:@"refresh_token"]) { // if token is expired don't bother starting this connection. - NSDate *tenSecondsAgo = [NSDate dateWithTimeIntervalSinceNow:(-10)]; - NSDate *tokenExpiresAt = client.accessToken.expiresAt; - if (client.accessToken.refreshToken && [tenSecondsAgo earlierDate:tokenExpiresAt] == tokenExpiresAt) { + if (client.accessToken.refreshToken && client.accessToken.hasExpired) { [self cancel]; [client refreshAccessTokenAndRetryConnection:self]; return nil; @@ -415,10 +413,10 @@ - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLRespon } } } - if (/*self.statusCode == 401 // TODO: check for status code once the bug returning 500 is fixed - &&*/ client.accessToken.refreshToken != nil - && authenticateHeader - && [authenticateHeader rangeOfString:@"expired_token"].location != NSNotFound) { + + BOOL shouldRefresh = (self.statusCode == 401) && (client.accessToken.hasExpired) && (client.accessToken.refreshToken != nil); + + if (shouldRefresh) { [self cancel]; [client refreshAccessTokenAndRetryConnection:self]; } else { From 6e89cd5192bafa0997a2279e9c9ab3e4aac8b34f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=CC=88ller?= Date: Thu, 11 Sep 2014 12:43:46 +0200 Subject: [PATCH 3/9] additional authorisation header field --- Sources/OAuth2Client/NXOAuth2Connection.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Sources/OAuth2Client/NXOAuth2Connection.m b/Sources/OAuth2Client/NXOAuth2Connection.m index 96de8ee7..e0e987d1 100644 --- a/Sources/OAuth2Client/NXOAuth2Connection.m +++ b/Sources/OAuth2Client/NXOAuth2Connection.m @@ -185,6 +185,8 @@ - (NSURLConnection *)createConnection; if (oauthAuthorizationHeader) { [startRequest setValue:oauthAuthorizationHeader forHTTPHeaderField:@"Authorization"]; + // some services require the access token in the "t_auth_token" header field + [startRequest setValue:client.accessToken.accessToken forHTTPHeaderField:@"t_auth_token"]; } if (client.userAgent && ![startRequest valueForHTTPHeaderField:@"User-Agent"]) { From 732f7d5fdc50da4ea16e8502d7a5d66227b9fafd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=CC=88ller?= Date: Thu, 11 Sep 2014 14:42:38 +0200 Subject: [PATCH 4/9] apply custom header fields to token refresh request --- Sources/OAuth2Client/NXOAuth2Client.m | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Sources/OAuth2Client/NXOAuth2Client.m b/Sources/OAuth2Client/NXOAuth2Client.m index d8c07f8d..506d5e15 100644 --- a/Sources/OAuth2Client/NXOAuth2Client.m +++ b/Sources/OAuth2Client/NXOAuth2Client.m @@ -478,6 +478,12 @@ - (void)refreshAccessTokenAndRetryConnection:(NXOAuth2Connection *)retryConnecti if (self.additionalAuthenticationParameters) { [parameters addEntriesFromDictionary:self.additionalAuthenticationParameters]; } + + if (self.customHeaderFields) { + [self.customHeaderFields enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *obj, BOOL *stop) { + [tokenRequest addValue:obj forHTTPHeaderField:key]; + }]; + } if (self.desiredScope) { [parameters setObject:[[self.desiredScope allObjects] componentsJoinedByString:@" "] forKey:@"scope"]; From a16e2f61468ad1697233245b06fabbbdab6c497a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=CC=88ller?= Date: Tue, 21 Oct 2014 13:43:15 +0200 Subject: [PATCH 5/9] fixed parameter encoding --- Sources/NSString+NXOAuth2.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/NSString+NXOAuth2.m b/Sources/NSString+NXOAuth2.m index 0a6893c2..d75bb08e 100644 --- a/Sources/NSString+NXOAuth2.m +++ b/Sources/NSString+NXOAuth2.m @@ -61,7 +61,7 @@ - (NSString *)nxoauth2_URLEncodedString; return (__bridge_transfer NSString *) CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, //Allocator (__bridge CFStringRef)self, //Original String NULL, //Characters to leave unescaped - CFSTR("!*'();:@&=+$,/?%#[]"), //Legal Characters to be escaped + NULL, //CFSTR("!*'();:@&=+$,/?%#[]"), //Legal Characters to be escaped kCFStringEncodingUTF8); //Encoding } From c6b05eda62bd615a49fb5c79407fb50ee499cc8e Mon Sep 17 00:00:00 2001 From: Jonathan Chou Date: Fri, 17 Apr 2015 16:57:10 -0700 Subject: [PATCH 6/9] made some changes based on comments --- Sources/OAuth2Client/NXOAuth2Connection.m | 4 +++- Sources/OAuth2Client/NXOAuth2Request.h | 4 ++-- Sources/OAuth2Client/NXOAuth2Request.m | 8 ++++---- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Sources/OAuth2Client/NXOAuth2Connection.m b/Sources/OAuth2Client/NXOAuth2Connection.m index d4e6e0b5..1621704f 100644 --- a/Sources/OAuth2Client/NXOAuth2Connection.m +++ b/Sources/OAuth2Client/NXOAuth2Connection.m @@ -163,7 +163,9 @@ - (NSURLConnection *)createConnection; ![[requestParameters objectForKey:@"grant_type"] isEqualToString:@"refresh_token"]) { // if token is expired don't bother starting this connection. - if (client.accessToken.refreshToken && client.accessToken.hasExpired) { + NSDate *tenSecondsAgo = [NSDate dateWithTimeIntervalSinceNow:(-10)]; + NSDate *tokenExpiresAt = client.accessToken.expiresAt; + if (client.accessToken.refreshToken && [tenSecondsAgo earlierDate:tokenExpiresAt] == tokenExpiresAt) { [self cancel]; [client refreshAccessTokenAndRetryConnection:self]; return nil; diff --git a/Sources/OAuth2Client/NXOAuth2Request.h b/Sources/OAuth2Client/NXOAuth2Request.h index eaf566d2..ca795827 100644 --- a/Sources/OAuth2Client/NXOAuth2Request.h +++ b/Sources/OAuth2Client/NXOAuth2Request.h @@ -20,7 +20,7 @@ @interface NXOAuth2Request : NSObject { @private NSDictionary *parameters; - NSDictionary *headerFields; + NSDictionary *customHeaderFields; NSURL *resource; NSString *requestMethod; NXOAuth2Account *account; @@ -61,7 +61,7 @@ @property (nonatomic, strong, readwrite) NSString *requestMethod; @property (nonatomic, strong, readwrite) NSURL *resource; @property (nonatomic, strong, readwrite) NSDictionary *parameters; -@property (nonatomic, strong, readwrite) NSDictionary *headerFields; +@property (nonatomic, strong, readwrite) NSDictionary *customHeaderFields; #pragma mark Signed NSURLRequest diff --git a/Sources/OAuth2Client/NXOAuth2Request.m b/Sources/OAuth2Client/NXOAuth2Request.m index c0e49fa1..8d128ca6 100644 --- a/Sources/OAuth2Client/NXOAuth2Request.m +++ b/Sources/OAuth2Client/NXOAuth2Request.m @@ -46,7 +46,7 @@ + (void)performMethod:(NSString *)aMethod method:aMethod parameters:someParameters]; request.account = anAccount; - request.headerFields = headerFields; + request.customHeaderFields = headerFields; [request performRequestWithSendingProgressHandler:progressHandler responseHandler:responseHandler]; } @@ -82,7 +82,7 @@ - (instancetype)initWithResource:(NSURL *)aResource method:(NSString *)aMethod p #pragma mark Accessors @synthesize parameters; -@synthesize headerFields; +@synthesize customHeaderFields; @synthesize resource; @synthesize requestMethod; @synthesize account; @@ -123,8 +123,8 @@ - (void)performRequestWithSendingProgressHandler:(NXOAuth2ConnectionSendingProgr NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:self.resource]; [request setHTTPMethod:self.requestMethod]; - if (self.headerFields) { - [self.headerFields enumerateKeysAndObjectsUsingBlock:^(NSString *field, NSString *value, BOOL *stop) { + if (self.customHeaderFields) { + [self.customHeaderFields enumerateKeysAndObjectsUsingBlock:^(NSString *field, NSString *value, BOOL *stop) { if ([field isKindOfClass:NSString.class] && [value isKindOfClass:NSString.class]) { [request setValue:value forHTTPHeaderField:field]; } From f26a4297547f14c845956e4480015b892e720178 Mon Sep 17 00:00:00 2001 From: Jonathan Chou Date: Fri, 17 Apr 2015 17:06:10 -0700 Subject: [PATCH 7/9] removing commented code --- Sources/NSString+NXOAuth2.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/NSString+NXOAuth2.m b/Sources/NSString+NXOAuth2.m index d75bb08e..851c7d7f 100644 --- a/Sources/NSString+NXOAuth2.m +++ b/Sources/NSString+NXOAuth2.m @@ -61,7 +61,7 @@ - (NSString *)nxoauth2_URLEncodedString; return (__bridge_transfer NSString *) CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, //Allocator (__bridge CFStringRef)self, //Original String NULL, //Characters to leave unescaped - NULL, //CFSTR("!*'();:@&=+$,/?%#[]"), //Legal Characters to be escaped + NULL, kCFStringEncodingUTF8); //Encoding } From 645d723414eb8d1e359698376fced1be4718e58b Mon Sep 17 00:00:00 2001 From: Jonathan Chou Date: Mon, 20 Apr 2015 14:19:56 -0700 Subject: [PATCH 8/9] re-added characters to be escaped and small organizational changes --- Sources/NSString+NXOAuth2.m | 2 +- Sources/OAuth2Client/NXOAuth2Connection.m | 5 ++--- Sources/OAuth2Client/NXOAuth2Request.m | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Sources/NSString+NXOAuth2.m b/Sources/NSString+NXOAuth2.m index 851c7d7f..0a6893c2 100644 --- a/Sources/NSString+NXOAuth2.m +++ b/Sources/NSString+NXOAuth2.m @@ -61,7 +61,7 @@ - (NSString *)nxoauth2_URLEncodedString; return (__bridge_transfer NSString *) CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, //Allocator (__bridge CFStringRef)self, //Original String NULL, //Characters to leave unescaped - NULL, + CFSTR("!*'();:@&=+$,/?%#[]"), //Legal Characters to be escaped kCFStringEncodingUTF8); //Encoding } diff --git a/Sources/OAuth2Client/NXOAuth2Connection.m b/Sources/OAuth2Client/NXOAuth2Connection.m index 1621704f..d84342da 100644 --- a/Sources/OAuth2Client/NXOAuth2Connection.m +++ b/Sources/OAuth2Client/NXOAuth2Connection.m @@ -187,8 +187,6 @@ - (NSURLConnection *)createConnection; if (oauthAuthorizationHeader) { [startRequest setValue:oauthAuthorizationHeader forHTTPHeaderField:@"Authorization"]; - // some services require the access token in the "t_auth_token" header field - [startRequest setValue:client.accessToken.accessToken forHTTPHeaderField:@"t_auth_token"]; } if (client.userAgent && ![startRequest valueForHTTPHeaderField:@"User-Agent"]) { @@ -418,7 +416,8 @@ - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLRespon } } - BOOL shouldRefresh = (self.statusCode == 401) && (client.accessToken.hasExpired) && (client.accessToken.refreshToken != nil); + BOOL shouldRefresh = (self.statusCode == 401) && (client.accessToken.hasExpired) && (client.accessToken.refreshToken != nil) && authenticateHeader + && [authenticateHeader rangeOfString:@"expired_token"].location != NSNotFound; if (shouldRefresh) { [self cancel]; diff --git a/Sources/OAuth2Client/NXOAuth2Request.m b/Sources/OAuth2Client/NXOAuth2Request.m index 8d128ca6..f945f2ab 100644 --- a/Sources/OAuth2Client/NXOAuth2Request.m +++ b/Sources/OAuth2Client/NXOAuth2Request.m @@ -125,9 +125,9 @@ - (void)performRequestWithSendingProgressHandler:(NXOAuth2ConnectionSendingProgr if (self.customHeaderFields) { [self.customHeaderFields enumerateKeysAndObjectsUsingBlock:^(NSString *field, NSString *value, BOOL *stop) { - if ([field isKindOfClass:NSString.class] && [value isKindOfClass:NSString.class]) { + NSAssert([field isKindOfClass:NSString.class], @"Invalid Type For Field - String Expected"); + NSAssert([value isKindOfClass:NSString.class], @"Invalid Type For Value - String Expected"); [request setValue:value forHTTPHeaderField:field]; - } }]; } From 062e59fc1b4fa7dc601a2bc1c692d54fafc8548d Mon Sep 17 00:00:00 2001 From: Jonathan Chou Date: Mon, 20 Apr 2015 18:05:08 -0700 Subject: [PATCH 9/9] merged dev into feature --- Sources/OAuth2Client/NXOAuth2Connection.m | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Sources/OAuth2Client/NXOAuth2Connection.m b/Sources/OAuth2Client/NXOAuth2Connection.m index d84342da..2a1156cb 100644 --- a/Sources/OAuth2Client/NXOAuth2Connection.m +++ b/Sources/OAuth2Client/NXOAuth2Connection.m @@ -416,7 +416,10 @@ - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLRespon } } - BOOL shouldRefresh = (self.statusCode == 401) && (client.accessToken.hasExpired) && (client.accessToken.refreshToken != nil) && authenticateHeader + BOOL shouldRefresh = (self.statusCode == 401) + && (client.accessToken.hasExpired) + && (client.accessToken.refreshToken != nil) + && authenticateHeader && [authenticateHeader rangeOfString:@"expired_token"].location != NSNotFound; if (shouldRefresh) {