From 124b5ea12892b197c87dbfbed6e7317deb492469 Mon Sep 17 00:00:00 2001 From: Paul Beusterien Date: Wed, 2 Oct 2024 16:22:35 -0700 Subject: [PATCH 1/6] [Auth] Eliminate possibility of multiple AuthBackendRPCImplementation instances --- FirebaseAuth/Sources/Swift/Backend/AuthBackend.swift | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/FirebaseAuth/Sources/Swift/Backend/AuthBackend.swift b/FirebaseAuth/Sources/Swift/Backend/AuthBackend.swift index 444a97c1c07..a11a00e9b62 100644 --- a/FirebaseAuth/Sources/Swift/Backend/AuthBackend.swift +++ b/FirebaseAuth/Sources/Swift/Backend/AuthBackend.swift @@ -76,21 +76,16 @@ class AuthBackend { return "FirebaseAuth.iOS/\(FirebaseVersion()) \(GTMFetcherStandardUserAgentString(nil))" } - private static var gBackendImplementation: AuthBackendImplementation? + private static var gBackendImplementation = AuthBackendRPCImplementation() class func setDefaultBackendImplementationWithRPCIssuer(issuer: AuthBackendRPCIssuer?) { - let defaultImplementation = AuthBackendRPCImplementation() if let issuer = issuer { - defaultImplementation.rpcIssuer = issuer + gBackendImplementation.rpcIssuer = issuer } - gBackendImplementation = defaultImplementation } class func implementation() -> AuthBackendImplementation { - if gBackendImplementation == nil { - gBackendImplementation = AuthBackendRPCImplementation() - } - return gBackendImplementation! + return gBackendImplementation } class func call(with request: T) async throws -> T.Response { From 513c9564d091c2d33cb23d8ebedf635b5dd65709 Mon Sep 17 00:00:00 2001 From: Paul Beusterien Date: Thu, 3 Oct 2024 13:39:39 -0700 Subject: [PATCH 2/6] fix tests --- .../Sources/Swift/Backend/AuthBackend.swift | 13 ++++++++----- FirebaseAuth/Tests/Unit/RPCBaseTests.swift | 4 ++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/FirebaseAuth/Sources/Swift/Backend/AuthBackend.swift b/FirebaseAuth/Sources/Swift/Backend/AuthBackend.swift index a11a00e9b62..84bf5ec55c9 100644 --- a/FirebaseAuth/Sources/Swift/Backend/AuthBackend.swift +++ b/FirebaseAuth/Sources/Swift/Backend/AuthBackend.swift @@ -76,12 +76,15 @@ class AuthBackend { return "FirebaseAuth.iOS/\(FirebaseVersion()) \(GTMFetcherStandardUserAgentString(nil))" } - private static var gBackendImplementation = AuthBackendRPCImplementation() + private static var realRPCBackend = AuthBackendRPCImplementation() + private static var gBackendImplementation = realRPCBackend - class func setDefaultBackendImplementationWithRPCIssuer(issuer: AuthBackendRPCIssuer?) { - if let issuer = issuer { - gBackendImplementation.rpcIssuer = issuer - } + class func setTestRPCIssuer(issuer: AuthBackendRPCIssuer) { + gBackendImplementation.rpcIssuer = issuer + } + + class func resetRPCIssuer() { + gBackendImplementation.rpcIssuer = realRPCBackend.rpcIssuer } class func implementation() -> AuthBackendImplementation { diff --git a/FirebaseAuth/Tests/Unit/RPCBaseTests.swift b/FirebaseAuth/Tests/Unit/RPCBaseTests.swift index cca4e1ee3cb..567b3aa4bbd 100644 --- a/FirebaseAuth/Tests/Unit/RPCBaseTests.swift +++ b/FirebaseAuth/Tests/Unit/RPCBaseTests.swift @@ -72,13 +72,13 @@ class RPCBaseTests: XCTestCase { override func setUp() { rpcIssuer = FakeBackendRPCIssuer() - AuthBackend.setDefaultBackendImplementationWithRPCIssuer(issuer: rpcIssuer) + AuthBackend.setTestRPCIssuer(issuer: rpcIssuer) rpcImplementation = AuthBackend.implementation() } override func tearDown() { rpcIssuer = nil - AuthBackend.setDefaultBackendImplementationWithRPCIssuer(issuer: nil) + AuthBackend.resetRPCIssuer() } /** @fn checkRequest From 531b3f8455cede40d90feb10ad7909811e37e7de Mon Sep 17 00:00:00 2001 From: Paul Beusterien Date: Thu, 3 Oct 2024 14:34:13 -0700 Subject: [PATCH 3/6] fix test failure --- .../Swift/AuthProvider/OAuthProvider.swift | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/FirebaseAuth/Sources/Swift/AuthProvider/OAuthProvider.swift b/FirebaseAuth/Sources/Swift/AuthProvider/OAuthProvider.swift index c14fed69031..6fff479334f 100644 --- a/FirebaseAuth/Sources/Swift/AuthProvider/OAuthProvider.swift +++ b/FirebaseAuth/Sources/Swift/AuthProvider/OAuthProvider.swift @@ -336,13 +336,10 @@ import Foundation } } - /// Used to obtain an auth credential via a mobile web flow. - /// This method is available on iOS only. - /// - Parameter uiDelegate: An optional UI delegate used to present the mobile web flow. - @available(iOS 13, tvOS 13, macOS 10.15, watchOS 8, *) - @objc(getCredentialWithUIDelegate:completion:) - @MainActor - open func credential(with uiDelegate: AuthUIDelegate?) async throws -> AuthCredential { + // Run the actual getCredential off the main thread. but the public API must return on the + // main thread. + private func getCredentialInternal(with uiDelegate: AuthUIDelegate?) async throws + -> AuthCredential { return try await withCheckedThrowingContinuation { continuation in getCredentialWith(uiDelegate) { credential, error in if let credential = credential { @@ -353,6 +350,16 @@ import Foundation } } } + + /// Used to obtain an auth credential via a mobile web flow. + /// This method is available on iOS only. + /// - Parameter uiDelegate: An optional UI delegate used to present the mobile web flow. + @available(iOS 13, tvOS 13, macOS 10.15, watchOS 8, *) + @objc(getCredentialWithUIDelegate:completion:) + @MainActor + open func credential(with uiDelegate: AuthUIDelegate?) async throws -> AuthCredential { + return try await getCredentialInternal(with: uiDelegate) + } #endif /// Creates an `AuthCredential` for the Sign in with Apple OAuth 2 provider identified by ID From ff8a37eefedea8a2f9087ef53c6375e01b25038e Mon Sep 17 00:00:00 2001 From: Paul Beusterien Date: Thu, 3 Oct 2024 15:17:47 -0700 Subject: [PATCH 4/6] Remove problematic test --- .../Tests/Unit/FIROAuthProviderTests.m | 26 ------------------- 1 file changed, 26 deletions(-) diff --git a/FirebaseAuth/Tests/Unit/FIROAuthProviderTests.m b/FirebaseAuth/Tests/Unit/FIROAuthProviderTests.m index b5921312caa..cd0e4c1beba 100644 --- a/FirebaseAuth/Tests/Unit/FIROAuthProviderTests.m +++ b/FirebaseAuth/Tests/Unit/FIROAuthProviderTests.m @@ -162,32 +162,6 @@ - (void)testObtainingOAuthCredentialWithIDToken { XCTAssertEqualObjects(OAuthCredential.IDToken, kFakeIDToken); } -/** @fn testGetCredentialWithUIDelegateWithClientIDOnMainThread - @brief Verifies @c getCredentialWithUIDelegate:completion: calls its completion handler on the - main thread. Regression test for firebase/FirebaseUI-iOS#1199. - */ -- (void)testGetCredentialWithUIDelegateWithClientIDOnMainThread { - XCTestExpectation *expectation = [self expectationWithDescription:@"callback"]; - - FIROptions *options = - [[FIROptions alloc] initWithGoogleAppID:@"0:0000000000000:ios:0000000000000000" - GCMSenderID:@"00000000000000000-00000000000-000000000"]; - options.APIKey = kFakeAPIKey; - options.projectID = @"myProjectID"; - options.clientID = kFakeClientID; - [FIRApp configureWithName:@"objAppName" options:options]; - FIRAuth *auth = [FIRAuth authWithApp:[FIRApp appNamed:@"objAppName"]]; - [auth setMainBundleUrlTypes:@[ @{@"CFBundleURLSchemes" : @[ kFakeReverseClientID ]} ]]; - - FIROAuthProvider *provider = [FIROAuthProvider providerWithProviderID:kFakeProviderID auth:auth]; - [provider getCredentialWithUIDelegate:nil - completion:^(FIRAuthCredential *_Nullable credential, - NSError *_Nullable error) { - XCTAssertTrue([NSThread isMainThread]); - [expectation fulfill]; - }]; - [self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil]; -} @end #endif // TARGET_OS_IOS From 33d6e8a0e8af8d13e89cbfbee9788db78162fc89 Mon Sep 17 00:00:00 2001 From: Paul Beusterien Date: Thu, 3 Oct 2024 15:19:25 -0700 Subject: [PATCH 5/6] revert testing code --- .../Swift/AuthProvider/OAuthProvider.swift | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/FirebaseAuth/Sources/Swift/AuthProvider/OAuthProvider.swift b/FirebaseAuth/Sources/Swift/AuthProvider/OAuthProvider.swift index 6fff479334f..c14fed69031 100644 --- a/FirebaseAuth/Sources/Swift/AuthProvider/OAuthProvider.swift +++ b/FirebaseAuth/Sources/Swift/AuthProvider/OAuthProvider.swift @@ -336,10 +336,13 @@ import Foundation } } - // Run the actual getCredential off the main thread. but the public API must return on the - // main thread. - private func getCredentialInternal(with uiDelegate: AuthUIDelegate?) async throws - -> AuthCredential { + /// Used to obtain an auth credential via a mobile web flow. + /// This method is available on iOS only. + /// - Parameter uiDelegate: An optional UI delegate used to present the mobile web flow. + @available(iOS 13, tvOS 13, macOS 10.15, watchOS 8, *) + @objc(getCredentialWithUIDelegate:completion:) + @MainActor + open func credential(with uiDelegate: AuthUIDelegate?) async throws -> AuthCredential { return try await withCheckedThrowingContinuation { continuation in getCredentialWith(uiDelegate) { credential, error in if let credential = credential { @@ -350,16 +353,6 @@ import Foundation } } } - - /// Used to obtain an auth credential via a mobile web flow. - /// This method is available on iOS only. - /// - Parameter uiDelegate: An optional UI delegate used to present the mobile web flow. - @available(iOS 13, tvOS 13, macOS 10.15, watchOS 8, *) - @objc(getCredentialWithUIDelegate:completion:) - @MainActor - open func credential(with uiDelegate: AuthUIDelegate?) async throws -> AuthCredential { - return try await getCredentialInternal(with: uiDelegate) - } #endif /// Creates an `AuthCredential` for the Sign in with Apple OAuth 2 provider identified by ID From 9be938f348435d24a17259967ea3f809a4f17fec Mon Sep 17 00:00:00 2001 From: Paul Beusterien Date: Thu, 3 Oct 2024 15:53:02 -0700 Subject: [PATCH 6/6] warning fix --- FirebaseAuth/Tests/Unit/FIROAuthProviderTests.m | 5 ----- 1 file changed, 5 deletions(-) diff --git a/FirebaseAuth/Tests/Unit/FIROAuthProviderTests.m b/FirebaseAuth/Tests/Unit/FIROAuthProviderTests.m index cd0e4c1beba..0a8e7d30b05 100644 --- a/FirebaseAuth/Tests/Unit/FIROAuthProviderTests.m +++ b/FirebaseAuth/Tests/Unit/FIROAuthProviderTests.m @@ -22,11 +22,6 @@ @import FirebaseAuth; @import FirebaseCore; -/** @var kExpectationTimeout - @brief The maximum time waiting for expectations to fulfill. - */ -static const NSTimeInterval kExpectationTimeout = 1; - /** @var kFakeAuthorizedDomain @brief A fake authorized domain for the app. */