Skip to content

Commit

Permalink
#2573 Upgrade GTMAppAuth to v4 (#2633)
Browse files Browse the repository at this point in the history
* feat: upgraded GTMAppAuth to v4

* fix: unit test
  • Loading branch information
ioanmo226 authored Nov 4, 2024
1 parent e2bce84 commit 1482265
Show file tree
Hide file tree
Showing 9 changed files with 34 additions and 30 deletions.
2 changes: 1 addition & 1 deletion FlowCrypt.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -3887,7 +3887,7 @@
repositoryURL = "https://github.com/google/GTMAppAuth";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 2.0.0;
minimumVersion = 4.0.0;
};
};
51A1A12629070CDF007F1188 /* XCRemoteSwiftPackageReference "Texture" */ = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"originHash" : "672e29829148463333cfe67147f4218035ae9dc45722e5edd9d0f3ce2cf783a7",
"originHash" : "05430bf1fc71f707204c86e319466dfc225d7e8224d4328e53f7059acda7dbd3",
"pins" : [
{
"identity" : "appauth-ios",
Expand Down Expand Up @@ -42,8 +42,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GoogleSignIn-iOS",
"state" : {
"revision" : "7932d33686c1dc4d7df7a919aae47361d1cdfda4",
"version" : "7.0.0"
"revision" : "a7965d134c5d3567026c523e0a8a583f73b62b0d",
"version" : "7.1.0"
}
},
{
Expand All @@ -60,8 +60,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/GTMAppAuth.git",
"state" : {
"revision" : "cee3c709307912d040bd1e06ca919875a92339c6",
"version" : "2.0.0"
"revision" : "5d7d66f647400952b1758b230e019b07c0b4b22a",
"version" : "4.1.1"
}
},
{
Expand Down
2 changes: 1 addition & 1 deletion FlowCrypt/Controllers/Compose/ComposeViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ final class ComposeViewController: TableNodeViewController {
self.googleAuthManager = GoogleAuthManager(
appDelegateGoogleSessionContainer: UIApplication.shared.delegate as? AppDelegate
)
self.contactsProvider = GoogleContactsProvider(authorization: self.googleAuthManager.authorization(for: appContext.user.email))
self.contactsProvider = try GoogleContactsProvider(authorization: self.googleAuthManager.authorization(for: appContext.user.email))

let draftsApiClient = try appContext.getRequiredMailProvider().draftsApiClient

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ extension ComposeViewController {
for: .gmailLogin(self),
appContext: appContext
)
contactsProvider.authorization = googleAuthManager.authorization(for: appContext.user.email)
contactsProvider.authorization = try googleAuthManager.authorization(for: appContext.user.email)
shouldEvaluateRecipientInput = true
reload(sections: [.contacts])
} catch {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Foundation
import GTMAppAuth

protocol ContactsProviderType {
var authorization: GTMAppAuthFetcherAuthorization? { get set }
var authorization: GTMAppAuth.AuthSession? { get set }
var isContactsScopeEnabled: Bool { get }
func searchContacts(query: String) async throws -> [Recipient]
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ enum ContactsProviderError: Error {
}

class GoogleContactsProvider: ContactsProviderType {
var authorization: GTMAppAuthFetcherAuthorization? {
var authorization: GTMAppAuth.AuthSession? {
didSet {
guard isContactsScopeEnabled else { return }
runWarmupQuery()
Expand Down Expand Up @@ -68,7 +68,7 @@ class GoogleContactsProvider: ContactsProviderType {
}
}

init(authorization: GTMAppAuthFetcherAuthorization?) {
init(authorization: GTMAppAuth.AuthSession?) {
self.authorization = authorization
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class GmailService: MailServiceProvider {
self?.progressHandler?(progress)
}

guard let authorization = googleAuthManager.authorization(for: currentUserEmail) else {
guard let authorization = try? googleAuthManager.authorization(for: currentUserEmail) else {
logger.logWarning("authorization for current user is nil")
return service
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ enum GoogleAuthManagerError: Error, CustomStringConvertible {
}

protocol GoogleAuthManagerType {
func authorization(for email: String?) -> GTMAppAuthFetcherAuthorization?
func authorization(for email: String?) throws -> GTMAppAuth.AuthSession?
}

// this is here so that we don't have to include AppDelegate in test target
Expand All @@ -64,16 +64,17 @@ final class GoogleAuthManager: NSObject, GoogleAuthManagerType {

lazy var logger = Logger.nested(in: Self.self, with: .userAppStart)

private func idToken(for email: String?) -> String? {
return authorization(for: email)?.authState.lastTokenResponse?.idToken
private func idToken(for email: String?) throws -> String? {
return try authorization(for: email)?.authState.lastTokenResponse?.idToken
}

func authorization(for email: String?) -> GTMAppAuthFetcherAuthorization? {
func authorization(for email: String?) throws -> GTMAppAuth.AuthSession? {
guard let email else {
return nil
}
let keychainStore = GTMAppAuth.KeychainStore(itemName: Constants.index + email)
// get authorization from keychain
return GTMAppAuthFetcherAuthorization(fromKeychainForName: Constants.index + email)
return try keychainStore.retrieveAuthSession()
}

private var authorizationConfiguration: OIDServiceConfiguration {
Expand All @@ -83,7 +84,7 @@ final class GoogleAuthManager: NSObject, GoogleAuthManagerType {
tokenEndpoint: URL(string: "\(GeneralConstants.Mock.backendUrl)/token")!
)
} else {
return GTMAppAuthFetcherAuthorization.configurationForGoogle()
return GTMAppAuth.AuthSession.configurationForGoogle()
}
}
}
Expand Down Expand Up @@ -129,7 +130,8 @@ extension GoogleAuthManager {
func signOut(user email: String) {
DispatchQueue.main.async {
self.appDelegateGoogleSessionContainer?.googleAuthSession = nil
GTMAppAuthFetcherAuthorization.removeFromKeychain(forName: Constants.index + email)
let keychainStore = GTMAppAuth.KeychainStore(itemName: Constants.index + email)
try? keychainStore.removeAuthSession()
}
}

Expand Down Expand Up @@ -163,7 +165,7 @@ extension GoogleAuthManager {
scopes: [GoogleScope],
userEmail: String?
) async throws -> SessionType {
let authorization = GTMAppAuthFetcherAuthorization(authState: authState)
let authorization = GTMAppAuth.AuthSession(authState: authState)

guard let email = authorization.userEmail else {
throw GoogleAuthManagerError.inconsistentState("Missing email")
Expand All @@ -178,7 +180,7 @@ extension GoogleAuthManager {
email: authorization.userEmail
)
}
saveAuth(state: authState, for: email)
try saveAuth(state: authState, for: email)
guard let token = authState.lastTokenResponse?.accessToken else {
throw GoogleAuthManagerError.inconsistentState("Missing token")
}
Expand Down Expand Up @@ -210,14 +212,16 @@ extension GoogleAuthManager {
}

// save auth session to keychain
private func saveAuth(state: OIDAuthState, for email: String) {
private func saveAuth(state: OIDAuthState, for email: String) throws {
state.stateChangeDelegate = self
let authorization = GTMAppAuthFetcherAuthorization(authState: state)
GTMAppAuthFetcherAuthorization.save(authorization, toKeychainForName: Constants.index + email)
let authorization = GTMAppAuth.AuthSession(authState: state)
let keychainStore = GTMAppAuth.KeychainStore(itemName: Constants.index + email)

try keychainStore.save(authSession: authorization)
}

private func fetchGoogleUser(
with authorization: GTMAppAuthFetcherAuthorization
with authorization: GTMAppAuth.AuthSession
) async throws -> GTLROauth2_Userinfo {
return try await withCheckedThrowingContinuation { continuation in
let query = GTLROauth2Query_UserinfoGet.query()
Expand Down Expand Up @@ -249,7 +253,7 @@ extension GoogleAuthManager {
// MARK: - Tokens
extension GoogleAuthManager {
func getCachedOrRefreshedIdToken(minExpiryDuration: Double = 0, email: String?) async throws -> String {
guard let idToken = idToken(for: email) else { throw (IdTokenError.missingToken) }
guard let idToken = try idToken(for: email) else { throw (IdTokenError.missingToken) }

let decodedToken = try decode(idToken: idToken)

Expand Down Expand Up @@ -282,7 +286,7 @@ extension GoogleAuthManager {

private func performTokenRefresh(email: String?) async throws -> (accessToken: String, idToken: String) {
return try await withCheckedThrowingContinuation { continuation in
let authorization = authorization(for: email)
let authorization = try? authorization(for: email)
authorization?.authState.setNeedsTokenRefresh()
authorization?.authState.performAction { accessToken, idToken, error in
guard let accessToken, let idToken else {
Expand All @@ -299,10 +303,10 @@ extension GoogleAuthManager {
// MARK: - OIDAuthStateChangeDelegate
extension GoogleAuthManager: OIDAuthStateChangeDelegate {
func didChange(_ state: OIDAuthState) {
let authorization = GTMAppAuthFetcherAuthorization(authState: state)
let authorization = GTMAppAuth.AuthSession(authState: state)
guard let email = authorization.userEmail else {
return
}
saveAuth(state: state, for: email)
try? saveAuth(state: state, for: email)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class GmailServiceTest: XCTestCase {

// MARK: - Mock
class GoogleAuthManagerMock: GoogleAuthManagerType {
func authorization(for email: String?) -> GTMAppAuthFetcherAuthorization? {
func authorization(for email: String?) -> GTMAppAuth.AuthSession? {
return nil
}

Expand Down

0 comments on commit 1482265

Please sign in to comment.