2
0

Bump External dependencies.

This commit is contained in:
Maarten Billemont
2013-08-11 00:08:25 -04:00
parent 77439af486
commit 8375808cdc
224 changed files with 13810 additions and 2949 deletions

View File

@@ -29,10 +29,6 @@ static const NSTimeInterval kDefaultNetworkLossTimeoutInterval = 30.0;
NSString *const kOOBString = @"urn:ietf:wg:oauth:2.0:oob";
@interface GTMOAuth2Authentication (InternalMethods)
- (NSDictionary *)dictionaryWithJSONData:(NSData *)data;
@end
@interface GTMOAuth2SignIn ()
@property (assign) BOOL hasHandledCallback;
@property (retain) GTMHTTPFetcher *pendingFetcher;
@@ -68,6 +64,8 @@ finishedWithFetcher:(GTMHTTPFetcher *)fetcher
- (void)reachabilityTarget:(SCNetworkReachabilityRef)reachabilityRef
changedFlags:(SCNetworkConnectionFlags)flags;
- (void)reachabilityTimerFired:(NSTimer *)timer;
+ (NSData *)decodeWebSafeBase64:(NSString *)base64Str;
@end
@implementation GTMOAuth2SignIn
@@ -559,12 +557,17 @@ finishedWithFetcher:(GTMHTTPFetcher *)fetcher
NSURL *infoURL = [[self class] googleUserInfoURL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:infoURL];
NSString *userAgent = [auth userAgent];
[request setValue:userAgent forHTTPHeaderField:@"User-Agent"];
if ([auth respondsToSelector:@selector(userAgent)]) {
NSString *userAgent = [auth userAgent];
[request setValue:userAgent forHTTPHeaderField:@"User-Agent"];
}
[request setValue:@"no-cache" forHTTPHeaderField:@"Cache-Control"];
GTMHTTPFetcher *fetcher;
id <GTMHTTPFetcherServiceProtocol> fetcherService = auth.fetcherService;
id <GTMHTTPFetcherServiceProtocol> fetcherService = nil;
if ([auth respondsToSelector:@selector(fetcherService)]) {
fetcherService = auth.fetcherService;
};
if (fetcherService) {
fetcher = [fetcherService fetcherWithRequest:request];
} else {
@@ -578,7 +581,36 @@ finishedWithFetcher:(GTMHTTPFetcher *)fetcher
}
- (void)fetchGoogleUserInfo {
// fetch the user's email address or profile
if (!self.shouldFetchGoogleUserProfile) {
// If we only need email and user ID, not the full profile, and we have an
// id_token, it may have the email and user ID so we won't need to fetch
// them.
GTMOAuth2Authentication *auth = self.authentication;
NSString *idToken = [auth.parameters objectForKey:@"id_token"];
if ([idToken length] > 0) {
// The id_token has three dot-delimited parts. The second is the
// JSON profile.
//
// http://www.tbray.org/ongoing/When/201x/2013/04/04/ID-Tokens
NSArray *parts = [idToken componentsSeparatedByString:@"."];
if ([parts count] == 3) {
NSString *part2 = [parts objectAtIndex:1];
if ([part2 length] > 0) {
NSData *data = [[self class] decodeWebSafeBase64:part2];
if ([data length] > 0) {
[self updateGoogleUserInfoWithData:data];
if ([[auth userID] length] > 0 && [[auth userEmail] length] > 0) {
// We obtained user ID and email from the ID token.
[self finishSignInWithError:nil];
return;
}
}
}
}
}
}
// Fetch the email and profile from the userinfo endpoint.
GTMOAuth2Authentication *auth = self.authentication;
GTMHTTPFetcher *fetcher = [[self class] userInfoFetcherWithAuth:auth];
[fetcher beginFetchWithDelegate:self
@@ -611,27 +643,40 @@ finishedWithFetcher:(GTMHTTPFetcher *)fetcher
#endif
} else {
// We have the authenticated user's info
if (data) {
NSDictionary *profileDict = [auth dictionaryWithJSONData:data];
if (profileDict) {
self.userProfile = profileDict;
// Save the ID into the auth object
NSString *identifier = [profileDict objectForKey:@"id"];
[auth setUserID:identifier];
// Save the email into the auth object
NSString *email = [profileDict objectForKey:@"email"];
[auth setUserEmail:email];
NSNumber *verified = [profileDict objectForKey:@"verified_email"];
[auth setUserEmailIsVerified:[verified stringValue]];
}
}
[self updateGoogleUserInfoWithData:data];
}
[self finishSignInWithError:error];
}
- (void)updateGoogleUserInfoWithData:(NSData *)data {
if (!data) return;
GTMOAuth2Authentication *auth = self.authentication;
NSDictionary *profileDict = [[auth class] dictionaryWithJSONData:data];
if (profileDict) {
self.userProfile = profileDict;
// Save the ID into the auth object
NSString *identifier = [profileDict objectForKey:@"id"];
[auth setUserID:identifier];
// Save the email into the auth object
NSString *email = [profileDict objectForKey:@"email"];
[auth setUserEmail:email];
// The verified_email key is a boolean NSNumber in the userinfo
// endpoint response, but it is a string like "true" in the id_token.
// We want to consistently save it as a string of the boolean value,
// like @"1".
id verified = [profileDict objectForKey:@"verified_email"];
if ([verified isKindOfClass:[NSString class]]) {
verified = [NSNumber numberWithBool:[verified boolValue]];
}
[auth setUserEmailIsVerified:[verified stringValue]];
}
}
#endif // !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
- (void)finishSignInWithError:(NSError *)error {
@@ -828,6 +873,62 @@ static void ReachabilityCallBack(SCNetworkReachabilityRef target,
}
[auth reset];
}
// Based on Cyrus Najmabadi's elegent little encoder and decoder from
// http://www.cocoadev.com/index.pl?BaseSixtyFour and on GTLBase64
+ (NSData *)decodeWebSafeBase64:(NSString *)base64Str {
static char decodingTable[128];
static BOOL hasInited = NO;
if (!hasInited) {
char webSafeEncodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
memset(decodingTable, 0, 128);
for (unsigned int i = 0; i < sizeof(webSafeEncodingTable); i++) {
decodingTable[(unsigned int) webSafeEncodingTable[i]] = (char)i;
}
hasInited = YES;
}
// The input string should be plain ASCII.
const char *cString = [base64Str cStringUsingEncoding:NSASCIIStringEncoding];
if (cString == nil) return nil;
NSInteger inputLength = (NSInteger)strlen(cString);
// Input length is not being restricted to multiples of 4.
if (inputLength == 0) return [NSData data];
while (inputLength > 0 && cString[inputLength - 1] == '=') {
inputLength--;
}
NSInteger outputLength = inputLength * 3 / 4;
NSMutableData* data = [NSMutableData dataWithLength:(NSUInteger)outputLength];
uint8_t *output = [data mutableBytes];
NSInteger inputPoint = 0;
NSInteger outputPoint = 0;
char *table = decodingTable;
while (inputPoint < inputLength - 1) {
int i0 = cString[inputPoint++];
int i1 = cString[inputPoint++];
int i2 = inputPoint < inputLength ? cString[inputPoint++] : 'A'; // 'A' will decode to \0
int i3 = inputPoint < inputLength ? cString[inputPoint++] : 'A';
output[outputPoint++] = (uint8_t)((table[i0] << 2) | (table[i1] >> 4));
if (outputPoint < outputLength) {
output[outputPoint++] = (uint8_t)(((table[i1] & 0xF) << 4) | (table[i2] >> 2));
}
if (outputPoint < outputLength) {
output[outputPoint++] = (uint8_t)(((table[i2] & 0x3) << 6) | table[i3]);
}
}
return data;
}
#endif // !GTM_OAUTH2_SKIP_GOOGLE_SUPPORT
@end