From d5ef990ddbc8e7b9d68d8f92cdc9ad5d086e09ac Mon Sep 17 00:00:00 2001 From: Fahim Salam Chowdhury Date: Fri, 15 Jul 2022 16:29:25 +0600 Subject: [PATCH 1/5] 5356-fix_google_auth_issue issue: https://gitlab.e.foundation/e/backlog/-/issues/5356 authState was missing for googleAccounts handled by accountManager. authState is saved for new googleAccount creation & checked for missing authStates & update for backword-compatibility. --- .../k9/controller/MessagingController.java | 8 +- .../java/com/fsck/k9/job/MailSyncWorker.kt | 4 +- .../fsck/k9/setup/AccountManagerConstants.kt | 26 +++++++ .../com/fsck/k9/setup/EeloAccountHelper.kt | 75 +++++++++++++++++++ .../k9/backends/RealOAuth2TokenProvider.kt | 64 +++------------- .../accountmanager/AccountManagerConstants.kt | 8 -- .../accountmanager/EeloAccountCreator.java | 14 ++-- 7 files changed, 129 insertions(+), 70 deletions(-) create mode 100644 app/core/src/main/java/com/fsck/k9/setup/AccountManagerConstants.kt create mode 100644 app/core/src/main/java/com/fsck/k9/setup/EeloAccountHelper.kt delete mode 100644 app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/AccountManagerConstants.kt diff --git a/app/core/src/main/java/com/fsck/k9/controller/MessagingController.java b/app/core/src/main/java/com/fsck/k9/controller/MessagingController.java index 3b9eac1298..5bc73151b2 100644 --- a/app/core/src/main/java/com/fsck/k9/controller/MessagingController.java +++ b/app/core/src/main/java/com/fsck/k9/controller/MessagingController.java @@ -84,6 +84,7 @@ import com.fsck.k9.notification.NotificationController; import com.fsck.k9.notification.NotificationStrategy; import com.fsck.k9.search.LocalSearch; import com.fsck.k9.search.SearchAccount; +import com.fsck.k9.setup.EeloAccountHelper; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import timber.log.Timber; @@ -2573,8 +2574,11 @@ public class MessagingController { ServerSettings serverSettings = incoming ? account.getIncomingServerSettings() : account.getOutgoingServerSettings(); - return serverSettings.isMissingCredentials() || - serverSettings.authenticationType == AuthType.XOAUTH2 && account.getOAuthState() == null; + if (serverSettings.isMissingCredentials()) { + return true; + } + EeloAccountHelper.INSTANCE.updateOAuthStateIfMissing(context, preferences, account); + return serverSettings.authenticationType == AuthType.XOAUTH2 && account.getOAuthState() == null; } private void actOnMessagesGroupedByAccountAndFolder(List messages, MessageActor actor) { diff --git a/app/core/src/main/java/com/fsck/k9/job/MailSyncWorker.kt b/app/core/src/main/java/com/fsck/k9/job/MailSyncWorker.kt index 32a8bea1a5..b9f01eb336 100644 --- a/app/core/src/main/java/com/fsck/k9/job/MailSyncWorker.kt +++ b/app/core/src/main/java/com/fsck/k9/job/MailSyncWorker.kt @@ -9,12 +9,13 @@ import com.fsck.k9.K9 import com.fsck.k9.Preferences import com.fsck.k9.controller.MessagingController import com.fsck.k9.mail.AuthType +import com.fsck.k9.setup.EeloAccountHelper import timber.log.Timber class MailSyncWorker( private val messagingController: MessagingController, private val preferences: Preferences, - context: Context, + private val context: Context, parameters: WorkerParameters ) : Worker(context, parameters) { @@ -45,6 +46,7 @@ class MailSyncWorker( return Result.success() } + EeloAccountHelper.updateOAuthStateIfMissing(context, preferences, account) if (account.incomingServerSettings.authenticationType == AuthType.XOAUTH2 && account.oAuthState == null) { Timber.d("Account requires sign-in. Skipping mail sync.") return Result.success() diff --git a/app/core/src/main/java/com/fsck/k9/setup/AccountManagerConstants.kt b/app/core/src/main/java/com/fsck/k9/setup/AccountManagerConstants.kt new file mode 100644 index 0000000000..1beb26693f --- /dev/null +++ b/app/core/src/main/java/com/fsck/k9/setup/AccountManagerConstants.kt @@ -0,0 +1,26 @@ +/* + * Copyright ECORP SAS 2022 + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.fsck.k9.setup + +object AccountManagerConstants { + const val EELO_ACCOUNT_TYPE = "e.foundation.webdav.eelo" + const val GOOGLE_ACCOUNT_TYPE = "e.foundation.webdav.google" + const val ACCOUNT_EMAIL_ADDRESS_KEY = "email_address" + const val MAIL_CONTENT_AUTHORITY = "foundation.e.mail.provider.AppContentProvider" + const val AUTH_TOKEN_TYPE = "oauth2-access-token" + const val KEY_AUTH_STATE = "auth_state" +} diff --git a/app/core/src/main/java/com/fsck/k9/setup/EeloAccountHelper.kt b/app/core/src/main/java/com/fsck/k9/setup/EeloAccountHelper.kt new file mode 100644 index 0000000000..b0d151457c --- /dev/null +++ b/app/core/src/main/java/com/fsck/k9/setup/EeloAccountHelper.kt @@ -0,0 +1,75 @@ +/* + * Copyright ECORP SAS 2022 + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.fsck.k9.setup + +import android.content.Context +import com.fsck.k9.Account +import com.fsck.k9.mail.AuthType +import com.fsck.k9.preferences.AccountManager + +object EeloAccountHelper { + + // to support backward-compatibility + // In previous versions google accounts loaded from accountManager doesn't store oAuthState in the db. + // This method check if the oAuthState is missing or not, if missing, update the oAuthState + fun updateOAuthStateIfMissing(context: Context?, accountManager: AccountManager?, account: Account?) { + // check params + if (context == null || accountManager == null || account == null) { + return + } + // validation + if (account.incomingServerSettings.authenticationType != AuthType.XOAUTH2 || account.oAuthState != null) { + return + } + val googleAccount = retrieveGoogleAccountFromAccountManager(context, account.email) ?: return + val osAccountManager = android.accounts.AccountManager.get(context) + account.oAuthState = osAccountManager.getUserData(googleAccount, AccountManagerConstants.KEY_AUTH_STATE) + if (account.oAuthState != null) { + accountManager.saveAccount(account) + } + } + + // If token is updated by mail, also update the accountManager + fun updateAuthTokenAndStateForAccountManagerAccount( + context: Context?, + account: android.accounts.Account?, + authState: String?, + accessToken: String? + ) { + if (context == null || account == null || authState == null || accessToken == null) { + return + } + val accountManager = android.accounts.AccountManager.get(context) + accountManager.setAuthToken(account, AccountManagerConstants.AUTH_TOKEN_TYPE, accessToken) + accountManager.setUserData(account, AccountManagerConstants.KEY_AUTH_STATE, authState) + } + + fun retrieveGoogleAccountFromAccountManager(context: Context?, email: String?): android.accounts.Account? { + if (context == null || email == null || email.isEmpty()) { + return null + } + val accountManager = android.accounts.AccountManager.get(context) + val googleAccounts = accountManager.getAccountsByType(AccountManagerConstants.GOOGLE_ACCOUNT_TYPE) + for (googleAccount in googleAccounts) { + val emailId = accountManager.getUserData(googleAccount, AccountManagerConstants.ACCOUNT_EMAIL_ADDRESS_KEY) + if (email.equals(emailId, ignoreCase = true)) { + return googleAccount + } + } + return null + } +} \ No newline at end of file diff --git a/app/k9mail/src/main/java/com/fsck/k9/backends/RealOAuth2TokenProvider.kt b/app/k9mail/src/main/java/com/fsck/k9/backends/RealOAuth2TokenProvider.kt index 94d0afc5c9..eb3cbd5ce9 100644 --- a/app/k9mail/src/main/java/com/fsck/k9/backends/RealOAuth2TokenProvider.kt +++ b/app/k9mail/src/main/java/com/fsck/k9/backends/RealOAuth2TokenProvider.kt @@ -1,13 +1,11 @@ package com.fsck.k9.backends import android.content.Context -import android.os.Bundle -import android.os.Handler -import android.os.HandlerThread import com.fsck.k9.Account import com.fsck.k9.mail.AuthenticationFailedException import com.fsck.k9.mail.oauth.OAuth2TokenProvider import com.fsck.k9.preferences.AccountManager +import com.fsck.k9.setup.EeloAccountHelper import java.util.concurrent.CountDownLatch import java.util.concurrent.TimeUnit import net.openid.appauth.AuthState @@ -15,29 +13,17 @@ import net.openid.appauth.AuthorizationException import net.openid.appauth.AuthorizationService class RealOAuth2TokenProvider( - context: Context, + private val context: Context, private val accountManager: AccountManager, private val account: Account ) : OAuth2TokenProvider { - companion object { - const val GOOGLE_ACCOUNT_TYPE = "e.foundation.webdav.google" - const val EELO_ACCOUNT_TYPE = "e.foundation.webdav.eelo" - const val ACCOUNT_EMAIL_ADDRESS_KEY = "email_address" - const val AUTH_TOKEN_TYPE = "oauth2-access-token" - } - private val authService = AuthorizationService(context) private var requestFreshToken = false - private val osAccountManager by lazy { - android.accounts.AccountManager.get(context) - } - override fun getToken(email: String, timeoutMillis: Long): String { - getTokenFromAccountManager(email)?.let { - return it - } + val accountManagerAccount = EeloAccountHelper.retrieveGoogleAccountFromAccountManager(context, email) + EeloAccountHelper.updateOAuthStateIfMissing(context, accountManager, account) val latch = CountDownLatch(1) var token: String? = null @@ -68,6 +54,12 @@ class RealOAuth2TokenProvider( requestFreshToken = false account.oAuthState = authState.jsonSerializeString() accountManager.saveAccount(account) + EeloAccountHelper.updateAuthTokenAndStateForAccountManagerAccount( + context, + accountManagerAccount, + authState.jsonSerializeString(), + authState.accessToken + ) } exception?.let { authException -> @@ -84,40 +76,4 @@ class RealOAuth2TokenProvider( override fun invalidateToken() { requestFreshToken = true } - - private fun getTokenFromAccountManager(emailId: String): String? { - - var authToken: String? = null - val handlerThread = HandlerThread("callbackThread") - - handlerThread.start() - val handler = Handler(handlerThread.looper) - - val accounts: ArrayList = arrayListOf() - for (account in osAccountManager.getAccountsByType(GOOGLE_ACCOUNT_TYPE)) { - accounts.add(account) - } - - for (account in osAccountManager.getAccountsByType(EELO_ACCOUNT_TYPE)) { - accounts.add(account) - } - - for (account in accounts) { - val accountEmailId = osAccountManager.getUserData(account, ACCOUNT_EMAIL_ADDRESS_KEY) - if (emailId == accountEmailId) { - val latch = CountDownLatch(1) - osAccountManager.getAuthToken( - account, AUTH_TOKEN_TYPE, Bundle(), false, - { future -> - authToken = future?.result?.getString(android.accounts.AccountManager.KEY_AUTHTOKEN) - latch.countDown() - }, - handler - ) - latch.await() - } - } - - return authToken - } } diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/AccountManagerConstants.kt b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/AccountManagerConstants.kt deleted file mode 100644 index a958a5e269..0000000000 --- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/AccountManagerConstants.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.fsck.k9.activity.setup.accountmanager - -object AccountManagerConstants { - const val EELO_ACCOUNT_TYPE = "e.foundation.webdav.eelo" - const val GOOGLE_ACCOUNT_TYPE = "e.foundation.webdav.google" - const val ACCOUNT_EMAIL_ADDRESS_KEY = "email_address" - const val MAIL_CONTENT_AUTHORITY = "foundation.e.mail.provider.AppContentProvider" -} diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java index 07571c3ef3..631dc4d8ac 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java +++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java @@ -43,6 +43,7 @@ import com.fsck.k9.mail.ConnectionSecurity; import com.fsck.k9.mail.ServerSettings; import com.fsck.k9.mailstore.SpecialLocalFoldersCreator; import com.fsck.k9.preferences.Protocols; +import com.fsck.k9.setup.AccountManagerConstants; import com.fsck.k9.ui.ConnectionSettings; import timber.log.Timber; @@ -89,7 +90,8 @@ public class EeloAccountCreator { .peek(account -> updateAccountNameIfMissing(context, emailId, account)) .findAny().isPresent(); if (!accountAlreadyPresent) { - createAccount(context, emailId, "", true); + String authState = accountManager.getUserData(googleAccount, AccountManagerConstants.KEY_AUTH_STATE); + createAccount(context, emailId, "", authState); } } } @@ -121,7 +123,7 @@ public class EeloAccountCreator { .noneMatch(account -> emailId.equalsIgnoreCase(account.getEmail())); if (isNewAccount) { String password = accountManager.getPassword(eeloAccount); - createAccount(context, emailId, password, false); + createAccount(context, emailId, password, null); } } } @@ -132,7 +134,7 @@ public class EeloAccountCreator { .forEach(account -> accountRemover.removeAccountAsync(account.getUuid())); } - private static void createAccount(Context context, String emailId, String password, boolean isGoogleAccount) { + private static void createAccount(Context context, String emailId, String password, String authState) { Preferences preferences = Preferences.getPreferences(context); Account account = preferences.newAccount(); @@ -146,9 +148,9 @@ public class EeloAccountCreator { connectionSettings = MailAutoConfigDiscovery.retrieveConfigFromApi(emailId); } // providers.xml doesn't have the connection details & can't retrieve details from api - // & it is google account, meaning custom domain for google account is used. + // & it is google account (authState should not be null), meaning custom domain for google account is used. // In this case, provide default gmail configuration. - if (connectionSettings == null && isGoogleAccount) { + if (connectionSettings == null && authState != null) { connectionSettings = providersDefaultGoogleAccountDiscover(emailId); } if (connectionSettings == null) { @@ -160,6 +162,8 @@ public class EeloAccountCreator { ServerSettings outgoingSettings = connectionSettings.getOutgoing().newPassword(password); account.setOutgoingServerSettings(outgoingSettings); + account.setOAuthState(authState); + DeletePolicy deletePolicy = accountCreator.getDefaultDeletePolicy(incomingSettings.type); account.setDeletePolicy(deletePolicy); -- GitLab From bf581517c8cde8a001b32049a4d941cffd47fe49 Mon Sep 17 00:00:00 2001 From: Fahim Salam Chowdhury Date: Fri, 15 Jul 2022 16:59:12 +0600 Subject: [PATCH 2/5] refactor accountManager multiple time loading issue --- .../java/com/fsck/k9/setup/EeloAccountHelper.kt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/app/core/src/main/java/com/fsck/k9/setup/EeloAccountHelper.kt b/app/core/src/main/java/com/fsck/k9/setup/EeloAccountHelper.kt index b0d151457c..1090103491 100644 --- a/app/core/src/main/java/com/fsck/k9/setup/EeloAccountHelper.kt +++ b/app/core/src/main/java/com/fsck/k9/setup/EeloAccountHelper.kt @@ -35,8 +35,8 @@ object EeloAccountHelper { if (account.incomingServerSettings.authenticationType != AuthType.XOAUTH2 || account.oAuthState != null) { return } - val googleAccount = retrieveGoogleAccountFromAccountManager(context, account.email) ?: return val osAccountManager = android.accounts.AccountManager.get(context) + val googleAccount = retrieveGoogleAccountFromAccountManager(osAccountManager, account.email) ?: return account.oAuthState = osAccountManager.getUserData(googleAccount, AccountManagerConstants.KEY_AUTH_STATE) if (account.oAuthState != null) { accountManager.saveAccount(account) @@ -59,10 +59,20 @@ object EeloAccountHelper { } fun retrieveGoogleAccountFromAccountManager(context: Context?, email: String?): android.accounts.Account? { - if (context == null || email == null || email.isEmpty()) { + if (context == null) { return null } val accountManager = android.accounts.AccountManager.get(context) + return retrieveGoogleAccountFromAccountManager(accountManager, email) + } + + fun retrieveGoogleAccountFromAccountManager( + accountManager: android.accounts.AccountManager?, + email: String? + ): android.accounts.Account? { + if (accountManager == null || email == null || email.isEmpty()) { + return null + } val googleAccounts = accountManager.getAccountsByType(AccountManagerConstants.GOOGLE_ACCOUNT_TYPE) for (googleAccount in googleAccounts) { val emailId = accountManager.getUserData(googleAccount, AccountManagerConstants.ACCOUNT_EMAIL_ADDRESS_KEY) -- GitLab From 6d2ab51930d40a3fa4d0511b81adb22034d3951a Mon Sep 17 00:00:00 2001 From: Fahim Salam Chowdhury Date: Fri, 15 Jul 2022 18:17:08 +0600 Subject: [PATCH 3/5] refactor code syntax --- .../com/fsck/k9/setup/EeloAccountHelper.kt | 22 +++++++++---------- .../k9/backends/RealOAuth2TokenProvider.kt | 2 +- .../accountmanager/EeloAccountCreator.java | 2 +- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/app/core/src/main/java/com/fsck/k9/setup/EeloAccountHelper.kt b/app/core/src/main/java/com/fsck/k9/setup/EeloAccountHelper.kt index 1090103491..d26335f45a 100644 --- a/app/core/src/main/java/com/fsck/k9/setup/EeloAccountHelper.kt +++ b/app/core/src/main/java/com/fsck/k9/setup/EeloAccountHelper.kt @@ -26,15 +26,17 @@ object EeloAccountHelper { // to support backward-compatibility // In previous versions google accounts loaded from accountManager doesn't store oAuthState in the db. // This method check if the oAuthState is missing or not, if missing, update the oAuthState - fun updateOAuthStateIfMissing(context: Context?, accountManager: AccountManager?, account: Account?) { + fun updateOAuthStateIfMissing(context: Context, accountManager: AccountManager, account: Account?) { // check params - if (context == null || accountManager == null || account == null) { + if (account == null) { return } + // validation if (account.incomingServerSettings.authenticationType != AuthType.XOAUTH2 || account.oAuthState != null) { return } + val osAccountManager = android.accounts.AccountManager.get(context) val googleAccount = retrieveGoogleAccountFromAccountManager(osAccountManager, account.email) ?: return account.oAuthState = osAccountManager.getUserData(googleAccount, AccountManagerConstants.KEY_AUTH_STATE) @@ -44,15 +46,11 @@ object EeloAccountHelper { } // If token is updated by mail, also update the accountManager - fun updateAuthTokenAndStateForAccountManagerAccount( - context: Context?, - account: android.accounts.Account?, - authState: String?, - accessToken: String? - ) { + fun updateAccountInAccountManager(context: Context?, account: android.accounts.Account?, authState: String?, accessToken: String?) { if (context == null || account == null || authState == null || accessToken == null) { return } + val accountManager = android.accounts.AccountManager.get(context) accountManager.setAuthToken(account, AccountManagerConstants.AUTH_TOKEN_TYPE, accessToken) accountManager.setUserData(account, AccountManagerConstants.KEY_AUTH_STATE, authState) @@ -62,17 +60,16 @@ object EeloAccountHelper { if (context == null) { return null } + val accountManager = android.accounts.AccountManager.get(context) return retrieveGoogleAccountFromAccountManager(accountManager, email) } - fun retrieveGoogleAccountFromAccountManager( - accountManager: android.accounts.AccountManager?, - email: String? - ): android.accounts.Account? { + fun retrieveGoogleAccountFromAccountManager(accountManager: android.accounts.AccountManager?, email: String?): android.accounts.Account? { if (accountManager == null || email == null || email.isEmpty()) { return null } + val googleAccounts = accountManager.getAccountsByType(AccountManagerConstants.GOOGLE_ACCOUNT_TYPE) for (googleAccount in googleAccounts) { val emailId = accountManager.getUserData(googleAccount, AccountManagerConstants.ACCOUNT_EMAIL_ADDRESS_KEY) @@ -80,6 +77,7 @@ object EeloAccountHelper { return googleAccount } } + return null } } \ No newline at end of file diff --git a/app/k9mail/src/main/java/com/fsck/k9/backends/RealOAuth2TokenProvider.kt b/app/k9mail/src/main/java/com/fsck/k9/backends/RealOAuth2TokenProvider.kt index eb3cbd5ce9..ca6fd4e9a0 100644 --- a/app/k9mail/src/main/java/com/fsck/k9/backends/RealOAuth2TokenProvider.kt +++ b/app/k9mail/src/main/java/com/fsck/k9/backends/RealOAuth2TokenProvider.kt @@ -54,7 +54,7 @@ class RealOAuth2TokenProvider( requestFreshToken = false account.oAuthState = authState.jsonSerializeString() accountManager.saveAccount(account) - EeloAccountHelper.updateAuthTokenAndStateForAccountManagerAccount( + EeloAccountHelper.updateAccountInAccountManager( context, accountManagerAccount, authState.jsonSerializeString(), diff --git a/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java index 631dc4d8ac..780f92a17d 100644 --- a/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java +++ b/app/ui/legacy/src/main/java/com/fsck/k9/activity/setup/accountmanager/EeloAccountCreator.java @@ -134,7 +134,7 @@ public class EeloAccountCreator { .forEach(account -> accountRemover.removeAccountAsync(account.getUuid())); } - private static void createAccount(Context context, String emailId, String password, String authState) { + private static void createAccount(Context context, String emailId, String password, @Nullable String authState) { Preferences preferences = Preferences.getPreferences(context); Account account = preferences.newAccount(); -- GitLab From 82f9234bc1ba7cdc2e4cce13e437e7e66ee28fe7 Mon Sep 17 00:00:00 2001 From: Fahim Salam Chowdhury Date: Mon, 18 Jul 2022 12:02:19 +0600 Subject: [PATCH 4/5] refactor according code-review --- .../k9/controller/MessagingController.java | 4 ++-- .../com/fsck/k9/setup/EeloAccountHelper.kt | 22 +++++++++++-------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/app/core/src/main/java/com/fsck/k9/controller/MessagingController.java b/app/core/src/main/java/com/fsck/k9/controller/MessagingController.java index 5bc73151b2..d0325b17cc 100644 --- a/app/core/src/main/java/com/fsck/k9/controller/MessagingController.java +++ b/app/core/src/main/java/com/fsck/k9/controller/MessagingController.java @@ -2571,12 +2571,12 @@ public class MessagingController { } private boolean isAuthenticationProblem(Account account, boolean incoming) { - ServerSettings serverSettings = incoming ? - account.getIncomingServerSettings() : account.getOutgoingServerSettings(); + ServerSettings serverSettings = incoming ? account.getIncomingServerSettings() : account.getOutgoingServerSettings(); if (serverSettings.isMissingCredentials()) { return true; } + EeloAccountHelper.INSTANCE.updateOAuthStateIfMissing(context, preferences, account); return serverSettings.authenticationType == AuthType.XOAUTH2 && account.getOAuthState() == null; } diff --git a/app/core/src/main/java/com/fsck/k9/setup/EeloAccountHelper.kt b/app/core/src/main/java/com/fsck/k9/setup/EeloAccountHelper.kt index d26335f45a..c2720ffece 100644 --- a/app/core/src/main/java/com/fsck/k9/setup/EeloAccountHelper.kt +++ b/app/core/src/main/java/com/fsck/k9/setup/EeloAccountHelper.kt @@ -20,12 +20,16 @@ import android.content.Context import com.fsck.k9.Account import com.fsck.k9.mail.AuthType import com.fsck.k9.preferences.AccountManager +import android.accounts.AccountManager as OsAccountManager +import android.accounts.Account as OsAccount object EeloAccountHelper { - // to support backward-compatibility - // In previous versions google accounts loaded from accountManager doesn't store oAuthState in the db. - // This method check if the oAuthState is missing or not, if missing, update the oAuthState + /** + * to support backward-compatibility. + * In previous versions google accounts loaded from accountManager doesn't store oAuthState in the db. + * This method check if the oAuthState is missing or not, if missing, update the oAuthState + */ fun updateOAuthStateIfMissing(context: Context, accountManager: AccountManager, account: Account?) { // check params if (account == null) { @@ -37,7 +41,7 @@ object EeloAccountHelper { return } - val osAccountManager = android.accounts.AccountManager.get(context) + val osAccountManager = OsAccountManager.get(context) val googleAccount = retrieveGoogleAccountFromAccountManager(osAccountManager, account.email) ?: return account.oAuthState = osAccountManager.getUserData(googleAccount, AccountManagerConstants.KEY_AUTH_STATE) if (account.oAuthState != null) { @@ -46,26 +50,26 @@ object EeloAccountHelper { } // If token is updated by mail, also update the accountManager - fun updateAccountInAccountManager(context: Context?, account: android.accounts.Account?, authState: String?, accessToken: String?) { + fun updateAccountInAccountManager(context: Context?, account: OsAccount?, authState: String?, accessToken: String?) { if (context == null || account == null || authState == null || accessToken == null) { return } - val accountManager = android.accounts.AccountManager.get(context) + val accountManager = OsAccountManager.get(context) accountManager.setAuthToken(account, AccountManagerConstants.AUTH_TOKEN_TYPE, accessToken) accountManager.setUserData(account, AccountManagerConstants.KEY_AUTH_STATE, authState) } - fun retrieveGoogleAccountFromAccountManager(context: Context?, email: String?): android.accounts.Account? { + fun retrieveGoogleAccountFromAccountManager(context: Context?, email: String?): OsAccount? { if (context == null) { return null } - val accountManager = android.accounts.AccountManager.get(context) + val accountManager = OsAccountManager.get(context) return retrieveGoogleAccountFromAccountManager(accountManager, email) } - fun retrieveGoogleAccountFromAccountManager(accountManager: android.accounts.AccountManager?, email: String?): android.accounts.Account? { + private fun retrieveGoogleAccountFromAccountManager(accountManager: OsAccountManager?, email: String?): OsAccount? { if (accountManager == null || email == null || email.isEmpty()) { return null } -- GitLab From 5779ebfd3552e8bed1cbeff50cdfbd1db555181e Mon Sep 17 00:00:00 2001 From: Fahim Salam Chowdhury Date: Mon, 18 Jul 2022 14:59:53 +0600 Subject: [PATCH 5/5] refactor code syntax: add warning log --- .../java/com/fsck/k9/controller/MessagingController.java | 1 + .../src/main/java/com/fsck/k9/setup/EeloAccountHelper.kt | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/app/core/src/main/java/com/fsck/k9/controller/MessagingController.java b/app/core/src/main/java/com/fsck/k9/controller/MessagingController.java index d0325b17cc..e654e6d066 100644 --- a/app/core/src/main/java/com/fsck/k9/controller/MessagingController.java +++ b/app/core/src/main/java/com/fsck/k9/controller/MessagingController.java @@ -2574,6 +2574,7 @@ public class MessagingController { ServerSettings serverSettings = incoming ? account.getIncomingServerSettings() : account.getOutgoingServerSettings(); if (serverSettings.isMissingCredentials()) { + Timber.w("account authenticationProblem detected, missing credentials"); return true; } diff --git a/app/core/src/main/java/com/fsck/k9/setup/EeloAccountHelper.kt b/app/core/src/main/java/com/fsck/k9/setup/EeloAccountHelper.kt index c2720ffece..2af9c11552 100644 --- a/app/core/src/main/java/com/fsck/k9/setup/EeloAccountHelper.kt +++ b/app/core/src/main/java/com/fsck/k9/setup/EeloAccountHelper.kt @@ -22,6 +22,7 @@ import com.fsck.k9.mail.AuthType import com.fsck.k9.preferences.AccountManager import android.accounts.AccountManager as OsAccountManager import android.accounts.Account as OsAccount +import timber.log.Timber object EeloAccountHelper { @@ -33,11 +34,13 @@ object EeloAccountHelper { fun updateOAuthStateIfMissing(context: Context, accountManager: AccountManager, account: Account?) { // check params if (account == null) { + Timber.w("updating OAuthState failed, account is null") return } // validation if (account.incomingServerSettings.authenticationType != AuthType.XOAUTH2 || account.oAuthState != null) { + Timber.w("updating oAuthState failed, not oauth2 authType") return } @@ -52,6 +55,7 @@ object EeloAccountHelper { // If token is updated by mail, also update the accountManager fun updateAccountInAccountManager(context: Context?, account: OsAccount?, authState: String?, accessToken: String?) { if (context == null || account == null || authState == null || accessToken == null) { + Timber.w("updating account for accountManager failed, invalid param.") return } @@ -62,6 +66,7 @@ object EeloAccountHelper { fun retrieveGoogleAccountFromAccountManager(context: Context?, email: String?): OsAccount? { if (context == null) { + Timber.w("retrieve google accounts from accountManager failed, null context.") return null } @@ -71,6 +76,7 @@ object EeloAccountHelper { private fun retrieveGoogleAccountFromAccountManager(accountManager: OsAccountManager?, email: String?): OsAccount? { if (accountManager == null || email == null || email.isEmpty()) { + Timber.w("retrieve google account from accountManager failed, invalid param") return null } -- GitLab