Skip to content

Commit

Permalink
Handle lock-out for Google Drive and show a user readable error
Browse files Browse the repository at this point in the history
  • Loading branch information
d4rken committed Aug 29, 2024
1 parent 66177e6 commit afe3115
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import eu.darken.octi.common.debug.logging.logTag
import eu.darken.octi.common.navigation.navArgs
import eu.darken.octi.common.uix.ViewModel3
import eu.darken.octi.sync.core.getConnectorById
import eu.darken.octi.syncs.gdrive.core.GDriveAppDataConnector
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.map
import javax.inject.Inject
Expand All @@ -25,16 +26,14 @@ class GDriveActionsVM @Inject constructor(
val account: eu.darken.octi.syncs.gdrive.core.GoogleAccount
)

val state =
syncManager.getConnectorById<eu.darken.octi.syncs.gdrive.core.GDriveAppDataConnector>(navArgs.identifier)
.map {
State(it.account)
}
.catch {
if (it is NoSuchElementException) popNavStack()
else throw it
}
.asLiveData2()
val state = syncManager.getConnectorById<GDriveAppDataConnector>(navArgs.identifier)
.map {
State(it.account)
}
.catch {
if (it is NoSuchElementException) popNavStack() else throw it
}
.asLiveData2()

fun disconnct() = launch {
log(TAG) { "disconnct()" }
Expand Down
18 changes: 16 additions & 2 deletions sync-core/src/main/java/eu/darken/octi/sync/core/SyncManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,21 @@ import eu.darken.octi.common.debug.logging.logTag
import eu.darken.octi.common.flow.setupCommonEventHandlers
import eu.darken.octi.common.flow.shareLatest
import eu.darken.octi.sync.core.cache.SyncCache
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.joinAll
import kotlinx.coroutines.launch
import kotlinx.coroutines.plus
import kotlinx.coroutines.withContext
import javax.inject.Inject
import javax.inject.Singleton

Expand Down Expand Up @@ -128,6 +141,7 @@ class SyncManager @Inject constructor(
}
} catch (e: Exception) {
log(TAG, ERROR) { "disconnect($identifier) failed: ${e.asLog()}" }
throw e
} finally {
disabledConnectors.value -= connector
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package eu.darken.octi.syncs.gdrive.core

import com.google.android.gms.auth.UserRecoverableAuthException
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException
import eu.darken.octi.common.coroutine.AppScope
import eu.darken.octi.common.coroutine.DispatcherProvider
import eu.darken.octi.common.debug.logging.Logging.Priority.ERROR
import eu.darken.octi.common.debug.logging.asLog
import eu.darken.octi.common.debug.logging.log
import eu.darken.octi.common.debug.logging.logTag
import eu.darken.octi.common.flow.setupCommonEventHandlers
import eu.darken.octi.common.flow.shareLatest
import eu.darken.octi.sync.core.ConnectorHub
import eu.darken.octi.sync.core.ConnectorId
import eu.darken.octi.sync.core.SyncConnector
import eu.darken.octi.sync.core.SyncSettings
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.NonCancellable
Expand Down Expand Up @@ -36,7 +40,7 @@ class GDriveHub @Inject constructor(
.setupCommonEventHandlers(TAG) { "connectors" }
.shareLatest(scope + dispatcherProvider.Default)

override val connectors: Flow<Collection<eu.darken.octi.sync.core.SyncConnector>> = _connectors
override val connectors: Flow<Collection<SyncConnector>> = _connectors

override suspend fun owns(connectorId: ConnectorId): Boolean {
return _connectors.first().any { it.identifier == connectorId }
Expand All @@ -46,9 +50,12 @@ class GDriveHub @Inject constructor(
log(TAG) { "remove(id=$connectorId)" }
val connector = _connectors.first().single { it.identifier == connectorId }
try {
throw UserRecoverableAuthIOException(UserRecoverableAuthException("", null))
connector.deleteDevice(syncSettings.deviceId)
} catch (e: UserRecoverableAuthIOException) {
// User was locked out
log(TAG, ERROR) { "Failed to delete device, access was locked out:\n${e.asLog()}" }
throw UserLockedOutException(e)
}
accountRepo.remove(connector.account.id)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package eu.darken.octi.syncs.gdrive.core

import android.content.Context
import eu.darken.octi.common.error.HasLocalizedError
import eu.darken.octi.common.error.LocalizedError
import eu.darken.octi.syncs.gdrive.R

class UserLockedOutException(
cause: Exception,
) : IllegalStateException(cause), HasLocalizedError {
override fun getLocalizedError(context: Context): LocalizedError = LocalizedError(
throwable = this,
label = context.getString(R.string.gdrive_account_lockout_error_label),
description = context.getString(R.string.gdrive_account_lockout_error_description)
)
}
2 changes: 2 additions & 0 deletions syncs-gdrive/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<resources>
<string name="gdrive_account_scope_error_label">Permission error</string>
<string name="gdrive_account_scope_error_description">Octi has not been granted the required access scope. Try again and check that permissions are being granted.</string>
<string name="gdrive_account_lockout_error_label">Lock out error</string>
<string name="gdrive_account_lockout_error_description">This device is locked out and can\'t access Google Drive anymore. It\'s access to your Google account has been revoked. Re-grant access and try again.</string>
</resources>

0 comments on commit afe3115

Please sign in to comment.