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

Commit 048ab146 authored by Mohammed Althaf T's avatar Mohammed Althaf T 😊
Browse files

Add authstate checks for token refresh

parent 2699945b
Loading
Loading
Loading
Loading
Loading
+32 −7
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ import at.bitfire.davdroid.BuildConfig
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import foundation.e.accountmanager.token.MurenaTokenManager
import net.openid.appauth.AuthState
import net.openid.appauth.AuthorizationException
import net.openid.appauth.AuthorizationService
@@ -69,6 +70,20 @@ class OAuthInterceptor @AssistedInject constructor(
        // if possible, use cached access token
        val authState = readAuthState() ?: return null

        val authorizationException = authState.authorizationException
        if (authorizationException != null && MurenaTokenManager.isInvalidGrant(authorizationException)) {
            throw AuthorizationException.TokenRequestErrors.INVALID_GRANT
        }

        val expiresAt = authState.accessTokenExpirationTime
        if (expiresAt != null) {
            val refreshDeadline = expiresAt - MurenaTokenManager.earlyTriggerTime
            if (refreshDeadline <= System.currentTimeMillis()) {
                logger.info("Token expired or near expiry, refreshing immediately.")
                authState.needsTokenRefresh = true
            }
        }

        if (authState.isAuthorized && authState.accessToken != null && !authState.needsTokenRefresh) {
            if (BuildConfig.DEBUG)      // log sensitive information (refresh/access token) only in debug builds
                logger.log(Level.FINEST, "Using cached AuthState", authState.jsonSerializeString())
@@ -85,13 +100,23 @@ class OAuthInterceptor @AssistedInject constructor(
                if (BuildConfig.DEBUG)
                    logger.log(Level.FINEST, "Got new AuthState", authState.jsonSerializeString())

                when {
                    accessToken != null -> {
                        // persist updated AuthState
                        writeAuthState(authState)
                        accessTokenFuture.complete(accessToken)
                    }

                if (ex != null)
                    ex != null -> {
                        logger.log(Level.WARNING, "Token refresh failed: $ex")
                        accessTokenFuture.completeExceptionally(ex)
                else if (accessToken != null)
                    accessTokenFuture.complete(accessToken)
                    }

                    else -> {
                        // Unexpected: neither token nor exception. treat as failure.
                        accessTokenFuture.completeExceptionally(IllegalStateException("No token, no exception"))
                    }
                }
            }

            accessTokenFuture.join()
+1 −1
Original line number Diff line number Diff line
@@ -190,7 +190,7 @@ object MurenaTokenManager {
    }

    // Checks whether the given AuthorizationException indicates an invalid grant (requires re-login).
    private fun isInvalidGrant(ex: AuthorizationException?): Boolean {
    fun isInvalidGrant(ex: AuthorizationException?): Boolean {
        val invalidGrant = AuthorizationException.TokenRequestErrors.INVALID_GRANT
        return ex?.code == invalidGrant.code && ex.error == invalidGrant.error
    }