Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
30699df
Add KVO in GIDGoogleUser
Alex-4-Git Sep 20, 2022
9ac5478
Observe KVO in GIDGoogleUserTest
Alex-4-Git Sep 20, 2022
26784fe
Utilize the class extension and automatic KVO notifications
Alex-4-Git Sep 22, 2022
f2b0a5f
Merge branch 'GIDGoogleUser-restructure' into pin-AddKVOInGoogleUser
Alex-4-Git Sep 22, 2022
6e5d21a
Only update tokens if necessary
Alex-4-Git Sep 22, 2022
9f32608
Merge branch 'pin-AddKVOInGoogleUser' of https://github.com/google/Go…
Alex-4-Git Sep 22, 2022
d45e398
Remove the KVO testing
Alex-4-Git Sep 22, 2022
a56786b
Test tokens unchanged
Alex-4-Git Sep 23, 2022
58d2acf
Move fetcherAuthorizer from GIDAuthentication to GIDGoogleUser
Alex-4-Git Sep 26, 2022
f843c57
Merge branch 'GIDGoogleUser-restructure' into pin-moveFetcherAuthorizaer
Alex-4-Git Sep 26, 2022
3d29212
Move `fetcherAuthorizer` into GIDGoogleUser API
Alex-4-Git Sep 26, 2022
ca97c30
Create GIDAppAuthFetcherAuthorizationWithEMMSupport class
Alex-4-Git Sep 28, 2022
ad40f6c
Minor improvements.
Alex-4-Git Sep 29, 2022
bd3257d
Update GIDAppAuthFetcherAuthorizationWithEMMSupport.m
Alex-4-Git Sep 29, 2022
f87f063
Create fetcherAuthorizer at initialization
Alex-4-Git Sep 29, 2022
9f9f85a
Fix test failures
Alex-4-Git Sep 29, 2022
c622c97
Suppress the deprecation warnings.
Alex-4-Git Sep 29, 2022
51bb424
Added Utility class GIDEMMSupport to handle EMM related issues.
Alex-4-Git Oct 1, 2022
befe977
Minor improvement.
Alex-4-Git Oct 3, 2022
d8ae1af
Update GIDAppAuthFetcherAuthorizationWithEMMSupport.m
Alex-4-Git Oct 3, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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 <TargetConditionals.h>

#if TARGET_OS_IOS && !TARGET_OS_MACCATALYST

#ifdef SWIFT_PACKAGE
@import GTMAppAuth;
#else
#import <GTMAppAuth/GTMAppAuth.h>
#endif

NS_ASSUME_NONNULL_BEGIN

// A specialized GTMAppAuthFetcherAuthorization subclass with EMM support.
@interface GIDAppAuthFetcherAuthorizationWithEMMSupport : GTMAppAuthFetcherAuthorization

@end

NS_ASSUME_NONNULL_END

#endif // TARGET_OS_IOS && !TARGET_OS_MACCATALYST
129 changes: 129 additions & 0 deletions GoogleSignIn/Sources/GIDAppAuthFetcherAuthorizationWithEMMSupport.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/*
* 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 <TargetConditionals.h>

#if TARGET_OS_IOS && !TARGET_OS_MACCATALYST

#import "GoogleSignIn/Sources/GIDAppAuthFetcherAuthorizationWithEMMSupport.h"

#import "GoogleSignIn/Sources/GIDEMMSupport.h"

#ifdef SWIFT_PACKAGE
@import AppAuth;
@import GTMAppAuth;
#else
#import <AppAuth/AppAuth.h>
#import <GTMAppAuth/GTMAppAuth.h>
#endif

NS_ASSUME_NONNULL_BEGIN

// The specialized GTMAppAuthFetcherAuthorization delegate that handles potential EMM error
// responses.
@interface GIDAppAuthFetcherAuthorizationEMMChainedDelegate : NSObject

// Initializes with chained delegate and selector.
- (instancetype)initWithDelegate:(id)delegate selector:(SEL)selector;

// The callback method for GTMAppAuthFetcherAuthorization to invoke.
- (void)authentication:(GTMAppAuthFetcherAuthorization *)auth
request:(NSMutableURLRequest *)request
finishedWithError:(nullable NSError *)error;

@end

@implementation GIDAppAuthFetcherAuthorizationEMMChainedDelegate {
// We use a weak reference here to match GTMAppAuthFetcherAuthorization.
__weak id _delegate;
SEL _selector;
// We need to maintain a reference to the chained delegate because GTMAppAuthFetcherAuthorization
// only keeps a weak reference.
GIDAppAuthFetcherAuthorizationEMMChainedDelegate *_retained_self;
}

- (instancetype)initWithDelegate:(id)delegate selector:(SEL)selector {
self = [super init];
if (self) {
_delegate = delegate;
_selector = selector;
_retained_self = self;
}
return self;
}

- (void)authentication:(GTMAppAuthFetcherAuthorization *)auth
request:(NSMutableURLRequest *)request
finishedWithError:(nullable NSError *)error {
[GIDEMMSupport handleTokenFetchEMMError:error completion:^(NSError *_Nullable error) {
if (!self->_delegate || !self->_selector) {
return;
}
NSMethodSignature *signature = [self->_delegate methodSignatureForSelector:self->_selector];
if (!signature) {
return;
}
id argument1 = auth;
id argument2 = request;
id argument3 = error;
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setTarget:self->_delegate]; // index 0
[invocation setSelector:self->_selector]; // index 1
[invocation setArgument:&argument1 atIndex:2];
[invocation setArgument:&argument2 atIndex:3];
[invocation setArgument:&argument3 atIndex:4];
[invocation invoke];
}];
// Prepare to deallocate the chained delegate instance because the above block will retain the
// iVar references it uses.
_retained_self = nil;
}

@end

@implementation GIDAppAuthFetcherAuthorizationWithEMMSupport

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
- (void)authorizeRequest:(nullable NSMutableURLRequest *)request
delegate:(id)delegate
didFinishSelector:(SEL)sel {
#pragma clang diagnostic pop
GIDAppAuthFetcherAuthorizationEMMChainedDelegate *chainedDelegate =
[[GIDAppAuthFetcherAuthorizationEMMChainedDelegate alloc] initWithDelegate:delegate
selector:sel];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[super authorizeRequest:request
delegate:chainedDelegate
didFinishSelector:@selector(authentication:request:finishedWithError:)];
#pragma clang diagnostic pop
}

- (void)authorizeRequest:(nullable NSMutableURLRequest *)request
completionHandler:(GTMAppAuthFetcherAuthorizationCompletion)handler {
[super authorizeRequest:request completionHandler:^(NSError *_Nullable error) {
[GIDEMMSupport handleTokenFetchEMMError:error completion:^(NSError *_Nullable error) {
handler(error);
}];
}];
}

@end

NS_ASSUME_NONNULL_END

#endif // TARGET_OS_IOS && !TARGET_OS_MACCATALYST
137 changes: 0 additions & 137 deletions GoogleSignIn/Sources/GIDAuthentication.m
Original file line number Diff line number Diff line change
Expand Up @@ -57,106 +57,6 @@
// New UIDevice system name for iOS.
static NSString *const kNewIOSSystemName = @"iOS";

#if TARGET_OS_IOS && !TARGET_OS_MACCATALYST

// The specialized GTMAppAuthFetcherAuthorization delegate that handles potential EMM error
// responses.
@interface GTMAppAuthFetcherAuthorizationEMMChainedDelegate : NSObject

// Initializes with chained delegate and selector.
- (instancetype)initWithDelegate:(id)delegate selector:(SEL)selector;

// The callback method for GTMAppAuthFetcherAuthorization to invoke.
- (void)authentication:(GTMAppAuthFetcherAuthorization *)auth
request:(NSMutableURLRequest *)request
finishedWithError:(nullable NSError *)error;

@end

@implementation GTMAppAuthFetcherAuthorizationEMMChainedDelegate {
// We use a weak reference here to match GTMAppAuthFetcherAuthorization.
__weak id _delegate;
SEL _selector;
// We need to maintain a reference to the chained delegate because GTMAppAuthFetcherAuthorization
// only keeps a weak reference.
GTMAppAuthFetcherAuthorizationEMMChainedDelegate *_retained_self;
}

- (instancetype)initWithDelegate:(id)delegate selector:(SEL)selector {
self = [super init];
if (self) {
_delegate = delegate;
_selector = selector;
_retained_self = self;
}
return self;
}

- (void)authentication:(GTMAppAuthFetcherAuthorization *)auth
request:(NSMutableURLRequest *)request
finishedWithError:(nullable NSError *)error {
[GIDAuthentication handleTokenFetchEMMError:error completion:^(NSError *_Nullable error) {
if (!self->_delegate || !self->_selector) {
return;
}
NSMethodSignature *signature = [self->_delegate methodSignatureForSelector:self->_selector];
if (!signature) {
return;
}
id argument1 = auth;
id argument2 = request;
id argument3 = error;
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setTarget:self->_delegate]; // index 0
[invocation setSelector:self->_selector]; // index 1
[invocation setArgument:&argument1 atIndex:2];
[invocation setArgument:&argument2 atIndex:3];
[invocation setArgument:&argument3 atIndex:4];
[invocation invoke];
}];
// Prepare to deallocate the chained delegate instance because the above block will retain the
// iVar references it uses.
_retained_self = nil;
}

@end

// A specialized GTMAppAuthFetcherAuthorization subclass with EMM support.
@interface GTMAppAuthFetcherAuthorizationWithEMMSupport : GTMAppAuthFetcherAuthorization
@end

@implementation GTMAppAuthFetcherAuthorizationWithEMMSupport

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
- (void)authorizeRequest:(nullable NSMutableURLRequest *)request
delegate:(id)delegate
didFinishSelector:(SEL)sel {
#pragma clang diagnostic pop
GTMAppAuthFetcherAuthorizationEMMChainedDelegate *chainedDelegate =
[[GTMAppAuthFetcherAuthorizationEMMChainedDelegate alloc] initWithDelegate:delegate
selector:sel];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[super authorizeRequest:request
delegate:chainedDelegate
didFinishSelector:@selector(authentication:request:finishedWithError:)];
#pragma clang diagnostic pop
}

- (void)authorizeRequest:(nullable NSMutableURLRequest *)request
completionHandler:(GTMAppAuthFetcherAuthorizationCompletion)handler {
[super authorizeRequest:request completionHandler:^(NSError *_Nullable error) {
[GIDAuthentication handleTokenFetchEMMError:error completion:^(NSError *_Nullable error) {
handler(error);
}];
}];
}

@end

#endif // TARGET_OS_IOS && !TARGET_OS_MACCATALYST

@implementation GIDAuthentication {
// A queue for pending authentication handlers so we don't fire multiple requests in parallel.
// Access to this ivar should be synchronized.
Expand Down Expand Up @@ -201,33 +101,8 @@ - (nullable NSDate *)idTokenExpirationDate {
return [[[OIDIDToken alloc] initWithIDTokenString:self.idToken] expiresAt];
}

#pragma mark - Private property accessors

#if TARGET_OS_IOS && !TARGET_OS_MACCATALYST
- (NSString *)emmSupport {
return
_authState.lastAuthorizationResponse.request.additionalParameters[kEMMSupportParameterName];
}
#endif // TARGET_OS_IOS && !TARGET_OS_MACCATALYST

#pragma mark - Public methods

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- (id<GTMFetcherAuthorizationProtocol>)fetcherAuthorizer {
#pragma clang diagnostic pop
#if TARGET_OS_IOS && !TARGET_OS_MACCATALYST
GTMAppAuthFetcherAuthorization *authorization = self.emmSupport ?
[[GTMAppAuthFetcherAuthorizationWithEMMSupport alloc] initWithAuthState:_authState] :
[[GTMAppAuthFetcherAuthorization alloc] initWithAuthState:_authState];
#elif TARGET_OS_OSX || TARGET_OS_MACCATALYST
GTMAppAuthFetcherAuthorization *authorization =
[[GTMAppAuthFetcherAuthorization alloc] initWithAuthState:_authState];
#endif // TARGET_OS_IOS && !TARGET_OS_MACCATALYST
authorization.tokenRefreshDelegate = self;
return authorization;
}

- (void)doWithFreshTokens:(GIDAuthenticationCompletion)completion {
if (!([self.accessTokenExpirationDate timeIntervalSinceNow] < kMinimalTimeToExpire ||
(self.idToken && [self.idTokenExpirationDate timeIntervalSinceNow] < kMinimalTimeToExpire))) {
Expand Down Expand Up @@ -360,18 +235,6 @@ + (void)handleTokenFetchEMMError:(nullable NSError *)error

#endif // TARGET_OS_IOS && !TARGET_OS_MACCATALYST

#pragma mark - GTMAppAuthFetcherAuthorizationTokenRefreshDelegate

- (nullable NSDictionary *)additionalRefreshParameters:
(GTMAppAuthFetcherAuthorization *)authorization {
#if TARGET_OS_IOS && !TARGET_OS_MACCATALYST
return [GIDAuthentication updatedEMMParametersWithParameters:
authorization.authState.lastTokenResponse.request.additionalParameters];
#elif TARGET_OS_OSX || TARGET_OS_MACCATALYST
return authorization.authState.lastTokenResponse.request.additionalParameters;
#endif // TARGET_OS_IOS && !TARGET_OS_MACCATALYST
}

#pragma mark - NSSecureCoding

+ (BOOL)supportsSecureCoding {
Expand Down
29 changes: 1 addition & 28 deletions GoogleSignIn/Sources/GIDAuthentication_Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,43 +16,16 @@

#import "GoogleSignIn/Sources/Public/GoogleSignIn/GIDAuthentication.h"

#ifdef SWIFT_PACKAGE
@import AppAuth;
@import GTMAppAuth;
#else
#import <AppAuth/AppAuth.h>
#import <GTMAppAuth/GTMAppAuth.h>
#endif

NS_ASSUME_NONNULL_BEGIN

// Internal methods for the class that are not part of the public API.
@interface GIDAuthentication () <GTMAppAuthFetcherAuthorizationTokenRefreshDelegate>
@interface GIDAuthentication ()

// A representation of the state of the OAuth session for this instance.
@property(nonatomic, readonly) OIDAuthState *authState;

#if TARGET_OS_IOS && !TARGET_OS_MACCATALYST
// A string indicating support for Enterprise Mobility Management.
@property(nonatomic, readonly) NSString *emmSupport;
#endif // TARGET_OS_IOS && !TARGET_OS_MACCATALYST

- (instancetype)initWithAuthState:(OIDAuthState *)authState;

#if TARGET_OS_IOS && !TARGET_OS_MACCATALYST
// Gets a new set of URL parameters that also contains EMM-related URL parameters if needed.
+ (NSDictionary *)parametersWithParameters:(NSDictionary *)parameters
emmSupport:(nullable NSString *)emmSupport
isPasscodeInfoRequired:(BOOL)isPasscodeInfoRequired;

// Gets a new set of URL parameters that contains updated EMM-related URL parameters if needed.
+ (NSDictionary *)updatedEMMParametersWithParameters:(NSDictionary *)parameters;

// Handles potential EMM error from token fetch response.
+ (void)handleTokenFetchEMMError:(nullable NSError *)error
completion:(void (^)(NSError *_Nullable))completion;
#endif // TARGET_OS_IOS && !TARGET_OS_MACCATALYST

@end

NS_ASSUME_NONNULL_END
Loading