Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 84f132c1 authored by cketti's avatar cketti
Browse files

Add abstraction for storing and retrieving the OAuth state

parent 0c0e57f7
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
package com.fsck.k9.backends

import com.fsck.k9.Account
import com.fsck.k9.mail.oauth.AuthStateStorage
import com.fsck.k9.preferences.AccountManager

class AccountAuthStateStorage(
    private val accountManager: AccountManager,
    private val account: Account,
) : AuthStateStorage {
    override fun getAuthorizationState(): String? {
        return account.oAuthState
    }

    override fun updateAuthorizationState(authorizationState: String?) {
        account.oAuthState = authorizationState
        accountManager.saveAccount(account)
    }
}
+7 −2
Original line number Diff line number Diff line
@@ -50,7 +50,7 @@ class ImapBackendFactory(
        val serverSettings = account.toImapServerSettings()

        val oAuth2TokenProvider = if (serverSettings.authenticationType == AuthType.XOAUTH2) {
            RealOAuth2TokenProvider(context, accountManager, account)
            createOAuth2TokenProvider(account)
        } else {
            null
        }
@@ -78,7 +78,7 @@ class ImapBackendFactory(
    private fun createSmtpTransport(account: Account): SmtpTransport {
        val serverSettings = account.outgoingServerSettings
        val oauth2TokenProvider = if (serverSettings.authenticationType == AuthType.XOAUTH2) {
            RealOAuth2TokenProvider(context, accountManager, account)
            createOAuth2TokenProvider(account)
        } else {
            null
        }
@@ -86,6 +86,11 @@ class ImapBackendFactory(
        return SmtpTransport(serverSettings, trustedSocketFactory, oauth2TokenProvider)
    }

    private fun createOAuth2TokenProvider(account: Account): RealOAuth2TokenProvider {
        val authStateStorage = AccountAuthStateStorage(accountManager, account)
        return RealOAuth2TokenProvider(context, authStateStorage)
    }

    private fun createPushConfigProvider(account: Account) = object : ImapPushConfigProvider {
        override val maxPushFoldersFlow: Flow<Int>
            get() = accountManager.getAccountFlow(account.uuid)
+5 −9
Original line number Diff line number Diff line
package com.fsck.k9.backends

import android.content.Context
import com.fsck.k9.Account
import com.fsck.k9.mail.AuthenticationFailedException
import com.fsck.k9.mail.oauth.AuthStateStorage
import com.fsck.k9.mail.oauth.OAuth2TokenProvider
import com.fsck.k9.preferences.AccountManager
import java.io.IOException
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
@@ -16,8 +15,7 @@ import net.openid.appauth.AuthorizationService

class RealOAuth2TokenProvider(
    context: Context,
    private val accountManager: AccountManager,
    private val account: Account,
    private val authStateStorage: AuthStateStorage,
) : OAuth2TokenProvider {
    private val authService = AuthorizationService(context)
    private var requestFreshToken = false
@@ -27,7 +25,7 @@ class RealOAuth2TokenProvider(
        var token: String? = null
        var exception: AuthorizationException? = null

        val authState = account.oAuthState?.let { AuthState.jsonDeserialize(it) }
        val authState = authStateStorage.getAuthorizationState()?.let { AuthState.jsonDeserialize(it) }
            ?: throw AuthenticationFailedException("Login required")

        if (requestFreshToken) {
@@ -53,8 +51,7 @@ class RealOAuth2TokenProvider(
        ) {
            throw IOException("Error while fetching an access token", authException)
        } else if (authException != null) {
            account.oAuthState = null
            accountManager.saveAccount(account)
            authStateStorage.updateAuthorizationState(authorizationState = null)

            throw AuthenticationFailedException(
                message = "Failed to fetch an access token",
@@ -63,8 +60,7 @@ class RealOAuth2TokenProvider(
            )
        } else if (token != oldAccessToken) {
            requestFreshToken = false
            account.oAuthState = authState.jsonSerializeString()
            accountManager.saveAccount(account)
            authStateStorage.updateAuthorizationState(authorizationState = authState.jsonSerializeString())
        }

        return token ?: throw AuthenticationFailedException("Failed to fetch an access token")
+6 −0
Original line number Diff line number Diff line
package com.fsck.k9.mail.oauth

interface AuthStateStorage {
    fun getAuthorizationState(): String?
    fun updateAuthorizationState(authorizationState: String?)
}