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

Commit 41ca5908 authored by Jonathan Klee's avatar Jonathan Klee
Browse files

fix: do not refresh at startup

parent de0eaa0f
Loading
Loading
Loading
Loading
+0 −25
Original line number Diff line number Diff line
package foundation.e.apps.data.login.playstore

import com.aurora.gplayapi.data.models.AuthData
import com.aurora.gplayapi.data.models.PlayResponse
import foundation.e.apps.data.playstore.utils.CustomAuthValidator
import foundation.e.apps.data.playstore.utils.GPlayHttpClient
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import javax.inject.Inject

class PlayStoreAuthDataVerifier @Inject constructor(
    private val gPlayHttpClient: GPlayHttpClient,
) {
    suspend fun validate(authData: AuthData?): PlayResponse {
        if (authData == null) {
            return PlayResponse()
        }
        var result = PlayResponse()
        withContext(Dispatchers.IO) {
            val authValidator = CustomAuthValidator(authData).using(gPlayHttpClient)
            result = authValidator.getValidityResponse()
        }
        return result
    }
}
+2 −12
Original line number Diff line number Diff line
@@ -40,7 +40,7 @@ import javax.inject.Singleton

/**
 * Class to get GPlay auth data. Call [login] to get an already saved auth data
 * or to fetch a new one for first use. Handles auth validation internally.
 * or to fetch a new one for first use.
 *
 * https://gitlab.e.foundation/e/backlog/-/issues/5680
 */
@@ -51,7 +51,6 @@ class PlayStoreAuthenticator @Inject constructor(
    private val appLoungeDataStore: AppLoungeDataStore,
    private val appLoungePreference: AppLoungePreference,
    private val authDataCache: AuthDataCache,
    private val authDataVerifier: PlayStoreAuthDataVerifier,
    private val googleLoginManager: GoogleLoginManager,
    private val microgLoginManager: MicrogLoginManager,
    private val anonymousLoginManager: AnonymousLoginManager,
@@ -89,7 +88,7 @@ class PlayStoreAuthenticator @Inject constructor(
     */
    override suspend fun login(): StoreAuthResult {
        val user = appLoungeDataStore.getUser()
        val validSavedAuth = getValidSavedAuthData()
        val validSavedAuth = authDataCache.getSavedAuthData()
        val authDataResult = if (validSavedAuth == null) {
            retryWithBackoff { loginForUserType(user) }
        } else {
@@ -204,15 +203,6 @@ class PlayStoreAuthenticator @Inject constructor(
        }
    }

    private suspend fun isAuthDataValid(savedAuth: AuthData?): Boolean {
        return savedAuth != null && authDataVerifier.validate(savedAuth).isSuccessful
    }

    private suspend fun getValidSavedAuthData(): AuthData? {
        val savedAuth = authDataCache.getSavedAuthData()
        return if (isAuthDataValid(savedAuth)) savedAuth else null
    }

    private fun buildErrorAuthResult(
        user: User,
        authDataResult: ResultSupreme<AuthData?>
+1 −0
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@ class AuthenticatorRepository @Inject constructor(
    suspend fun getValidatedAuthData(): ResultSupreme<AuthData?> {
        val authenticator = authenticators.firstOrNull { it.storeType == StoreType.PLAY_STORE }
            ?: return ResultSupreme.Error("Play Store authenticator not available")
        authenticator.logout()
        val authResult = authenticator.login()
        authResult.authDataToPersist?.let { appLoungeDataStore.saveAuthData(it) }
        val authObject = authResult.authObject as? AuthObject.GPlayAuth
+16 −9
Original line number Diff line number Diff line
@@ -115,16 +115,16 @@ class UpdatesWorker @AssistedInject constructor(
        val appsNeededToUpdate = mutableListOf<Application>()
        val user = getUser()
        val loginState = getLoginState()
        val authData = authenticatorRepository.getValidatedAuthData().data
        val authData = appLoungeDataStore.getAuthData()
        val resultStatus: ResultStatus

        if (user in listOf(User.ANONYMOUS, User.GOOGLE) && authData != null) {
        if (user in listOf(User.ANONYMOUS, User.GOOGLE)) {
            /*
             * Signifies valid Google user and valid auth data to update
             * apps from Google Play store.
             * The user check will be more useful in No-Google mode.
             */
            val updateData = updatesManagerRepository.getUpdates()
            val updateData = fetchUpdatesWithAuthRetry()
            appsNeededToUpdate.addAll(updateData.first)
            resultStatus = updateData.second
        } else if (loginState != LoginState.UNAVAILABLE) {
@@ -161,16 +161,23 @@ class UpdatesWorker @AssistedInject constructor(
            triggerUpdateProcessOnSettings(
                isConnectedToUnMeteredNetwork,
                appsNeededToUpdate,
                /*
                 * If authData is null, only cleanApk data will be present
                 * in appsNeededToUpdate list. Hence it is safe to proceed with
                 * blank AuthData.
                 */
                authData ?: AuthData("", ""),
                authData,
            )
        }
    }

    private suspend fun fetchUpdatesWithAuthRetry(): Pair<List<Application>, ResultStatus> {
        val updateData = updatesManagerRepository.getUpdates()
        if (updateData.second == ResultStatus.OK) {
            return updateData
        }

        val refreshedAuth = authenticatorRepository.getValidatedAuthData().data
        val shouldRetry = refreshedAuth != null

        return if (shouldRetry) updatesManagerRepository.getUpdates() else updateData
    }

    private suspend fun manageRetry(extraMessage: String) {
        retryCount++
        if (retryCount == 1) {
+0 −67
Original line number Diff line number Diff line
package foundation.e.apps.data.login.playstore

import com.aurora.gplayapi.data.models.AuthData
import com.aurora.gplayapi.data.models.PlayResponse
import com.aurora.gplayapi.data.providers.DeviceInfoProvider
import com.google.common.truth.Truth.assertThat
import foundation.e.apps.data.playstore.utils.GPlayHttpClient
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import kotlinx.coroutines.test.runTest
import org.junit.Test
import java.util.Locale

class PlayStoreAuthDataVerifierTest {

    private val gPlayHttpClient: GPlayHttpClient = mockk()
    private val verifier = PlayStoreAuthDataVerifier(gPlayHttpClient)

    @Test
    fun validate_returnsEmptyResponseWhenAuthDataIsNull() = runTest {
        val result = verifier.validate(null)

        assertThat(result).isNotNull()
        verify(exactly = 0) {
            gPlayHttpClient.post(
                any<String>(),
                any<Map<String, String>>(),
                any<Map<String, String>>()
            )
        }
    }

    @Test
    fun validate_usesHttpClientWhenAuthDataIsPresent() = runTest {
        val deviceInfoProvider: DeviceInfoProvider = mockk {
            every { userAgentString } returns "ua"
            every { mccMnc } returns ""
        }
        val authData = AuthData(
            email = "email",
            authToken = "token",
            gsfId = "gsf",
            locale = Locale.US,
            deviceInfoProvider = deviceInfoProvider
        )
        val response = PlayResponse()
        every {
            gPlayHttpClient.post(
                any<String>(),
                any<Map<String, String>>(),
                any<Map<String, String>>()
            )
        } returns response

        val result = verifier.validate(authData)

        assertThat(result).isEqualTo(response)
        verify(exactly = 1) {
            gPlayHttpClient.post(
                any<String>(),
                any<Map<String, String>>(),
                any<Map<String, String>>()
            )
        }
    }
}
Loading