Skip to content

Commit

Permalink
Fix account selection
Browse files Browse the repository at this point in the history
  • Loading branch information
anod committed Oct 21, 2024
1 parent e7b32c3 commit b632cbf
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@ fun AuthAccount(androidAccount: Account, gfsIdResult: GfsIdResult, deviceConfig:
deviceConfig = deviceConfig
)

fun AuthAccount.toAndroidAccount() = Account(name, type)
fun AuthAccount.toAndroidAccount() = Account(name, type)

fun AuthAccount.toGfsResult() = GfsIdResult(gfsId, gfsIdToken)
Original file line number Diff line number Diff line change
Expand Up @@ -14,43 +14,55 @@ class AuthAccountInitializer(
private val dfeApi: DfeApi
) {
suspend fun initialize(account: Account): AuthAccount {
authToken.refreshToken(account)
val existingAccount = preferences.account
if (existingAccount == null || needToRetrieveGfsId(existingAccount, account)) {
val gfsIdResult = retrieveGsfId()
val deviceConfigToken = dfeApi.uploadDeviceConfig().uploadDeviceConfigToken
val authAccount = AuthAccount(account, gfsIdResult, deviceConfigToken)
preferences.account = authAccount
return authAccount
val tokenResult = authToken.checkToken(account)
val isNewAccount = existingAccount?.name != account.name
var gfsIdResult: GfsIdResult? = if (isNewAccount) null else existingAccount?.toGfsResult()
var deviceConfigToken: String? = if (isNewAccount) null else existingAccount?.deviceConfig
if (needToRetrieveGfsId(existingAccount, account, tokenResult)) {
gfsIdResult = retrieveGsfId()
deviceConfigToken = dfeApi.uploadDeviceConfig().uploadDeviceConfigToken
}
return existingAccount
val authAccount = AuthAccount(
account,
gfsIdResult ?: GfsIdResult("", ""),
deviceConfigToken ?: ""
)
preferences.account = authAccount
return authAccount
}

suspend fun refresh() {
val account = preferences.account ?: throw IllegalStateException("Account should not be null")
val androidAccount = account.toAndroidAccount()
authToken.refreshToken(androidAccount)
if (needToRetrieveGfsId(account, androidAccount)) {
val tokenResult = authToken.checkToken(androidAccount)
if (needToRetrieveGfsId(account, androidAccount, tokenResult)) {
val gfsIdResult = retrieveGsfId()
val deviceConfigToken = dfeApi.uploadDeviceConfig().uploadDeviceConfigToken
val authAccount = AuthAccount(androidAccount, gfsIdResult, deviceConfigToken)
preferences.account = authAccount
}
}

private suspend fun needToRetrieveGfsId(existingAccount: AuthAccount, newAccount: Account): Boolean {
private suspend fun needToRetrieveGfsId(existingAccount: AuthAccount?, newAccount: Account, tokenResult: CheckTokenResult): Boolean {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM) {
return false
}
return existingAccount.deviceConfig.isEmpty()
val tokenInvalidated = if (tokenResult is CheckTokenResult.Success) tokenResult.invalidated else false
return existingAccount == null
|| existingAccount.deviceConfig.isEmpty()
|| existingAccount.name != newAccount.name
|| !validate()
|| tokenInvalidated
|| canRequest()
}

private suspend fun validate(): Boolean {
private suspend fun canRequest(): Boolean {
if (preferences.account == null) {
return false
}
return try {
val app = dfeApi.details("details?doc=com.android.chrome").toDocument()
val result = app?.appDetails?.packageName == "com.android.chrome"
val app = dfeApi.details("details?doc=com.anod.appwatcher").toDocument()
val result = app?.appDetails?.packageName == "com.anod.appwatcher"
AppLog.d("Auth verification result: $result")
result
} catch (e: Exception) {
Expand Down
26 changes: 13 additions & 13 deletions app/src/main/java/com/anod/appwatcher/accounts/AuthTokenBlocking.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ sealed interface CheckTokenError {
}

sealed interface CheckTokenResult {
object Success : CheckTokenResult
class Success(val invalidated: Boolean) : CheckTokenResult
class Error(val error: CheckTokenError) : CheckTokenResult
}

Expand All @@ -46,14 +46,10 @@ class AuthTokenBlocking(context: ApplicationContext) {

suspend fun checkToken(account: Account): CheckTokenResult {
if (isFresh) {
return CheckTokenResult.Success
return CheckTokenResult.Success(invalidated = false)
}
return try {
if (!refreshToken(account)) {
AppLog.e("Error retrieving token")
CheckTokenResult.Error(CheckTokenError.NoToken)
}
CheckTokenResult.Success
return refreshToken(account)
} catch (e: AuthTokenStartIntent) {
CheckTokenResult.Error(CheckTokenError.RequiresInteraction(e.intent))
} catch (e: Exception) {
Expand All @@ -62,17 +58,20 @@ class AuthTokenBlocking(context: ApplicationContext) {
}
}

suspend fun refreshToken(account: Account): Boolean = withContext(Dispatchers.Main) {
tokenState.value = retrieve(account)
private suspend fun refreshToken(account: Account): CheckTokenResult = withContext(Dispatchers.Main) {
val (token, invalidated) = retrieve(account)
tokenState.value = token
if (tokenState.value.isEmpty()) {
return@withContext false
AppLog.e("Error retrieving token")
return@withContext CheckTokenResult.Error(CheckTokenError.NoToken)
}
lastUpdated = System.currentTimeMillis()
return@withContext true
return@withContext CheckTokenResult.Success(invalidated = invalidated)
}

private suspend fun retrieve(acc: Account): String = withContext(Dispatchers.IO) {
private suspend fun retrieve(acc: Account): Pair<String, Boolean> = withContext(Dispatchers.IO) {
var token = ""
var invalidated = false
try {
token = getAuthToken(acc)
} catch (e: Exception) {
Expand All @@ -84,6 +83,7 @@ class AuthTokenBlocking(context: ApplicationContext) {
}

if (token.isNotEmpty()) {
invalidated = true
accountManager.invalidateAuthToken(ACCOUNT_TYPE, token)
}

Expand All @@ -92,7 +92,7 @@ class AuthTokenBlocking(context: ApplicationContext) {
} catch (e: Exception) {
throw e
}
return@withContext token
return@withContext Pair(token, invalidated)
}

@Throws(AuthenticatorException::class, OperationCanceledException::class, IOException::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import androidx.palette.graphics.Palette
import com.anod.appwatcher.R
import com.anod.appwatcher.accounts.AuthTokenBlocking
import com.anod.appwatcher.accounts.AuthTokenStartIntent
import com.anod.appwatcher.accounts.CheckTokenResult
import com.anod.appwatcher.accounts.toAndroidAccount
import info.anodsplace.framework.content.CommonActivityAction
import com.anod.appwatcher.database.AppListTable
Expand Down Expand Up @@ -363,7 +364,7 @@ class DetailsViewModel(
if (account != null) {
var loadError = false
try {
if (authToken.refreshToken(account)) {
if (authToken.checkToken(account) is CheckTokenResult.Success) {
try {
val document = dfeApi.details(viewState.detailsUrl).toDocument()
onRemoteDetailsFetched(localChanges, document)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ class InstalledListViewModel(state: SavedStateHandle) : BaseFlowViewModel<Instal
false
}

CheckTokenResult.Success -> true
is CheckTokenResult.Success -> true
}
}
}
Expand Down

0 comments on commit b632cbf

Please sign in to comment.