From 971d06ad06caadb369e318112bba0e039188cfc2 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Thu, 6 Aug 2015 20:45:37 -0700 Subject: [PATCH 1/5] Fix build breakage --- src/objective-c/GRPCClient/private/GRPCHost.m | 1 + 1 file changed, 1 insertion(+) diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 6636c486202..45e5f0602da 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -78,6 +78,7 @@ if (cachedHost) { return cachedHost; } + } if ((self = [super init])) { _address = address; From 594ae574ad94476e9913c9cb723d929f09c4b918 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Thu, 6 Aug 2015 22:08:53 -0700 Subject: [PATCH 2/5] Add OAuth2 headers category to GRPCCall --- src/objective-c/GRPCClient/GRPCCall+OAuth2.h | 49 +++++++++++++++ src/objective-c/GRPCClient/GRPCCall+OAuth2.m | 63 ++++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 src/objective-c/GRPCClient/GRPCCall+OAuth2.h create mode 100644 src/objective-c/GRPCClient/GRPCCall+OAuth2.m diff --git a/src/objective-c/GRPCClient/GRPCCall+OAuth2.h b/src/objective-c/GRPCClient/GRPCCall+OAuth2.h new file mode 100644 index 00000000000..f14fe254b0f --- /dev/null +++ b/src/objective-c/GRPCClient/GRPCCall+OAuth2.h @@ -0,0 +1,49 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#import "GRPCCall.h" + +// Helpers for setting and reading headers compatible with OAuth2. +@interface GRPCCall (OAuth2) + +// Setting this property is equivalent to setting "Bearer " as the value of the +// request header with key "authorization" (the authorization header). Setting it to nil removes the +// authorization header from the request. +// The value obtained by getting the property is the OAuth2 bearer token if the authorization header +// of the request has the form "Bearer ", or nil otherwise. +@property(atomic, copy) NSString *oauth2_accessToken; + +// Returns the value (if any) of the "www-authenticate" response header (the challenge header). +@property(atomic, readonly) NSString *oauth2_challengeHeader; + +@end diff --git a/src/objective-c/GRPCClient/GRPCCall+OAuth2.m b/src/objective-c/GRPCClient/GRPCCall+OAuth2.m new file mode 100644 index 00000000000..77d00f260eb --- /dev/null +++ b/src/objective-c/GRPCClient/GRPCCall+OAuth2.m @@ -0,0 +1,63 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#import "GRPCCall+OAuth2.h" + +static NSString * const kAuthorizationHeader = @"authorization"; +static NSString * const kBearerPrefix = @"Bearer "; +static NSString * const kChallengeHeader = @"www-authenticate"; + +@implementation GRPCCall (OAuth2) + +- (NSString *)oauth2_accessToken { + NSString *headerValue = self.requestMetadata[kAuthorizationHeader]; + if ([headerValue hasPrefix:kBearerPrefix]) { + return [headerValue substringFromIndex:kBearerPrefix.length]; + } else { + return nil; + } +} + +- (void)setOauth2_accessToken:(NSString *)token { + if (token) { + self.requestMetadata[kAuthorizationHeader] = [kBearerPrefix stringByAppendingString:token]; + } else { + [self.requestMetadata removeObjectForKey:kAuthorizationHeader]; + } +} + +- (NSString *)oauth2_challengeHeader { + return self.responseMetadata[kChallengeHeader]; +} + +@end From 631dc004811bb7b046736faff7666db1d379c1fe Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Thu, 6 Aug 2015 23:08:41 -0700 Subject: [PATCH 3/5] Exercise GRPCCall+OAuth2 in the tests --- src/objective-c/tests/GRPCClientTests.m | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index e5d7e43ed92..1c8461c8e64 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -35,6 +35,7 @@ #import #import +#import #import #import #import @@ -160,7 +161,7 @@ static ProtoMethod *kUnaryCallMethod; path:kUnaryCallMethod.HTTPPath requestsWriter:requestsWriter]; - call.requestMetadata[@"Authorization"] = @"Bearer bogusToken"; + call.oauth2_accessToken = @"bogusToken"; id responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) { XCTFail(@"Received unexpected response: %@", value); @@ -169,7 +170,7 @@ static ProtoMethod *kUnaryCallMethod; XCTAssertEqual(errorOrNil.code, 16, @"Finished with unexpected error: %@", errorOrNil); XCTAssertEqualObjects(call.responseMetadata, errorOrNil.userInfo[kGRPCStatusMetadataKey], @"Metadata in the NSError object and call object differ."); - NSString *challengeHeader = call.responseMetadata[@"www-authenticate"]; + NSString *challengeHeader = call.oauth2_challengeHeader; XCTAssertGreaterThan(challengeHeader.length, 0, @"No challenge in response headers %@", call.responseMetadata); [expectation fulfill]; From 26e0c9ee4c70ad209a5d1d9609c517235e1d1b21 Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Fri, 7 Aug 2015 09:48:33 -0700 Subject: [PATCH 4/5] Fixup for 971d06ad06caadb369e318112bba0e039188cfc2 --- src/objective-c/GRPCClient/private/GRPCHost.m | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 45e5f0602da..d902f95b516 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -78,12 +78,12 @@ if (cachedHost) { return cachedHost; } - } - if ((self = [super init])) { - _address = address; - _secure = YES; - hostCache[address] = self; + if ((self = [super init])) { + _address = address; + _secure = YES; + hostCache[address] = self; + } } return self; } From 721b7a3923996c7ac8aa7258f1fe7d5bc416af2b Mon Sep 17 00:00:00 2001 From: Jorge Canizales Date: Fri, 7 Aug 2015 10:11:16 -0700 Subject: [PATCH 5/5] Rename oauth2_lowerCamel -> oauth2UpperCamel --- src/objective-c/GRPCClient/GRPCCall+OAuth2.h | 4 ++-- src/objective-c/GRPCClient/GRPCCall+OAuth2.m | 6 +++--- src/objective-c/tests/GRPCClientTests.m | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall+OAuth2.h b/src/objective-c/GRPCClient/GRPCCall+OAuth2.h index f14fe254b0f..2e379a71572 100644 --- a/src/objective-c/GRPCClient/GRPCCall+OAuth2.h +++ b/src/objective-c/GRPCClient/GRPCCall+OAuth2.h @@ -41,9 +41,9 @@ // authorization header from the request. // The value obtained by getting the property is the OAuth2 bearer token if the authorization header // of the request has the form "Bearer ", or nil otherwise. -@property(atomic, copy) NSString *oauth2_accessToken; +@property(atomic, copy) NSString *oauth2AccessToken; // Returns the value (if any) of the "www-authenticate" response header (the challenge header). -@property(atomic, readonly) NSString *oauth2_challengeHeader; +@property(atomic, readonly) NSString *oauth2ChallengeHeader; @end diff --git a/src/objective-c/GRPCClient/GRPCCall+OAuth2.m b/src/objective-c/GRPCClient/GRPCCall+OAuth2.m index 77d00f260eb..ed39d4b0f7a 100644 --- a/src/objective-c/GRPCClient/GRPCCall+OAuth2.m +++ b/src/objective-c/GRPCClient/GRPCCall+OAuth2.m @@ -39,7 +39,7 @@ static NSString * const kChallengeHeader = @"www-authenticate"; @implementation GRPCCall (OAuth2) -- (NSString *)oauth2_accessToken { +- (NSString *)oauth2AccessToken { NSString *headerValue = self.requestMetadata[kAuthorizationHeader]; if ([headerValue hasPrefix:kBearerPrefix]) { return [headerValue substringFromIndex:kBearerPrefix.length]; @@ -48,7 +48,7 @@ static NSString * const kChallengeHeader = @"www-authenticate"; } } -- (void)setOauth2_accessToken:(NSString *)token { +- (void)setOauth2AccessToken:(NSString *)token { if (token) { self.requestMetadata[kAuthorizationHeader] = [kBearerPrefix stringByAppendingString:token]; } else { @@ -56,7 +56,7 @@ static NSString * const kChallengeHeader = @"www-authenticate"; } } -- (NSString *)oauth2_challengeHeader { +- (NSString *)oauth2ChallengeHeader { return self.responseMetadata[kChallengeHeader]; } diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index 1c8461c8e64..e85dd6e65cd 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -161,7 +161,7 @@ static ProtoMethod *kUnaryCallMethod; path:kUnaryCallMethod.HTTPPath requestsWriter:requestsWriter]; - call.oauth2_accessToken = @"bogusToken"; + call.oauth2AccessToken = @"bogusToken"; id responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) { XCTFail(@"Received unexpected response: %@", value); @@ -170,7 +170,7 @@ static ProtoMethod *kUnaryCallMethod; XCTAssertEqual(errorOrNil.code, 16, @"Finished with unexpected error: %@", errorOrNil); XCTAssertEqualObjects(call.responseMetadata, errorOrNil.userInfo[kGRPCStatusMetadataKey], @"Metadata in the NSError object and call object differ."); - NSString *challengeHeader = call.oauth2_challengeHeader; + NSString *challengeHeader = call.oauth2ChallengeHeader; XCTAssertGreaterThan(challengeHeader.length, 0, @"No challenge in response headers %@", call.responseMetadata); [expectation fulfill];