Browse Source

Add GIDDataFetcher protocol and implementation

pinlu 3 years ago
parent
commit
915c67a57e

+ 38 - 0
GoogleSignIn/Sources/GIDDataFetcher/API/GIDDataFetcher.h

@@ -0,0 +1,38 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import <Foundation/Foundation.h>
+
+@class OIDAuthState;
+
+NS_ASSUME_NONNULL_BEGIN
+
+@protocol GIDDataFetcher <NSObject>
+
+/// Fetches the data from an URL
+///
+/// @param URL The endpoint to fetch data.
+/// @param authState The state of the current OAuth session.
+/// @param comment The comment for logging purpose.
+/// @param completion The block that is called on completion asynchronously.
+- (void)startFetchURL:(NSURL *)URL
+    fromAuthState:(OIDAuthState *)authState
+      withComment:(NSString *)comment
+       completion:(void (^)(NSData *, NSError *))completion;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 26 - 0
GoogleSignIn/Sources/GIDDataFetcher/Implementations/GIDDataFetcher.h

@@ -0,0 +1,26 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import <Foundation/Foundation.h>
+
+#import "GoogleSignIn/Sources/GIDDataFetcher/API/GIDDataFetcher.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface GIDDataFetcher : NSObject<GIDDataFetcher>
+@end
+
+NS_ASSUME_NONNULL_END

+ 40 - 0
GoogleSignIn/Sources/GIDDataFetcher/Implementations/GIDDataFetcher.m

@@ -0,0 +1,40 @@
+#import "GoogleSignIn/Sources/GIDDataFetcher/Implementations/GIDDataFetcher.h"
+
+#ifdef SWIFT_PACKAGE
+@import AppAuth;
+@import GTMAppAuth;
+#else
+#import <AppAuth/AppAuth.h>
+#import <GTMAppAuth/GTMAppAuth.h>
+#endif
+
+NS_ASSUME_NONNULL_BEGIN
+
+// Maximum retry interval in seconds for the fetcher.
+static const NSTimeInterval kFetcherMaxRetryInterval = 15.0;
+
+@implementation GIDDataFetcher
+
+- (void)startFetchURL:(NSURL *)URL
+    fromAuthState:(OIDAuthState *)authState
+      withComment:(NSString *)comment
+       completion:(void (^)(NSData *, NSError *))completion {
+  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
+  GTMSessionFetcher *fetcher;
+  GTMAppAuthFetcherAuthorization *authorization =
+      [[GTMAppAuthFetcherAuthorization alloc] initWithAuthState:authState];
+  id<GTMSessionFetcherServiceProtocol> fetcherService = authorization.fetcherService;
+  if (fetcherService) {
+    fetcher = [fetcherService fetcherWithRequest:request];
+  } else {
+    fetcher = [GTMSessionFetcher fetcherWithRequest:request];
+  }
+  fetcher.retryEnabled = YES;
+  fetcher.maxRetryInterval = kFetcherMaxRetryInterval;
+  fetcher.comment = comment;
+  [fetcher beginFetchWithCompletionHandler:completion];
+}
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 20 - 30
GoogleSignIn/Sources/GIDSignIn.m

@@ -21,6 +21,8 @@
 #import "GoogleSignIn/Sources/Public/GoogleSignIn/GIDProfileData.h"
 #import "GoogleSignIn/Sources/Public/GoogleSignIn/GIDSignInResult.h"
 
+#import "GoogleSignIn/Sources/GIDDataFetcher/API/GIDDataFetcher.h"
+#import "GoogleSignIn/Sources/GIDDataFetcher/Implementations/GIDDataFetcher.h"
 #import "GoogleSignIn/Sources/GIDEMMSupport.h"
 #import "GoogleSignIn/Sources/GIDKeychainHandler/API/GIDKeychainHandler.h"
 #import "GoogleSignIn/Sources/GIDKeychainHandler/Implementations/GIDKeychainHandler.h"
@@ -170,6 +172,9 @@ static NSString *const kConfigOpenIDRealmKey = @"GIDOpenIDRealm";
   BOOL _restarting;
   
   id<GIDKeychainHandler> _keychainHandler;
+  
+  // The class to fetches data from an url end point.
+  id<GIDDataFetcher> _dataFetcher;
 }
 
 #pragma mark - Public methods
@@ -421,10 +426,10 @@ static NSString *const kConfigOpenIDRealmKey = @"GIDOpenIDRealm";
                      kEnvironmentLoggingParameter,
                      GIDEnvironment()];
   NSURL *revokeURL = [NSURL URLWithString:revokeURLString];
-  [self startFetchURL:revokeURL
-              fromAuthState:authState
-                withComment:@"GIDSignIn: revoke tokens"
-      withCompletionHandler:^(NSData *data, NSError *error) {
+  [_dataFetcher startFetchURL:revokeURL
+                fromAuthState:authState
+                  withComment:@"GIDSignIn: revoke tokens"
+                   completion:^(NSData *data, NSError *error) {
     // Revoking an already revoked token seems always successful, which helps us here.
     if (!error) {
       [self signOut];
@@ -452,10 +457,13 @@ static NSString *const kConfigOpenIDRealmKey = @"GIDOpenIDRealm";
 
 - (id)initPrivate {
   GIDKeychainHandler *keychainHandler = [[GIDKeychainHandler alloc] init];
-  return [self initWithKeychainHandler:keychainHandler];
+  GIDDataFetcher *dataFetcher = [[GIDDataFetcher alloc] init];
+  return [self initWithKeychainHandler:keychainHandler
+                           dataFetcher:dataFetcher];
 }
 
-- (instancetype)initWithKeychainHandler:(id<GIDKeychainHandler>)keychainHandler {
+- (instancetype)initWithKeychainHandler:(id<GIDKeychainHandler>)keychainHandler
+                            dataFetcher:(id<GIDDataFetcher>)dataFetcher{
   self = [super init];
   if (self) {
     // Get the bundle of the current executable.
@@ -491,6 +499,7 @@ static NSString *const kConfigOpenIDRealmKey = @"GIDOpenIDRealm";
 #endif // TARGET_OS_IOS && !TARGET_OS_MACCATALYST
     
     _keychainHandler = keychainHandler;
+    _dataFetcher = dataFetcher;
   }
   return self;
 }
@@ -821,10 +830,11 @@ static NSString *const kConfigOpenIDRealmKey = @"GIDOpenIDRealm";
           [NSString stringWithFormat:kUserInfoURLTemplate,
               [GIDSignInPreferences googleUserInfoServer],
               authState.lastTokenResponse.accessToken]];
-      [self startFetchURL:infoURL
-                  fromAuthState:authState
-                    withComment:@"GIDSignIn: fetch basic profile info"
-          withCompletionHandler:^(NSData *data, NSError *error) {
+      
+      [_dataFetcher startFetchURL:infoURL
+                    fromAuthState:authState
+                      withComment:@"GIDSignIn: fetch basic profile info"
+                       completion:^(NSData *data, NSError *error) {
         if (data && !error) {
           NSError *jsonDeserializationError;
           NSDictionary<NSString *, NSString *> *profileDict =
@@ -874,26 +884,6 @@ static NSString *const kConfigOpenIDRealmKey = @"GIDOpenIDRealm";
   }];
 }
 
-- (void)startFetchURL:(NSURL *)URL
-            fromAuthState:(OIDAuthState *)authState
-              withComment:(NSString *)comment
-    withCompletionHandler:(void (^)(NSData *, NSError *))handler {
-  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
-  GTMSessionFetcher *fetcher;
-  GTMAppAuthFetcherAuthorization *authorization =
-      [[GTMAppAuthFetcherAuthorization alloc] initWithAuthState:authState];
-  id<GTMSessionFetcherServiceProtocol> fetcherService = authorization.fetcherService;
-  if (fetcherService) {
-    fetcher = [fetcherService fetcherWithRequest:request];
-  } else {
-    fetcher = [GTMSessionFetcher fetcherWithRequest:request];
-  }
-  fetcher.retryEnabled = YES;
-  fetcher.maxRetryInterval = kFetcherMaxRetryInterval;
-  fetcher.comment = comment;
-  [fetcher beginFetchWithCompletionHandler:handler];
-}
-
 // Parse incoming URL from the Google Device Policy app.
 - (BOOL)handleDevicePolicyAppURL:(NSURL *)url {
   OIDURLQueryComponent *queryComponent = [[OIDURLQueryComponent alloc] initWithURL:url];

+ 2 - 0
GoogleSignIn/Sources/GIDSignIn_Private.h

@@ -29,6 +29,7 @@ NS_ASSUME_NONNULL_BEGIN
 @class GIDGoogleUser;
 @class GIDSignInInternalOptions;
 
+@protocol GIDDataFetcher;
 @protocol GIDKeychainHandler;
 
 /// Represents a completion block that takes a `GIDSignInResult` on success or an error if the
@@ -50,6 +51,7 @@ typedef void (^GIDDisconnectCompletion)(NSError *_Nullable error);
 
 /// The designated initializer.
 - (instancetype)initWithKeychainHandler:(id<GIDKeychainHandler>)keychainHandler
+                            dataFetcher:(id<GIDDataFetcher>)dataFetcher
     NS_DESIGNATED_INITIALIZER;
 
 /// Authenticates with extra options.

+ 7 - 1
GoogleSignIn/Tests/Unit/GIDSignInTest.m

@@ -31,6 +31,7 @@
 #import "GoogleSignIn/Sources/GIDSignIn_Private.h"
 #import "GoogleSignIn/Sources/GIDSignInPreferences.h"
 #import "GoogleSignIn/Sources/GIDKeychainHandler/Implementations/Fakes/GIDFakeKeychainHandler.h"
+#import "GoogleSignIn/Sources/GIDDataFetcher/Implementations/GIDDataFetcher.h"
 
 #if TARGET_OS_IOS && !TARGET_OS_MACCATALYST
 #import "GoogleSignIn/Sources/GIDEMMErrorHandler.h"
@@ -194,6 +195,7 @@ static NSString *const kNewScope = @"newScope";
   // Mock |GTMAppAuthFetcherAuthorization|.
   id _authorization;
   
+  // Fake for |GIDKeychainHandler|
   GIDFakeKeychainHandler *_keychainHandler;
 
 #if TARGET_OS_IOS || TARGET_OS_MACCATALYST
@@ -308,7 +310,11 @@ static NSString *const kNewScope = @"newScope";
                                           forKey:kAppHasRunBeforeKey];
 
   _keychainHandler = [[GIDFakeKeychainHandler alloc] init];
-  _signIn = [[GIDSignIn alloc] initWithKeychainHandler:_keychainHandler];
+  
+  // TODO:Add the GIDFakeDataFetcher class and replace the real one.
+  GIDDataFetcher* dataFetcher = [[GIDDataFetcher alloc] init];
+  _signIn = [[GIDSignIn alloc] initWithKeychainHandler:_keychainHandler
+                                           dataFetcher:dataFetcher];
   _hint = nil;
 
   __weak GIDSignInTest *weakSelf = self;