Skip to content

Commit e3ff2c1

Browse files
authored
Fix migration bugs (#533)
1 parent 6f340a9 commit e3ff2c1

File tree

8 files changed

+149
-66
lines changed

8 files changed

+149
-66
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#import "GoogleSignIn/Sources/GIDAuthStateMigration/GIDAuthStateMigration.h"
18+
19+
/// A fake |GIDAuthStateMigration| for testing.
20+
@interface GIDFakeAuthStateMigration : GIDAuthStateMigration
21+
22+
/// Callback that is called when `migrateIfNeededWithTokenURL` is invoked.
23+
@property (nonatomic, nullable) void (^migrationInvokedCallback)
24+
(NSURL * _Nullable tokenURL, NSString * _Nullable callbackPath, BOOL isFreshInstall);
25+
26+
@end
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#import "GoogleSignIn/Sources/GIDAuthStateMigration/Fake/GIDFakeAuthStateMigration.h"
18+
19+
NS_ASSUME_NONNULL_BEGIN
20+
21+
@implementation GIDFakeAuthStateMigration
22+
23+
@synthesize migrationInvokedCallback = _migrationInvokedCallback;
24+
25+
- (instancetype)initWithKeychainStore:(GTMKeychainStore *)keychainStore {
26+
self = [super initWithKeychainStore:keychainStore];
27+
return self;
28+
}
29+
30+
- (void)migrateIfNeededWithTokenURL:(NSURL *)tokenURL
31+
callbackPath:(NSString *)callbackPath
32+
isFreshInstall:(BOOL)isFreshInstall {
33+
if (_migrationInvokedCallback) {
34+
_migrationInvokedCallback(tokenURL, callbackPath, isFreshInstall);
35+
}
36+
return;
37+
}
38+
39+
@end
40+
41+
NS_ASSUME_NONNULL_END

GoogleSignIn/Sources/GIDAuthStateMigration.h renamed to GoogleSignIn/Sources/GIDAuthStateMigration/GIDAuthStateMigration.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ NS_ASSUME_NONNULL_BEGIN
3030
/// Perform necessary migrations from legacy auth state storage to most recent GTMAppAuth version.
3131
- (void)migrateIfNeededWithTokenURL:(NSURL *)tokenURL
3232
callbackPath:(NSString *)callbackPath
33-
keychainName:(NSString *)keychainName
3433
isFreshInstall:(BOOL)isFreshInstall;
3534

3635
@end

GoogleSignIn/Sources/GIDAuthStateMigration.m renamed to GoogleSignIn/Sources/GIDAuthStateMigration/Implementation/GIDAuthStateMigration.m

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
#import "GoogleSignIn/Sources/GIDAuthStateMigration.h"
16-
15+
#import "GoogleSignIn/Sources/GIDAuthStateMigration/GIDAuthStateMigration.h"
1716
#import "GoogleSignIn/Sources/GIDSignInCallbackSchemes.h"
1817

1918
@import GTMAppAuth;
@@ -65,30 +64,28 @@ - (instancetype)init {
6564

6665
- (void)migrateIfNeededWithTokenURL:(NSURL *)tokenURL
6766
callbackPath:(NSString *)callbackPath
68-
keychainName:(NSString *)keychainName
6967
isFreshInstall:(BOOL)isFreshInstall {
7068
// If this is a fresh install, take no action and mark the migration checks as having been
7169
// performed.
7270
if (isFreshInstall) {
7371
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
74-
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
72+
#if TARGET_OS_OSX
7573
[defaults setBool:YES forKey:kDataProtectedMigrationCheckPerformedKey];
76-
#elif TARGET_OS_IOS
74+
#elif TARGET_OS_IOS && !TARGET_OS_MACCATALYST
7775
[defaults setBool:YES forKey:kGTMAppAuthMigrationCheckPerformedKey];
78-
#endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST
76+
#endif // TARGET_OS_OSX
7977
return;
8078
}
8179

82-
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
80+
#if TARGET_OS_OSX
8381
[self performDataProtectedMigrationIfNeeded];
84-
#elif TARGET_OS_IOS
82+
#elif TARGET_OS_IOS && !TARGET_OS_MACCATALYST
8583
[self performGIDMigrationIfNeededWithTokenURL:tokenURL
86-
callbackPath:callbackPath
87-
keychainName:keychainName];
88-
#endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST
84+
callbackPath:callbackPath];
85+
#endif // TARGET_OS_OSX
8986
}
9087

91-
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
88+
#if TARGET_OS_OSX
9289
// Migrate from the fileBasedKeychain to dataProtectedKeychain with GTMAppAuth 5.0.
9390
- (void)performDataProtectedMigrationIfNeeded {
9491
// See if we've performed the migration check previously.
@@ -107,23 +104,18 @@ - (void)performDataProtectedMigrationIfNeeded {
107104
if (authSession) {
108105
NSError *err;
109106
[self.keychainStore saveAuthSession:authSession error:&err];
110-
// If we're unable to save to the keychain, return without marking migration performed.
111-
if (err) {
112-
return;
113-
};
114107
[keychainStoreLegacy removeAuthSessionWithError:nil];
115108
}
116109

117110
// Mark the migration check as having been performed.
118111
[defaults setBool:YES forKey:kDataProtectedMigrationCheckPerformedKey];
119112
}
120113

121-
#elif TARGET_OS_IOS
114+
#elif TARGET_OS_IOS && !TARGET_OS_MACCATALYST
122115
// Migrate from GPPSignIn 1.x or GIDSignIn 1.0 - 4.x to the GTMAppAuth storage introduced in
123116
// GIDSignIn 5.0.
124117
- (void)performGIDMigrationIfNeededWithTokenURL:(NSURL *)tokenURL
125-
callbackPath:(NSString *)callbackPath
126-
keychainName:(NSString *)keychainName {
118+
callbackPath:(NSString *)callbackPath {
127119
// See if we've performed the migration check previously.
128120
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
129121
if ([defaults boolForKey:kGTMAppAuthMigrationCheckPerformedKey]) {
@@ -138,10 +130,6 @@ - (void)performGIDMigrationIfNeededWithTokenURL:(NSURL *)tokenURL
138130
if (authSession) {
139131
NSError *err;
140132
[self.keychainStore saveAuthSession:authSession error:&err];
141-
// If we're unable to save to the keychain, return without marking migration performed.
142-
if (err) {
143-
return;
144-
};
145133
}
146134

147135
// Mark the migration check as having been performed.
@@ -246,7 +234,7 @@ + (nullable NSString *)passwordForService:(NSString *)service {
246234
NSString *password = [[NSString alloc] initWithData:passwordData encoding:NSUTF8StringEncoding];
247235
return password;
248236
}
249-
#endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST
237+
#endif // TARGET_OS_OSX
250238

251239
@end
252240

GoogleSignIn/Sources/GIDSignIn.m

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#import "GoogleSignIn/Sources/Public/GoogleSignIn/GIDProfileData.h"
2222
#import "GoogleSignIn/Sources/Public/GoogleSignIn/GIDSignInResult.h"
2323

24-
#import "GoogleSignIn/Sources/GIDAuthStateMigration.h"
24+
#import "GoogleSignIn/Sources/GIDAuthStateMigration/GIDAuthStateMigration.h"
2525
#import "GoogleSignIn/Sources/GIDEMMSupport.h"
2626
#import "GoogleSignIn/Sources/GIDSignInInternalOptions.h"
2727
#import "GoogleSignIn/Sources/GIDSignInPreferences.h"
@@ -490,15 +490,19 @@ + (GIDSignIn *)sharedInstance {
490490
dispatch_once(&once, ^{
491491
GTMKeychainStore *keychainStore =
492492
[[GTMKeychainStore alloc] initWithItemName:kGTMAppAuthKeychainName];
493+
GIDAuthStateMigration *authStateMigrationService =
494+
[[GIDAuthStateMigration alloc] initWithKeychainStore:keychainStore];
493495
#if TARGET_OS_IOS && !TARGET_OS_MACCATALYST
494496
if (@available(iOS 14.0, *)) {
495497
GIDAppCheck *appCheck = [GIDAppCheck appCheckUsingAppAttestProvider];
496498
sharedInstance = [[self alloc] initWithKeychainStore:keychainStore
499+
authStateMigrationService:authStateMigrationService
497500
appCheck:appCheck];
498501
}
499502
#endif // TARGET_OS_IOS && !TARGET_OS_MACCATALYST
500503
if (!sharedInstance) {
501-
sharedInstance = [[self alloc] initWithKeychainStore:keychainStore];
504+
sharedInstance = [[self alloc] initWithKeychainStore:keychainStore
505+
authStateMigrationService:authStateMigrationService];
502506
}
503507
});
504508
return sharedInstance;
@@ -533,7 +537,8 @@ - (void)configureDebugProviderWithAPIKey:(NSString *)APIKey
533537

534538
#pragma mark - Private methods
535539

536-
- (instancetype)initWithKeychainStore:(GTMKeychainStore *)keychainStore {
540+
- (instancetype)initWithKeychainStore:(GTMKeychainStore *)keychainStore
541+
authStateMigrationService:(GIDAuthStateMigration *)authStateMigrationService {
537542
self = [super init];
538543
if (self) {
539544
// Get the bundle of the current executable.
@@ -561,20 +566,19 @@ - (instancetype)initWithKeychainStore:(GTMKeychainStore *)keychainStore {
561566
tokenEndpoint:[NSURL URLWithString:tokenEndpointURL]];
562567
_keychainStore = keychainStore;
563568
// Perform migration of auth state from old versions of the SDK if needed.
564-
GIDAuthStateMigration *migration =
565-
[[GIDAuthStateMigration alloc] initWithKeychainStore:_keychainStore];
566-
[migration migrateIfNeededWithTokenURL:_appAuthConfiguration.tokenEndpoint
567-
callbackPath:kBrowserCallbackPath
568-
keychainName:kGTMAppAuthKeychainName
569-
isFreshInstall:isFreshInstall];
569+
[authStateMigrationService migrateIfNeededWithTokenURL:_appAuthConfiguration.tokenEndpoint
570+
callbackPath:kBrowserCallbackPath
571+
isFreshInstall:isFreshInstall];
570572
}
571573
return self;
572574
}
573575

574576
#if TARGET_OS_IOS && !TARGET_OS_MACCATALYST
575577
- (instancetype)initWithKeychainStore:(GTMKeychainStore *)keychainStore
578+
authStateMigrationService:(GIDAuthStateMigration *)authStateMigrationService
576579
appCheck:(GIDAppCheck *)appCheck {
577-
self = [self initWithKeychainStore:keychainStore];
580+
self = [self initWithKeychainStore:keychainStore
581+
authStateMigrationService:authStateMigrationService];
578582
if (self) {
579583
_appCheck = appCheck;
580584
_configureAppCheckCalled = NO;

GoogleSignIn/Sources/GIDSignIn_Private.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ NS_ASSUME_NONNULL_BEGIN
3030
@class GIDSignInInternalOptions;
3131
@class GTMKeychainStore;
3232
@class GIDAppCheck;
33+
@class GIDAuthStateMigration;
3334

3435
/// Represents a completion block that takes a `GIDSignInResult` on success or an error if the
3536
/// operation was unsuccessful.
@@ -46,11 +47,13 @@ typedef void (^GIDDisconnectCompletion)(NSError *_Nullable error);
4647
@property(nonatomic, readwrite, nullable) GIDGoogleUser *currentUser;
4748

4849
/// Private initializer taking a `GTMKeychainStore`.
49-
- (instancetype)initWithKeychainStore:(GTMKeychainStore *)keychainStore;
50+
- (instancetype)initWithKeychainStore:(GTMKeychainStore *)keychainStore
51+
authStateMigrationService:(GIDAuthStateMigration *)authStateMigrationService;
5052

5153
#if TARGET_OS_IOS && !TARGET_OS_MACCATALYST
5254
/// Private initializer taking a `GTMKeychainStore` and `GIDAppCheckProvider`.
5355
- (instancetype)initWithKeychainStore:(GTMKeychainStore *)keychainStore
56+
authStateMigrationService:(GIDAuthStateMigration *)authStateMigrationService
5457
appCheck:(GIDAppCheck *)appCheck
5558
API_AVAILABLE(ios(14));
5659
#endif // TARGET_OS_IOS || !TARGET_OS_MACCATALYST

0 commit comments

Comments
 (0)